OSDN Git Service

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