OSDN Git Service

Use drm gem acess userdata IOCTL for set/get interlace
[android-x86/external-minigbm.git] / cros_gralloc / gralloc1 / cros_gralloc1_module.cc
index 8af90a2..f0b3f04 100644 (file)
 #define LOG_TAG "CrosGralloc1 "
 //#define LOG_NDEBUG 0
 
+#include <errno.h>
 #include "cros_gralloc1_module.h"
 #include "drv.h"
 
 #include <hardware/gralloc.h>
 
 #include <inttypes.h>
+#include "../i915_private_android.h"
+#include "../i915_private_android_types.h"
 
 template <typename PFN, typename T> static gralloc1_function_pointer_t asFP(T function)
 {
@@ -31,7 +34,7 @@ template <typename PFN, typename T> static gralloc1_function_pointer_t asFP(T fu
        return reinterpret_cast<gralloc1_function_pointer_t>(function);
 }
 
-uint64_t cros_gralloc1_convert_flags(uint64_t producer_flags, uint64_t consumer_flags)
+uint64_t cros_gralloc1_convert_usage(uint64_t producer_flags, uint64_t consumer_flags)
 {
        uint64_t usage = BO_USE_NONE;
 
@@ -54,8 +57,7 @@ uint64_t cros_gralloc1_convert_flags(uint64_t producer_flags, uint64_t consumer_
        if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CAMERA)
                usage |= BO_USE_CAMERA_READ;
        if (consumer_flags & GRALLOC1_CONSUMER_USAGE_RENDERSCRIPT)
-               /* We use CPU for compute. */
-               usage |= BO_USE_LINEAR;
+               usage |= BO_USE_RENDERSCRIPT;
 
        if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ)
                usage |= BO_USE_SW_READ_RARELY;
@@ -78,6 +80,44 @@ uint64_t cros_gralloc1_convert_flags(uint64_t producer_flags, uint64_t consumer_
        return usage;
 }
 
+uint64_t cros_gralloc1_convert_map_usage(uint64_t producer_flags, uint64_t consumer_flags)
+{
+       uint64_t usage = BO_USE_NONE;
+
+       if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ)
+               usage |= BO_MAP_READ;
+       if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN)
+               usage |= BO_MAP_READ;
+       if (consumer_flags & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER)
+               /*HACK: See b/30054495 */
+               usage |= BO_MAP_READ;
+
+       if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ)
+               usage |= BO_MAP_READ;
+       if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)
+               usage |= BO_MAP_READ;
+       if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE)
+               usage |= BO_MAP_WRITE;
+       if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)
+               usage |= BO_MAP_WRITE;
+
+       return usage;
+}
+
+bool IsSupportedYUVFormat(uint32_t droid_format)
+{
+       switch (droid_format) {
+       case HAL_PIXEL_FORMAT_YCbCr_420_888:
+       case HAL_PIXEL_FORMAT_YV12:
+       case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+               return true;
+       default:
+               return i915_private_supported_yuv_format(droid_format);
+       }
+
+       return false;
+}
+
 namespace android
 {
 
@@ -123,8 +163,8 @@ void CrosGralloc1::doGetCapabilities(uint32_t *outCount, int32_t *outCapabilitie
 gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor)
 {
        constexpr auto lastDescriptor = static_cast<int32_t>(GRALLOC1_LAST_FUNCTION);
-       if (intDescriptor < 0 || intDescriptor > lastDescriptor) {
-               ALOGE("Invalid function descriptor");
+       if (intDescriptor < 0 || ((intDescriptor > lastDescriptor) && ((intDescriptor < 100) || (intDescriptor > GRALLOC1_LAST_CUSTOM)))) {
+               ALOGE("Invalid function descriptor %d", intDescriptor);
                return nullptr;
        }
 
@@ -156,6 +196,10 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor)
                return asFP<GRALLOC1_PFN_GET_PRODUCER_USAGE>(getProducerUsageHook);
        case GRALLOC1_FUNCTION_GET_STRIDE:
                return asFP<GRALLOC1_PFN_GET_STRIDE>(getStrideHook);
+       case GRALLOC1_FUNCTION_GET_BYTE_STRIDE:
+               return asFP<GRALLOC1_PFN_GET_BYTE_STRIDE>(getByteStrideHook);
+        case GRALLOC1_FUNCTION_GET_PRIME:
+                return asFP<GRALLOC1_PFN_GET_PRIME>(getPrimeHook);
        case GRALLOC1_FUNCTION_ALLOCATE:
                if (driver) {
                        return asFP<GRALLOC1_PFN_ALLOCATE>(allocateBuffers);
@@ -175,6 +219,14 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor)
                    lockHook<struct android_flex_layout, &CrosGralloc1::lockFlex>);
        case GRALLOC1_FUNCTION_UNLOCK:
                return asFP<GRALLOC1_PFN_UNLOCK>(unlockHook);
+       case GRALLOC1_FUNCTION_SET_MODIFIER:
+               return asFP<GRALLOC1_PFN_SET_MODIFIER>(setModifierHook);
+       case GRALLOC1_FUNCTION_SET_INTERLACE:
+               return asFP<GRALLOC1_PFN_SET_INTERLACE>(setInterlaceHook);
+       case GRALLOC1_FUNCTION_GET_INTERLACE:
+               return asFP<GRALLOC1_PFN_GET_INTERLACE>(getInterlaceHook);
+       case GRALLOC1_FUNCTION_SET_PROTECTIONINFO:
+               return asFP<GRALLOC1_PFN_SET_PROTECTIONINFO>(setProtectionInfoHook);
        case GRALLOC1_FUNCTION_INVALID:
                ALOGE("Invalid function descriptor");
                return nullptr;
@@ -237,6 +289,41 @@ int32_t CrosGralloc1::setFormat(gralloc1_buffer_descriptor_t descriptorId, int32
        return CROS_GRALLOC_ERROR_NONE;
 }
 
+int32_t CrosGralloc1::setInterlace(buffer_handle_t buffer, uint32_t interlace)
+{
+        auto hnd = (cros_gralloc_handle*) cros_gralloc_convert_handle(buffer);
+       if (!hnd) {
+               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+       }
+       return driver->setinterlace(buffer, interlace);
+}
+
+int32_t CrosGralloc1::getInterlace(buffer_handle_t buffer, uint32_t *interlace)
+{
+       auto hnd = (cros_gralloc_handle *)cros_gralloc_convert_handle(buffer);
+       if (!hnd) {
+               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+       }
+       return driver->getinterlace(buffer, interlace);
+}
+
+int32_t CrosGralloc1::setProtectionInfo(buffer_handle_t buffer, uint32_t protection_info)
+{
+        auto hnd = (cros_gralloc_handle*) cros_gralloc_convert_handle(buffer);
+        if (!hnd) {
+                return CROS_GRALLOC_ERROR_BAD_HANDLE;
+        }
+        hnd->is_encrypted = protection_info;
+        return CROS_GRALLOC_ERROR_NONE;
+}
+
+int32_t CrosGralloc1::setModifier(gralloc1_buffer_descriptor_t descriptorId, uint64_t modifier)
+{
+       auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId;
+       hnd->modifier = modifier;
+       return CROS_GRALLOC_ERROR_NONE;
+}
+
 int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor,
                               buffer_handle_t *outBufferHandle)
 {
@@ -244,7 +331,7 @@ int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor
        // pointer, which only occurs when mDevice has been loaded successfully and
        // we are permitted to allocate
        uint64_t usage =
-           cros_gralloc1_convert_flags(descriptor->producer_usage, descriptor->consumer_usage);
+           cros_gralloc1_convert_usage(descriptor->producer_usage, descriptor->consumer_usage);
        descriptor->use_flags = usage;
        bool supported = driver->is_supported(descriptor);
        if (!supported && (descriptor->consumer_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER)) {
@@ -309,8 +396,7 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage
                           const gralloc1_rect_t &accessRegion, void **outData,
                           int32_t acquireFence)
 {
-       int32_t ret;
-       uint64_t flags;
+       uint64_t map_flags;
        uint8_t *addr[DRV_MAX_PLANES];
 
        auto hnd = cros_gralloc_convert_handle(bufferHandle);
@@ -319,14 +405,9 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
 
-       if ((hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888)) {
-               cros_gralloc_error("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
-       }
-
-       flags = cros_gralloc1_convert_flags(producerUsage, consumerUsage);
+       map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage);
 
-       if (driver->lock(bufferHandle, acquireFence, flags, addr))
+       if (driver->lock(bufferHandle, acquireFence, map_flags, addr))
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
 
        *outData = addr[0];
@@ -338,19 +419,29 @@ android_flex_plane_t ycbcrplanes[3];
 
 int32_t update_flex_layout(struct android_ycbcr *ycbcr, struct android_flex_layout *outFlexLayout)
 {
-       /*Need to add generic support*/
+       outFlexLayout->format = FLEX_FORMAT_YCbCr;
+       outFlexLayout->num_planes = 3;
+       for (uint32_t i = 0; i < outFlexLayout->num_planes; i++) {
+               ycbcrplanes[i].bits_per_component = 8;
+               ycbcrplanes[i].bits_used = 8;
+       }
+
+       ycbcrplanes[0].top_left = static_cast<uint8_t *>(ycbcr->y);
        ycbcrplanes[0].component = FLEX_COMPONENT_Y;
-       ycbcrplanes[0].top_left = (uint8_t *)ycbcr->y;
-       ycbcrplanes[0].h_increment = ycbcr->ystride;
+       ycbcrplanes[0].h_increment = 1;
+       ycbcrplanes[0].v_increment = static_cast<int32_t>(ycbcr->ystride);
+
+       ycbcrplanes[1].top_left = static_cast<uint8_t *>(ycbcr->cb);
        ycbcrplanes[1].component = FLEX_COMPONENT_Cb;
-       ycbcrplanes[1].top_left = (uint8_t *)ycbcr->cb;
-       ycbcrplanes[1].h_increment = ycbcr->cstride;
+       ycbcrplanes[1].h_increment = static_cast<int32_t>(ycbcr->chroma_step);
+       ycbcrplanes[1].v_increment = static_cast<int32_t>(ycbcr->cstride);
+
+       ycbcrplanes[2].top_left = static_cast<uint8_t *>(ycbcr->cr);
        ycbcrplanes[2].component = FLEX_COMPONENT_Cr;
-       ycbcrplanes[2].top_left = (uint8_t *)ycbcr->cr;
-       ycbcrplanes[2].h_increment = ycbcr->chroma_step;
-       outFlexLayout->format = FLEX_FORMAT_YCbCr;
+       ycbcrplanes[2].h_increment = static_cast<int32_t>(ycbcr->chroma_step);
+       ycbcrplanes[2].v_increment = static_cast<int32_t>(ycbcr->cstride);
+
        outFlexLayout->planes = ycbcrplanes;
-       outFlexLayout->num_planes = 3;
        return 0;
 }
 
@@ -361,7 +452,6 @@ int32_t CrosGralloc1::lockFlex(buffer_handle_t bufferHandle,
                               struct android_flex_layout *outData, int32_t acquireFence)
 {
        int32_t ret = -EINVAL;
-       int32_t outReleaseFence = 0;
        struct android_ycbcr ycbcrData;
 
        /*Check the format and support only for YUV format */
@@ -371,8 +461,7 @@ int32_t CrosGralloc1::lockFlex(buffer_handle_t bufferHandle,
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
 
-       if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) &&
-           (hnd->droid_format != HAL_PIXEL_FORMAT_YV12)) {
+       if (!IsSupportedYUVFormat(hnd->droid_format)) {
                cros_gralloc_error("lockFlex: Non-YUV format not compatible.");
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
@@ -392,8 +481,7 @@ int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle,
                                const gralloc1_rect_t &accessRegion, struct android_ycbcr *ycbcr,
                                int32_t acquireFence)
 {
-       uint64_t flags;
-       int32_t ret;
+       uint64_t map_flags;
        uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr };
 
        auto hnd = cros_gralloc_convert_handle(bufferHandle);
@@ -402,18 +490,18 @@ int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle,
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
 
-       if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) &&
-           (hnd->droid_format != HAL_PIXEL_FORMAT_YV12)) {
+       if (!IsSupportedYUVFormat(hnd->droid_format)) {
                cros_gralloc_error("Non-YUV format not compatible.");
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
 
-       flags = cros_gralloc1_convert_flags(producerUsage, consumerUsage);
-       if (driver->lock(bufferHandle, acquireFence, flags, addr))
+       map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage);
+       if (driver->lock(bufferHandle, acquireFence, map_flags, addr))
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
 
        switch (hnd->format) {
        case DRM_FORMAT_NV12:
+       case DRM_FORMAT_NV12_Y_TILED_INTEL:
                ycbcr->y = addr[0];
                ycbcr->cb = addr[1];
                ycbcr->cr = addr[1] + 1;
@@ -430,6 +518,14 @@ int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle,
                ycbcr->cstride = hnd->strides[1];
                ycbcr->chroma_step = 1;
                break;
+       case DRM_FORMAT_P010:
+               ycbcr->y = addr[0];
+               ycbcr->cb = addr[1];
+               ycbcr->cr = addr[1] + 2;
+               ycbcr->ystride = hnd->strides[0];
+               ycbcr->cstride = hnd->strides[1];
+               ycbcr->chroma_step = 4;
+               break;
        default:
                return CROS_GRALLOC_ERROR_UNSUPPORTED;
        }
@@ -529,6 +625,37 @@ int32_t CrosGralloc1::getStride(buffer_handle_t buffer, uint32_t *outStride)
        return CROS_GRALLOC_ERROR_NONE;
 }
 
+int32_t CrosGralloc1::getPrime(buffer_handle_t buffer, uint32_t *prime)
+{
+       auto hnd = cros_gralloc_convert_handle(buffer);
+       if (!hnd) {
+               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+       }
+
+       *prime = hnd->fds[0];
+       return CROS_GRALLOC_ERROR_NONE;
+}
+
+int32_t CrosGralloc1::getByteStride(buffer_handle_t buffer, uint32_t *outStride, uint32_t size)
+{
+    auto hnd = cros_gralloc_convert_handle(buffer);
+
+    if (!outStride)
+        return -EINVAL;
+
+    if (!hnd) {
+        return CROS_GRALLOC_ERROR_BAD_HANDLE;
+    }
+
+    if (size != drv_num_planes_from_format(hnd->format)) {
+        ALOGE("Invalid array size- %d", size);
+        return -EINVAL;
+    }
+
+    memcpy(outStride, hnd->strides, sizeof(*outStride) * size);
+    return CROS_GRALLOC_ERROR_NONE;
+}
+
 // static
 int CrosGralloc1::HookDevOpen(const struct hw_module_t *mod, const char *name,
                              struct hw_device_t **device)