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.
7 #include "cros_gralloc_buffer.h"
12 cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo,
13 struct cros_gralloc_handle *acquire_handle,
14 int32_t reserved_region_fd, uint64_t reserved_region_size)
15 : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0),
16 reserved_region_fd_(reserved_region_fd), reserved_region_size_(reserved_region_size),
17 reserved_region_addr_(nullptr)
20 num_planes_ = drv_bo_get_num_planes(bo_);
21 for (uint32_t plane = 0; plane < num_planes_; plane++)
22 lock_data_[plane] = nullptr;
25 cros_gralloc_buffer::~cros_gralloc_buffer()
29 native_handle_close(&hnd_->base);
32 if (reserved_region_addr_) {
33 munmap(reserved_region_addr_, reserved_region_size_);
37 uint32_t cros_gralloc_buffer::get_id() const
42 int32_t cros_gralloc_buffer::increase_refcount()
47 int32_t cros_gralloc_buffer::decrease_refcount()
49 assert(refcount_ > 0);
53 int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_flags,
54 uint8_t *addr[DRV_MAX_PLANES])
56 void *vaddr = nullptr;
58 memset(addr, 0, DRV_MAX_PLANES * sizeof(*addr));
61 * Gralloc consumers don't support more than one kernel buffer per buffer object yet, so
62 * just use the first kernel buffer.
64 if (drv_num_buffers_per_bo(bo_) != 1) {
65 drv_log("Can only support one buffer per bo.\n");
71 drv_bo_invalidate(bo_, lock_data_[0]);
72 vaddr = lock_data_[0]->vma->addr;
74 struct rectangle r = *rect;
76 if (!r.width && !r.height && !r.x && !r.y) {
78 * Android IMapper.hal: An accessRegion of all-zeros means the
81 r.width = drv_bo_get_width(bo_);
82 r.height = drv_bo_get_height(bo_);
85 vaddr = drv_bo_map(bo_, &r, map_flags, &lock_data_[0], 0);
88 if (vaddr == MAP_FAILED) {
89 drv_log("Mapping failed.\n");
94 for (uint32_t plane = 0; plane < num_planes_; plane++)
95 addr[plane] = static_cast<uint8_t *>(vaddr) + drv_bo_get_plane_offset(bo_, plane);
101 int32_t cros_gralloc_buffer::unlock()
103 if (lockcount_ <= 0) {
104 drv_log("Buffer was not locked.\n");
110 drv_bo_flush_or_unmap(bo_, lock_data_[0]);
111 lock_data_[0] = nullptr;
118 int32_t cros_gralloc_buffer::resource_info(uint32_t strides[DRV_MAX_PLANES],
119 uint32_t offsets[DRV_MAX_PLANES])
121 return drv_resource_info(bo_, strides, offsets);
124 int32_t cros_gralloc_buffer::invalidate()
126 if (lockcount_ <= 0) {
127 drv_log("Buffer was not locked.\n");
132 return drv_bo_invalidate(bo_, lock_data_[0]);
138 int32_t cros_gralloc_buffer::flush()
140 if (lockcount_ <= 0) {
141 drv_log("Buffer was not locked.\n");
146 return drv_bo_flush(bo_, lock_data_[0]);
152 int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size)
154 if (reserved_region_fd_ <= 0) {
155 drv_log("Buffer does not have reserved region.\n");
159 if (!reserved_region_addr_) {
160 reserved_region_addr_ = mmap(nullptr, reserved_region_size_, PROT_WRITE | PROT_READ,
161 MAP_SHARED, reserved_region_fd_, 0);
162 if (reserved_region_addr_ == MAP_FAILED) {
163 drv_log("Failed to mmap reserved region: %s.\n", strerror(errno));
168 *addr = reserved_region_addr_;
169 *size = reserved_region_size_;