• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#objective-cqt誰得cocoapythonrubywindowsphpgameguibathyscaphec翻訳omegatframework計画中(planning stage)twitterdombtronvb.nettestarduinodirectxpreviewerゲームエンジン

external/gbm_gralloc


Commit MetaInfo

Revision9a78d4f87eafcb1ab950ab3b4a07f45f10bbc16e (tree)
Time2019-01-02 11:43:54
AuthorMauro Rossi <issor.oruam@gmai...>
CommiterChih-Wei Huang

Log Message

android: add gralloctest

gralloctest executable is added for Android based on minigbm/cros_gralloc commits:

b57dffc ("minigbm: move gralloctest to this repo")
2eeaf5a ("minigbm: cros_gralloc: fix -Wimplicit-function-declaration warnings in gralloctest")

Signed-off-by: Mauro Rossi <issor.oruam@gmail.com>

Change Summary

Incremental Difference

--- a/Android.mk
+++ b/Android.mk
@@ -41,3 +41,4 @@ LOCAL_MODULE_RELATIVE_PATH := hw
4141 LOCAL_PROPRIETARY_MODULE := true
4242
4343 include $(BUILD_SHARED_LIBRARY)
44+include $(LOCAL_PATH)/tests/Android.mk
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,36 @@
1+# Copyright 2016 The Chromium OS Authors
2+# Copyright 2018 Mauro Rossi <issor.oruam@gmailc.com>
3+#
4+# Permission is hereby granted, free of charge, to any person obtaining a
5+# copy of this software and associated documentation files (the "Software"),
6+# to deal in the Software without restriction, including without limitation
7+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+# and/or sell copies of the Software, and to permit persons to whom the
9+# Software is furnished to do so, subject to the following conditions:
10+#
11+# The above copyright notice and this permission notice shall be included
12+# in all copies or substantial portions of the Software.
13+#
14+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+# DEALINGS IN THE SOFTWARE.
21+
22+LOCAL_PATH := $(call my-dir)
23+
24+include $(CLEAR_VARS)
25+include $(LOCAL_PATH)/Makefile.sources
26+
27+LOCAL_SRC_FILES := $(GRALLOCTEST_FILES)
28+
29+LOCAL_MODULE := gralloctest
30+
31+LOCAL_SHARED_LIBRARIES := \
32+ libhardware \
33+ libsync \
34+ libcutils
35+
36+include $(BUILD_EXECUTABLE)
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,30 @@
1+# Copyright 2016 The Chromium OS Authors. All rights reserved.
2+# Use of this source code is governed by a BSD-style license that can be
3+# found in the LICENSE file.
4+
5+GRALLOCTEST = gralloctest
6+SOURCES += gralloctest.c
7+
8+CCFLAGS += -g -O2 -Wall -fPIE
9+LIBS += -lhardware -lsync -lcutils -pie
10+
11+OBJS = $(foreach source, $(SOURCES), $(addsuffix .o, $(basename $(source))))
12+
13+OBJECTS = $(addprefix $(TARGET_DIR), $(notdir $(OBJS)))
14+BINARY = $(addprefix $(TARGET_DIR), $(GRALLOCTEST))
15+
16+.PHONY: all clean
17+
18+all: $(BINARY)
19+
20+$(BINARY): $(OBJECTS)
21+
22+clean:
23+ $(RM) $(BINARY)
24+ $(RM) $(OBJECTS)
25+
26+$(BINARY):
27+ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)
28+
29+$(TARGET_DIR)%.o: %.c
30+ $(CC) $(CFLAGS) -c $^ -o $@ -MMD
--- /dev/null
+++ b/tests/Makefile.sources
@@ -0,0 +1,2 @@
1+GRALLOCTEST_FILES := \
2+ gralloctest.c
--- /dev/null
+++ b/tests/gralloctest.c
@@ -0,0 +1,705 @@
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+}