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