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
cros_gralloc_buffer(uint32_t id,struct bo * acquire_bo,struct cros_gralloc_handle * acquire_handle)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
~cros_gralloc_buffer()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
get_id() const31 uint32_t cros_gralloc_buffer::get_id() const
32 {
33 return id_;
34 }
35
increase_refcount()36 int32_t cros_gralloc_buffer::increase_refcount()
37 {
38 return ++refcount_;
39 }
40
decrease_refcount()41 int32_t cros_gralloc_buffer::decrease_refcount()
42 {
43 assert(refcount_ > 0);
44 return --refcount_;
45 }
46
lock(const struct rectangle * rect,uint32_t map_flags,uint8_t * addr[DRV_MAX_PLANES])47 int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_flags,
48 uint8_t *addr[DRV_MAX_PLANES])
49 {
50 void *vaddr = nullptr;
51
52 memset(addr, 0, DRV_MAX_PLANES * sizeof(*addr));
53
54 /*
55 * Gralloc consumers don't support more than one kernel buffer per buffer object yet, so
56 * just use the first kernel buffer.
57 */
58 if (drv_num_buffers_per_bo(bo_) != 1) {
59 drv_log("Can only support one buffer per bo.\n");
60 return -EINVAL;
61 }
62
63 if (map_flags) {
64 if (lock_data_[0]) {
65 drv_bo_invalidate(bo_, lock_data_[0]);
66 vaddr = lock_data_[0]->vma->addr;
67 } else {
68 vaddr = drv_bo_map(bo_, rect, map_flags, &lock_data_[0], 0);
69 }
70
71 if (vaddr == MAP_FAILED) {
72 drv_log("Mapping failed.\n");
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
unlock()84 int32_t cros_gralloc_buffer::unlock()
85 {
86 if (lockcount_ <= 0) {
87 drv_log("Buffer was not locked.\n");
88 return -EINVAL;
89 }
90
91 if (!--lockcount_) {
92 if (lock_data_[0]) {
93 drv_bo_flush_or_unmap(bo_, lock_data_[0]);
94 lock_data_[0] = nullptr;
95 }
96 }
97
98 return 0;
99 }
100