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
266 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module);
267 if (err)
268 return NULL;
269
270 gralloc_open(hw_module, &ctx->device);
271 ctx->module = (gralloc_module_t *)hw_module;
272 if (!ctx->module || !ctx->device)
273 return NULL;
274
275 switch (ctx->module->common.module_api_version) {
276 case GRALLOC_MODULE_API_VERSION_0_3:
277 ctx->api = 3;
278 break;
279 case GRALLOC_MODULE_API_VERSION_0_2:
280 ctx->api = 2;
281 break;
282 default:
283 ctx->api = 1;
284 }
285
286 return ctx;
287 }
288
test_close_gralloc(struct gralloctest_context * ctx)289 static int test_close_gralloc(struct gralloctest_context *ctx)
290 {
291 CHECK(gralloc_close(ctx->device) == 0);
292 return 1;
293 }
294
295 /* This function tests allocation with varying buffer dimensions. */
test_alloc_varying_sizes(struct gralloctest_context * ctx)296 static int test_alloc_varying_sizes(struct gralloctest_context *ctx)
297 {
298 struct grallocinfo info;
299 int i;
300
301 grallocinfo_init(&info, 0, 0, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN);
302
303 for (i = 1; i < 1920; i++) {
304 info.w = i;
305 info.h = i;
306 CHECK(allocate(ctx->device, &info));
307 CHECK(deallocate(ctx->device, &info));
308 }
309
310 info.w = 1;
311 for (i = 1; i < 1920; i++) {
312 info.h = i;
313 CHECK(allocate(ctx->device, &info));
314 CHECK(deallocate(ctx->device, &info));
315 }
316
317 info.h = 1;
318 for (i = 1; i < 1920; i++) {
319 info.w = i;
320 CHECK(allocate(ctx->device, &info));
321 CHECK(deallocate(ctx->device, &info));
322 }
323
324 return 1;
325 }
326
327 /*
328 * This function tests that we find at least one working format for each
329 * combos which we consider important.
330 */
test_alloc_combinations(struct gralloctest_context * ctx)331 static int test_alloc_combinations(struct gralloctest_context *ctx)
332 {
333 int i;
334
335 struct grallocinfo info;
336 grallocinfo_init(&info, 512, 512, 0, 0);
337
338 for (i = 0; i < ARRAY_SIZE(combos); i++) {
339 info.format = combos[i].format;
340 info.usage = combos[i].usage;
341 CHECK(allocate(ctx->device, &info));
342 CHECK(deallocate(ctx->device, &info));
343 }
344
345 return 1;
346 }
347
348 /*
349 * This function tests the advertised API version.
350 * Version_0_2 added (*lock_ycbcr)() method.
351 * Version_0_3 added fence passing to/from lock/unlock.
352 */
test_api(struct gralloctest_context * ctx)353 static int test_api(struct gralloctest_context *ctx)
354 {
355
356 CHECK(ctx->module->registerBuffer);
357 CHECK(ctx->module->unregisterBuffer);
358 CHECK(ctx->module->lock);
359 CHECK(ctx->module->unlock);
360
361 switch (ctx->module->common.module_api_version) {
362 case GRALLOC_MODULE_API_VERSION_0_3:
363 CHECK(ctx->module->lock_ycbcr);
364 CHECK(ctx->module->lockAsync);
365 CHECK(ctx->module->unlockAsync);
366 CHECK(ctx->module->lockAsync_ycbcr);
367 break;
368 case GRALLOC_MODULE_API_VERSION_0_2:
369 CHECK(ctx->module->lock_ycbcr);
370 CHECK(ctx->module->lockAsync == NULL);
371 CHECK(ctx->module->unlockAsync == NULL);
372 CHECK(ctx->module->lockAsync_ycbcr == NULL);
373 break;
374 case GRALLOC_MODULE_API_VERSION_0_1:
375 CHECK(ctx->module->lockAsync == NULL);
376 CHECK(ctx->module->unlockAsync == NULL);
377 CHECK(ctx->module->lockAsync_ycbcr == NULL);
378 CHECK(ctx->module->lock_ycbcr == NULL);
379 break;
380 default:
381 return 0;
382 }
383
384 return 1;
385 }
386
387 /*
388 * This function registers, unregisters, locks and unlocks the buffer in
389 * various orders.
390 */
test_gralloc_order(struct gralloctest_context * ctx)391 static int test_gralloc_order(struct gralloctest_context *ctx)
392 {
393 struct grallocinfo info, duplicate;
394
395 grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN);
396
397 grallocinfo_init(&duplicate, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
398 GRALLOC_USAGE_SW_READ_OFTEN);
399
400 CHECK(allocate(ctx->device, &info));
401
402 /*
403 * Duplicate the buffer handle to simulate an additional reference
404 * in same process.
405 */
406 native_handle_t *native_handle = duplicate_buffer_handle(info.handle);
407 duplicate.handle = native_handle;
408
409 CHECK(unregister_buffer(ctx->module, &duplicate) == 0);
410 CHECK(register_buffer(ctx->module, &duplicate));
411
412 CHECK(unlock(ctx->module, &duplicate) == 0);
413
414 CHECK(lock(ctx->module, &duplicate));
415 CHECK(duplicate.vaddr);
416 CHECK(unlock(ctx->module, &duplicate));
417
418 CHECK(unregister_buffer(ctx->module, &duplicate));
419
420 CHECK(register_buffer(ctx->module, &duplicate));
421 CHECK(unregister_buffer(ctx->module, &duplicate));
422 CHECK(unregister_buffer(ctx->module, &duplicate) == 0);
423
424 CHECK(register_buffer(ctx->module, &duplicate));
425 CHECK(deallocate(ctx->device, &info));
426
427 CHECK(lock(ctx->module, &duplicate));
428 CHECK(lock(ctx->module, &duplicate));
429 CHECK(unlock(ctx->module, &duplicate));
430 CHECK(unlock(ctx->module, &duplicate));
431 CHECK(unlock(ctx->module, &duplicate) == 0);
432 CHECK(unregister_buffer(ctx->module, &duplicate));
433
434 CHECK(native_handle_close(duplicate.handle) == 0);
435 CHECK(native_handle_delete(native_handle) == 0);
436
437 return 1;
438 }
439
440 /* This function tests CPU reads and writes. */
test_mapping(struct gralloctest_context * ctx)441 static int test_mapping(struct gralloctest_context *ctx)
442 {
443 struct grallocinfo info;
444 uint32_t *ptr = NULL;
445 uint32_t magic_number = 0x000ABBA;
446
447 grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
448 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
449
450 CHECK(allocate(ctx->device, &info));
451 CHECK(lock(ctx->module, &info));
452
453 ptr = (uint32_t *)info.vaddr;
454 CHECK(ptr);
455 ptr[(info.w) / 2] = magic_number;
456
457 CHECK(unlock(ctx->module, &info));
458 info.vaddr = NULL;
459 ptr = NULL;
460
461 CHECK(lock(ctx->module, &info));
462 ptr = (uint32_t *)info.vaddr;
463 CHECK(ptr);
464 CHECK(ptr[info.w / 2] == magic_number);
465
466 CHECK(unlock(ctx->module, &info));
467 CHECK(deallocate(ctx->device, &info));
468
469 return 1;
470 }
471
472 /* This function tests the private API we use in ARC++ -- not part of official
473 * gralloc. */
test_perform(struct gralloctest_context * ctx)474 static int test_perform(struct gralloctest_context *ctx)
475 {
476 int32_t format;
477 uint64_t id1, id2;
478 uint32_t stride, width, height, req_usage, gralloc_usage;
479 struct grallocinfo info, duplicate;
480 struct gralloc_module_t *mod = ctx->module;
481
482 grallocinfo_init(&info, 650, 408, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_SW_READ_OFTEN);
483
484 CHECK(allocate(ctx->device, &info));
485
486 CHECK(mod->perform(mod, GRALLOC_DRM_GET_STRIDE, info.handle, &stride) == 0);
487 CHECK(stride >= info.stride);
488
489 CHECK(mod->perform(mod, GRALLOC_DRM_GET_FORMAT, info.handle, &format) == 0);
490 CHECK(format == info.format);
491
492 CHECK(mod->perform(mod, GRALLOC_DRM_GET_DIMENSIONS, info.handle, &width, &height) == 0);
493 CHECK(width == info.w);
494 CHECK(height == info.h);
495
496 native_handle_t *native_handle = duplicate_buffer_handle(info.handle);
497 duplicate.handle = native_handle;
498
499 CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, duplicate.handle, &id2));
500 CHECK(register_buffer(mod, &duplicate));
501
502 CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, info.handle, &id1) == 0);
503 CHECK(mod->perform(mod, GRALLOC_DRM_GET_BACKING_STORE, duplicate.handle, &id2) == 0);
504 CHECK(id1 == id2);
505
506 CHECK(unregister_buffer(mod, &duplicate));
507 CHECK(deallocate(ctx->device, &info));
508
509 req_usage = 0;
510 gralloc_usage = 0;
511 CHECK(mod->perform(mod, GRALLOC_DRM_GET_USAGE, req_usage, &gralloc_usage) == 0);
512 CHECK(gralloc_usage == 0);
513
514 req_usage = GRALLOC_DRM_GET_USAGE_FRONT_RENDERING_BIT;
515 gralloc_usage = 0;
516 CHECK(mod->perform(mod, GRALLOC_DRM_GET_USAGE, req_usage, &gralloc_usage) == 0);
517 CHECK(gralloc_usage == BUFFER_USAGE_FRONT_RENDERING);
518
519 return 1;
520 }
521
522 /* This function tests that only YUV buffers work with *lock_ycbcr. */
test_ycbcr(struct gralloctest_context * ctx)523 static int test_ycbcr(struct gralloctest_context *ctx)
524
525 {
526 struct grallocinfo info;
527 grallocinfo_init(&info, 512, 512, HAL_PIXEL_FORMAT_YCbCr_420_888,
528 GRALLOC_USAGE_SW_READ_OFTEN);
529
530 CHECK(allocate(ctx->device, &info));
531
532 CHECK(lock(ctx->module, &info) == 0);
533 CHECK(lock_ycbcr(ctx->module, &info));
534 CHECK(info.ycbcr.y);
535 CHECK(info.ycbcr.cb);
536 CHECK(info.ycbcr.cr);
537 CHECK(unlock(ctx->module, &info));
538
539 CHECK(deallocate(ctx->device, &info));
540
541 info.format = HAL_PIXEL_FORMAT_BGRA_8888;
542 CHECK(allocate(ctx->device, &info));
543
544 CHECK(lock_ycbcr(ctx->module, &info) == 0);
545 CHECK(lock(ctx->module, &info));
546 CHECK(unlock(ctx->module, &info));
547
548 CHECK(deallocate(ctx->device, &info));
549
550 return 1;
551 }
552
553 /*
554 * This function tests a method ARC++ uses to query YUV buffer
555 * info -- not part of official gralloc API. This is used in
556 * Mali, Mesa, the ArcCodec and wayland_service.
557 */
test_yuv_info(struct gralloctest_context * ctx)558 static int test_yuv_info(struct gralloctest_context *ctx)
559 {
560 struct grallocinfo info;
561 uintptr_t y_size, c_stride, c_size, cr_offset, cb_offset;
562 uint32_t width, height;
563 width = height = 512;
564
565 /* <system/graphics.h> defines YV12 as having:
566 * - an even width
567 * - an even height
568 * - a horizontal stride multiple of 16 pixels
569 * - a vertical stride equal to the height
570 *
571 * y_size = stride * height.
572 * c_stride = ALIGN(stride/2, 16).
573 * c_size = c_stride * height/2.
574 * size = y_size + c_size * 2.
575 * cr_offset = y_size.
576 * cb_offset = y_size + c_size.
577 */
578
579 grallocinfo_init(&info, width, height, HAL_PIXEL_FORMAT_YV12, GRALLOC_USAGE_SW_READ_OFTEN);
580
581 CHECK(allocate(ctx->device, &info));
582
583 y_size = info.stride * height;
584 c_stride = ALIGN(info.stride / 2, 16);
585 c_size = c_stride * height / 2;
586 cr_offset = y_size;
587 cb_offset = y_size + c_size;
588
589 info.usage = 0;
590
591 /*
592 * Check if the (*lock_ycbcr) with usage of zero returns the
593 * offsets and strides of the YV12 buffer. This is unofficial
594 * behavior we are testing here.
595 */
596 CHECK(lock_ycbcr(ctx->module, &info));
597
598 CHECK(info.stride == info.ycbcr.ystride);
599 CHECK(c_stride == info.ycbcr.cstride);
600 CHECK(cr_offset == (uintptr_t)info.ycbcr.cr);
601 CHECK(cb_offset == (uintptr_t)info.ycbcr.cb);
602
603 CHECK(unlock(ctx->module, &info));
604
605 CHECK(deallocate(ctx->device, &info));
606
607 return 1;
608 }
609
610 /* This function tests asynchronous locking and unlocking of buffers. */
test_async(struct gralloctest_context * ctx)611 static int test_async(struct gralloctest_context *ctx)
612
613 {
614 struct grallocinfo rgba_info, ycbcr_info;
615 grallocinfo_init(&rgba_info, 512, 512, HAL_PIXEL_FORMAT_BGRA_8888,
616 GRALLOC_USAGE_SW_READ_OFTEN);
617 grallocinfo_init(&ycbcr_info, 512, 512, HAL_PIXEL_FORMAT_YCbCr_420_888,
618 GRALLOC_USAGE_SW_READ_OFTEN);
619
620 CHECK(allocate(ctx->device, &rgba_info));
621 CHECK(allocate(ctx->device, &ycbcr_info));
622
623 CHECK(lock_async(ctx->module, &rgba_info));
624 CHECK(lock_async_ycbcr(ctx->module, &ycbcr_info));
625
626 CHECK(rgba_info.vaddr);
627 CHECK(ycbcr_info.ycbcr.y);
628 CHECK(ycbcr_info.ycbcr.cb);
629 CHECK(ycbcr_info.ycbcr.cr);
630
631 /*
632 * Wait on the fence returned from unlock_async and check it doesn't
633 * return an error.
634 */
635 CHECK(unlock_async(ctx->module, &rgba_info));
636 CHECK(unlock_async(ctx->module, &ycbcr_info));
637
638 if (rgba_info.fence_fd >= 0) {
639 CHECK(sync_wait(rgba_info.fence_fd, 10000) >= 0);
640 CHECK(close(rgba_info.fence_fd) == 0);
641 }
642
643 if (ycbcr_info.fence_fd >= 0) {
644 CHECK(sync_wait(ycbcr_info.fence_fd, 10000) >= 0);
645 CHECK(close(ycbcr_info.fence_fd) == 0);
646 }
647
648 CHECK(deallocate(ctx->device, &rgba_info));
649 CHECK(deallocate(ctx->device, &ycbcr_info));
650
651 return 1;
652 }
653
654 static const struct gralloc_testcase tests[] = {
655 { "alloc_varying_sizes", test_alloc_varying_sizes, 1 },
656 { "alloc_combinations", test_alloc_combinations, 1 },
657 { "api", test_api, 1 },
658 { "gralloc_order", test_gralloc_order, 1 },
659 { "mapping", test_mapping, 1 },
660 { "perform", test_perform, 1 },
661 { "ycbcr", test_ycbcr, 2 },
662 { "yuv_info", test_yuv_info, 2 },
663 { "async", test_async, 3 },
664 };
665
print_help(const char * argv0)666 static void print_help(const char *argv0)
667 {
668 uint32_t i;
669 printf("usage: %s <test_name>\n\n", argv0);
670 printf("A valid name test is one the following:\n");
671 for (i = 0; i < ARRAY_SIZE(tests); i++)
672 printf("%s\n", tests[i].name);
673 }
674
main(int argc,char * argv[])675 int main(int argc, char *argv[])
676 {
677 int ret = 0;
678 uint32_t num_run = 0;
679
680 setbuf(stdout, NULL);
681 if (argc == 2) {
682 uint32_t i;
683 char *name = argv[1];
684
685 struct gralloctest_context *ctx = test_init_gralloc();
686 if (!ctx) {
687 fprintf(stderr, "[ FAILED ] to initialize gralloc.\n");
688 return 1;
689 }
690
691 for (i = 0; i < ARRAY_SIZE(tests); i++) {
692 if (strcmp(tests[i].name, name) && strcmp("all", name))
693 continue;
694
695 printf("[ RUN ] gralloctest.%s\n", tests[i].name);
696
697 int success = 1;
698 if (ctx->api >= tests[i].required_api)
699 success = tests[i].run_test(ctx);
700
701 if (!success) {
702 fprintf(stderr, "[ FAILED ] gralloctest.%s\n", tests[i].name);
703 ret |= 1;
704 } else {
705 printf("[ PASSED ] gralloctest.%s\n", tests[i].name);
706 }
707
708 num_run++;
709 }
710
711 if (!test_close_gralloc(ctx)) {
712 fprintf(stderr, "[ FAILED ] to close gralloc.\n");
713 return 1;
714 }
715
716 if (!num_run)
717 goto print_usage;
718
719 return ret;
720 }
721
722 print_usage:
723 print_help(argv[0]);
724 return 0;
725 }
726