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