• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 /*
8  * Please run clang-format on this file after making changes:
9  *
10  * clang-format -style=file -i gralloctest.c
11  *
12  */
13 
14 #define _GNU_SOURCE
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 #include <cutils/native_handle.h>
19 #include <hardware/gralloc.h>
20 #include <system/graphics.h>
21 #include <sync/sync.h>
22 
23 #define ALIGN(A, B) (((A) + (B)-1) / (B) * (B))
24 #define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
25 
26 #define CHECK(cond)                                                            \
27 	do {                                                                   \
28 		if (!(cond)) {                                                 \
29 			fprintf(stderr, "[  FAILED  ] check in %s() %s:%d\n",  \
30 				__func__, __FILE__, __LINE__);                 \
31 			return 0;                                              \
32 		}                                                              \
33 	} while (0)
34 
35 #define CHECK_NO_MSG(cond)                                                     \
36 	do {                                                                   \
37 		if (!(cond)) {                                                 \
38 			return 0;                                              \
39 		}                                                              \
40 	} while (0)
41 
42 /* Private API enumeration -- see <gralloc_drm.h> */
43 enum { GRALLOC_DRM_GET_STRIDE,
44        GRALLOC_DRM_GET_FORMAT,
45        GRALLOC_DRM_GET_DIMENSIONS,
46        GRALLOC_DRM_GET_BACKING_STORE,
47 };
48 
49 struct gralloctest_context {
50 	struct gralloc_module_t *module;
51 	struct alloc_device_t *device;
52 	int api;
53 };
54 
55 struct gralloc_testcase {
56 	const char *name;
57 	int (*run_test)(struct gralloctest_context *ctx);
58 	int required_api;
59 };
60 
61 struct combinations {
62 	int32_t format;
63 	int32_t usage;
64 };
65 
66 // clang-format off
67 static struct combinations combos[] = {
68 	{ HAL_PIXEL_FORMAT_RGBA_8888,
69 	  GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
70 	  GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER |
71 	  GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_CURSOR },
72 	{ HAL_PIXEL_FORMAT_RGBA_8888,
73 	  GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER |
74 	  GRALLOC_USAGE_HW_COMPOSER },
75 	{ HAL_PIXEL_FORMAT_RGBX_8888,
76 	  GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN },
77 	{ HAL_PIXEL_FORMAT_YCbCr_420_888,
78 	  GRALLOC_USAGE_EXTERNAL_DISP | GRALLOC_USAGE_HW_COMPOSER |
79 	  GRALLOC_USAGE_HW_TEXTURE },
80 	{ HAL_PIXEL_FORMAT_YCbCr_420_888,
81 	  GRALLOC_USAGE_RENDERSCRIPT | GRALLOC_USAGE_SW_READ_OFTEN |
82 	  GRALLOC_USAGE_SW_WRITE_OFTEN },
83 	{ HAL_PIXEL_FORMAT_YV12,
84 	  GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_COMPOSER |
85 	  GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP },
86 	{ HAL_PIXEL_FORMAT_RGB_565,
87 	  GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN },
88 	{ HAL_PIXEL_FORMAT_BGRA_8888,
89 	  GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN },
90 	{ HAL_PIXEL_FORMAT_BLOB,
91 	  GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN },
92 };
93 // clang-format on
94 
95 struct grallocinfo {
96 	buffer_handle_t handle;     /* handle to the buffer */
97 	int w;			    /* width  of buffer */
98 	int h;			    /* height of buffer */
99 	int format;		    /* format of the buffer */
100 	int usage;		    /* bitfield indicating usage */
101 	int fence_fd;		    /* fence file descriptor */
102 	void *vaddr;		    /* buffer virtual memory address */
103 	int stride;		    /* stride in pixels */
104 	struct android_ycbcr ycbcr; /* sw access for yuv buffers */
105 };
106 
107 /* This function is meant to initialize the test to commonly used defaults. */
grallocinfo_init(struct grallocinfo * info,int w,int h,int format,int usage)108 void grallocinfo_init(struct grallocinfo *info, int w, int h, int format,
109 		      int usage)
110 {
111 	info->w = w;
112 	info->h = h;
113 	info->format = format;
114 	info->usage = usage;
115 	info->fence_fd = -1;
116 	info->vaddr = NULL;
117 	info->ycbcr.y = NULL;
118 	info->ycbcr.cb = NULL;
119 	info->ycbcr.cr = NULL;
120 	info->stride = 0;
121 }
122 
duplicate_buffer_handle(buffer_handle_t handle)123 static native_handle_t *duplicate_buffer_handle(buffer_handle_t handle)
124 {
125 	native_handle_t *hnd =
126 	    native_handle_create(handle->numFds, handle->numInts);
127 
128 	if (hnd == NULL)
129 		return NULL;
130 
131 	const int *old_data = handle->data;
132 	int *new_data = hnd->data;
133 
134 	int i;
135 	for (i = 0; i < handle->numFds; i++) {
136 		*new_data = dup(*old_data);
137 		old_data++;
138 		new_data++;
139 	}
140 
141 	memcpy(new_data, old_data, sizeof(int) * handle->numInts);
142 
143 	return hnd;
144 }
145 
146 /****************************************************************
147  * Wrappers around gralloc_module_t and alloc_device_t functions.
148  * GraphicBufferMapper/GraphicBufferAllocator could replace this
149  * in theory.
150  ***************************************************************/
151 
allocate(struct alloc_device_t * device,struct grallocinfo * info)152 static int allocate(struct alloc_device_t *device, struct grallocinfo *info)
153 {
154 	int ret;
155 
156 	ret = device->alloc(device, info->w, info->h, info->format, info->usage,
157 			    &info->handle, &info->stride);
158 
159 	CHECK_NO_MSG(ret == 0);
160 	CHECK_NO_MSG(info->handle->version > 0);
161 	CHECK_NO_MSG(info->handle->numInts >= 0);
162 	CHECK_NO_MSG(info->handle->numFds >= 0);
163 	CHECK_NO_MSG(info->stride >= 0);
164 
165 	return 1;
166 }
167 
deallocate(struct alloc_device_t * device,struct grallocinfo * info)168 static int deallocate(struct alloc_device_t *device, struct grallocinfo *info)
169 {
170 	int ret;
171 	ret = device->free(device, info->handle);
172 	CHECK(ret == 0);
173 	return 1;
174 }
175 
register_buffer(struct gralloc_module_t * module,struct grallocinfo * info)176 static int register_buffer(struct gralloc_module_t *module,
177 			   struct grallocinfo *info)
178 {
179 	int ret;
180 	ret = module->registerBuffer(module, info->handle);
181 	return (ret == 0);
182 }
183 
unregister_buffer(struct gralloc_module_t * module,struct grallocinfo * info)184 static int unregister_buffer(struct gralloc_module_t *module,
185 			     struct grallocinfo *info)
186 {
187 	int ret;
188 	ret = module->unregisterBuffer(module, info->handle);
189 	return (ret == 0);
190 }
191 
lock(struct gralloc_module_t * module,struct grallocinfo * info)192 static int lock(struct gralloc_module_t *module, struct grallocinfo *info)
193 {
194 	int ret;
195 
196 	ret = module->lock(module, info->handle, info->usage, 0, 0,
197 			   (info->w) / 2, (info->h) / 2, &info->vaddr);
198 
199 	return (ret == 0);
200 }
201 
unlock(struct gralloc_module_t * module,struct grallocinfo * info)202 static int unlock(struct gralloc_module_t *module, struct grallocinfo *info)
203 {
204 	int ret;
205 	ret = module->unlock(module, info->handle);
206 	return (ret == 0);
207 }
208 
lock_ycbcr(struct gralloc_module_t * module,struct grallocinfo * info)209 static int lock_ycbcr(struct gralloc_module_t *module, struct grallocinfo *info)
210 {
211 	int ret;
212 
213 	ret = module->lock_ycbcr(module, info->handle, info->usage, 0, 0,
214 				 (info->w) / 2, (info->h) / 2, &info->ycbcr);
215 
216 	return (ret == 0);
217 }
218 
lock_async(struct gralloc_module_t * module,struct grallocinfo * info)219 static int lock_async(struct gralloc_module_t *module, struct grallocinfo *info)
220 {
221 	int ret;
222 
223 	ret = module->lockAsync(module, info->handle, info->usage, 0, 0,
224 				(info->w) / 2, (info->h) / 2, &info->vaddr,
225 				info->fence_fd);
226 
227 	return (ret == 0);
228 }
229 
unlock_async(struct gralloc_module_t * module,struct grallocinfo * info)230 static int unlock_async(struct gralloc_module_t *module,
231 			struct grallocinfo *info)
232 {
233 	int ret;
234 
235 	ret = module->unlockAsync(module, info->handle, &info->fence_fd);
236 
237 	return (ret == 0);
238 }
239 
lock_async_ycbcr(struct gralloc_module_t * module,struct grallocinfo * info)240 static int lock_async_ycbcr(struct gralloc_module_t *module,
241 			    struct grallocinfo *info)
242 {
243 	int ret;
244 
245 	ret = module->lockAsync_ycbcr(module, info->handle, info->usage, 0, 0,
246 				      (info->w) / 2, (info->h) / 2,
247 				      &info->ycbcr, info->fence_fd);
248 
249 	return (ret == 0);
250 }
251 
252 /**************************************************************
253  * END WRAPPERS                                               *
254  **************************************************************/
255 
256 /* This function tests initialization of gralloc module and allocator. */
test_init_gralloc()257 static struct gralloctest_context *test_init_gralloc()
258 {
259 	int err;
260 	hw_module_t const *hw_module;
261 	struct gralloctest_context *ctx = calloc(1, sizeof(*ctx));
262 
263 	err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module);
264 	if (err)
265 		return NULL;
266 
267 	gralloc_open(hw_module, &ctx->device);
268 	ctx->module = (gralloc_module_t *)hw_module;
269 	if (!ctx->module || !ctx->device)
270 		return NULL;
271 
272 	switch (ctx->module->common.module_api_version) {
273 	case GRALLOC_MODULE_API_VERSION_0_3:
274 		ctx->api = 3;
275 		break;
276 	case GRALLOC_MODULE_API_VERSION_0_2:
277 		ctx->api = 2;
278 		break;
279 	default:
280 		ctx->api = 1;
281 	}
282 
283 	return ctx;
284 }
285 
test_close_gralloc(struct gralloctest_context * ctx)286 static int test_close_gralloc(struct gralloctest_context *ctx)
287 {
288 	CHECK(gralloc_close(ctx->device) == 0);
289 	return 1;
290 }
291 
292 /* This function tests allocation with varying buffer dimensions. */
test_alloc_varying_sizes(struct gralloctest_context * ctx)293 static int test_alloc_varying_sizes(struct gralloctest_context *ctx)
294 {
295 	struct grallocinfo info;
296 	int i;
297 
298 	grallocinfo_init(&info, 0, 0, HAL_PIXEL_FORMAT_BGRA_8888,
299 			 GRALLOC_USAGE_SW_READ_OFTEN);
300 
301 	for (i = 1; i < 1920; i++) {
302 		info.w = i;
303 		info.h = i;
304 		CHECK(allocate(ctx->device, &info));
305 		CHECK(deallocate(ctx->device, &info));
306 	}
307 
308 	info.w = 1;
309 	for (i = 1; i < 1920; i++) {
310 		info.h = i;
311 		CHECK(allocate(ctx->device, &info));
312 		CHECK(deallocate(ctx->device, &info));
313 	}
314 
315 	info.h = 1;
316 	for (i = 1; i < 1920; i++) {
317 		info.w = i;
318 		CHECK(allocate(ctx->device, &info));
319 		CHECK(deallocate(ctx->device, &info));
320 	}
321 
322 	return 1;
323 }
324 
325 /*
326  * This function tests that we find at least one working format for each
327  * combos which we consider important.
328  */
test_alloc_combinations(struct gralloctest_context * ctx)329 static int test_alloc_combinations(struct gralloctest_context *ctx)
330 {
331 	int i;
332 
333 	struct grallocinfo info;
334 	grallocinfo_init(&info, 512, 512, 0, 0);
335 
336 	for (i = 0; i < ARRAY_SIZE(combos); i++) {
337 		info.format = combos[i].format;
338 		info.usage = combos[i].usage;
339 		CHECK(allocate(ctx->device, &info));
340 		CHECK(deallocate(ctx->device, &info));
341 	}
342 
343 	return 1;
344 }
345 
346 /*
347  * This function tests the advertised API version.
348  * Version_0_2 added (*lock_ycbcr)() method.
349  * Version_0_3 added fence passing to/from lock/unlock.
350  */
test_api(struct gralloctest_context * ctx)351 static int test_api(struct gralloctest_context *ctx)
352 {
353 
354 	CHECK(ctx->module->registerBuffer);
355 	CHECK(ctx->module->unregisterBuffer);
356 	CHECK(ctx->module->lock);
357 	CHECK(ctx->module->unlock);
358 
359 	switch (ctx->module->common.module_api_version) {
360 	case GRALLOC_MODULE_API_VERSION_0_3:
361 		CHECK(ctx->module->lock_ycbcr);
362 		CHECK(ctx->module->lockAsync);
363 		CHECK(ctx->module->unlockAsync);
364 		CHECK(ctx->module->lockAsync_ycbcr);
365 		break;
366 	case GRALLOC_MODULE_API_VERSION_0_2:
367 		CHECK(ctx->module->lock_ycbcr);
368 		CHECK(ctx->module->lockAsync == NULL);
369 		CHECK(ctx->module->unlockAsync == NULL);
370 		CHECK(ctx->module->lockAsync_ycbcr == NULL);
371 		break;
372 	case GRALLOC_MODULE_API_VERSION_0_1:
373 		CHECK(ctx->module->lockAsync == NULL);
374 		CHECK(ctx->module->unlockAsync == NULL);
375 		CHECK(ctx->module->lockAsync_ycbcr == NULL);
376 		CHECK(ctx->module->lock_ycbcr == NULL);
377 		break;
378 	default:
379 		return 0;
380 	}
381 
382 	return 1;
383 }
384 
385 /*
386  * This function registers, unregisters, locks and unlocks the buffer in
387  * various orders.
388  */
test_gralloc_order(struct gralloctest_context * ctx)389 static int test_gralloc_order(struct gralloctest_context *ctx)
390 {
391 	struct grallocinfo info, duplicate;
392 
393 	grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
394 			 GRALLOC_USAGE_SW_READ_OFTEN);
395 
396 	grallocinfo_init(&duplicate, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
397 			 GRALLOC_USAGE_SW_READ_OFTEN);
398 
399 	CHECK(allocate(ctx->device, &info));
400 
401 	/*
402 	 * Duplicate the buffer handle to simulate an additional reference
403 	 * in same process.
404 	 */
405 	native_handle_t *native_handle = duplicate_buffer_handle(info.handle);
406 	duplicate.handle = native_handle;
407 
408 	CHECK(unregister_buffer(ctx->module, &duplicate) == 0);
409 	CHECK(register_buffer(ctx->module, &duplicate));
410 
411 	CHECK(unlock(ctx->module, &duplicate) == 0);
412 
413 	CHECK(lock(ctx->module, &duplicate));
414 	CHECK(duplicate.vaddr);
415 	CHECK(unlock(ctx->module, &duplicate));
416 
417 	CHECK(unregister_buffer(ctx->module, &duplicate));
418 
419 	CHECK(register_buffer(ctx->module, &duplicate));
420 	CHECK(unregister_buffer(ctx->module, &duplicate));
421 	CHECK(unregister_buffer(ctx->module, &duplicate) == 0);
422 
423 	CHECK(register_buffer(ctx->module, &duplicate));
424 	CHECK(deallocate(ctx->device, &info));
425 
426 	CHECK(lock(ctx->module, &duplicate));
427 	CHECK(lock(ctx->module, &duplicate));
428 	CHECK(unlock(ctx->module, &duplicate));
429 	CHECK(unlock(ctx->module, &duplicate));
430 	CHECK(unlock(ctx->module, &duplicate) == 0);
431 	CHECK(unregister_buffer(ctx->module, &duplicate));
432 
433 	CHECK(native_handle_close(duplicate.handle) == 0);
434 	CHECK(native_handle_delete(native_handle) == 0);
435 
436 	return 1;
437 }
438 
439 /* This function tests CPU reads and writes. */
test_mapping(struct gralloctest_context * ctx)440 static int test_mapping(struct gralloctest_context *ctx)
441 {
442 	struct grallocinfo info;
443 	uint32_t *ptr = NULL;
444 	uint32_t magic_number = 0x000ABBA;
445 
446 	grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
447 			 GRALLOC_USAGE_SW_READ_OFTEN |
448 			     GRALLOC_USAGE_SW_WRITE_OFTEN);
449 
450 	CHECK(allocate(ctx->device, &info));
451 	CHECK(lock(ctx->module, &info));
452 
453 	ptr = (uint32_t *)info.vaddr;
454 	CHECK(ptr);
455 	ptr[(info.w) / 2] = magic_number;
456 
457 	CHECK(unlock(ctx->module, &info));
458 	info.vaddr = NULL;
459 	ptr = NULL;
460 
461 	CHECK(lock(ctx->module, &info));
462 	ptr = (uint32_t *)info.vaddr;
463 	CHECK(ptr);
464 	CHECK(ptr[info.w / 2] == magic_number);
465 
466 	CHECK(unlock(ctx->module, &info));
467 	CHECK(deallocate(ctx->device, &info));
468 
469 	return 1;
470 }
471 
472 /* This function tests the private API we use in ARC++ -- not part of official
473  * gralloc. */
test_perform(struct gralloctest_context * ctx)474 static int test_perform(struct gralloctest_context *ctx)
475 {
476 	int32_t format;
477 	uint64_t id1, id2;
478 	uint32_t stride, width, height;
479 	struct grallocinfo info, duplicate;
480 	struct gralloc_module_t *mod = ctx->module;
481 
482 	grallocinfo_init(&info, 650, 408, HAL_PIXEL_FORMAT_BGRA_8888,
483 			 GRALLOC_USAGE_SW_READ_OFTEN);
484 
485 	CHECK(allocate(ctx->device, &info));
486 
487 	CHECK(mod->perform(mod, GRALLOC_DRM_GET_STRIDE, info.handle, &stride) ==
488 	      0);
489 	CHECK(stride == info.stride);
490 
491 	CHECK(mod->perform(mod, GRALLOC_DRM_GET_FORMAT, info.handle, &format) ==
492 	      0);
493 	CHECK(format == info.format);
494 
495 	CHECK(mod->perform(mod, GRALLOC_DRM_GET_DIMENSIONS, info.handle, &width,
496 			   &height) == 0);
497 	CHECK(width == info.w);
498 	CHECK(height == info.h);
499 
500 	native_handle_t *native_handle = duplicate_buffer_handle(info.handle);
501 	duplicate.handle = native_handle;
502 
503 	CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, duplicate.handle,
504 			   &id2));
505 	CHECK(register_buffer(mod, &duplicate));
506 
507 	CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, info.handle,
508 			   &id1) == 0);
509 	CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, duplicate.handle,
510 			   &id2) == 0);
511 	CHECK(id1 == id2);
512 
513 	CHECK(unregister_buffer(mod, &duplicate));
514 	CHECK(deallocate(ctx->device, &info));
515 
516 	return 1;
517 }
518 
519 /* This function tests that only YUV buffers work with *lock_ycbcr. */
test_ycbcr(struct gralloctest_context * ctx)520 static int test_ycbcr(struct gralloctest_context *ctx)
521 
522 {
523 	struct grallocinfo info;
524 	grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_YCbCr_420_888,
525 			 GRALLOC_USAGE_SW_READ_OFTEN);
526 
527 	CHECK(allocate(ctx->device, &info));
528 
529 	CHECK(lock(ctx->module, &info) == 0);
530 	CHECK(lock_ycbcr(ctx->module, &info));
531 	CHECK(info.ycbcr.y);
532 	CHECK(info.ycbcr.cb);
533 	CHECK(info.ycbcr.cr);
534 	CHECK(unlock(ctx->module, &info));
535 
536 	CHECK(deallocate(ctx->device, &info));
537 
538 	info.format = HAL_PIXEL_FORMAT_BGRA_8888;
539 	CHECK(allocate(ctx->device, &info));
540 
541 	CHECK(lock_ycbcr(ctx->module, &info) == 0);
542 	CHECK(lock(ctx->module, &info));
543 	CHECK(unlock(ctx->module, &info));
544 
545 	CHECK(deallocate(ctx->device, &info));
546 
547 	return 1;
548 }
549 
550 /*
551  * This function tests a method ARC++ uses to query YUV buffer
552  * info -- not part of official gralloc API.  This is used in
553  * Mali, Mesa, the ArcCodec and  wayland_service.
554  */
test_yuv_info(struct gralloctest_context * ctx)555 static int test_yuv_info(struct gralloctest_context *ctx)
556 {
557 	struct grallocinfo info;
558 	uint32_t y_size, c_stride, c_size, cr_offset, cb_offset;
559 	uint32_t width, height;
560 	width = height = 512;
561 
562 	/* <system/graphics.h> defines YV12 as having:
563 	 * - an even width
564 	 * - an even height
565 	 * - a horizontal stride multiple of 16 pixels
566 	 * - a vertical stride equal to the height
567 	 *
568 	 *   y_size = stride * height.
569 	 *   c_stride = ALIGN(stride/2, 16).
570 	 *   c_size = c_stride * height/2.
571 	 *   size = y_size + c_size * 2.
572 	 *   cr_offset = y_size.
573 	 *   cb_offset = y_size + c_size.
574 	 */
575 
576 	grallocinfo_init(&info, width, height, HAL_PIXEL_FORMAT_YV12,
577 			 GRALLOC_USAGE_SW_READ_OFTEN);
578 
579 	CHECK(allocate(ctx->device, &info));
580 
581 	y_size = info.stride * height;
582 	c_stride = ALIGN(info.stride / 2, 16);
583 	c_size = c_stride * height / 2;
584 	cr_offset = y_size;
585 	cb_offset = y_size + c_size;
586 
587 	info.usage = 0;
588 
589 	/*
590 	 * Check if the (*lock_ycbcr) with usage of zero returns the
591 	 * offsets and strides of the YV12 buffer. This is unofficial
592 	 * behavior we are testing here.
593 	 */
594 	CHECK(lock_ycbcr(ctx->module, &info));
595 
596 	CHECK(info.stride == info.ycbcr.ystride);
597 	CHECK(c_stride == info.ycbcr.cstride);
598 	CHECK(cr_offset == (uint32_t)info.ycbcr.cr);
599 	CHECK(cb_offset == (uint32_t)info.ycbcr.cb);
600 
601 	CHECK(unlock(ctx->module, &info));
602 
603 	CHECK(deallocate(ctx->device, &info));
604 
605 	return 1;
606 }
607 
608 /* This function tests asynchronous locking and unlocking of buffers. */
test_async(struct gralloctest_context * ctx)609 static int test_async(struct gralloctest_context *ctx)
610 
611 {
612 	struct grallocinfo rgba_info, ycbcr_info;
613 	grallocinfo_init(&rgba_info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
614 			 GRALLOC_USAGE_SW_READ_OFTEN);
615 	grallocinfo_init(&ycbcr_info, 512, 512, HAL_PIXEL_FORMAT_YCbCr_420_888,
616 			 GRALLOC_USAGE_SW_READ_OFTEN);
617 
618 	CHECK(allocate(ctx->device, &rgba_info));
619 	CHECK(allocate(ctx->device, &ycbcr_info));
620 
621 	CHECK(lock_async(ctx->module, &rgba_info));
622 	CHECK(lock_async_ycbcr(ctx->module, &ycbcr_info));
623 
624 	CHECK(rgba_info.vaddr);
625 	CHECK(ycbcr_info.ycbcr.y);
626 	CHECK(ycbcr_info.ycbcr.cb);
627 	CHECK(ycbcr_info.ycbcr.cr);
628 
629 	/*
630 	 * Wait on the fence returned from unlock_async and check it doesn't
631 	 * return an error.
632 	 */
633 	CHECK(unlock_async(ctx->module, &rgba_info));
634 	CHECK(unlock_async(ctx->module, &ycbcr_info));
635 
636 	if (rgba_info.fence_fd >= 0) {
637 		CHECK(sync_wait(rgba_info.fence_fd, 10000) >= 0);
638 		CHECK(close(rgba_info.fence_fd) == 0);
639 	}
640 
641 	if (ycbcr_info.fence_fd >= 0) {
642 		CHECK(sync_wait(ycbcr_info.fence_fd, 10000) >= 0);
643 		CHECK(close(ycbcr_info.fence_fd) == 0);
644 	}
645 
646 	CHECK(deallocate(ctx->device, &rgba_info));
647 	CHECK(deallocate(ctx->device, &ycbcr_info));
648 
649 	return 1;
650 }
651 
652 static const struct gralloc_testcase tests[] = {
653 	{ "alloc_varying_sizes", test_alloc_varying_sizes, 1 },
654 	{ "alloc_combinations", test_alloc_combinations, 1 },
655 	{ "api", test_api, 1 },
656 	{ "gralloc_order", test_gralloc_order, 1 },
657 	{ "mapping", test_mapping, 1 },
658 	{ "perform", test_perform, 1 },
659 	{ "ycbcr", test_ycbcr, 2 },
660 	{ "yuv_info", test_yuv_info, 2 },
661 	{ "async", test_async, 3 },
662 };
663 
print_help(const char * argv0)664 static void print_help(const char *argv0)
665 {
666 	uint32_t i;
667 	printf("usage: %s <test_name>\n\n", argv0);
668 	printf("A valid name test is one the following:\n");
669 	for (i = 0; i < ARRAY_SIZE(tests); i++)
670 		printf("%s\n", tests[i].name);
671 }
672 
main(int argc,char * argv[])673 int main(int argc, char *argv[])
674 {
675 	int ret = 0;
676 	uint32_t num_run = 0;
677 
678 	setbuf(stdout, NULL);
679 	if (argc == 2) {
680 		uint32_t i;
681 		char *name = argv[1];
682 
683 		struct gralloctest_context *ctx = test_init_gralloc();
684 		if (!ctx) {
685 			fprintf(stderr,
686 				"[  FAILED  ] to initialize gralloc.\n");
687 			return 1;
688 		}
689 
690 		for (i = 0; i < ARRAY_SIZE(tests); i++) {
691 			if (strcmp(tests[i].name, name) && strcmp("all", name))
692 				continue;
693 
694 			int success = 1;
695 			if (ctx->api >= tests[i].required_api)
696 				success = tests[i].run_test(ctx);
697 
698 			printf("[ RUN      ] gralloctest.%s\n", tests[i].name);
699 			if (!success) {
700 				fprintf(stderr, "[  FAILED  ] gralloctest.%s\n",
701 					tests[i].name);
702 				ret |= 1;
703 			} else {
704 				printf("[  PASSED  ] gralloctest.%s\n",
705 				       tests[i].name);
706 			}
707 
708 			num_run++;
709 		}
710 
711 		if (!test_close_gralloc(ctx)) {
712 			fprintf(stderr, "[  FAILED  ] to close gralloc.\n");
713 			return 1;
714 		}
715 
716 		if (!num_run)
717 			goto print_usage;
718 
719 		return ret;
720 	}
721 
722 print_usage:
723 	print_help(argv[0]);
724 	return 0;
725 }
726