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