huangcm
2025-02-24 69ed55dec4b2116a19e4cca4393cbc014fce5fb2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * Copyright 2017 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
 
#include "cros_gralloc_buffer.h"
 
#include <assert.h>
#include <sys/mman.h>
 
cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo,
                    struct cros_gralloc_handle *acquire_handle)
    : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0)
{
   assert(bo_);
   num_planes_ = drv_bo_get_num_planes(bo_);
   for (uint32_t plane = 0; plane < num_planes_; plane++)
       lock_data_[plane] = nullptr;
}
 
cros_gralloc_buffer::~cros_gralloc_buffer()
{
   drv_bo_destroy(bo_);
   if (hnd_) {
       native_handle_close(&hnd_->base);
       delete hnd_;
   }
}
 
uint32_t cros_gralloc_buffer::get_id() const
{
   return id_;
}
 
int32_t cros_gralloc_buffer::increase_refcount()
{
   return ++refcount_;
}
 
int32_t cros_gralloc_buffer::decrease_refcount()
{
   assert(refcount_ > 0);
   return --refcount_;
}
 
int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_flags,
                 uint8_t *addr[DRV_MAX_PLANES])
{
   void *vaddr = nullptr;
 
   memset(addr, 0, DRV_MAX_PLANES * sizeof(*addr));
 
   /*
    * Gralloc consumers don't support more than one kernel buffer per buffer object yet, so
    * just use the first kernel buffer.
    */
   if (drv_num_buffers_per_bo(bo_) != 1) {
       drv_log("Can only support one buffer per bo.\n");
       return -EINVAL;
   }
 
   if (map_flags) {
       if (lock_data_[0]) {
           drv_bo_invalidate(bo_, lock_data_[0]);
           vaddr = lock_data_[0]->vma->addr;
       } else {
           vaddr = drv_bo_map(bo_, rect, map_flags, &lock_data_[0], 0);
       }
 
       if (vaddr == MAP_FAILED) {
           drv_log("Mapping failed.\n");
           return -EFAULT;
       }
   }
 
   for (uint32_t plane = 0; plane < num_planes_; plane++)
       addr[plane] = static_cast<uint8_t *>(vaddr) + drv_bo_get_plane_offset(bo_, plane);
 
   lockcount_++;
   return 0;
}
 
int32_t cros_gralloc_buffer::unlock()
{
   if (lockcount_ <= 0) {
       drv_log("Buffer was not locked.\n");
       return -EINVAL;
   }
 
   if (!--lockcount_) {
       if (lock_data_[0]) {
           drv_bo_flush_or_unmap(bo_, lock_data_[0]);
           lock_data_[0] = nullptr;
       }
   }
 
   return 0;
}