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