OSDN Git Service

Merge 'aosp/upstream-master' into HEAD
[android-x86/external-minigbm.git] / cros_gralloc / gralloc0 / gralloc0.cc
index 004b76b..4ab73f2 100644 (file)
@@ -4,6 +4,7 @@
  * found in the LICENSE file.
  */
 
+#include "../../util.h"
 #include "../cros_gralloc_driver.h"
 
 #include <cassert>
@@ -18,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 <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,6 +40,7 @@ enum {
        GRALLOC_DRM_GET_FORMAT,
        GRALLOC_DRM_GET_DIMENSIONS,
        GRALLOC_DRM_GET_BACKING_STORE,
+       GRALLOC_DRM_GET_BUFFER_INFO,
 };
 // clang-format on
 
@@ -69,8 +80,9 @@ 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;
+               use_flags |= BO_USE_LINEAR;
        if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
                use_flags |= BO_USE_HW_VIDEO_ENCODER;
                /*HACK: See b/30054495 */
@@ -118,9 +130,10 @@ 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)) {
@@ -247,7 +260,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;
 
@@ -261,6 +274,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) {
@@ -268,6 +284,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;
@@ -286,7 +303,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 *);
@@ -302,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;
        }
@@ -346,7 +384,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;
 }
@@ -364,6 +402,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),
@@ -389,17 +429,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:
@@ -407,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: