• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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