diff options
author | Gurchetan Singh <gurchetansingh@chromium.org> | 2017-10-03 10:39:13 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-10-10 05:31:01 -0700 |
commit | b57dffc6187a6bf810a36d491f0a0ddeade0d405 (patch) | |
tree | 60946dfcef9f657cd6109b6fdc020f6863d65ee3 | |
parent | c26fd1e5f7f54f42326f3e5f03551e93b3b84604 (diff) |
minigbm: move gralloctest to this repo
The autotest eclass has issues when compiling for multilib, and plus
we can keep the test with the source code.
BUG=b:63610343
TEST=emerge-eve arc-cros-gralloc
CQ-DEPEND=CL:699675, CL:699734
Change-Id: I9ec3185f7e18f4717ef560e599e635f03b0a999d
Reviewed-on: https://chromium-review.googlesource.com/699676
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
-rw-r--r-- | cros_gralloc/gralloc0/tests/Makefile | 30 | ||||
-rw-r--r-- | cros_gralloc/gralloc0/tests/gralloctest.c | 703 |
2 files changed, 733 insertions, 0 deletions
diff --git a/cros_gralloc/gralloc0/tests/Makefile b/cros_gralloc/gralloc0/tests/Makefile new file mode 100644 index 0000000..b81f8ec --- /dev/null +++ b/cros_gralloc/gralloc0/tests/Makefile @@ -0,0 +1,30 @@ +# Copyright 2016 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +GRALLOCTEST = gralloctest +SOURCES += gralloctest.c + +CCFLAGS += -g -O2 -Wall -fPIE +LIBS += -lhardware -lsync -lcutils -pie + +OBJS = $(foreach source, $(SOURCES), $(addsuffix .o, $(basename $(source)))) + +OBJECTS = $(addprefix $(TARGET_DIR), $(notdir $(OBJS))) +BINARY = $(addprefix $(TARGET_DIR), $(GRALLOCTEST)) + +.PHONY: all clean + +all: $(BINARY) + +$(BINARY): $(OBJECTS) + +clean: + $(RM) $(BINARY) + $(RM) $(OBJECTS) + +$(BINARY): + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS) + +$(TARGET_DIR)%.o: %.c + $(CC) $(CFLAGS) -c $^ -o $@ -MMD diff --git a/cros_gralloc/gralloc0/tests/gralloctest.c b/cros_gralloc/gralloc0/tests/gralloctest.c new file mode 100644 index 0000000..9fc3b88 --- /dev/null +++ b/cros_gralloc/gralloc0/tests/gralloctest.c @@ -0,0 +1,703 @@ +/* + * Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * Please run clang-format on this file after making changes: + * + * clang-format -style=file -i gralloctest.c + * + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> + +#include <cutils/native_handle.h> +#include <hardware/gralloc.h> +#include <sync/sync.h> +#include <system/graphics.h> + +#define ALIGN(A, B) (((A) + (B)-1) / (B) * (B)) +#define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A))) + +#define CHECK(cond) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, "[ FAILED ] check in %s() %s:%d\n", __func__, __FILE__, \ + __LINE__); \ + return 0; \ + } \ + } while (0) + +#define CHECK_NO_MSG(cond) \ + do { \ + if (!(cond)) { \ + return 0; \ + } \ + } while (0) + +/* Private API enumeration -- see <gralloc_drm.h> */ +enum { GRALLOC_DRM_GET_STRIDE, + GRALLOC_DRM_GET_FORMAT, + GRALLOC_DRM_GET_DIMENSIONS, + GRALLOC_DRM_GET_BACKING_STORE, +}; + +struct gralloctest_context { + struct gralloc_module_t *module; + struct alloc_device_t *device; + int api; +}; + +struct gralloc_testcase { + const char *name; + int (*run_test)(struct gralloctest_context *ctx); + int required_api; +}; + +struct combinations { + int32_t format; + int32_t usage; +}; + +// clang-format off +static struct combinations combos[] = { + { HAL_PIXEL_FORMAT_RGBA_8888, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | + GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | + GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_CURSOR }, + { HAL_PIXEL_FORMAT_RGBA_8888, + GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | + GRALLOC_USAGE_HW_COMPOSER }, + { HAL_PIXEL_FORMAT_RGBX_8888, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN }, + { HAL_PIXEL_FORMAT_YCbCr_420_888, + GRALLOC_USAGE_EXTERNAL_DISP | GRALLOC_USAGE_HW_COMPOSER | + GRALLOC_USAGE_HW_TEXTURE }, + { HAL_PIXEL_FORMAT_YCbCr_420_888, + GRALLOC_USAGE_RENDERSCRIPT | GRALLOC_USAGE_SW_READ_OFTEN | + GRALLOC_USAGE_SW_WRITE_OFTEN }, + { HAL_PIXEL_FORMAT_YV12, + GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_COMPOSER | + GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP }, + { HAL_PIXEL_FORMAT_RGB_565, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN }, + { HAL_PIXEL_FORMAT_BGRA_8888, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN }, + { HAL_PIXEL_FORMAT_BLOB, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN }, +}; +// clang-format on + +struct grallocinfo { + buffer_handle_t handle; /* handle to the buffer */ + int w; /* width of buffer */ + int h; /* height of buffer */ + int format; /* format of the buffer */ + int usage; /* bitfield indicating usage */ + int fence_fd; /* fence file descriptor */ + void *vaddr; /* buffer virtual memory address */ + int stride; /* stride in pixels */ + struct android_ycbcr ycbcr; /* sw access for yuv buffers */ +}; + +/* This function is meant to initialize the test to commonly used defaults. */ +void grallocinfo_init(struct grallocinfo *info, int w, int h, int format, int usage) +{ + info->w = w; + info->h = h; + info->format = format; + info->usage = usage; + info->fence_fd = -1; + info->vaddr = NULL; + info->ycbcr.y = NULL; + info->ycbcr.cb = NULL; + info->ycbcr.cr = NULL; + info->stride = 0; +} + +static native_handle_t *duplicate_buffer_handle(buffer_handle_t handle) +{ + native_handle_t *hnd = native_handle_create(handle->numFds, handle->numInts); + + if (hnd == NULL) + return NULL; + + const int *old_data = handle->data; + int *new_data = hnd->data; + + int i; + for (i = 0; i < handle->numFds; i++) { + *new_data = dup(*old_data); + old_data++; + new_data++; + } + + memcpy(new_data, old_data, sizeof(int) * handle->numInts); + + return hnd; +} + +/**************************************************************** + * Wrappers around gralloc_module_t and alloc_device_t functions. + * GraphicBufferMapper/GraphicBufferAllocator could replace this + * in theory. + ***************************************************************/ + +static int allocate(struct alloc_device_t *device, struct grallocinfo *info) +{ + int ret; + + ret = device->alloc(device, info->w, info->h, info->format, info->usage, &info->handle, + &info->stride); + + CHECK_NO_MSG(ret == 0); + CHECK_NO_MSG(info->handle->version > 0); + CHECK_NO_MSG(info->handle->numInts >= 0); + CHECK_NO_MSG(info->handle->numFds >= 0); + CHECK_NO_MSG(info->stride >= 0); + + return 1; +} + +static int deallocate(struct alloc_device_t *device, struct grallocinfo *info) +{ + int ret; + ret = device->free(device, info->handle); + CHECK(ret == 0); + return 1; +} + +static int register_buffer(struct gralloc_module_t *module, struct grallocinfo *info) +{ + int ret; + ret = module->registerBuffer(module, info->handle); + return (ret == 0); +} + +static int unregister_buffer(struct gralloc_module_t *module, struct grallocinfo *info) +{ + int ret; + ret = module->unregisterBuffer(module, info->handle); + return (ret == 0); +} + +static int lock(struct gralloc_module_t *module, struct grallocinfo *info) +{ + int ret; + + ret = module->lock(module, info->handle, info->usage, 0, 0, (info->w) / 2, (info->h) / 2, + &info->vaddr); + + return (ret == 0); +} + +static int unlock(struct gralloc_module_t *module, struct grallocinfo *info) +{ + int ret; + ret = module->unlock(module, info->handle); + return (ret == 0); +} + +static int lock_ycbcr(struct gralloc_module_t *module, struct grallocinfo *info) +{ + int ret; + + ret = module->lock_ycbcr(module, info->handle, info->usage, 0, 0, (info->w) / 2, + (info->h) / 2, &info->ycbcr); + + return (ret == 0); +} + +static int lock_async(struct gralloc_module_t *module, struct grallocinfo *info) +{ + int ret; + + ret = module->lockAsync(module, info->handle, info->usage, 0, 0, (info->w) / 2, + (info->h) / 2, &info->vaddr, info->fence_fd); + + return (ret == 0); +} + +static int unlock_async(struct gralloc_module_t *module, struct grallocinfo *info) +{ + int ret; + + ret = module->unlockAsync(module, info->handle, &info->fence_fd); + + return (ret == 0); +} + +static int lock_async_ycbcr(struct gralloc_module_t *module, struct grallocinfo *info) +{ + int ret; + + ret = module->lockAsync_ycbcr(module, info->handle, info->usage, 0, 0, (info->w) / 2, + (info->h) / 2, &info->ycbcr, info->fence_fd); + + return (ret == 0); +} + +/************************************************************** + * END WRAPPERS * + **************************************************************/ + +/* This function tests initialization of gralloc module and allocator. */ +static struct gralloctest_context *test_init_gralloc() +{ + int err; + hw_module_t const *hw_module; + struct gralloctest_context *ctx = calloc(1, sizeof(*ctx)); + + err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module); + if (err) + return NULL; + + gralloc_open(hw_module, &ctx->device); + ctx->module = (gralloc_module_t *)hw_module; + if (!ctx->module || !ctx->device) + return NULL; + + switch (ctx->module->common.module_api_version) { + case GRALLOC_MODULE_API_VERSION_0_3: + ctx->api = 3; + break; + case GRALLOC_MODULE_API_VERSION_0_2: + ctx->api = 2; + break; + default: + ctx->api = 1; + } + + return ctx; +} + +static int test_close_gralloc(struct gralloctest_context *ctx) +{ + CHECK(gralloc_close(ctx->device) == 0); + return 1; +} + +/* This function tests allocation with varying buffer dimensions. */ +static int test_alloc_varying_sizes(struct gralloctest_context *ctx) +{ + struct grallocinfo info; + int i; + + grallocinfo_init(&info, 0, 0, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN); + + for (i = 1; i < 1920; i++) { + info.w = i; + info.h = i; + CHECK(allocate(ctx->device, &info)); + CHECK(deallocate(ctx->device, &info)); + } + + info.w = 1; + for (i = 1; i < 1920; i++) { + info.h = i; + CHECK(allocate(ctx->device, &info)); + CHECK(deallocate(ctx->device, &info)); + } + + info.h = 1; + for (i = 1; i < 1920; i++) { + info.w = i; + CHECK(allocate(ctx->device, &info)); + CHECK(deallocate(ctx->device, &info)); + } + + return 1; +} + +/* + * This function tests that we find at least one working format for each + * combos which we consider important. + */ +static int test_alloc_combinations(struct gralloctest_context *ctx) +{ + int i; + + struct grallocinfo info; + grallocinfo_init(&info, 512, 512, 0, 0); + + for (i = 0; i < ARRAY_SIZE(combos); i++) { + info.format = combos[i].format; + info.usage = combos[i].usage; + CHECK(allocate(ctx->device, &info)); + CHECK(deallocate(ctx->device, &info)); + } + + return 1; +} + +/* + * This function tests the advertised API version. + * Version_0_2 added (*lock_ycbcr)() method. + * Version_0_3 added fence passing to/from lock/unlock. + */ +static int test_api(struct gralloctest_context *ctx) +{ + + CHECK(ctx->module->registerBuffer); + CHECK(ctx->module->unregisterBuffer); + CHECK(ctx->module->lock); + CHECK(ctx->module->unlock); + + switch (ctx->module->common.module_api_version) { + case GRALLOC_MODULE_API_VERSION_0_3: + CHECK(ctx->module->lock_ycbcr); + CHECK(ctx->module->lockAsync); + CHECK(ctx->module->unlockAsync); + CHECK(ctx->module->lockAsync_ycbcr); + break; + case GRALLOC_MODULE_API_VERSION_0_2: + CHECK(ctx->module->lock_ycbcr); + CHECK(ctx->module->lockAsync == NULL); + CHECK(ctx->module->unlockAsync == NULL); + CHECK(ctx->module->lockAsync_ycbcr == NULL); + break; + case GRALLOC_MODULE_API_VERSION_0_1: + CHECK(ctx->module->lockAsync == NULL); + CHECK(ctx->module->unlockAsync == NULL); + CHECK(ctx->module->lockAsync_ycbcr == NULL); + CHECK(ctx->module->lock_ycbcr == NULL); + break; + default: + return 0; + } + + return 1; +} + +/* + * This function registers, unregisters, locks and unlocks the buffer in + * various orders. + */ +static int test_gralloc_order(struct gralloctest_context *ctx) +{ + struct grallocinfo info, duplicate; + + grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN); + + grallocinfo_init(&duplicate, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888, + GRALLOC_USAGE_SW_READ_OFTEN); + + CHECK(allocate(ctx->device, &info)); + + /* + * Duplicate the buffer handle to simulate an additional reference + * in same process. + */ + native_handle_t *native_handle = duplicate_buffer_handle(info.handle); + duplicate.handle = native_handle; + + CHECK(unregister_buffer(ctx->module, &duplicate) == 0); + CHECK(register_buffer(ctx->module, &duplicate)); + + CHECK(unlock(ctx->module, &duplicate) == 0); + + CHECK(lock(ctx->module, &duplicate)); + CHECK(duplicate.vaddr); + CHECK(unlock(ctx->module, &duplicate)); + + CHECK(unregister_buffer(ctx->module, &duplicate)); + + CHECK(register_buffer(ctx->module, &duplicate)); + CHECK(unregister_buffer(ctx->module, &duplicate)); + CHECK(unregister_buffer(ctx->module, &duplicate) == 0); + + CHECK(register_buffer(ctx->module, &duplicate)); + CHECK(deallocate(ctx->device, &info)); + + CHECK(lock(ctx->module, &duplicate)); + CHECK(lock(ctx->module, &duplicate)); + CHECK(unlock(ctx->module, &duplicate)); + CHECK(unlock(ctx->module, &duplicate)); + CHECK(unlock(ctx->module, &duplicate) == 0); + CHECK(unregister_buffer(ctx->module, &duplicate)); + + CHECK(native_handle_close(duplicate.handle) == 0); + CHECK(native_handle_delete(native_handle) == 0); + + return 1; +} + +/* This function tests CPU reads and writes. */ +static int test_mapping(struct gralloctest_context *ctx) +{ + struct grallocinfo info; + uint32_t *ptr = NULL; + uint32_t magic_number = 0x000ABBA; + + grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + + CHECK(allocate(ctx->device, &info)); + CHECK(lock(ctx->module, &info)); + + ptr = (uint32_t *)info.vaddr; + CHECK(ptr); + ptr[(info.w) / 2] = magic_number; + + CHECK(unlock(ctx->module, &info)); + info.vaddr = NULL; + ptr = NULL; + + CHECK(lock(ctx->module, &info)); + ptr = (uint32_t *)info.vaddr; + CHECK(ptr); + CHECK(ptr[info.w / 2] == magic_number); + + CHECK(unlock(ctx->module, &info)); + CHECK(deallocate(ctx->device, &info)); + + return 1; +} + +/* This function tests the private API we use in ARC++ -- not part of official + * gralloc. */ +static int test_perform(struct gralloctest_context *ctx) +{ + int32_t format; + uint64_t id1, id2; + uint32_t stride, width, height; + struct grallocinfo info, duplicate; + struct gralloc_module_t *mod = ctx->module; + + grallocinfo_init(&info, 650, 408, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN); + + CHECK(allocate(ctx->device, &info)); + + CHECK(mod->perform(mod, GRALLOC_DRM_GET_STRIDE, info.handle, &stride) == 0); + CHECK(stride == info.stride); + + CHECK(mod->perform(mod, GRALLOC_DRM_GET_FORMAT, info.handle, &format) == 0); + CHECK(format == info.format); + + CHECK(mod->perform(mod, GRALLOC_DRM_GET_DIMENSIONS, info.handle, &width, &height) == 0); + CHECK(width == info.w); + CHECK(height == info.h); + + native_handle_t *native_handle = duplicate_buffer_handle(info.handle); + duplicate.handle = native_handle; + + CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, duplicate.handle, &id2)); + CHECK(register_buffer(mod, &duplicate)); + + CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, info.handle, &id1) == 0); + CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, duplicate.handle, &id2) == 0); + CHECK(id1 == id2); + + CHECK(unregister_buffer(mod, &duplicate)); + CHECK(deallocate(ctx->device, &info)); + + return 1; +} + +/* This function tests that only YUV buffers work with *lock_ycbcr. */ +static int test_ycbcr(struct gralloctest_context *ctx) + +{ + struct grallocinfo info; + grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_YCbCr_420_888, + GRALLOC_USAGE_SW_READ_OFTEN); + + CHECK(allocate(ctx->device, &info)); + + CHECK(lock(ctx->module, &info) == 0); + CHECK(lock_ycbcr(ctx->module, &info)); + CHECK(info.ycbcr.y); + CHECK(info.ycbcr.cb); + CHECK(info.ycbcr.cr); + CHECK(unlock(ctx->module, &info)); + + CHECK(deallocate(ctx->device, &info)); + + info.format = HAL_PIXEL_FORMAT_BGRA_8888; + CHECK(allocate(ctx->device, &info)); + + CHECK(lock_ycbcr(ctx->module, &info) == 0); + CHECK(lock(ctx->module, &info)); + CHECK(unlock(ctx->module, &info)); + + CHECK(deallocate(ctx->device, &info)); + + return 1; +} + +/* + * This function tests a method ARC++ uses to query YUV buffer + * info -- not part of official gralloc API. This is used in + * Mali, Mesa, the ArcCodec and wayland_service. + */ +static int test_yuv_info(struct gralloctest_context *ctx) +{ + struct grallocinfo info; + uintptr_t y_size, c_stride, c_size, cr_offset, cb_offset; + uint32_t width, height; + width = height = 512; + + /* <system/graphics.h> defines YV12 as having: + * - an even width + * - an even height + * - a horizontal stride multiple of 16 pixels + * - a vertical stride equal to the height + * + * y_size = stride * height. + * c_stride = ALIGN(stride/2, 16). + * c_size = c_stride * height/2. + * size = y_size + c_size * 2. + * cr_offset = y_size. + * cb_offset = y_size + c_size. + */ + + grallocinfo_init(&info, width, height, HAL_PIXEL_FORMAT_YV12, GRALLOC_USAGE_SW_READ_OFTEN); + + CHECK(allocate(ctx->device, &info)); + + y_size = info.stride * height; + c_stride = ALIGN(info.stride / 2, 16); + c_size = c_stride * height / 2; + cr_offset = y_size; + cb_offset = y_size + c_size; + + info.usage = 0; + + /* + * Check if the (*lock_ycbcr) with usage of zero returns the + * offsets and strides of the YV12 buffer. This is unofficial + * behavior we are testing here. + */ + CHECK(lock_ycbcr(ctx->module, &info)); + + CHECK(info.stride == info.ycbcr.ystride); + CHECK(c_stride == info.ycbcr.cstride); + CHECK(cr_offset == (uintptr_t)info.ycbcr.cr); + CHECK(cb_offset == (uintptr_t)info.ycbcr.cb); + + CHECK(unlock(ctx->module, &info)); + + CHECK(deallocate(ctx->device, &info)); + + return 1; +} + +/* This function tests asynchronous locking and unlocking of buffers. */ +static int test_async(struct gralloctest_context *ctx) + +{ + struct grallocinfo rgba_info, ycbcr_info; + grallocinfo_init(&rgba_info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888, + GRALLOC_USAGE_SW_READ_OFTEN); + grallocinfo_init(&ycbcr_info, 512, 512, HAL_PIXEL_FORMAT_YCbCr_420_888, + GRALLOC_USAGE_SW_READ_OFTEN); + + CHECK(allocate(ctx->device, &rgba_info)); + CHECK(allocate(ctx->device, &ycbcr_info)); + + CHECK(lock_async(ctx->module, &rgba_info)); + CHECK(lock_async_ycbcr(ctx->module, &ycbcr_info)); + + CHECK(rgba_info.vaddr); + CHECK(ycbcr_info.ycbcr.y); + CHECK(ycbcr_info.ycbcr.cb); + CHECK(ycbcr_info.ycbcr.cr); + + /* + * Wait on the fence returned from unlock_async and check it doesn't + * return an error. + */ + CHECK(unlock_async(ctx->module, &rgba_info)); + CHECK(unlock_async(ctx->module, &ycbcr_info)); + + if (rgba_info.fence_fd >= 0) { + CHECK(sync_wait(rgba_info.fence_fd, 10000) >= 0); + CHECK(close(rgba_info.fence_fd) == 0); + } + + if (ycbcr_info.fence_fd >= 0) { + CHECK(sync_wait(ycbcr_info.fence_fd, 10000) >= 0); + CHECK(close(ycbcr_info.fence_fd) == 0); + } + + CHECK(deallocate(ctx->device, &rgba_info)); + CHECK(deallocate(ctx->device, &ycbcr_info)); + + return 1; +} + +static const struct gralloc_testcase tests[] = { + { "alloc_varying_sizes", test_alloc_varying_sizes, 1 }, + { "alloc_combinations", test_alloc_combinations, 1 }, + { "api", test_api, 1 }, + { "gralloc_order", test_gralloc_order, 1 }, + { "mapping", test_mapping, 1 }, + { "perform", test_perform, 1 }, + { "ycbcr", test_ycbcr, 2 }, + { "yuv_info", test_yuv_info, 2 }, + { "async", test_async, 3 }, +}; + +static void print_help(const char *argv0) +{ + uint32_t i; + printf("usage: %s <test_name>\n\n", argv0); + printf("A valid name test is one the following:\n"); + for (i = 0; i < ARRAY_SIZE(tests); i++) + printf("%s\n", tests[i].name); +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + uint32_t num_run = 0; + + setbuf(stdout, NULL); + if (argc == 2) { + uint32_t i; + char *name = argv[1]; + + struct gralloctest_context *ctx = test_init_gralloc(); + if (!ctx) { + fprintf(stderr, "[ FAILED ] to initialize gralloc.\n"); + return 1; + } + + for (i = 0; i < ARRAY_SIZE(tests); i++) { + if (strcmp(tests[i].name, name) && strcmp("all", name)) + continue; + + int success = 1; + if (ctx->api >= tests[i].required_api) + success = tests[i].run_test(ctx); + + printf("[ RUN ] gralloctest.%s\n", tests[i].name); + if (!success) { + fprintf(stderr, "[ FAILED ] gralloctest.%s\n", tests[i].name); + ret |= 1; + } else { + printf("[ PASSED ] gralloctest.%s\n", tests[i].name); + } + + num_run++; + } + + if (!test_close_gralloc(ctx)) { + fprintf(stderr, "[ FAILED ] to close gralloc.\n"); + return 1; + } + + if (!num_run) + goto print_usage; + + return ret; + } + +print_usage: + print_help(argv[0]); + return 0; +} |