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.
7 #include "../cros_gralloc_driver.h"
9 #include <hardware/gralloc.h>
12 #include "../i915_private_android.h"
13 #include "../i915_private_android_types.h"
15 struct gralloc0_module {
16 gralloc_module_t base;
17 std::unique_ptr<alloc_device_t> alloc;
18 std::unique_ptr<cros_gralloc_driver> driver;
20 SpinLock initialization_mutex;
23 /* This enumeration must match the one in <gralloc_drm.h>.
24 * The functions supported by this gralloc's temporary private API are listed
25 * below. Use of these functions is highly discouraged and should only be
26 * reserved for cases where no alternative to get same information (such as
27 * querying ANativeWindow) exists.
31 GRALLOC_DRM_GET_STRIDE,
32 GRALLOC_DRM_GET_FORMAT,
33 GRALLOC_DRM_GET_DIMENSIONS,
34 GRALLOC_DRM_GET_BACKING_STORE,
38 static uint64_t gralloc0_convert_usage(int usage)
40 uint64_t use_flags = BO_USE_NONE;
42 if (usage & GRALLOC_USAGE_CURSOR)
43 use_flags |= BO_USE_CURSOR;
44 if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY)
45 use_flags |= BO_USE_SW_READ_RARELY;
46 if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
47 use_flags |= BO_USE_SW_READ_OFTEN;
48 if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY)
49 use_flags |= BO_USE_SW_WRITE_RARELY;
50 if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN)
51 use_flags |= BO_USE_SW_WRITE_OFTEN;
52 if (usage & GRALLOC_USAGE_HW_TEXTURE)
53 use_flags |= BO_USE_TEXTURE;
54 if (usage & GRALLOC_USAGE_HW_RENDER)
55 use_flags |= BO_USE_RENDERING;
56 if (usage & GRALLOC_USAGE_HW_2D)
57 use_flags |= BO_USE_RENDERING;
58 if (usage & GRALLOC_USAGE_HW_COMPOSER)
59 /* HWC wants to use display hardware, but can defer to OpenGL. */
60 use_flags |= BO_USE_SCANOUT | BO_USE_TEXTURE;
61 if (usage & GRALLOC_USAGE_HW_FB)
62 use_flags |= BO_USE_NONE;
63 if (usage & GRALLOC_USAGE_EXTERNAL_DISP)
65 * This flag potentially covers external display for the normal drivers (i915,
66 * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it.
68 use_flags |= BO_USE_NONE;
69 if (usage & GRALLOC_USAGE_PROTECTED)
70 use_flags |= BO_USE_PROTECTED;
71 if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
72 /*HACK: See b/30054495 */
73 use_flags |= BO_USE_SW_READ_OFTEN;
74 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
75 use_flags |= BO_USE_CAMERA_WRITE;
76 if (usage & GRALLOC_USAGE_HW_CAMERA_READ)
77 use_flags |= BO_USE_CAMERA_READ;
78 if (usage & GRALLOC_USAGE_RENDERSCRIPT)
79 use_flags |= BO_USE_RENDERSCRIPT;
84 static uint32_t gralloc0_convert_map_usage(int map_usage)
86 uint32_t map_flags = BO_MAP_NONE;
88 if (map_usage & GRALLOC_USAGE_SW_READ_MASK)
89 map_flags |= BO_MAP_READ;
90 if (map_usage & GRALLOC_USAGE_SW_WRITE_MASK)
91 map_flags |= BO_MAP_WRITE;
96 static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage,
97 buffer_handle_t *handle, int *stride)
101 struct cros_gralloc_buffer_descriptor descriptor;
102 auto mod = (struct gralloc0_module *)dev->common.module;
104 descriptor.width = w;
105 descriptor.height = h;
106 descriptor.droid_format = format;
107 descriptor.producer_usage = descriptor.consumer_usage = usage;
108 descriptor.modifier = 0;
109 descriptor.drm_format = cros_gralloc_convert_format(format);
110 descriptor.use_flags = gralloc0_convert_usage(usage);
112 supported = mod->driver->is_supported(&descriptor);
113 if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) {
114 descriptor.use_flags &= ~BO_USE_SCANOUT;
115 supported = mod->driver->is_supported(&descriptor);
119 cros_gralloc_error("Unsupported combination -- HAL format: %u, HAL usage: %u, "
120 "drv_format: %4.4s, use_flags: %llu",
121 format, usage, drmFormat2Str(descriptor.drm_format),
122 static_cast<unsigned long long>(descriptor.use_flags));
126 ret = mod->driver->allocate(&descriptor, handle);
130 auto hnd = cros_gralloc_convert_handle(*handle);
131 *stride = hnd->pixel_stride;
136 static int gralloc0_free(alloc_device_t *dev, buffer_handle_t handle)
138 auto mod = (struct gralloc0_module *)dev->common.module;
139 return mod->driver->release(handle);
142 static int gralloc0_close(struct hw_device_t *dev)
144 /* Memory is freed by managed pointers on process close. */
148 static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc)
150 SCOPED_SPIN_LOCK(mod->initialization_mutex);
152 if (mod->initialized)
155 mod->driver = std::make_unique<cros_gralloc_driver>();
156 if (mod->driver->init()) {
157 cros_gralloc_error("Failed to initialize driver.");
161 if (initialize_alloc) {
162 mod->alloc = std::make_unique<alloc_device_t>();
163 mod->alloc->alloc = gralloc0_alloc;
164 mod->alloc->free = gralloc0_free;
165 mod->alloc->common.tag = HARDWARE_DEVICE_TAG;
166 mod->alloc->common.version = 0;
167 mod->alloc->common.module = (hw_module_t *)mod;
168 mod->alloc->common.close = gralloc0_close;
171 mod->initialized = true;
175 static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev)
177 auto module = (struct gralloc0_module *)mod;
179 if (module->initialized) {
180 *dev = &module->alloc->common;
184 /* On Android M, Surfaceflinger tries to open the gralloc device
185 * using name GRALLOC_HARDWARE_FB0.
187 if ((strcmp(name, GRALLOC_HARDWARE_GPU0)!=0) && (strcmp(name, GRALLOC_HARDWARE_FB0)!=0)) {
188 cros_gralloc_error("Incorrect device name - %s.", name);
192 if (gralloc0_init(module, true))
195 *dev = &module->alloc->common;
199 static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffer_handle_t handle)
201 auto mod = (struct gralloc0_module *)module;
203 if (!mod->initialized)
204 if (gralloc0_init(mod, false))
207 return mod->driver->retain(handle);
210 static int gralloc0_unregister_buffer(struct gralloc_module_t const *module, buffer_handle_t handle)
212 auto mod = (struct gralloc0_module *)module;
213 return mod->driver->release(handle);
216 static int gralloc0_lock(struct gralloc_module_t const *module, buffer_handle_t handle, int usage,
217 int l, int t, int w, int h, void **vaddr)
219 return module->lockAsync(module, handle, usage, l, t, w, h, vaddr, -1);
222 static int gralloc0_unlock(struct gralloc_module_t const *module, buffer_handle_t handle)
224 int32_t fence_fd, ret;
225 auto mod = (struct gralloc0_module *)module;
226 ret = mod->driver->unlock(handle, &fence_fd);
230 ret = cros_gralloc_sync_wait(fence_fd);
237 static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
240 int32_t *out_format, ret;
242 buffer_handle_t handle;
243 uint32_t *out_width, *out_height, *out_stride;
244 auto mod = (struct gralloc0_module *)module;
247 case GRALLOC_DRM_GET_STRIDE:
248 case GRALLOC_DRM_GET_FORMAT:
249 case GRALLOC_DRM_GET_DIMENSIONS:
250 case GRALLOC_DRM_GET_BACKING_STORE:
259 handle = va_arg(args, buffer_handle_t);
260 auto hnd = cros_gralloc_convert_handle(handle);
262 cros_gralloc_error("Invalid handle.");
267 case GRALLOC_DRM_GET_STRIDE:
268 out_stride = va_arg(args, uint32_t *);
269 *out_stride = hnd->pixel_stride;
271 case GRALLOC_DRM_GET_FORMAT:
272 out_format = va_arg(args, int32_t *);
273 *out_format = hnd->droid_format;
275 case GRALLOC_DRM_GET_DIMENSIONS:
276 out_width = va_arg(args, uint32_t *);
277 out_height = va_arg(args, uint32_t *);
278 *out_width = hnd->width;
279 *out_height = hnd->height;
281 case GRALLOC_DRM_GET_BACKING_STORE:
282 out_store = va_arg(args, uint64_t *);
283 ret = mod->driver->get_backing_store(handle, out_store);
294 static int gralloc0_lock_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle,
295 int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr)
297 return module->lockAsync_ycbcr(module, handle, usage, l, t, w, h, ycbcr, -1);
300 static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_handle_t handle,
301 int usage, int l, int t, int w, int h, void **vaddr, int fence_fd)
305 uint8_t *addr[DRV_MAX_PLANES];
306 auto mod = (struct gralloc0_module *)module;
308 auto hnd = cros_gralloc_convert_handle(handle);
310 cros_gralloc_error("Invalid handle.");
314 if (hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
315 cros_gralloc_error("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.");
319 map_flags = gralloc0_convert_map_usage(usage);
320 ret = mod->driver->lock(handle, fence_fd, map_flags, addr);
325 static int gralloc0_unlock_async(struct gralloc_module_t const *module, buffer_handle_t handle,
328 auto mod = (struct gralloc0_module *)module;
329 return mod->driver->unlock(handle, fence_fd);
332 static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle,
333 int usage, int l, int t, int w, int h,
334 struct android_ycbcr *ycbcr, int fence_fd)
338 uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr };
339 auto mod = (struct gralloc0_module *)module;
341 auto hnd = cros_gralloc_convert_handle(handle);
343 cros_gralloc_error("Invalid handle.");
347 if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) &&
348 (hnd->droid_format != HAL_PIXEL_FORMAT_YV12) &&
349 (hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) &&
350 !i915_private_supported_yuv_format(hnd->droid_format)) {
351 cros_gralloc_error("Non-YUV format not compatible.");
355 map_flags = gralloc0_convert_map_usage(usage);
356 ret = mod->driver->lock(handle, fence_fd, map_flags, addr);
360 switch (hnd->format) {
361 case DRM_FORMAT_NV12:
362 case DRM_FORMAT_NV12_Y_TILED_INTEL:
365 ycbcr->cr = addr[1] + 1;
366 ycbcr->ystride = hnd->strides[0];
367 ycbcr->cstride = hnd->strides[1];
368 ycbcr->chroma_step = 2;
370 case DRM_FORMAT_YVU420:
371 case DRM_FORMAT_YVU420_ANDROID:
375 ycbcr->ystride = hnd->strides[0];
376 ycbcr->cstride = hnd->strides[1];
377 ycbcr->chroma_step = 1;
380 module->unlock(module, handle);
388 static struct hw_module_methods_t gralloc0_module_methods = { .open = gralloc0_open };
391 struct gralloc0_module HAL_MODULE_INFO_SYM = {
396 .tag = HARDWARE_MODULE_TAG,
397 .module_api_version = GRALLOC_MODULE_API_VERSION_0_3,
398 .hal_api_version = 0,
399 .id = GRALLOC_HARDWARE_MODULE_ID,
400 .name = "CrOS Gralloc",
401 .author = "Chrome OS",
402 .methods = &gralloc0_module_methods,
405 .registerBuffer = gralloc0_register_buffer,
406 .unregisterBuffer = gralloc0_unregister_buffer,
407 .lock = gralloc0_lock,
408 .unlock = gralloc0_unlock,
409 .perform = gralloc0_perform,
410 .lock_ycbcr = gralloc0_lock_ycbcr,
411 .lockAsync = gralloc0_lock_async,
412 .unlockAsync = gralloc0_unlock_async,
413 .lockAsync_ycbcr = gralloc0_lock_async_ycbcr,
418 .initialized = false,