OSDN Git Service

Revert "Added Support for 64bit RGB format"
[android-x86/external-minigbm.git] / cros_gralloc / cros_gralloc_driver.cc
index 603e96d..f78c7e0 100644 (file)
@@ -7,9 +7,13 @@
 #include "cros_gralloc_driver.h"
 #include "../util.h"
 
+#include "i915_private_android.h"
+
+#include <errno.h>
 #include <cstdlib>
 #include <fcntl.h>
 #include <xf86drm.h>
+#include <unistd.h>
 
 cros_gralloc_driver::cros_gralloc_driver() : drv_(nullptr)
 {
@@ -56,29 +60,33 @@ int32_t cros_gralloc_driver::init()
                                continue;
 
                        version = drmGetVersion(fd);
-                       if (!version)
+                       if (!version) {
+                               close(fd);
                                continue;
+            }
 
                        if (undesired[i] && !strcmp(version->name, undesired[i])) {
                                drmFreeVersion(version);
+                               close(fd);
                                continue;
                        }
 
                        drmFreeVersion(version);
                        drv_ = drv_create(fd);
                        if (drv_)
-                               return CROS_GRALLOC_ERROR_NONE;
+                               return 0;
                }
        }
 
-       return CROS_GRALLOC_ERROR_NO_RESOURCES;
+       return -ENODEV;
 }
 
 bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor)
 {
        struct combination *combo;
-       combo = drv_get_combination(drv_, drv_resolve_format(drv_, descriptor->drm_format),
-                                   descriptor->drv_usage);
+       uint32_t resolved_format;
+       resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags);
+       combo = drv_get_combination(drv_, resolved_format, descriptor->use_flags);
        return (combo != nullptr);
 }
 
@@ -88,15 +96,22 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
        uint32_t id;
        uint64_t mod;
        size_t num_planes;
+       uint32_t resolved_format;
 
        struct bo *bo;
        struct cros_gralloc_handle *hnd;
 
-       bo = drv_bo_create(drv_, descriptor->width, descriptor->height,
-                          drv_resolve_format(drv_, descriptor->drm_format), descriptor->drv_usage);
+       resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags);
+       if (descriptor->modifier == 0) {
+               bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format,
+                                  descriptor->use_flags);
+       } else {
+               bo = drv_bo_create_with_modifiers(drv_, descriptor->width, descriptor->height,
+                                                 resolved_format, &descriptor->modifier, 1);
+       }
        if (!bo) {
                cros_gralloc_error("Failed to create bo.");
-               return CROS_GRALLOC_ERROR_NO_RESOURCES;
+               return -ENOMEM;
        }
 
        /*
@@ -107,7 +122,7 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
        if (drv_num_buffers_per_bo(bo) != 1) {
                drv_bo_destroy(bo);
                cros_gralloc_error("Can only support one buffer per bo.");
-               return CROS_GRALLOC_ERROR_NO_RESOURCES;
+               return -EINVAL;
        }
 
        hnd = new cros_gralloc_handle();
@@ -131,42 +146,51 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
        hnd->width = drv_bo_get_width(bo);
        hnd->height = drv_bo_get_height(bo);
        hnd->format = drv_bo_get_format(bo);
+       hnd->tiling_mode = drv_bo_get_stride_or_tiling(bo);
+       hnd->use_flags[0] = static_cast<uint32_t>(descriptor->use_flags >> 32);
+       hnd->use_flags[1] = static_cast<uint32_t>(descriptor->use_flags);
        hnd->pixel_stride = drv_bo_get_stride_in_pixels(bo);
        hnd->magic = cros_gralloc_magic;
-       hnd->droid_format = descriptor->droid_format;
+       int32_t format = i915_private_invert_format(hnd->format);
+       if (format == 0) {
+               format =  descriptor->droid_format;
+       }
+       hnd->droid_format = format;
        hnd->usage = descriptor->producer_usage;
+       hnd->producer_usage = descriptor->producer_usage;
+       hnd->consumer_usage = descriptor->consumer_usage;
 
        id = drv_bo_get_plane_handle(bo, 0).u32;
        auto buffer = new cros_gralloc_buffer(id, bo, hnd);
 
-       std::lock_guard<std::mutex> lock(mutex_);
+        SCOPED_SPIN_LOCK(mutex_);
        buffers_.emplace(id, buffer);
        handles_.emplace(hnd, std::make_pair(buffer, 1));
        *out_handle = &hnd->base;
-       return CROS_GRALLOC_ERROR_NONE;
+       return 0;
 }
 
 int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
 {
        uint32_t id;
-       std::lock_guard<std::mutex> lock(mutex_);
+        SCOPED_SPIN_LOCK(mutex_);
 
        auto hnd = cros_gralloc_convert_handle(handle);
        if (!hnd) {
                cros_gralloc_error("Invalid handle.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
        auto buffer = get_buffer(hnd);
        if (buffer) {
                handles_[hnd].second++;
                buffer->increase_refcount();
-               return CROS_GRALLOC_ERROR_NONE;
+               return 0;
        }
 
        if (drmPrimeFDToHandle(drv_get_fd(drv_), hnd->fds[0], &id)) {
                cros_gralloc_error("drmPrimeFDToHandle failed.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -errno;
        }
 
        if (buffers_.count(id)) {
@@ -178,11 +202,12 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
                data.format = hnd->format;
                data.width = hnd->width;
                data.height = hnd->height;
+               data.use_flags = static_cast<uint64_t>(hnd->use_flags[0]) << 32;
+               data.use_flags |= hnd->use_flags[1];
 
                memcpy(data.fds, hnd->fds, sizeof(data.fds));
                memcpy(data.strides, hnd->strides, sizeof(data.strides));
                memcpy(data.offsets, hnd->offsets, sizeof(data.offsets));
-               memcpy(data.sizes, hnd->sizes, sizeof(data.sizes));
                for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) {
                        data.format_modifiers[plane] =
                            static_cast<uint64_t>(hnd->format_modifiers[2 * plane]) << 32;
@@ -191,7 +216,7 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
 
                bo = drv_bo_import(drv_, &data);
                if (!bo)
-                       return CROS_GRALLOC_ERROR_NO_RESOURCES;
+                       return -EFAULT;
 
                id = drv_bo_get_plane_handle(bo, 0).u32;
 
@@ -200,23 +225,23 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
        }
 
        handles_.emplace(hnd, std::make_pair(buffer, 1));
-       return CROS_GRALLOC_ERROR_NONE;
+       return 0;
 }
 
 int32_t cros_gralloc_driver::release(buffer_handle_t handle)
 {
-       std::lock_guard<std::mutex> lock(mutex_);
+        SCOPED_SPIN_LOCK(mutex_);
 
        auto hnd = cros_gralloc_convert_handle(handle);
        if (!hnd) {
                cros_gralloc_error("Invalid handle.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
        auto buffer = get_buffer(hnd);
        if (!buffer) {
                cros_gralloc_error("Invalid Reference.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
        if (!--handles_[hnd].second)
@@ -227,71 +252,76 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle)
                delete buffer;
        }
 
-       return CROS_GRALLOC_ERROR_NONE;
+       return 0;
 }
 
-int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, uint64_t flags,
+int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, uint32_t map_flags,
                                  uint8_t *addr[DRV_MAX_PLANES])
 {
-       std::lock_guard<std::mutex> lock(mutex_);
+       int32_t ret = cros_gralloc_sync_wait(acquire_fence);
+       if (ret)
+               return ret;
 
+       SCOPED_SPIN_LOCK(mutex_);
        auto hnd = cros_gralloc_convert_handle(handle);
        if (!hnd) {
                cros_gralloc_error("Invalid handle.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
        auto buffer = get_buffer(hnd);
        if (!buffer) {
                cros_gralloc_error("Invalid Reference.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
-       if (acquire_fence >= 0) {
-               cros_gralloc_error("Sync wait not yet supported.");
-               return CROS_GRALLOC_ERROR_UNSUPPORTED;
-       }
-
-       return buffer->lock(flags, addr);
+       return buffer->lock(map_flags, addr);
 }
 
-int32_t cros_gralloc_driver::unlock(buffer_handle_t handle)
+int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fence)
 {
-       std::lock_guard<std::mutex> lock(mutex_);
+        SCOPED_SPIN_LOCK(mutex_);;
 
        auto hnd = cros_gralloc_convert_handle(handle);
        if (!hnd) {
                cros_gralloc_error("Invalid handle.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
        auto buffer = get_buffer(hnd);
        if (!buffer) {
                cros_gralloc_error("Invalid Reference.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
+       /*
+        * From the ANativeWindow::dequeueBuffer documentation:
+        *
+        * "A value of -1 indicates that the caller may access the buffer immediately without
+        * waiting on a fence."
+        */
+       *release_fence = -1;
        return buffer->unlock();
 }
 
 int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t *out_store)
 {
-       std::lock_guard<std::mutex> lock(mutex_);
+        SCOPED_SPIN_LOCK(mutex_);
 
        auto hnd = cros_gralloc_convert_handle(handle);
        if (!hnd) {
                cros_gralloc_error("Invalid handle.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
        auto buffer = get_buffer(hnd);
        if (!buffer) {
                cros_gralloc_error("Invalid Reference.");
-               return CROS_GRALLOC_ERROR_BAD_HANDLE;
+               return -EINVAL;
        }
 
        *out_store = static_cast<uint64_t>(buffer->get_id());
-       return CROS_GRALLOC_ERROR_NONE;
+       return 0;
 }
 
 cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd)