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. */ 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 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 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 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 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 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 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 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 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 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 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 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. */ 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 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. */ 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 */ 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 */ 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 */ 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. */ 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. */ 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. */ 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 */ 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. */ 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 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 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