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.
8 * Please run clang-format on this file after making changes:
10 * clang-format -style=file -i gralloctest.c
18 #include <cutils/native_handle.h>
19 #include <hardware/gralloc.h>
20 #include <sync/sync.h>
21 #include <system/graphics.h>
23 #define ALIGN(A, B) (((A) + (B)-1) / (B) * (B))
24 #define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
29 fprintf(stderr, "[ FAILED ] check in %s() %s:%d\n", __func__, __FILE__, \
35 #define CHECK_NO_MSG(cond) \
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,
49 struct gralloctest_context {
50 struct gralloc_module_t *module;
51 struct alloc_device_t *device;
55 struct gralloc_testcase {
57 int (*run_test)(struct gralloctest_context *ctx);
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 },
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 */
107 /* This function is meant to initialize the test to commonly used defaults. */
108 void grallocinfo_init(struct grallocinfo *info, int w, int h, int format, int usage)
112 info->format = format;
116 info->ycbcr.y = NULL;
117 info->ycbcr.cb = NULL;
118 info->ycbcr.cr = NULL;
122 static native_handle_t *duplicate_buffer_handle(buffer_handle_t handle)
124 native_handle_t *hnd = native_handle_create(handle->numFds, handle->numInts);
129 const int *old_data = handle->data;
130 int *new_data = hnd->data;
133 for (i = 0; i < handle->numFds; i++) {
134 *new_data = dup(*old_data);
139 memcpy(new_data, old_data, sizeof(int) * handle->numInts);
144 /****************************************************************
145 * Wrappers around gralloc_module_t and alloc_device_t functions.
146 * GraphicBufferMapper/GraphicBufferAllocator could replace this
148 ***************************************************************/
150 static int allocate(struct alloc_device_t *device, struct grallocinfo *info)
154 ret = device->alloc(device, info->w, info->h, info->format, info->usage, &info->handle,
157 CHECK_NO_MSG(ret == 0);
158 CHECK_NO_MSG(info->handle->version > 0);
159 CHECK_NO_MSG(info->handle->numInts >= 0);
160 CHECK_NO_MSG(info->handle->numFds >= 0);
161 CHECK_NO_MSG(info->stride >= 0);
166 static int deallocate(struct alloc_device_t *device, struct grallocinfo *info)
169 ret = device->free(device, info->handle);
174 static int register_buffer(struct gralloc_module_t *module, struct grallocinfo *info)
177 ret = module->registerBuffer(module, info->handle);
181 static int unregister_buffer(struct gralloc_module_t *module, struct grallocinfo *info)
184 ret = module->unregisterBuffer(module, info->handle);
188 static int lock(struct gralloc_module_t *module, struct grallocinfo *info)
192 ret = module->lock(module, info->handle, info->usage, 0, 0, (info->w) / 2, (info->h) / 2,
198 static int unlock(struct gralloc_module_t *module, struct grallocinfo *info)
201 ret = module->unlock(module, info->handle);
205 static int lock_ycbcr(struct gralloc_module_t *module, struct grallocinfo *info)
209 ret = module->lock_ycbcr(module, info->handle, info->usage, 0, 0, (info->w) / 2,
210 (info->h) / 2, &info->ycbcr);
215 static int lock_async(struct gralloc_module_t *module, struct grallocinfo *info)
219 ret = module->lockAsync(module, info->handle, info->usage, 0, 0, (info->w) / 2,
220 (info->h) / 2, &info->vaddr, info->fence_fd);
225 static int unlock_async(struct gralloc_module_t *module, struct grallocinfo *info)
229 ret = module->unlockAsync(module, info->handle, &info->fence_fd);
234 static int lock_async_ycbcr(struct gralloc_module_t *module, struct grallocinfo *info)
238 ret = module->lockAsync_ycbcr(module, info->handle, info->usage, 0, 0, (info->w) / 2,
239 (info->h) / 2, &info->ycbcr, info->fence_fd);
244 /**************************************************************
246 **************************************************************/
248 /* This function tests initialization of gralloc module and allocator. */
249 static struct gralloctest_context *test_init_gralloc()
252 hw_module_t const *hw_module;
253 struct gralloctest_context *ctx = calloc(1, sizeof(*ctx));
255 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module);
259 gralloc_open(hw_module, &ctx->device);
260 ctx->module = (gralloc_module_t *)hw_module;
261 if (!ctx->module || !ctx->device)
264 switch (ctx->module->common.module_api_version) {
265 case GRALLOC_MODULE_API_VERSION_0_3:
268 case GRALLOC_MODULE_API_VERSION_0_2:
278 static int test_close_gralloc(struct gralloctest_context *ctx)
280 CHECK(gralloc_close(ctx->device) == 0);
284 /* This function tests allocation with varying buffer dimensions. */
285 static int test_alloc_varying_sizes(struct gralloctest_context *ctx)
287 struct grallocinfo info;
290 grallocinfo_init(&info, 0, 0, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN);
292 for (i = 1; i < 1920; i++) {
295 CHECK(allocate(ctx->device, &info));
296 CHECK(deallocate(ctx->device, &info));
300 for (i = 1; i < 1920; i++) {
302 CHECK(allocate(ctx->device, &info));
303 CHECK(deallocate(ctx->device, &info));
307 for (i = 1; i < 1920; i++) {
309 CHECK(allocate(ctx->device, &info));
310 CHECK(deallocate(ctx->device, &info));
317 * This function tests that we find at least one working format for each
318 * combos which we consider important.
320 static int test_alloc_combinations(struct gralloctest_context *ctx)
324 struct grallocinfo info;
325 grallocinfo_init(&info, 512, 512, 0, 0);
327 for (i = 0; i < ARRAY_SIZE(combos); i++) {
328 info.format = combos[i].format;
329 info.usage = combos[i].usage;
330 CHECK(allocate(ctx->device, &info));
331 CHECK(deallocate(ctx->device, &info));
338 * This function tests the advertised API version.
339 * Version_0_2 added (*lock_ycbcr)() method.
340 * Version_0_3 added fence passing to/from lock/unlock.
342 static int test_api(struct gralloctest_context *ctx)
345 CHECK(ctx->module->registerBuffer);
346 CHECK(ctx->module->unregisterBuffer);
347 CHECK(ctx->module->lock);
348 CHECK(ctx->module->unlock);
350 switch (ctx->module->common.module_api_version) {
351 case GRALLOC_MODULE_API_VERSION_0_3:
352 CHECK(ctx->module->lock_ycbcr);
353 CHECK(ctx->module->lockAsync);
354 CHECK(ctx->module->unlockAsync);
355 CHECK(ctx->module->lockAsync_ycbcr);
357 case GRALLOC_MODULE_API_VERSION_0_2:
358 CHECK(ctx->module->lock_ycbcr);
359 CHECK(ctx->module->lockAsync == NULL);
360 CHECK(ctx->module->unlockAsync == NULL);
361 CHECK(ctx->module->lockAsync_ycbcr == NULL);
363 case GRALLOC_MODULE_API_VERSION_0_1:
364 CHECK(ctx->module->lockAsync == NULL);
365 CHECK(ctx->module->unlockAsync == NULL);
366 CHECK(ctx->module->lockAsync_ycbcr == NULL);
367 CHECK(ctx->module->lock_ycbcr == NULL);
377 * This function registers, unregisters, locks and unlocks the buffer in
380 static int test_gralloc_order(struct gralloctest_context *ctx)
382 struct grallocinfo info, duplicate;
384 grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN);
386 grallocinfo_init(&duplicate, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
387 GRALLOC_USAGE_SW_READ_OFTEN);
389 CHECK(allocate(ctx->device, &info));
392 * Duplicate the buffer handle to simulate an additional reference
395 native_handle_t *native_handle = duplicate_buffer_handle(info.handle);
396 duplicate.handle = native_handle;
398 CHECK(unregister_buffer(ctx->module, &duplicate) == 0);
399 CHECK(register_buffer(ctx->module, &duplicate));
401 CHECK(unlock(ctx->module, &duplicate) == 0);
403 CHECK(lock(ctx->module, &duplicate));
404 CHECK(duplicate.vaddr);
405 CHECK(unlock(ctx->module, &duplicate));
407 CHECK(unregister_buffer(ctx->module, &duplicate));
409 CHECK(register_buffer(ctx->module, &duplicate));
410 CHECK(unregister_buffer(ctx->module, &duplicate));
411 CHECK(unregister_buffer(ctx->module, &duplicate) == 0);
413 CHECK(register_buffer(ctx->module, &duplicate));
414 CHECK(deallocate(ctx->device, &info));
416 CHECK(lock(ctx->module, &duplicate));
417 CHECK(lock(ctx->module, &duplicate));
418 CHECK(unlock(ctx->module, &duplicate));
419 CHECK(unlock(ctx->module, &duplicate));
420 CHECK(unlock(ctx->module, &duplicate) == 0);
421 CHECK(unregister_buffer(ctx->module, &duplicate));
423 CHECK(native_handle_close(duplicate.handle) == 0);
424 CHECK(native_handle_delete(native_handle) == 0);
429 /* This function tests CPU reads and writes. */
430 static int test_mapping(struct gralloctest_context *ctx)
432 struct grallocinfo info;
433 uint32_t *ptr = NULL;
434 uint32_t magic_number = 0x000ABBA;
436 grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
437 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
439 CHECK(allocate(ctx->device, &info));
440 CHECK(lock(ctx->module, &info));
442 ptr = (uint32_t *)info.vaddr;
444 ptr[(info.w) / 2] = magic_number;
446 CHECK(unlock(ctx->module, &info));
450 CHECK(lock(ctx->module, &info));
451 ptr = (uint32_t *)info.vaddr;
453 CHECK(ptr[info.w / 2] == magic_number);
455 CHECK(unlock(ctx->module, &info));
456 CHECK(deallocate(ctx->device, &info));
461 /* This function tests the private API we use in ARC++ -- not part of official
463 static int test_perform(struct gralloctest_context *ctx)
467 uint32_t stride, width, height;
468 struct grallocinfo info, duplicate;
469 struct gralloc_module_t *mod = ctx->module;
471 grallocinfo_init(&info, 650, 408, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN);
473 CHECK(allocate(ctx->device, &info));
475 CHECK(mod->perform(mod, GRALLOC_DRM_GET_STRIDE, info.handle, &stride) == 0);
476 CHECK(stride == info.stride);
478 CHECK(mod->perform(mod, GRALLOC_DRM_GET_FORMAT, info.handle, &format) == 0);
479 CHECK(format == info.format);
481 CHECK(mod->perform(mod, GRALLOC_DRM_GET_DIMENSIONS, info.handle, &width, &height) == 0);
482 CHECK(width == info.w);
483 CHECK(height == info.h);
485 native_handle_t *native_handle = duplicate_buffer_handle(info.handle);
486 duplicate.handle = native_handle;
488 CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, duplicate.handle, &id2));
489 CHECK(register_buffer(mod, &duplicate));
491 CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, info.handle, &id1) == 0);
492 CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, duplicate.handle, &id2) == 0);
495 CHECK(unregister_buffer(mod, &duplicate));
496 CHECK(deallocate(ctx->device, &info));
501 /* This function tests that only YUV buffers work with *lock_ycbcr. */
502 static int test_ycbcr(struct gralloctest_context *ctx)
505 struct grallocinfo info;
506 grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_YCbCr_420_888,
507 GRALLOC_USAGE_SW_READ_OFTEN);
509 CHECK(allocate(ctx->device, &info));
511 CHECK(lock(ctx->module, &info) == 0);
512 CHECK(lock_ycbcr(ctx->module, &info));
514 CHECK(info.ycbcr.cb);
515 CHECK(info.ycbcr.cr);
516 CHECK(unlock(ctx->module, &info));
518 CHECK(deallocate(ctx->device, &info));
520 info.format = HAL_PIXEL_FORMAT_BGRA_8888;
521 CHECK(allocate(ctx->device, &info));
523 CHECK(lock_ycbcr(ctx->module, &info) == 0);
524 CHECK(lock(ctx->module, &info));
525 CHECK(unlock(ctx->module, &info));
527 CHECK(deallocate(ctx->device, &info));
533 * This function tests a method ARC++ uses to query YUV buffer
534 * info -- not part of official gralloc API. This is used in
535 * Mali, Mesa, the ArcCodec and wayland_service.
537 static int test_yuv_info(struct gralloctest_context *ctx)
539 struct grallocinfo info;
540 uintptr_t y_size, c_stride, c_size, cr_offset, cb_offset;
541 uint32_t width, height;
542 width = height = 512;
544 /* <system/graphics.h> defines YV12 as having:
547 * - a horizontal stride multiple of 16 pixels
548 * - a vertical stride equal to the height
550 * y_size = stride * height.
551 * c_stride = ALIGN(stride/2, 16).
552 * c_size = c_stride * height/2.
553 * size = y_size + c_size * 2.
554 * cr_offset = y_size.
555 * cb_offset = y_size + c_size.
558 grallocinfo_init(&info, width, height, HAL_PIXEL_FORMAT_YV12, GRALLOC_USAGE_SW_READ_OFTEN);
560 CHECK(allocate(ctx->device, &info));
562 y_size = info.stride * height;
563 c_stride = ALIGN(info.stride / 2, 16);
564 c_size = c_stride * height / 2;
566 cb_offset = y_size + c_size;
571 * Check if the (*lock_ycbcr) with usage of zero returns the
572 * offsets and strides of the YV12 buffer. This is unofficial
573 * behavior we are testing here.
575 CHECK(lock_ycbcr(ctx->module, &info));
577 CHECK(info.stride == info.ycbcr.ystride);
578 CHECK(c_stride == info.ycbcr.cstride);
579 CHECK(cr_offset == (uintptr_t)info.ycbcr.cr);
580 CHECK(cb_offset == (uintptr_t)info.ycbcr.cb);
582 CHECK(unlock(ctx->module, &info));
584 CHECK(deallocate(ctx->device, &info));
589 /* This function tests asynchronous locking and unlocking of buffers. */
590 static int test_async(struct gralloctest_context *ctx)
593 struct grallocinfo rgba_info, ycbcr_info;
594 grallocinfo_init(&rgba_info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
595 GRALLOC_USAGE_SW_READ_OFTEN);
596 grallocinfo_init(&ycbcr_info, 512, 512, HAL_PIXEL_FORMAT_YCbCr_420_888,
597 GRALLOC_USAGE_SW_READ_OFTEN);
599 CHECK(allocate(ctx->device, &rgba_info));
600 CHECK(allocate(ctx->device, &ycbcr_info));
602 CHECK(lock_async(ctx->module, &rgba_info));
603 CHECK(lock_async_ycbcr(ctx->module, &ycbcr_info));
605 CHECK(rgba_info.vaddr);
606 CHECK(ycbcr_info.ycbcr.y);
607 CHECK(ycbcr_info.ycbcr.cb);
608 CHECK(ycbcr_info.ycbcr.cr);
611 * Wait on the fence returned from unlock_async and check it doesn't
614 CHECK(unlock_async(ctx->module, &rgba_info));
615 CHECK(unlock_async(ctx->module, &ycbcr_info));
617 if (rgba_info.fence_fd >= 0) {
618 CHECK(sync_wait(rgba_info.fence_fd, 10000) >= 0);
619 CHECK(close(rgba_info.fence_fd) == 0);
622 if (ycbcr_info.fence_fd >= 0) {
623 CHECK(sync_wait(ycbcr_info.fence_fd, 10000) >= 0);
624 CHECK(close(ycbcr_info.fence_fd) == 0);
627 CHECK(deallocate(ctx->device, &rgba_info));
628 CHECK(deallocate(ctx->device, &ycbcr_info));
633 static const struct gralloc_testcase tests[] = {
634 { "alloc_varying_sizes", test_alloc_varying_sizes, 1 },
635 { "alloc_combinations", test_alloc_combinations, 1 },
636 { "api", test_api, 1 },
637 { "gralloc_order", test_gralloc_order, 1 },
638 { "mapping", test_mapping, 1 },
639 { "perform", test_perform, 1 },
640 { "ycbcr", test_ycbcr, 2 },
641 { "yuv_info", test_yuv_info, 2 },
642 { "async", test_async, 3 },
645 static void print_help(const char *argv0)
648 printf("usage: %s <test_name>\n\n", argv0);
649 printf("A valid name test is one the following:\n");
650 for (i = 0; i < ARRAY_SIZE(tests); i++)
651 printf("%s\n", tests[i].name);
654 int main(int argc, char *argv[])
657 uint32_t num_run = 0;
659 setbuf(stdout, NULL);
662 char *name = argv[1];
664 struct gralloctest_context *ctx = test_init_gralloc();
666 fprintf(stderr, "[ FAILED ] to initialize gralloc.\n");
670 for (i = 0; i < ARRAY_SIZE(tests); i++) {
671 if (strcmp(tests[i].name, name) && strcmp("all", name))
675 if (ctx->api >= tests[i].required_api)
676 success = tests[i].run_test(ctx);
678 printf("[ RUN ] gralloctest.%s\n", tests[i].name);
680 fprintf(stderr, "[ FAILED ] gralloctest.%s\n", tests[i].name);
683 printf("[ PASSED ] gralloctest.%s\n", tests[i].name);
689 if (!test_close_gralloc(ctx)) {
690 fprintf(stderr, "[ FAILED ] to close gralloc.\n");