xref: /aosp_15_r20/external/minigbm/cros_gralloc/cros_gralloc_driver.cc (revision d95af8df99a05bcb8679a54dc3ab8e5cd312b38e)
1*d95af8dfSAndroid Build Coastguard Worker /*
2*d95af8dfSAndroid Build Coastguard Worker  * Copyright 2017 The Chromium OS Authors. All rights reserved.
3*d95af8dfSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
4*d95af8dfSAndroid Build Coastguard Worker  * found in the LICENSE file.
5*d95af8dfSAndroid Build Coastguard Worker  */
6*d95af8dfSAndroid Build Coastguard Worker 
7*d95af8dfSAndroid Build Coastguard Worker #include "cros_gralloc_driver.h"
8*d95af8dfSAndroid Build Coastguard Worker 
9*d95af8dfSAndroid Build Coastguard Worker #include <cstdlib>
10*d95af8dfSAndroid Build Coastguard Worker #include <cutils/properties.h>
11*d95af8dfSAndroid Build Coastguard Worker #include <fcntl.h>
12*d95af8dfSAndroid Build Coastguard Worker #include <hardware/gralloc.h>
13*d95af8dfSAndroid Build Coastguard Worker #include <sys/mman.h>
14*d95af8dfSAndroid Build Coastguard Worker #include <syscall.h>
15*d95af8dfSAndroid Build Coastguard Worker #include <xf86drm.h>
16*d95af8dfSAndroid Build Coastguard Worker 
17*d95af8dfSAndroid Build Coastguard Worker #include "../drv_helpers.h"
18*d95af8dfSAndroid Build Coastguard Worker #include "../drv_priv.h"
19*d95af8dfSAndroid Build Coastguard Worker #include "../util.h"
20*d95af8dfSAndroid Build Coastguard Worker #include "cros_gralloc_buffer_metadata.h"
21*d95af8dfSAndroid Build Coastguard Worker 
22*d95af8dfSAndroid Build Coastguard Worker // Constants taken from pipe_loader_drm.c in Mesa
23*d95af8dfSAndroid Build Coastguard Worker 
24*d95af8dfSAndroid Build Coastguard Worker #define DRM_NUM_NODES 63
25*d95af8dfSAndroid Build Coastguard Worker 
26*d95af8dfSAndroid Build Coastguard Worker // DRM Render nodes start at 128
27*d95af8dfSAndroid Build Coastguard Worker #define DRM_RENDER_NODE_START 128
28*d95af8dfSAndroid Build Coastguard Worker 
29*d95af8dfSAndroid Build Coastguard Worker // DRM Card nodes start at 0
30*d95af8dfSAndroid Build Coastguard Worker #define DRM_CARD_NODE_START 0
31*d95af8dfSAndroid Build Coastguard Worker 
32*d95af8dfSAndroid Build Coastguard Worker class cros_gralloc_driver_preloader
33*d95af8dfSAndroid Build Coastguard Worker {
34*d95af8dfSAndroid Build Coastguard Worker       public:
cros_gralloc_driver_preloader()35*d95af8dfSAndroid Build Coastguard Worker 	cros_gralloc_driver_preloader()
36*d95af8dfSAndroid Build Coastguard Worker 	{
37*d95af8dfSAndroid Build Coastguard Worker 		drv_preload(true);
38*d95af8dfSAndroid Build Coastguard Worker 	}
39*d95af8dfSAndroid Build Coastguard Worker 
~cros_gralloc_driver_preloader()40*d95af8dfSAndroid Build Coastguard Worker 	~cros_gralloc_driver_preloader()
41*d95af8dfSAndroid Build Coastguard Worker 	{
42*d95af8dfSAndroid Build Coastguard Worker 		drv_preload(false);
43*d95af8dfSAndroid Build Coastguard Worker 	}
44*d95af8dfSAndroid Build Coastguard Worker };
45*d95af8dfSAndroid Build Coastguard Worker 
46*d95af8dfSAndroid Build Coastguard Worker static class cros_gralloc_driver_preloader cros_gralloc_driver_preloader;
47*d95af8dfSAndroid Build Coastguard Worker 
memfd_create_wrapper(const char * name,unsigned int flags)48*d95af8dfSAndroid Build Coastguard Worker int memfd_create_wrapper(const char *name, unsigned int flags)
49*d95af8dfSAndroid Build Coastguard Worker {
50*d95af8dfSAndroid Build Coastguard Worker 	int fd;
51*d95af8dfSAndroid Build Coastguard Worker 
52*d95af8dfSAndroid Build Coastguard Worker #if defined(HAVE_MEMFD_CREATE)
53*d95af8dfSAndroid Build Coastguard Worker 	fd = memfd_create(name, flags);
54*d95af8dfSAndroid Build Coastguard Worker #elif defined(__NR_memfd_create)
55*d95af8dfSAndroid Build Coastguard Worker 	fd = syscall(__NR_memfd_create, name, flags);
56*d95af8dfSAndroid Build Coastguard Worker #else
57*d95af8dfSAndroid Build Coastguard Worker 	ALOGE("Failed to create memfd '%s': memfd_create not available.", name);
58*d95af8dfSAndroid Build Coastguard Worker 	return -1;
59*d95af8dfSAndroid Build Coastguard Worker #endif
60*d95af8dfSAndroid Build Coastguard Worker 
61*d95af8dfSAndroid Build Coastguard Worker 	if (fd == -1)
62*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Failed to create memfd '%s': %s.", name, strerror(errno));
63*d95af8dfSAndroid Build Coastguard Worker 
64*d95af8dfSAndroid Build Coastguard Worker 	return fd;
65*d95af8dfSAndroid Build Coastguard Worker }
66*d95af8dfSAndroid Build Coastguard Worker 
memfd_create_reserved_region(const std::string & buffer_name,uint64_t reserved_region_size)67*d95af8dfSAndroid Build Coastguard Worker int memfd_create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size)
68*d95af8dfSAndroid Build Coastguard Worker {
69*d95af8dfSAndroid Build Coastguard Worker 	const std::string reserved_region_name = buffer_name + " reserved region";
70*d95af8dfSAndroid Build Coastguard Worker 
71*d95af8dfSAndroid Build Coastguard Worker 	int reserved_region_fd = memfd_create_wrapper(reserved_region_name.c_str(), FD_CLOEXEC);
72*d95af8dfSAndroid Build Coastguard Worker 	if (reserved_region_fd == -1)
73*d95af8dfSAndroid Build Coastguard Worker 		return -errno;
74*d95af8dfSAndroid Build Coastguard Worker 
75*d95af8dfSAndroid Build Coastguard Worker 	if (ftruncate(reserved_region_fd, reserved_region_size)) {
76*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Failed to set reserved region size: %s.", strerror(errno));
77*d95af8dfSAndroid Build Coastguard Worker 		return -errno;
78*d95af8dfSAndroid Build Coastguard Worker 	}
79*d95af8dfSAndroid Build Coastguard Worker 
80*d95af8dfSAndroid Build Coastguard Worker 	return reserved_region_fd;
81*d95af8dfSAndroid Build Coastguard Worker }
82*d95af8dfSAndroid Build Coastguard Worker 
get_instance()83*d95af8dfSAndroid Build Coastguard Worker std::shared_ptr<cros_gralloc_driver> cros_gralloc_driver::get_instance()
84*d95af8dfSAndroid Build Coastguard Worker {
85*d95af8dfSAndroid Build Coastguard Worker 	static std::shared_ptr<cros_gralloc_driver> s_instance = []() {
86*d95af8dfSAndroid Build Coastguard Worker 		return std::shared_ptr<cros_gralloc_driver>(new cros_gralloc_driver());
87*d95af8dfSAndroid Build Coastguard Worker 	}();
88*d95af8dfSAndroid Build Coastguard Worker 
89*d95af8dfSAndroid Build Coastguard Worker 	if (!s_instance->is_initialized()) {
90*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Failed to initialize driver.");
91*d95af8dfSAndroid Build Coastguard Worker 		return nullptr;
92*d95af8dfSAndroid Build Coastguard Worker 	}
93*d95af8dfSAndroid Build Coastguard Worker 
94*d95af8dfSAndroid Build Coastguard Worker 	return s_instance;
95*d95af8dfSAndroid Build Coastguard Worker }
96*d95af8dfSAndroid Build Coastguard Worker 
init_try_node(int idx,char const * str)97*d95af8dfSAndroid Build Coastguard Worker static struct driver *init_try_node(int idx, char const *str)
98*d95af8dfSAndroid Build Coastguard Worker {
99*d95af8dfSAndroid Build Coastguard Worker 	int fd;
100*d95af8dfSAndroid Build Coastguard Worker 	char *node;
101*d95af8dfSAndroid Build Coastguard Worker 	struct driver *drv;
102*d95af8dfSAndroid Build Coastguard Worker 
103*d95af8dfSAndroid Build Coastguard Worker 	if (asprintf(&node, str, DRM_DIR_NAME, idx) < 0)
104*d95af8dfSAndroid Build Coastguard Worker 		return NULL;
105*d95af8dfSAndroid Build Coastguard Worker 
106*d95af8dfSAndroid Build Coastguard Worker 	fd = open(node, O_RDWR, 0);
107*d95af8dfSAndroid Build Coastguard Worker 	free(node);
108*d95af8dfSAndroid Build Coastguard Worker 
109*d95af8dfSAndroid Build Coastguard Worker 	if (fd < 0)
110*d95af8dfSAndroid Build Coastguard Worker 		return NULL;
111*d95af8dfSAndroid Build Coastguard Worker 
112*d95af8dfSAndroid Build Coastguard Worker 	drv = drv_create(fd);
113*d95af8dfSAndroid Build Coastguard Worker 	if (!drv)
114*d95af8dfSAndroid Build Coastguard Worker 		close(fd);
115*d95af8dfSAndroid Build Coastguard Worker 
116*d95af8dfSAndroid Build Coastguard Worker 	return drv;
117*d95af8dfSAndroid Build Coastguard Worker }
118*d95af8dfSAndroid Build Coastguard Worker 
init_try_nodes()119*d95af8dfSAndroid Build Coastguard Worker static struct driver *init_try_nodes()
120*d95af8dfSAndroid Build Coastguard Worker {
121*d95af8dfSAndroid Build Coastguard Worker 	/*
122*d95af8dfSAndroid Build Coastguard Worker 	 * Create a driver from render nodes first, then try card
123*d95af8dfSAndroid Build Coastguard Worker 	 * nodes.
124*d95af8dfSAndroid Build Coastguard Worker 	 *
125*d95af8dfSAndroid Build Coastguard Worker 	 * TODO(gsingh): Enable render nodes on udl/evdi.
126*d95af8dfSAndroid Build Coastguard Worker 	 */
127*d95af8dfSAndroid Build Coastguard Worker 
128*d95af8dfSAndroid Build Coastguard Worker 	struct driver *drv;
129*d95af8dfSAndroid Build Coastguard Worker 	char const *render_nodes_fmt = "%s/renderD%d";
130*d95af8dfSAndroid Build Coastguard Worker 	char const *card_nodes_fmt = "%s/card%d";
131*d95af8dfSAndroid Build Coastguard Worker 	uint32_t num_nodes = DRM_NUM_NODES;
132*d95af8dfSAndroid Build Coastguard Worker 	uint32_t min_render_node = DRM_RENDER_NODE_START;
133*d95af8dfSAndroid Build Coastguard Worker 	uint32_t max_render_node = (min_render_node + num_nodes);
134*d95af8dfSAndroid Build Coastguard Worker 	uint32_t min_card_node = DRM_CARD_NODE_START;
135*d95af8dfSAndroid Build Coastguard Worker 	uint32_t max_card_node = (min_card_node + num_nodes);
136*d95af8dfSAndroid Build Coastguard Worker 
137*d95af8dfSAndroid Build Coastguard Worker 	// Try render nodes...
138*d95af8dfSAndroid Build Coastguard Worker 	for (uint32_t i = min_render_node; i < max_render_node; i++) {
139*d95af8dfSAndroid Build Coastguard Worker 		drv = init_try_node(i, render_nodes_fmt);
140*d95af8dfSAndroid Build Coastguard Worker 		if (drv)
141*d95af8dfSAndroid Build Coastguard Worker 			return drv;
142*d95af8dfSAndroid Build Coastguard Worker 	}
143*d95af8dfSAndroid Build Coastguard Worker 
144*d95af8dfSAndroid Build Coastguard Worker 	// Try card nodes... for vkms mostly.
145*d95af8dfSAndroid Build Coastguard Worker 	for (uint32_t i = min_card_node; i < max_card_node; i++) {
146*d95af8dfSAndroid Build Coastguard Worker 		drv = init_try_node(i, card_nodes_fmt);
147*d95af8dfSAndroid Build Coastguard Worker 		if (drv)
148*d95af8dfSAndroid Build Coastguard Worker 			return drv;
149*d95af8dfSAndroid Build Coastguard Worker 	}
150*d95af8dfSAndroid Build Coastguard Worker 
151*d95af8dfSAndroid Build Coastguard Worker 	return nullptr;
152*d95af8dfSAndroid Build Coastguard Worker }
153*d95af8dfSAndroid Build Coastguard Worker 
drv_destroy_and_close(struct driver * drv)154*d95af8dfSAndroid Build Coastguard Worker static void drv_destroy_and_close(struct driver *drv)
155*d95af8dfSAndroid Build Coastguard Worker {
156*d95af8dfSAndroid Build Coastguard Worker 	int fd = drv_get_fd(drv);
157*d95af8dfSAndroid Build Coastguard Worker 	drv_destroy(drv);
158*d95af8dfSAndroid Build Coastguard Worker 	close(fd);
159*d95af8dfSAndroid Build Coastguard Worker }
160*d95af8dfSAndroid Build Coastguard Worker 
is_running_with_software_rendering()161*d95af8dfSAndroid Build Coastguard Worker static bool is_running_with_software_rendering()
162*d95af8dfSAndroid Build Coastguard Worker {
163*d95af8dfSAndroid Build Coastguard Worker 	const char *vulkan_driver = drv_get_os_option("ro.hardware.vulkan");
164*d95af8dfSAndroid Build Coastguard Worker 	return (vulkan_driver != nullptr && strstr(vulkan_driver, "pastel") != nullptr);
165*d95af8dfSAndroid Build Coastguard Worker }
166*d95af8dfSAndroid Build Coastguard Worker 
cros_gralloc_driver()167*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_driver::cros_gralloc_driver()
168*d95af8dfSAndroid Build Coastguard Worker     : drv_(init_try_nodes(), drv_destroy_and_close),
169*d95af8dfSAndroid Build Coastguard Worker       is_running_with_software_rendering_(is_running_with_software_rendering())
170*d95af8dfSAndroid Build Coastguard Worker {
171*d95af8dfSAndroid Build Coastguard Worker }
172*d95af8dfSAndroid Build Coastguard Worker 
~cros_gralloc_driver()173*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_driver::~cros_gralloc_driver()
174*d95af8dfSAndroid Build Coastguard Worker {
175*d95af8dfSAndroid Build Coastguard Worker 	buffers_.clear();
176*d95af8dfSAndroid Build Coastguard Worker 	handles_.clear();
177*d95af8dfSAndroid Build Coastguard Worker }
178*d95af8dfSAndroid Build Coastguard Worker 
is_initialized()179*d95af8dfSAndroid Build Coastguard Worker bool cros_gralloc_driver::is_initialized()
180*d95af8dfSAndroid Build Coastguard Worker {
181*d95af8dfSAndroid Build Coastguard Worker 	return drv_ != nullptr;
182*d95af8dfSAndroid Build Coastguard Worker }
183*d95af8dfSAndroid Build Coastguard Worker 
get_resolved_format_and_use_flags(const struct cros_gralloc_buffer_descriptor * descriptor,uint32_t * out_format,uint64_t * out_use_flags)184*d95af8dfSAndroid Build Coastguard Worker bool cros_gralloc_driver::get_resolved_format_and_use_flags(
185*d95af8dfSAndroid Build Coastguard Worker     const struct cros_gralloc_buffer_descriptor *descriptor, uint32_t *out_format,
186*d95af8dfSAndroid Build Coastguard Worker     uint64_t *out_use_flags)
187*d95af8dfSAndroid Build Coastguard Worker {
188*d95af8dfSAndroid Build Coastguard Worker 	uint32_t resolved_format;
189*d95af8dfSAndroid Build Coastguard Worker 	uint64_t resolved_use_flags;
190*d95af8dfSAndroid Build Coastguard Worker 	struct combination *combo;
191*d95af8dfSAndroid Build Coastguard Worker 
192*d95af8dfSAndroid Build Coastguard Worker 	uint64_t use_flags = descriptor->use_flags;
193*d95af8dfSAndroid Build Coastguard Worker 	if (is_running_with_software_rendering_ && (use_flags & BO_USE_GPU_HW) != 0) {
194*d95af8dfSAndroid Build Coastguard Worker 		use_flags |= (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN);
195*d95af8dfSAndroid Build Coastguard Worker 	}
196*d95af8dfSAndroid Build Coastguard Worker 
197*d95af8dfSAndroid Build Coastguard Worker 	drv_resolve_format_and_use_flags(drv_.get(), descriptor->drm_format, descriptor->use_flags,
198*d95af8dfSAndroid Build Coastguard Worker 					 &resolved_format, &resolved_use_flags);
199*d95af8dfSAndroid Build Coastguard Worker 
200*d95af8dfSAndroid Build Coastguard Worker 	combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
201*d95af8dfSAndroid Build Coastguard Worker 	if (!combo && (descriptor->droid_usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
202*d95af8dfSAndroid Build Coastguard Worker 	    descriptor->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
203*d95af8dfSAndroid Build Coastguard Worker 		// Unmask BO_USE_HW_VIDEO_ENCODER for other formats. They are mostly
204*d95af8dfSAndroid Build Coastguard Worker 		// intermediate formats not passed directly to the encoder (e.g.
205*d95af8dfSAndroid Build Coastguard Worker 		// camera). YV12 is passed to the encoder component, but it is converted
206*d95af8dfSAndroid Build Coastguard Worker 		// to YCbCr_420_888 before being passed to the hw encoder.
207*d95af8dfSAndroid Build Coastguard Worker 		resolved_use_flags &= ~BO_USE_HW_VIDEO_ENCODER;
208*d95af8dfSAndroid Build Coastguard Worker 		combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
209*d95af8dfSAndroid Build Coastguard Worker 	}
210*d95af8dfSAndroid Build Coastguard Worker 	if (!combo && (descriptor->droid_usage & BUFFER_USAGE_FRONT_RENDERING_MASK)) {
211*d95af8dfSAndroid Build Coastguard Worker 		resolved_use_flags &= ~BO_USE_FRONT_RENDERING;
212*d95af8dfSAndroid Build Coastguard Worker 		resolved_use_flags |= BO_USE_LINEAR;
213*d95af8dfSAndroid Build Coastguard Worker 		combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
214*d95af8dfSAndroid Build Coastguard Worker 	}
215*d95af8dfSAndroid Build Coastguard Worker 	if (!combo)
216*d95af8dfSAndroid Build Coastguard Worker 		return false;
217*d95af8dfSAndroid Build Coastguard Worker 
218*d95af8dfSAndroid Build Coastguard Worker 	*out_format = resolved_format;
219*d95af8dfSAndroid Build Coastguard Worker 	*out_use_flags = resolved_use_flags;
220*d95af8dfSAndroid Build Coastguard Worker 	return true;
221*d95af8dfSAndroid Build Coastguard Worker }
222*d95af8dfSAndroid Build Coastguard Worker 
is_supported(const struct cros_gralloc_buffer_descriptor * descriptor)223*d95af8dfSAndroid Build Coastguard Worker bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor)
224*d95af8dfSAndroid Build Coastguard Worker {
225*d95af8dfSAndroid Build Coastguard Worker 	uint32_t resolved_format;
226*d95af8dfSAndroid Build Coastguard Worker 	uint64_t resolved_use_flags;
227*d95af8dfSAndroid Build Coastguard Worker 	uint32_t max_texture_size = drv_get_max_texture_2d_size(drv_.get());
228*d95af8dfSAndroid Build Coastguard Worker 	if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags))
229*d95af8dfSAndroid Build Coastguard Worker 		return false;
230*d95af8dfSAndroid Build Coastguard Worker 
231*d95af8dfSAndroid Build Coastguard Worker 	// Allow blob buffers to go beyond the limit.
232*d95af8dfSAndroid Build Coastguard Worker 	if (descriptor->droid_format == HAL_PIXEL_FORMAT_BLOB)
233*d95af8dfSAndroid Build Coastguard Worker 		return true;
234*d95af8dfSAndroid Build Coastguard Worker 
235*d95af8dfSAndroid Build Coastguard Worker 	return descriptor->width <= max_texture_size && descriptor->height <= max_texture_size;
236*d95af8dfSAndroid Build Coastguard Worker }
237*d95af8dfSAndroid Build Coastguard Worker 
create_reserved_region(const std::string & buffer_name,uint64_t reserved_region_size)238*d95af8dfSAndroid Build Coastguard Worker int cros_gralloc_driver::create_reserved_region(const std::string &buffer_name,
239*d95af8dfSAndroid Build Coastguard Worker 						uint64_t reserved_region_size)
240*d95af8dfSAndroid Build Coastguard Worker {
241*d95af8dfSAndroid Build Coastguard Worker 	int ret;
242*d95af8dfSAndroid Build Coastguard Worker 
243*d95af8dfSAndroid Build Coastguard Worker #if ANDROID_API_LEVEL >= 31 && defined(HAS_DMABUF_SYSTEM_HEAP)
244*d95af8dfSAndroid Build Coastguard Worker 	ret = allocator_.Alloc(kDmabufSystemHeapName, reserved_region_size);
245*d95af8dfSAndroid Build Coastguard Worker 	if (ret >= 0)
246*d95af8dfSAndroid Build Coastguard Worker 		return ret;
247*d95af8dfSAndroid Build Coastguard Worker #endif
248*d95af8dfSAndroid Build Coastguard Worker 
249*d95af8dfSAndroid Build Coastguard Worker 	ret = memfd_create_reserved_region(buffer_name, reserved_region_size);
250*d95af8dfSAndroid Build Coastguard Worker 	if (ret >= 0)
251*d95af8dfSAndroid Build Coastguard Worker 		return ret;
252*d95af8dfSAndroid Build Coastguard Worker 
253*d95af8dfSAndroid Build Coastguard Worker 	ALOGE("Failed to create_reserved_region.");
254*d95af8dfSAndroid Build Coastguard Worker 	return -1;
255*d95af8dfSAndroid Build Coastguard Worker }
256*d95af8dfSAndroid Build Coastguard Worker 
allocate(const struct cros_gralloc_buffer_descriptor * descriptor,native_handle_t ** out_handle)257*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor,
258*d95af8dfSAndroid Build Coastguard Worker 				      native_handle_t **out_handle)
259*d95af8dfSAndroid Build Coastguard Worker {
260*d95af8dfSAndroid Build Coastguard Worker 	int ret = 0;
261*d95af8dfSAndroid Build Coastguard Worker 	size_t num_planes;
262*d95af8dfSAndroid Build Coastguard Worker 	size_t num_fds;
263*d95af8dfSAndroid Build Coastguard Worker 	size_t num_ints;
264*d95af8dfSAndroid Build Coastguard Worker 	uint32_t resolved_format;
265*d95af8dfSAndroid Build Coastguard Worker 	uint32_t bytes_per_pixel;
266*d95af8dfSAndroid Build Coastguard Worker 	uint64_t resolved_use_flags;
267*d95af8dfSAndroid Build Coastguard Worker 	struct bo *bo;
268*d95af8dfSAndroid Build Coastguard Worker 	struct cros_gralloc_handle *hnd;
269*d95af8dfSAndroid Build Coastguard Worker 	std::unique_ptr<cros_gralloc_buffer> buffer;
270*d95af8dfSAndroid Build Coastguard Worker 
271*d95af8dfSAndroid Build Coastguard Worker 	if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) {
272*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Failed to resolve format and use_flags.");
273*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
274*d95af8dfSAndroid Build Coastguard Worker 	}
275*d95af8dfSAndroid Build Coastguard Worker 
276*d95af8dfSAndroid Build Coastguard Worker 	bo = drv_bo_create(drv_.get(), descriptor->width, descriptor->height, resolved_format,
277*d95af8dfSAndroid Build Coastguard Worker 			   resolved_use_flags);
278*d95af8dfSAndroid Build Coastguard Worker 	if (!bo) {
279*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Failed to create bo.");
280*d95af8dfSAndroid Build Coastguard Worker 		return -errno;
281*d95af8dfSAndroid Build Coastguard Worker 	}
282*d95af8dfSAndroid Build Coastguard Worker 
283*d95af8dfSAndroid Build Coastguard Worker 	num_planes = drv_bo_get_num_planes(bo);
284*d95af8dfSAndroid Build Coastguard Worker 	num_fds = num_planes;
285*d95af8dfSAndroid Build Coastguard Worker 
286*d95af8dfSAndroid Build Coastguard Worker 	if (descriptor->enable_metadata_fd)
287*d95af8dfSAndroid Build Coastguard Worker 		num_fds += 1;
288*d95af8dfSAndroid Build Coastguard Worker 
289*d95af8dfSAndroid Build Coastguard Worker 	num_ints = ((sizeof(struct cros_gralloc_handle) - sizeof(native_handle_t)) / sizeof(int)) -
290*d95af8dfSAndroid Build Coastguard Worker 		   num_fds;
291*d95af8dfSAndroid Build Coastguard Worker 
292*d95af8dfSAndroid Build Coastguard Worker 	hnd =
293*d95af8dfSAndroid Build Coastguard Worker 	    reinterpret_cast<struct cros_gralloc_handle *>(native_handle_create(num_fds, num_ints));
294*d95af8dfSAndroid Build Coastguard Worker 
295*d95af8dfSAndroid Build Coastguard Worker 	for (size_t i = 0; i < DRV_MAX_FDS; i++)
296*d95af8dfSAndroid Build Coastguard Worker 		hnd->fds[i] = -1;
297*d95af8dfSAndroid Build Coastguard Worker 
298*d95af8dfSAndroid Build Coastguard Worker 	hnd->num_planes = num_planes;
299*d95af8dfSAndroid Build Coastguard Worker 	for (size_t plane = 0; plane < num_planes; plane++) {
300*d95af8dfSAndroid Build Coastguard Worker 		ret = drv_bo_get_plane_fd(bo, plane);
301*d95af8dfSAndroid Build Coastguard Worker 		if (ret < 0)
302*d95af8dfSAndroid Build Coastguard Worker 			goto destroy_hnd;
303*d95af8dfSAndroid Build Coastguard Worker 
304*d95af8dfSAndroid Build Coastguard Worker 		hnd->fds[plane] = ret;
305*d95af8dfSAndroid Build Coastguard Worker 		hnd->strides[plane] = drv_bo_get_plane_stride(bo, plane);
306*d95af8dfSAndroid Build Coastguard Worker 		hnd->offsets[plane] = drv_bo_get_plane_offset(bo, plane);
307*d95af8dfSAndroid Build Coastguard Worker 		hnd->sizes[plane] = drv_bo_get_plane_size(bo, plane);
308*d95af8dfSAndroid Build Coastguard Worker 	}
309*d95af8dfSAndroid Build Coastguard Worker 
310*d95af8dfSAndroid Build Coastguard Worker 	hnd->reserved_region_size = 0;
311*d95af8dfSAndroid Build Coastguard Worker 	if (descriptor->enable_metadata_fd)
312*d95af8dfSAndroid Build Coastguard Worker 		hnd->reserved_region_size =
313*d95af8dfSAndroid Build Coastguard Worker 		    sizeof(struct cros_gralloc_buffer_metadata) + descriptor->client_metadata_size;
314*d95af8dfSAndroid Build Coastguard Worker 
315*d95af8dfSAndroid Build Coastguard Worker 	if (hnd->reserved_region_size > 0) {
316*d95af8dfSAndroid Build Coastguard Worker 		ret = create_reserved_region(descriptor->name, hnd->reserved_region_size);
317*d95af8dfSAndroid Build Coastguard Worker 		if (ret < 0)
318*d95af8dfSAndroid Build Coastguard Worker 			goto destroy_hnd;
319*d95af8dfSAndroid Build Coastguard Worker 
320*d95af8dfSAndroid Build Coastguard Worker 		hnd->fds[hnd->num_planes] = ret;
321*d95af8dfSAndroid Build Coastguard Worker 	}
322*d95af8dfSAndroid Build Coastguard Worker 
323*d95af8dfSAndroid Build Coastguard Worker 	static std::atomic<uint32_t> next_buffer_id{ 1 };
324*d95af8dfSAndroid Build Coastguard Worker 	hnd->id = next_buffer_id++;
325*d95af8dfSAndroid Build Coastguard Worker 	hnd->width = drv_bo_get_width(bo);
326*d95af8dfSAndroid Build Coastguard Worker 	hnd->height = drv_bo_get_height(bo);
327*d95af8dfSAndroid Build Coastguard Worker 	hnd->format = drv_bo_get_format(bo);
328*d95af8dfSAndroid Build Coastguard Worker 	hnd->tiling = drv_bo_get_tiling(bo);
329*d95af8dfSAndroid Build Coastguard Worker 	hnd->format_modifier = drv_bo_get_format_modifier(bo);
330*d95af8dfSAndroid Build Coastguard Worker 	hnd->use_flags = drv_bo_get_use_flags(bo);
331*d95af8dfSAndroid Build Coastguard Worker 	bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0);
332*d95af8dfSAndroid Build Coastguard Worker 	hnd->pixel_stride = DIV_ROUND_UP(hnd->strides[0], bytes_per_pixel);
333*d95af8dfSAndroid Build Coastguard Worker 	hnd->magic = cros_gralloc_magic;
334*d95af8dfSAndroid Build Coastguard Worker 	hnd->droid_format = descriptor->droid_format;
335*d95af8dfSAndroid Build Coastguard Worker 	hnd->usage = descriptor->droid_usage;
336*d95af8dfSAndroid Build Coastguard Worker 	hnd->total_size = hnd->reserved_region_size + drv_bo_get_total_size(bo);
337*d95af8dfSAndroid Build Coastguard Worker 
338*d95af8dfSAndroid Build Coastguard Worker 	buffer = cros_gralloc_buffer::create(bo, hnd);
339*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
340*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Failed to allocate: failed to create cros_gralloc_buffer.");
341*d95af8dfSAndroid Build Coastguard Worker 		ret = -1;
342*d95af8dfSAndroid Build Coastguard Worker 		goto destroy_hnd;
343*d95af8dfSAndroid Build Coastguard Worker 	}
344*d95af8dfSAndroid Build Coastguard Worker 
345*d95af8dfSAndroid Build Coastguard Worker 	ret = buffer->initialize_metadata(descriptor);
346*d95af8dfSAndroid Build Coastguard Worker 	if (ret) {
347*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Failed to allocate: failed to initialize cros_gralloc_buffer metadata.");
348*d95af8dfSAndroid Build Coastguard Worker 		goto destroy_hnd;
349*d95af8dfSAndroid Build Coastguard Worker 	}
350*d95af8dfSAndroid Build Coastguard Worker 
351*d95af8dfSAndroid Build Coastguard Worker 	{
352*d95af8dfSAndroid Build Coastguard Worker 		std::lock_guard<std::mutex> lock(mutex_);
353*d95af8dfSAndroid Build Coastguard Worker 
354*d95af8dfSAndroid Build Coastguard Worker 		struct cros_gralloc_imported_handle_info hnd_info = {
355*d95af8dfSAndroid Build Coastguard Worker 			.buffer = buffer.get(),
356*d95af8dfSAndroid Build Coastguard Worker 			.refcount = 1,
357*d95af8dfSAndroid Build Coastguard Worker 		};
358*d95af8dfSAndroid Build Coastguard Worker 		handles_.emplace(hnd, hnd_info);
359*d95af8dfSAndroid Build Coastguard Worker 		buffers_.emplace(hnd->id, std::move(buffer));
360*d95af8dfSAndroid Build Coastguard Worker 	}
361*d95af8dfSAndroid Build Coastguard Worker 
362*d95af8dfSAndroid Build Coastguard Worker 	*out_handle = hnd;
363*d95af8dfSAndroid Build Coastguard Worker 	return 0;
364*d95af8dfSAndroid Build Coastguard Worker 
365*d95af8dfSAndroid Build Coastguard Worker destroy_hnd:
366*d95af8dfSAndroid Build Coastguard Worker 	native_handle_close(hnd);
367*d95af8dfSAndroid Build Coastguard Worker 	native_handle_delete(hnd);
368*d95af8dfSAndroid Build Coastguard Worker 
369*d95af8dfSAndroid Build Coastguard Worker 	drv_bo_destroy(bo);
370*d95af8dfSAndroid Build Coastguard Worker 	return ret;
371*d95af8dfSAndroid Build Coastguard Worker }
372*d95af8dfSAndroid Build Coastguard Worker 
retain(buffer_handle_t handle)373*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
374*d95af8dfSAndroid Build Coastguard Worker {
375*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
376*d95af8dfSAndroid Build Coastguard Worker 
377*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = cros_gralloc_convert_handle(handle);
378*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd) {
379*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid handle.");
380*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
381*d95af8dfSAndroid Build Coastguard Worker 	}
382*d95af8dfSAndroid Build Coastguard Worker 
383*d95af8dfSAndroid Build Coastguard Worker 	auto hnd_it = handles_.find(hnd);
384*d95af8dfSAndroid Build Coastguard Worker 	if (hnd_it != handles_.end()) {
385*d95af8dfSAndroid Build Coastguard Worker 		// The underlying buffer (as multiple handles can refer to the same buffer)
386*d95af8dfSAndroid Build Coastguard Worker 		// has already been imported into this process and the given handle has
387*d95af8dfSAndroid Build Coastguard Worker 		// already been registered in this process. Increase both the buffer and
388*d95af8dfSAndroid Build Coastguard Worker 		// handle reference count.
389*d95af8dfSAndroid Build Coastguard Worker 		auto &hnd_info = hnd_it->second;
390*d95af8dfSAndroid Build Coastguard Worker 
391*d95af8dfSAndroid Build Coastguard Worker 		hnd_info.buffer->increase_refcount();
392*d95af8dfSAndroid Build Coastguard Worker 		hnd_info.refcount++;
393*d95af8dfSAndroid Build Coastguard Worker 
394*d95af8dfSAndroid Build Coastguard Worker 		return 0;
395*d95af8dfSAndroid Build Coastguard Worker 	}
396*d95af8dfSAndroid Build Coastguard Worker 
397*d95af8dfSAndroid Build Coastguard Worker 	uint32_t id = hnd->id;
398*d95af8dfSAndroid Build Coastguard Worker 
399*d95af8dfSAndroid Build Coastguard Worker 	cros_gralloc_buffer *buffer = nullptr;
400*d95af8dfSAndroid Build Coastguard Worker 
401*d95af8dfSAndroid Build Coastguard Worker 	auto buffer_it = buffers_.find(id);
402*d95af8dfSAndroid Build Coastguard Worker 	if (buffer_it != buffers_.end()) {
403*d95af8dfSAndroid Build Coastguard Worker 		// The underlying buffer (as multiple handles can refer to the same buffer)
404*d95af8dfSAndroid Build Coastguard Worker 		// has already been imported into this process but the given handle has not
405*d95af8dfSAndroid Build Coastguard Worker 		// yet been registered. Increase the buffer reference count (here) and start
406*d95af8dfSAndroid Build Coastguard Worker 		// to track the handle (below).
407*d95af8dfSAndroid Build Coastguard Worker 		buffer = buffer_it->second.get();
408*d95af8dfSAndroid Build Coastguard Worker 		buffer->increase_refcount();
409*d95af8dfSAndroid Build Coastguard Worker 	} else {
410*d95af8dfSAndroid Build Coastguard Worker 		// The underlying buffer has not yet been imported into this process. Import
411*d95af8dfSAndroid Build Coastguard Worker 		// and start to track the buffer (here) and start to track the handle (below).
412*d95af8dfSAndroid Build Coastguard Worker 		struct drv_import_fd_data data = {
413*d95af8dfSAndroid Build Coastguard Worker 			.format_modifier = hnd->format_modifier,
414*d95af8dfSAndroid Build Coastguard Worker 			.width = hnd->width,
415*d95af8dfSAndroid Build Coastguard Worker 			.height = hnd->height,
416*d95af8dfSAndroid Build Coastguard Worker 			.format = hnd->format,
417*d95af8dfSAndroid Build Coastguard Worker 			.tiling = hnd->tiling,
418*d95af8dfSAndroid Build Coastguard Worker 			.use_flags = hnd->use_flags,
419*d95af8dfSAndroid Build Coastguard Worker 		};
420*d95af8dfSAndroid Build Coastguard Worker 		memcpy(data.fds, hnd->fds, sizeof(data.fds));
421*d95af8dfSAndroid Build Coastguard Worker 		memcpy(data.strides, hnd->strides, sizeof(data.strides));
422*d95af8dfSAndroid Build Coastguard Worker 		memcpy(data.offsets, hnd->offsets, sizeof(data.offsets));
423*d95af8dfSAndroid Build Coastguard Worker 
424*d95af8dfSAndroid Build Coastguard Worker 		struct bo *bo = drv_bo_import(drv_.get(), &data);
425*d95af8dfSAndroid Build Coastguard Worker 		if (!bo)
426*d95af8dfSAndroid Build Coastguard Worker 			return -EFAULT;
427*d95af8dfSAndroid Build Coastguard Worker 
428*d95af8dfSAndroid Build Coastguard Worker 		auto scoped_buffer = cros_gralloc_buffer::create(bo, hnd);
429*d95af8dfSAndroid Build Coastguard Worker 		if (!scoped_buffer) {
430*d95af8dfSAndroid Build Coastguard Worker 			ALOGE("Failed to import: failed to create cros_gralloc_buffer.");
431*d95af8dfSAndroid Build Coastguard Worker 			return -1;
432*d95af8dfSAndroid Build Coastguard Worker 		}
433*d95af8dfSAndroid Build Coastguard Worker 		buffer = scoped_buffer.get();
434*d95af8dfSAndroid Build Coastguard Worker 		buffers_.emplace(id, std::move(scoped_buffer));
435*d95af8dfSAndroid Build Coastguard Worker 	}
436*d95af8dfSAndroid Build Coastguard Worker 
437*d95af8dfSAndroid Build Coastguard Worker 	struct cros_gralloc_imported_handle_info hnd_info = {
438*d95af8dfSAndroid Build Coastguard Worker 		.buffer = buffer,
439*d95af8dfSAndroid Build Coastguard Worker 		.refcount = 1,
440*d95af8dfSAndroid Build Coastguard Worker 	};
441*d95af8dfSAndroid Build Coastguard Worker 	handles_.emplace(hnd, hnd_info);
442*d95af8dfSAndroid Build Coastguard Worker 	return 0;
443*d95af8dfSAndroid Build Coastguard Worker }
444*d95af8dfSAndroid Build Coastguard Worker 
release(buffer_handle_t handle)445*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::release(buffer_handle_t handle)
446*d95af8dfSAndroid Build Coastguard Worker {
447*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
448*d95af8dfSAndroid Build Coastguard Worker 
449*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = cros_gralloc_convert_handle(handle);
450*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd) {
451*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid handle.");
452*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
453*d95af8dfSAndroid Build Coastguard Worker 	}
454*d95af8dfSAndroid Build Coastguard Worker 
455*d95af8dfSAndroid Build Coastguard Worker 	auto buffer = get_buffer(hnd);
456*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
457*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid reference (release() called on unregistered handle).");
458*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
459*d95af8dfSAndroid Build Coastguard Worker 	}
460*d95af8dfSAndroid Build Coastguard Worker 
461*d95af8dfSAndroid Build Coastguard Worker 	if (!--handles_[hnd].refcount)
462*d95af8dfSAndroid Build Coastguard Worker 		handles_.erase(hnd);
463*d95af8dfSAndroid Build Coastguard Worker 
464*d95af8dfSAndroid Build Coastguard Worker 	if (buffer->decrease_refcount() == 0) {
465*d95af8dfSAndroid Build Coastguard Worker 		buffers_.erase(buffer->get_id());
466*d95af8dfSAndroid Build Coastguard Worker 	}
467*d95af8dfSAndroid Build Coastguard Worker 
468*d95af8dfSAndroid Build Coastguard Worker 	return 0;
469*d95af8dfSAndroid Build Coastguard Worker }
470*d95af8dfSAndroid Build Coastguard Worker 
lock(buffer_handle_t handle,int32_t acquire_fence,bool close_acquire_fence,const struct rectangle * rect,uint32_t map_flags,uint8_t * addr[DRV_MAX_PLANES])471*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence,
472*d95af8dfSAndroid Build Coastguard Worker 				  bool close_acquire_fence, const struct rectangle *rect,
473*d95af8dfSAndroid Build Coastguard Worker 				  uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES])
474*d95af8dfSAndroid Build Coastguard Worker {
475*d95af8dfSAndroid Build Coastguard Worker 	int32_t ret = cros_gralloc_sync_wait(acquire_fence, close_acquire_fence);
476*d95af8dfSAndroid Build Coastguard Worker 	if (ret)
477*d95af8dfSAndroid Build Coastguard Worker 		return ret;
478*d95af8dfSAndroid Build Coastguard Worker 
479*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
480*d95af8dfSAndroid Build Coastguard Worker 
481*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = cros_gralloc_convert_handle(handle);
482*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd) {
483*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid handle.");
484*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
485*d95af8dfSAndroid Build Coastguard Worker 	}
486*d95af8dfSAndroid Build Coastguard Worker 
487*d95af8dfSAndroid Build Coastguard Worker 	if (!is_running_with_software_rendering_) {
488*d95af8dfSAndroid Build Coastguard Worker 		if ((hnd->usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) ==
489*d95af8dfSAndroid Build Coastguard Worker 		    0) {
490*d95af8dfSAndroid Build Coastguard Worker 			ALOGE("Attempted to lock() a buffer that was not allocated with a "
491*d95af8dfSAndroid Build Coastguard Worker 			      "BufferUsage::CPU_* usage.");
492*d95af8dfSAndroid Build Coastguard Worker 			return -EINVAL;
493*d95af8dfSAndroid Build Coastguard Worker 		}
494*d95af8dfSAndroid Build Coastguard Worker 	}
495*d95af8dfSAndroid Build Coastguard Worker 
496*d95af8dfSAndroid Build Coastguard Worker 	auto buffer = get_buffer(hnd);
497*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
498*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid reference (lock() called on unregistered handle).");
499*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
500*d95af8dfSAndroid Build Coastguard Worker 	}
501*d95af8dfSAndroid Build Coastguard Worker 
502*d95af8dfSAndroid Build Coastguard Worker 	return buffer->lock(rect, map_flags, addr);
503*d95af8dfSAndroid Build Coastguard Worker }
504*d95af8dfSAndroid Build Coastguard Worker 
unlock(buffer_handle_t handle,int32_t * release_fence)505*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fence)
506*d95af8dfSAndroid Build Coastguard Worker {
507*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
508*d95af8dfSAndroid Build Coastguard Worker 
509*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = cros_gralloc_convert_handle(handle);
510*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd) {
511*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid handle.");
512*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
513*d95af8dfSAndroid Build Coastguard Worker 	}
514*d95af8dfSAndroid Build Coastguard Worker 
515*d95af8dfSAndroid Build Coastguard Worker 	auto buffer = get_buffer(hnd);
516*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
517*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid reference (unlock() called on unregistered handle).");
518*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
519*d95af8dfSAndroid Build Coastguard Worker 	}
520*d95af8dfSAndroid Build Coastguard Worker 
521*d95af8dfSAndroid Build Coastguard Worker 	/*
522*d95af8dfSAndroid Build Coastguard Worker 	 * From the ANativeWindow::dequeueBuffer documentation:
523*d95af8dfSAndroid Build Coastguard Worker 	 *
524*d95af8dfSAndroid Build Coastguard Worker 	 * "A value of -1 indicates that the caller may access the buffer immediately without
525*d95af8dfSAndroid Build Coastguard Worker 	 * waiting on a fence."
526*d95af8dfSAndroid Build Coastguard Worker 	 */
527*d95af8dfSAndroid Build Coastguard Worker 	*release_fence = -1;
528*d95af8dfSAndroid Build Coastguard Worker 	return buffer->unlock();
529*d95af8dfSAndroid Build Coastguard Worker }
530*d95af8dfSAndroid Build Coastguard Worker 
invalidate(buffer_handle_t handle)531*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::invalidate(buffer_handle_t handle)
532*d95af8dfSAndroid Build Coastguard Worker {
533*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
534*d95af8dfSAndroid Build Coastguard Worker 
535*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = cros_gralloc_convert_handle(handle);
536*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd) {
537*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid handle.");
538*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
539*d95af8dfSAndroid Build Coastguard Worker 	}
540*d95af8dfSAndroid Build Coastguard Worker 
541*d95af8dfSAndroid Build Coastguard Worker 	auto buffer = get_buffer(hnd);
542*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
543*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid reference (invalidate() called on unregistered handle).");
544*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
545*d95af8dfSAndroid Build Coastguard Worker 	}
546*d95af8dfSAndroid Build Coastguard Worker 
547*d95af8dfSAndroid Build Coastguard Worker 	return buffer->invalidate();
548*d95af8dfSAndroid Build Coastguard Worker }
549*d95af8dfSAndroid Build Coastguard Worker 
flush(buffer_handle_t handle)550*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::flush(buffer_handle_t handle)
551*d95af8dfSAndroid Build Coastguard Worker {
552*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
553*d95af8dfSAndroid Build Coastguard Worker 
554*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = cros_gralloc_convert_handle(handle);
555*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd) {
556*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid handle.");
557*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
558*d95af8dfSAndroid Build Coastguard Worker 	}
559*d95af8dfSAndroid Build Coastguard Worker 
560*d95af8dfSAndroid Build Coastguard Worker 	auto buffer = get_buffer(hnd);
561*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
562*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid reference (flush() called on unregistered handle).");
563*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
564*d95af8dfSAndroid Build Coastguard Worker 	}
565*d95af8dfSAndroid Build Coastguard Worker 
566*d95af8dfSAndroid Build Coastguard Worker 	return buffer->flush();
567*d95af8dfSAndroid Build Coastguard Worker }
568*d95af8dfSAndroid Build Coastguard Worker 
get_backing_store(buffer_handle_t handle,uint64_t * out_store)569*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t *out_store)
570*d95af8dfSAndroid Build Coastguard Worker {
571*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
572*d95af8dfSAndroid Build Coastguard Worker 
573*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = cros_gralloc_convert_handle(handle);
574*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd) {
575*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid handle.");
576*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
577*d95af8dfSAndroid Build Coastguard Worker 	}
578*d95af8dfSAndroid Build Coastguard Worker 
579*d95af8dfSAndroid Build Coastguard Worker 	auto buffer = get_buffer(hnd);
580*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
581*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid reference (get_backing_store() called on unregistered handle).");
582*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
583*d95af8dfSAndroid Build Coastguard Worker 	}
584*d95af8dfSAndroid Build Coastguard Worker 
585*d95af8dfSAndroid Build Coastguard Worker 	*out_store = static_cast<uint64_t>(buffer->get_id());
586*d95af8dfSAndroid Build Coastguard Worker 	return 0;
587*d95af8dfSAndroid Build Coastguard Worker }
588*d95af8dfSAndroid Build Coastguard Worker 
resource_info(buffer_handle_t handle,uint32_t strides[DRV_MAX_PLANES],uint32_t offsets[DRV_MAX_PLANES],uint64_t * format_modifier)589*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::resource_info(buffer_handle_t handle, uint32_t strides[DRV_MAX_PLANES],
590*d95af8dfSAndroid Build Coastguard Worker 					   uint32_t offsets[DRV_MAX_PLANES],
591*d95af8dfSAndroid Build Coastguard Worker 					   uint64_t *format_modifier)
592*d95af8dfSAndroid Build Coastguard Worker {
593*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
594*d95af8dfSAndroid Build Coastguard Worker 
595*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = cros_gralloc_convert_handle(handle);
596*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd) {
597*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid handle.");
598*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
599*d95af8dfSAndroid Build Coastguard Worker 	}
600*d95af8dfSAndroid Build Coastguard Worker 
601*d95af8dfSAndroid Build Coastguard Worker 	auto buffer = get_buffer(hnd);
602*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
603*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid reference (resource_info() called on unregistered handle).");
604*d95af8dfSAndroid Build Coastguard Worker 		return -EINVAL;
605*d95af8dfSAndroid Build Coastguard Worker 	}
606*d95af8dfSAndroid Build Coastguard Worker 
607*d95af8dfSAndroid Build Coastguard Worker 	return buffer->resource_info(strides, offsets, format_modifier);
608*d95af8dfSAndroid Build Coastguard Worker }
609*d95af8dfSAndroid Build Coastguard Worker 
get_resolved_drm_format(uint32_t drm_format,uint64_t use_flags)610*d95af8dfSAndroid Build Coastguard Worker uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint64_t use_flags)
611*d95af8dfSAndroid Build Coastguard Worker {
612*d95af8dfSAndroid Build Coastguard Worker 	uint32_t resolved_format;
613*d95af8dfSAndroid Build Coastguard Worker 	uint64_t resolved_use_flags;
614*d95af8dfSAndroid Build Coastguard Worker 
615*d95af8dfSAndroid Build Coastguard Worker 	drv_resolve_format_and_use_flags(drv_.get(), drm_format, use_flags, &resolved_format,
616*d95af8dfSAndroid Build Coastguard Worker 					 &resolved_use_flags);
617*d95af8dfSAndroid Build Coastguard Worker 
618*d95af8dfSAndroid Build Coastguard Worker 	return resolved_format;
619*d95af8dfSAndroid Build Coastguard Worker }
620*d95af8dfSAndroid Build Coastguard Worker 
get_buffer(cros_gralloc_handle_t hnd)621*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd)
622*d95af8dfSAndroid Build Coastguard Worker {
623*d95af8dfSAndroid Build Coastguard Worker 	/* Assumes driver mutex is held. */
624*d95af8dfSAndroid Build Coastguard Worker 	if (handles_.count(hnd))
625*d95af8dfSAndroid Build Coastguard Worker 		return handles_[hnd].buffer;
626*d95af8dfSAndroid Build Coastguard Worker 
627*d95af8dfSAndroid Build Coastguard Worker 	return nullptr;
628*d95af8dfSAndroid Build Coastguard Worker }
629*d95af8dfSAndroid Build Coastguard Worker 
with_buffer(cros_gralloc_handle_t hnd,const std::function<void (cros_gralloc_buffer *)> & function)630*d95af8dfSAndroid Build Coastguard Worker void cros_gralloc_driver::with_buffer(cros_gralloc_handle_t hnd,
631*d95af8dfSAndroid Build Coastguard Worker 				      const std::function<void(cros_gralloc_buffer *)> &function)
632*d95af8dfSAndroid Build Coastguard Worker {
633*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
634*d95af8dfSAndroid Build Coastguard Worker 
635*d95af8dfSAndroid Build Coastguard Worker 	auto buffer = get_buffer(hnd);
636*d95af8dfSAndroid Build Coastguard Worker 	if (!buffer) {
637*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Invalid reference (with_buffer() called on unregistered handle).");
638*d95af8dfSAndroid Build Coastguard Worker 		return;
639*d95af8dfSAndroid Build Coastguard Worker 	}
640*d95af8dfSAndroid Build Coastguard Worker 
641*d95af8dfSAndroid Build Coastguard Worker 	function(buffer);
642*d95af8dfSAndroid Build Coastguard Worker }
643*d95af8dfSAndroid Build Coastguard Worker 
with_each_buffer(const std::function<void (cros_gralloc_buffer *)> & function)644*d95af8dfSAndroid Build Coastguard Worker void cros_gralloc_driver::with_each_buffer(
645*d95af8dfSAndroid Build Coastguard Worker     const std::function<void(cros_gralloc_buffer *)> &function)
646*d95af8dfSAndroid Build Coastguard Worker {
647*d95af8dfSAndroid Build Coastguard Worker 	std::lock_guard<std::mutex> lock(mutex_);
648*d95af8dfSAndroid Build Coastguard Worker 
649*d95af8dfSAndroid Build Coastguard Worker 	for (const auto &pair : buffers_)
650*d95af8dfSAndroid Build Coastguard Worker 		function(pair.second.get());
651*d95af8dfSAndroid Build Coastguard Worker }
652