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"
10 #include <hardware/gralloc.h>
13 #include "drm_framebuffer.h"
14 #include "gralloc_drm.h"
16 struct gralloc0_module {
17 gralloc_module_t base;
18 std::unique_ptr<alloc_device_t> alloc;
19 std::unique_ptr<cros_gralloc_driver> driver;
20 struct drm_framebuffer *fb;
22 std::mutex initialization_mutex;
25 /* This enumeration must match the one in <gralloc_drm.h>.
26 * The functions supported by this gralloc's temporary private API are listed
27 * below. Use of these functions is highly discouraged and should only be
28 * reserved for cases where no alternative to get same information (such as
29 * querying ANativeWindow) exists.
33 GRALLOC_DRM_GET_STRIDE,
34 GRALLOC_DRM_GET_FORMAT,
35 GRALLOC_DRM_GET_DIMENSIONS,
36 GRALLOC_DRM_GET_BACKING_STORE,
40 static uint64_t gralloc0_convert_usage(int usage)
42 uint64_t use_flags = BO_USE_NONE;
44 if (usage & GRALLOC_USAGE_CURSOR)
45 use_flags |= BO_USE_NONE;
46 if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY)
47 use_flags |= BO_USE_SW_READ_RARELY;
48 if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
49 use_flags |= BO_USE_SW_READ_OFTEN;
50 if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY)
51 use_flags |= BO_USE_SW_WRITE_RARELY;
52 if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN)
53 use_flags |= BO_USE_SW_WRITE_OFTEN;
54 if (usage & GRALLOC_USAGE_HW_TEXTURE)
55 use_flags |= BO_USE_TEXTURE;
56 if (usage & GRALLOC_USAGE_HW_RENDER)
57 use_flags |= BO_USE_RENDERING;
58 if (usage & GRALLOC_USAGE_HW_2D)
59 use_flags |= BO_USE_RENDERING;
60 if (usage & GRALLOC_USAGE_HW_COMPOSER)
61 /* HWC wants to use display hardware, but can defer to OpenGL. */
62 use_flags |= BO_USE_SCANOUT | BO_USE_TEXTURE;
63 if (usage & GRALLOC_USAGE_HW_FB)
64 use_flags |= BO_USE_FRAMEBUFFER;
65 if (usage & GRALLOC_USAGE_EXTERNAL_DISP)
67 * This flag potentially covers external display for the normal drivers (i915,
68 * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it.
70 use_flags |= BO_USE_NONE;
71 if (usage & GRALLOC_USAGE_PROTECTED)
72 use_flags |= BO_USE_PROTECTED;
73 if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
74 /*HACK: See b/30054495 */
75 use_flags |= BO_USE_SW_READ_OFTEN;
76 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
77 use_flags |= BO_USE_CAMERA_WRITE;
78 if (usage & GRALLOC_USAGE_HW_CAMERA_READ)
79 use_flags |= BO_USE_CAMERA_READ;
80 if (usage & GRALLOC_USAGE_RENDERSCRIPT)
81 use_flags |= BO_USE_RENDERSCRIPT;
86 static uint32_t gralloc0_convert_map_usage(int map_usage)
88 uint32_t map_flags = BO_MAP_NONE;
90 if (map_usage & GRALLOC_USAGE_SW_READ_MASK)
91 map_flags |= BO_MAP_READ;
92 if (map_usage & GRALLOC_USAGE_SW_WRITE_MASK)
93 map_flags |= BO_MAP_WRITE;
98 static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage,
99 buffer_handle_t *handle, int *stride)
103 struct cros_gralloc_buffer_descriptor descriptor;
104 auto mod = (struct gralloc0_module const *)dev->common.module;
106 descriptor.width = w;
107 descriptor.height = h;
108 descriptor.droid_format = format;
109 descriptor.producer_usage = descriptor.consumer_usage = usage;
110 descriptor.drm_format = cros_gralloc_convert_format(format);
111 descriptor.use_flags = gralloc0_convert_usage(usage);
113 supported = mod->driver->is_supported(&descriptor);
114 if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) {
115 descriptor.use_flags &= ~BO_USE_SCANOUT;
116 supported = mod->driver->is_supported(&descriptor);
120 drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, "
121 "drv_format: %4.4s, use_flags: %llu\n",
122 format, usage, reinterpret_cast<char *>(&descriptor.drm_format),
123 static_cast<unsigned long long>(descriptor.use_flags));
127 ret = mod->driver->allocate(&descriptor, handle);
131 auto hnd = cros_gralloc_convert_handle(*handle);
132 *stride = hnd->pixel_stride;
137 static int gralloc0_free(alloc_device_t *dev, buffer_handle_t handle)
139 auto mod = (struct gralloc0_module const *)dev->common.module;
140 return mod->driver->release(handle);
143 static int gralloc0_close(struct hw_device_t *dev)
145 /* Memory is freed by managed pointers on process close. */
149 static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc,
150 bool framebuffer = false)
152 std::lock_guard<std::mutex> lock(mod->initialization_mutex);
154 if (mod->initialized)
157 mod->driver = std::make_unique<cros_gralloc_driver>();
158 if (framebuffer ? mod->driver->init_master() : mod->driver->init()) {
159 drv_log("Failed to initialize driver.\n");
163 if (initialize_alloc) {
164 mod->alloc = std::make_unique<alloc_device_t>();
165 mod->alloc->alloc = gralloc0_alloc;
166 mod->alloc->free = gralloc0_free;
167 mod->alloc->common.tag = HARDWARE_DEVICE_TAG;
168 mod->alloc->common.version = 0;
169 mod->alloc->common.module = (hw_module_t *)mod;
170 mod->alloc->common.close = gralloc0_close;
174 int ret = drm_framebuffer_init(mod->driver->get_fd(), &mod->fb);
179 mod->initialized = true;
183 static int gralloc0_open_fb0(struct gralloc0_module *mod, struct hw_device_t **dev)
187 if (!mod->initialized) {
188 ret = gralloc0_init(mod, true, true);
195 * On Pie and above the FB HAL is opened before the Gralloc HAL.
196 * This has the advantage that we can open the DRM card node in this case,
197 * and open the render node in all other cases.
199 * On earlier Android versions this is not the case, so we need to make
200 * sure the FB HAL was actually initialized.
202 * TODO: Currently it does not attempt to set master on the opened render
203 * node. That means it will only work with DRM authentication disabled.
205 std::lock_guard<std::mutex> lock(mod->initialization_mutex);
206 drv_log("FB HAL opened after Gralloc HAL, we might not be DRM master!\n");
208 ret = drm_framebuffer_init(mod->driver->get_fd(), &mod->fb);
213 *dev = (struct hw_device_t *) mod->fb;
217 static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev)
219 auto const_module = reinterpret_cast<const struct gralloc0_module *>(mod);
220 auto module = const_cast<struct gralloc0_module *>(const_module);
222 if (!strcmp(name, GRALLOC_HARDWARE_FB0))
223 return gralloc0_open_fb0(module, dev);
225 if (module->initialized) {
226 *dev = &module->alloc->common;
230 if (strcmp(name, GRALLOC_HARDWARE_GPU0)) {
231 drv_log("Incorrect device name - %s.\n", name);
235 if (gralloc0_init(module, true))
238 *dev = &module->alloc->common;
242 static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffer_handle_t handle)
244 auto const_module = reinterpret_cast<const struct gralloc0_module *>(module);
245 auto mod = const_cast<struct gralloc0_module *>(const_module);
247 if (!mod->initialized)
248 if (gralloc0_init(mod, true))
251 int ret = mod->driver->retain(handle);
252 if (ret == 0 && mod->fb)
253 drm_framebuffer_import(mod->fb, handle);
257 static int gralloc0_unregister_buffer(struct gralloc_module_t const *module, buffer_handle_t handle)
259 auto mod = (struct gralloc0_module const *)module;
260 return mod->driver->release(handle);
263 static int gralloc0_lock(struct gralloc_module_t const *module, buffer_handle_t handle, int usage,
264 int l, int t, int w, int h, void **vaddr)
266 return module->lockAsync(module, handle, usage, l, t, w, h, vaddr, -1);
269 static int gralloc0_unlock(struct gralloc_module_t const *module, buffer_handle_t handle)
271 int32_t fence_fd, ret;
272 auto mod = (struct gralloc0_module const *)module;
273 ret = mod->driver->unlock(handle, &fence_fd);
277 ret = cros_gralloc_sync_wait(fence_fd);
284 static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
287 int32_t *out_format, ret;
289 buffer_handle_t handle;
290 uint32_t *out_width, *out_height, *out_stride;
291 auto mod = (struct gralloc0_module const *)module;
294 case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
295 case GRALLOC_MODULE_PERFORM_ENTER_VT:
296 case GRALLOC_MODULE_PERFORM_LEAVE_VT:
297 case GRALLOC_DRM_GET_STRIDE:
298 case GRALLOC_DRM_GET_FORMAT:
299 case GRALLOC_DRM_GET_DIMENSIONS:
300 case GRALLOC_DRM_GET_BACKING_STORE:
310 case GRALLOC_MODULE_PERFORM_GET_DRM_FD: {
311 int *fd = va_arg(args, int*);
312 *fd = mod->driver->get_fd();
315 case GRALLOC_MODULE_PERFORM_ENTER_VT:
316 ret = drmSetMaster(mod->driver->get_fd());
318 case GRALLOC_MODULE_PERFORM_LEAVE_VT:
319 ret = drmDropMaster(mod->driver->get_fd());
329 handle = va_arg(args, buffer_handle_t);
330 auto hnd = cros_gralloc_convert_handle(handle);
332 drv_log("Invalid handle.\n");
337 case GRALLOC_DRM_GET_STRIDE:
338 out_stride = va_arg(args, uint32_t *);
339 *out_stride = hnd->pixel_stride;
341 case GRALLOC_DRM_GET_FORMAT:
342 out_format = va_arg(args, int32_t *);
343 *out_format = hnd->droid_format;
345 case GRALLOC_DRM_GET_DIMENSIONS:
346 out_width = va_arg(args, uint32_t *);
347 out_height = va_arg(args, uint32_t *);
348 *out_width = hnd->width;
349 *out_height = hnd->height;
351 case GRALLOC_DRM_GET_BACKING_STORE:
352 out_store = va_arg(args, uint64_t *);
353 ret = mod->driver->get_backing_store(handle, out_store);
364 static int gralloc0_lock_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle,
365 int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr)
367 return module->lockAsync_ycbcr(module, handle, usage, l, t, w, h, ycbcr, -1);
370 static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_handle_t handle,
371 int usage, int l, int t, int w, int h, void **vaddr, int fence_fd)
375 uint8_t *addr[DRV_MAX_PLANES];
376 auto mod = (struct gralloc0_module const *)module;
377 struct rectangle rect = { .x = static_cast<uint32_t>(l),
378 .y = static_cast<uint32_t>(t),
379 .width = static_cast<uint32_t>(w),
380 .height = static_cast<uint32_t>(h) };
382 auto hnd = cros_gralloc_convert_handle(handle);
384 drv_log("Invalid handle.\n");
388 if (hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
389 drv_log("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.\n");
398 map_flags = gralloc0_convert_map_usage(usage);
399 ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr);
404 static int gralloc0_unlock_async(struct gralloc_module_t const *module, buffer_handle_t handle,
407 auto mod = (struct gralloc0_module const *)module;
408 return mod->driver->unlock(handle, fence_fd);
411 static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle,
412 int usage, int l, int t, int w, int h,
413 struct android_ycbcr *ycbcr, int fence_fd)
417 uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr };
418 auto mod = (struct gralloc0_module const *)module;
419 struct rectangle rect = { .x = static_cast<uint32_t>(l),
420 .y = static_cast<uint32_t>(t),
421 .width = static_cast<uint32_t>(w),
422 .height = static_cast<uint32_t>(h) };
424 auto hnd = cros_gralloc_convert_handle(handle);
426 drv_log("Invalid handle.\n");
430 if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) &&
431 (hnd->droid_format != HAL_PIXEL_FORMAT_YV12) &&
432 (hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) {
433 drv_log("Non-YUV format not compatible.\n");
442 map_flags = gralloc0_convert_map_usage(usage);
443 ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr);
447 switch (hnd->format) {
448 case DRM_FORMAT_NV12:
451 ycbcr->cr = addr[1] + 1;
452 ycbcr->ystride = hnd->strides[0];
453 ycbcr->cstride = hnd->strides[1];
454 ycbcr->chroma_step = 2;
456 case DRM_FORMAT_YVU420:
457 case DRM_FORMAT_YVU420_ANDROID:
461 ycbcr->ystride = hnd->strides[0];
462 ycbcr->cstride = hnd->strides[1];
463 ycbcr->chroma_step = 1;
466 module->unlock(module, handle);
474 static struct hw_module_methods_t gralloc0_module_methods = { .open = gralloc0_open };
477 struct gralloc0_module HAL_MODULE_INFO_SYM = {
482 .tag = HARDWARE_MODULE_TAG,
483 .module_api_version = GRALLOC_MODULE_API_VERSION_0_3,
484 .hal_api_version = 0,
485 .id = GRALLOC_HARDWARE_MODULE_ID,
486 .name = "CrOS Gralloc",
487 .author = "Chrome OS",
488 .methods = &gralloc0_module_methods,
491 .registerBuffer = gralloc0_register_buffer,
492 .unregisterBuffer = gralloc0_unregister_buffer,
493 .lock = gralloc0_lock,
494 .unlock = gralloc0_unlock,
495 .perform = gralloc0_perform,
496 .lock_ycbcr = gralloc0_lock_ycbcr,
497 .lockAsync = gralloc0_lock_async,
498 .unlockAsync = gralloc0_unlock_async,
499 .lockAsync_ycbcr = gralloc0_lock_async_ycbcr,
504 .initialized = false,