OSDN Git Service

Always export DRM_FORMAT_YVU420_ANDROID as DRM_FORMAT_YVU420
[android-x86/external-minigbm.git] / cros_gralloc / gralloc0 / gralloc0.cc
index df1f62c..c00db2a 100644 (file)
@@ -4,6 +4,8 @@
  * found in the LICENSE file.
  */
 
+#include "../../helpers.h"
+#include "../../util.h"
 #include "../cros_gralloc_driver.h"
 
 #include <cassert>
@@ -18,6 +20,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 <gralloc_drm.h>.
  * The functions supported by this gralloc's temporary private API are listed
  * below. Use of these functions is highly discouraged and should only be
@@ -30,9 +41,15 @@ enum {
        GRALLOC_DRM_GET_FORMAT,
        GRALLOC_DRM_GET_DIMENSIONS,
        GRALLOC_DRM_GET_BACKING_STORE,
+       GRALLOC_DRM_GET_BUFFER_INFO,
 };
 // clang-format on
 
+// 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 use_flags = BO_USE_NONE;
@@ -64,17 +81,22 @@ static uint64_t gralloc0_convert_usage(int usage)
                 * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it.
                 * */
                use_flags |= BO_USE_NONE;
+       /* Map this flag to linear until real HW protection is available on Android. */
        if (usage & GRALLOC_USAGE_PROTECTED)
-               use_flags |= BO_USE_PROTECTED;
-       if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
+               use_flags |= BO_USE_LINEAR;
+       if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+               use_flags |= BO_USE_HW_VIDEO_ENCODER;
                /*HACK: See b/30054495 */
                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;
 }
@@ -91,6 +113,13 @@ static uint32_t gralloc0_convert_map_usage(int map_usage)
        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,
                          buffer_handle_t *handle, int *stride)
 {
@@ -102,15 +131,24 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa
        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.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.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) {
                drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, "
@@ -223,7 +261,7 @@ static int gralloc0_unlock(struct gralloc_module_t const *module, buffer_handle_
        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;
 
@@ -237,6 +275,9 @@ 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;
+       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) {
@@ -244,6 +285,7 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
        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;
@@ -262,7 +304,17 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
        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 *);
@@ -278,6 +330,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 = drv_get_standard_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;
        }
@@ -322,7 +385,7 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han
        assert(h >= 0);
 
        map_flags = gralloc0_convert_map_usage(usage);
-       ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr);
+       ret = mod->driver->lock(handle, fence_fd, true, &rect, map_flags, addr);
        *vaddr = addr[0];
        return ret;
 }
@@ -340,6 +403,8 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff
 {
        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 const *)module;
        struct rectangle rect = { .x = static_cast<uint32_t>(l),
@@ -353,9 +418,8 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff
                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)) {
+       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;
        }
@@ -366,17 +430,27 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff
        assert(h >= 0);
 
        map_flags = gralloc0_convert_map_usage(usage);
-       ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr);
+       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<uint8_t *>(static_cast<uintptr_t>(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:
@@ -384,8 +458,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:
@@ -423,6 +497,8 @@ struct gralloc0_module HAL_MODULE_INFO_SYM = {
                .lockAsync = gralloc0_lock_async,
                .unlockAsync = gralloc0_unlock_async,
                .lockAsync_ycbcr = gralloc0_lock_async_ycbcr,
+                .validateBufferSize = NULL,
+                .getTransportSize = NULL,
            },
 
        .alloc = nullptr,