X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=cros_gralloc%2Fgralloc0%2Fgralloc0.cc;h=fd1843ecfb42fd64275c9a1f8fc1f5939dc5241a;hb=bbba9dde65832cf03f1a0e9739e81e8ad689a508;hp=533f8cac09966529e6b5ef365dc8ebec496d73be;hpb=4df286c26c38888fdc39d705bc5499a92d56d3a4;p=android-x86%2Fexternal-minigbm.git diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 533f8ca..fd1843e 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -4,8 +4,10 @@ * found in the LICENSE file. */ +#include "../../util.h" #include "../cros_gralloc_driver.h" +#include #include #include @@ -17,6 +19,15 @@ struct gralloc0_module { std::mutex initialization_mutex; }; +struct cros_gralloc0_buffer_info { + uint32_t drm_fourcc; + int num_fds; + int fds[4]; + uint64_t modifier; + uint32_t offset[4]; + uint32_t stride[4]; +}; + /* This enumeration must match the one in . * The functions supported by this gralloc's temporary private API are listed * below. Use of these functions is highly discouraged and should only be @@ -29,53 +40,83 @@ enum { GRALLOC_DRM_GET_FORMAT, GRALLOC_DRM_GET_DIMENSIONS, GRALLOC_DRM_GET_BACKING_STORE, + GRALLOC_DRM_GET_BUFFER_INFO, }; // clang-format on -static int64_t gralloc0_convert_flags(int flags) +// Gralloc0 doesn't define a video decoder flag. However, the IAllocator gralloc0 +// passthrough gives the low 32-bits of the BufferUsage flags to gralloc0 in their +// entirety, so we can detect the video decoder flag passed by IAllocator clients. +#define BUFFER_USAGE_VIDEO_DECODER (1 << 22) + +static uint64_t gralloc0_convert_usage(int usage) { - uint64_t usage = BO_USE_NONE; - - if (flags & GRALLOC_USAGE_CURSOR) - usage |= BO_USE_NONE; - if ((flags & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY) - usage |= BO_USE_SW_READ_RARELY; - if ((flags & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) - usage |= BO_USE_SW_READ_OFTEN; - if ((flags & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) - usage |= BO_USE_SW_WRITE_RARELY; - if ((flags & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN) - usage |= BO_USE_SW_WRITE_OFTEN; - if (flags & GRALLOC_USAGE_HW_TEXTURE) - usage |= BO_USE_TEXTURE; - if (flags & GRALLOC_USAGE_HW_RENDER) - usage |= BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_HW_2D) - usage |= BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_HW_COMPOSER) + uint64_t use_flags = BO_USE_NONE; + + if (usage & GRALLOC_USAGE_CURSOR) + use_flags |= BO_USE_NONE; + if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY) + use_flags |= BO_USE_SW_READ_RARELY; + if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) + use_flags |= BO_USE_SW_READ_OFTEN; + if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) + use_flags |= BO_USE_SW_WRITE_RARELY; + if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN) + use_flags |= BO_USE_SW_WRITE_OFTEN; + if (usage & GRALLOC_USAGE_HW_TEXTURE) + use_flags |= BO_USE_TEXTURE; + if (usage & GRALLOC_USAGE_HW_RENDER) + use_flags |= BO_USE_RENDERING; + if (usage & GRALLOC_USAGE_HW_2D) + use_flags |= BO_USE_RENDERING; + if (usage & GRALLOC_USAGE_HW_COMPOSER) /* HWC wants to use display hardware, but can defer to OpenGL. */ - usage |= BO_USE_SCANOUT | BO_USE_TEXTURE; - if (flags & GRALLOC_USAGE_HW_FB) - usage |= BO_USE_NONE; - if (flags & GRALLOC_USAGE_EXTERNAL_DISP) + use_flags |= BO_USE_SCANOUT | BO_USE_TEXTURE; + if (usage & GRALLOC_USAGE_HW_FB) + use_flags |= BO_USE_NONE; + if (usage & GRALLOC_USAGE_EXTERNAL_DISP) /* * This flag potentially covers external display for the normal drivers (i915, * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it. * */ - usage |= BO_USE_NONE; - if (flags & GRALLOC_USAGE_PROTECTED) - usage |= BO_USE_PROTECTED; - if (flags & GRALLOC_USAGE_HW_VIDEO_ENCODER) + use_flags |= BO_USE_NONE; + /* Ignore this flag until real HW protection is available on minigbm Android drivers. */ + if (usage & GRALLOC_USAGE_PROTECTED) + use_flags |= 0; + if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) { + use_flags |= BO_USE_HW_VIDEO_ENCODER; /*HACK: See b/30054495 */ - usage |= BO_USE_SW_READ_OFTEN; - if (flags & GRALLOC_USAGE_HW_CAMERA_WRITE) - usage |= BO_USE_CAMERA_WRITE; - if (flags & GRALLOC_USAGE_HW_CAMERA_READ) - usage |= BO_USE_CAMERA_READ; - if (flags & GRALLOC_USAGE_RENDERSCRIPT) - usage |= BO_USE_RENDERSCRIPT; - - return usage; + use_flags |= BO_USE_SW_READ_OFTEN; + } + if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) + use_flags |= BO_USE_CAMERA_WRITE; + if (usage & GRALLOC_USAGE_HW_CAMERA_READ) + use_flags |= BO_USE_CAMERA_READ; + if (usage & GRALLOC_USAGE_RENDERSCRIPT) + use_flags |= BO_USE_RENDERSCRIPT; + if (usage & BUFFER_USAGE_VIDEO_DECODER) + use_flags |= BO_USE_HW_VIDEO_DECODER; + + return use_flags; +} + +static uint32_t gralloc0_convert_map_usage(int map_usage) +{ + uint32_t map_flags = BO_MAP_NONE; + + if (map_usage & GRALLOC_USAGE_SW_READ_MASK) + map_flags |= BO_MAP_READ; + if (map_usage & GRALLOC_USAGE_SW_WRITE_MASK) + map_flags |= BO_MAP_WRITE; + + return map_flags; +} + +static int gralloc0_droid_yuv_format(int droid_format) +{ + + return (droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888 || + droid_format == HAL_PIXEL_FORMAT_YV12); } static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage, @@ -84,26 +125,35 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa int32_t ret; bool supported; struct cros_gralloc_buffer_descriptor descriptor; - auto mod = (struct gralloc0_module *)dev->common.module; + auto mod = (struct gralloc0_module const *)dev->common.module; descriptor.width = w; descriptor.height = h; descriptor.droid_format = format; - descriptor.producer_usage = descriptor.consumer_usage = usage; + descriptor.droid_usage = usage; descriptor.drm_format = cros_gralloc_convert_format(format); - descriptor.drv_usage = gralloc0_convert_flags(usage); + descriptor.use_flags = gralloc0_convert_usage(usage); + descriptor.reserved_region_size = 0; supported = mod->driver->is_supported(&descriptor); if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) { - descriptor.drv_usage &= ~BO_USE_SCANOUT; + descriptor.use_flags &= ~BO_USE_SCANOUT; + supported = mod->driver->is_supported(&descriptor); + } + if (!supported && (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && + !gralloc0_droid_yuv_format(format)) { + // Unmask BO_USE_HW_VIDEO_ENCODER in the case of non-yuv formats + // because they are not input to a hw encoder but used as an + // intermediate format (e.g. camera). + descriptor.use_flags &= ~BO_USE_HW_VIDEO_ENCODER; supported = mod->driver->is_supported(&descriptor); } if (!supported) { - cros_gralloc_error("Unsupported combination -- HAL format: %u, HAL flags: %u, " - "drv_format: %4.4s, drv_flags: %llu", - format, usage, reinterpret_cast(&descriptor.drm_format), - static_cast(descriptor.drv_usage)); + drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, " + "drv_format: %4.4s, use_flags: %llu\n", + format, usage, reinterpret_cast(&descriptor.drm_format), + static_cast(descriptor.use_flags)); return -EINVAL; } @@ -119,7 +169,7 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa static int gralloc0_free(alloc_device_t *dev, buffer_handle_t handle) { - auto mod = (struct gralloc0_module *)dev->common.module; + auto mod = (struct gralloc0_module const *)dev->common.module; return mod->driver->release(handle); } @@ -138,7 +188,7 @@ static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) mod->driver = std::make_unique(); if (mod->driver->init()) { - cros_gralloc_error("Failed to initialize driver."); + drv_log("Failed to initialize driver.\n"); return -ENODEV; } @@ -158,7 +208,8 @@ static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev) { - auto module = (struct gralloc0_module *)mod; + auto const_module = reinterpret_cast(mod); + auto module = const_cast(const_module); if (module->initialized) { *dev = &module->alloc->common; @@ -166,7 +217,7 @@ static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct } if (strcmp(name, GRALLOC_HARDWARE_GPU0)) { - cros_gralloc_error("Incorrect device name - %s.", name); + drv_log("Incorrect device name - %s.\n", name); return -EINVAL; } @@ -179,7 +230,8 @@ static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffer_handle_t handle) { - auto mod = (struct gralloc0_module *)module; + auto const_module = reinterpret_cast(module); + auto mod = const_cast(const_module); if (!mod->initialized) if (gralloc0_init(mod, false)) @@ -190,7 +242,7 @@ static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffe static int gralloc0_unregister_buffer(struct gralloc_module_t const *module, buffer_handle_t handle) { - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; return mod->driver->release(handle); } @@ -203,12 +255,12 @@ static int gralloc0_lock(struct gralloc_module_t const *module, buffer_handle_t static int gralloc0_unlock(struct gralloc_module_t const *module, buffer_handle_t handle) { int32_t fence_fd, ret; - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; ret = mod->driver->unlock(handle, &fence_fd); if (ret) return ret; - ret = cros_gralloc_sync_wait(fence_fd); + ret = cros_gralloc_sync_wait(fence_fd, /*close_acquire_fence=*/true); if (ret) return ret; @@ -222,13 +274,17 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) uint64_t *out_store; buffer_handle_t handle; uint32_t *out_width, *out_height, *out_stride; - auto mod = (struct gralloc0_module *)module; + uint32_t strides[DRV_MAX_PLANES] = { 0, 0, 0, 0 }; + uint32_t offsets[DRV_MAX_PLANES] = { 0, 0, 0, 0 }; + struct cros_gralloc0_buffer_info *info; + auto mod = (struct gralloc0_module const *)module; switch (op) { case GRALLOC_DRM_GET_STRIDE: case GRALLOC_DRM_GET_FORMAT: case GRALLOC_DRM_GET_DIMENSIONS: case GRALLOC_DRM_GET_BACKING_STORE: + case GRALLOC_DRM_GET_BUFFER_INFO: break; default: return -EINVAL; @@ -240,14 +296,24 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) handle = va_arg(args, buffer_handle_t); auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } switch (op) { case GRALLOC_DRM_GET_STRIDE: out_stride = va_arg(args, uint32_t *); - *out_stride = hnd->pixel_stride; + ret = mod->driver->resource_info(handle, strides, offsets); + if (ret) + break; + + if (strides[0] != hnd->strides[0]) { + uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0); + *out_stride = DIV_ROUND_UP(strides[0], bytes_per_pixel); + } else { + *out_stride = hnd->pixel_stride; + } + break; case GRALLOC_DRM_GET_FORMAT: out_format = va_arg(args, int32_t *); @@ -263,6 +329,17 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) out_store = va_arg(args, uint64_t *); ret = mod->driver->get_backing_store(handle, out_store); break; + case GRALLOC_DRM_GET_BUFFER_INFO: + info = va_arg(args, struct cros_gralloc0_buffer_info *); + info->drm_fourcc = hnd->format; + info->num_fds = hnd->num_planes; + info->modifier = hnd->format_modifier; + for (uint32_t i = 0; i < hnd->num_planes; i++) { + info->fds[i] = hnd->fds[i]; + info->offset[i] = hnd->offsets[i]; + info->stride[i] = hnd->strides[i]; + } + break; default: ret = -EINVAL; } @@ -282,23 +359,32 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han int usage, int l, int t, int w, int h, void **vaddr, int fence_fd) { int32_t ret; - uint64_t flags; + uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES]; - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; + struct rectangle rect = { .x = static_cast(l), + .y = static_cast(t), + .width = static_cast(w), + .height = static_cast(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } if (hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888) { - cros_gralloc_error("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible."); + drv_log("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.\n"); return -EINVAL; } - flags = gralloc0_convert_flags(usage); - ret = mod->driver->lock(handle, fence_fd, flags, addr); + assert(l >= 0); + assert(t >= 0); + assert(w >= 0); + assert(h >= 0); + + map_flags = gralloc0_convert_map_usage(usage); + ret = mod->driver->lock(handle, fence_fd, true, &rect, map_flags, addr); *vaddr = addr[0]; return ret; } @@ -306,7 +392,7 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han static int gralloc0_unlock_async(struct gralloc_module_t const *module, buffer_handle_t handle, int *fence_fd) { - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; return mod->driver->unlock(handle, fence_fd); } @@ -314,36 +400,56 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr, int fence_fd) { - uint64_t flags; int32_t ret; + uint32_t map_flags; + uint32_t strides[DRV_MAX_PLANES] = { 0, 0, 0, 0 }; + uint32_t offsets[DRV_MAX_PLANES] = { 0, 0, 0, 0 }; uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; + struct rectangle rect = { .x = static_cast(l), + .y = static_cast(t), + .width = static_cast(w), + .height = static_cast(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } - if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && - (hnd->droid_format != HAL_PIXEL_FORMAT_YV12) && - (hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) { - cros_gralloc_error("Non-YUV format not compatible."); + if (!gralloc0_droid_yuv_format(hnd->droid_format) && + hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { + drv_log("Non-YUV format not compatible.\n"); return -EINVAL; } - flags = gralloc0_convert_flags(usage); - ret = mod->driver->lock(handle, fence_fd, flags, addr); + assert(l >= 0); + assert(t >= 0); + assert(w >= 0); + assert(h >= 0); + + map_flags = gralloc0_convert_map_usage(usage); + ret = mod->driver->lock(handle, fence_fd, true, &rect, map_flags, addr); if (ret) return ret; + if (!map_flags) { + ret = mod->driver->resource_info(handle, strides, offsets); + if (ret) + return ret; + + for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) + addr[plane] = + reinterpret_cast(static_cast(offsets[plane])); + } + switch (hnd->format) { case DRM_FORMAT_NV12: ycbcr->y = addr[0]; ycbcr->cb = addr[1]; ycbcr->cr = addr[1] + 1; - ycbcr->ystride = hnd->strides[0]; - ycbcr->cstride = hnd->strides[1]; + ycbcr->ystride = (!map_flags) ? strides[0] : hnd->strides[0]; + ycbcr->cstride = (!map_flags) ? strides[1] : hnd->strides[1]; ycbcr->chroma_step = 2; break; case DRM_FORMAT_YVU420: @@ -351,8 +457,8 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff ycbcr->y = addr[0]; ycbcr->cb = addr[2]; ycbcr->cr = addr[1]; - ycbcr->ystride = hnd->strides[0]; - ycbcr->cstride = hnd->strides[1]; + ycbcr->ystride = (!map_flags) ? strides[0] : hnd->strides[0]; + ycbcr->cstride = (!map_flags) ? strides[1] : hnd->strides[1]; ycbcr->chroma_step = 1; break; default: