OSDN Git Service

minigbm: cros_gralloc: support GRALLOC_MODULE_API_VERSION_0_3
authorGurchetan Singh <gurchetansingh@google.com>
Fri, 23 Jun 2017 01:38:37 +0000 (18:38 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Sat, 29 Jul 2017 09:44:06 +0000 (02:44 -0700)
Let's support GRALLOC_MODULE_API_VERSION_0_3. This will more closely
mirror what gralloc1 and HIDL gralloc does.

We have the option to asychronously unlock with this version of the API,
but decided the added complexity wouldn't lead to any performance benefits.

We'll just set the release fence pointer to be -1, indicating the
the buffer is ready to use after the (*unlock_Async) call.

BUG=b:62069164
TEST=Android boots, play Youtube app, ./gralloctest all passes

Change-Id: Ia21a11b541796c4b36003c50cd8627d189b4bc56
Reviewed-on: https://chromium-review.googlesource.com/422661
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
cros_gralloc/Makefile
cros_gralloc/cros_gralloc_driver.cc
cros_gralloc/cros_gralloc_driver.h
cros_gralloc/cros_gralloc_helpers.cc
cros_gralloc/cros_gralloc_helpers.h
cros_gralloc/gralloc0/gralloc0.cc

index 9c23e7b..17e884f 100644 (file)
@@ -19,7 +19,7 @@ LIBDRM_LIBS := $(shell $(PKG_CONFIG) --libs libdrm)
 CPPFLAGS += -Wall -fPIC -Werror -flto $(LIBDRM_CFLAGS)
 CXXFLAGS += -std=c++14
 CFLAGS   += -std=c99
-LIBS     += -shared -lcutils -lhardware $(LIBDRM_LIBS)
+LIBS     += -shared -lcutils -lhardware -lsync $(LIBDRM_LIBS)
 
 OBJS =  $(foreach source, $(SOURCES), $(addsuffix .o, $(basename $(source))))
 
index 761895d..b4dd7d9 100644 (file)
@@ -236,8 +236,11 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle)
 int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, uint64_t 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;
 
+       std::lock_guard<std::mutex> lock(mutex_);
        auto hnd = cros_gralloc_convert_handle(handle);
        if (!hnd) {
                cros_gralloc_error("Invalid handle.");
@@ -250,15 +253,10 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence,
                return -EINVAL;
        }
 
-       if (acquire_fence >= 0) {
-               cros_gralloc_error("Sync wait not yet supported.");
-               return -EINVAL;
-       }
-
        return buffer->lock(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_);
 
@@ -274,6 +272,13 @@ int32_t cros_gralloc_driver::unlock(buffer_handle_t 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();
 }
 
index 7b3b668..b875497 100644 (file)
@@ -28,7 +28,7 @@ class cros_gralloc_driver
 
        int32_t lock(buffer_handle_t handle, int32_t acquire_fence, uint64_t flags,
                     uint8_t *addr[DRV_MAX_PLANES]);
-       int32_t unlock(buffer_handle_t handle);
+       int32_t unlock(buffer_handle_t handle, int32_t *release_fence);
 
        int32_t get_backing_store(buffer_handle_t handle, uint64_t *out_store);
 
index f0b667d..e662084 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <cstdlib>
 #include <cutils/log.h>
+#include <sync/sync.h>
 
 uint32_t cros_gralloc_convert_format(int format)
 {
@@ -54,6 +55,34 @@ cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle)
        return hnd;
 }
 
+int32_t cros_gralloc_sync_wait(int32_t acquire_fence)
+{
+       if (acquire_fence < 0)
+               return 0;
+
+       /*
+        * Wait initially for 1000 ms, and then wait indefinitely. The SYNC_IOC_WAIT
+        * documentation states the caller waits indefinitely on the fence if timeout < 0.
+        */
+       int err = sync_wait(acquire_fence, 1000);
+       if (err < 0) {
+               cros_gralloc_error("Timed out on sync wait, err = %s", strerror(errno));
+               err = sync_wait(acquire_fence, -1);
+               if (err < 0) {
+                       cros_gralloc_error("sync wait error = %s", strerror(errno));
+                       return -errno;
+               }
+       }
+
+       err = close(acquire_fence);
+       if (err) {
+               cros_gralloc_error("Unable to close fence fd, err = %s", strerror(errno));
+               return -errno;
+       }
+
+       return 0;
+}
+
 void cros_gralloc_log(const char *prefix, const char *file, int line, const char *format, ...)
 {
        char buf[50];
index f198dd9..cf90ec8 100644 (file)
@@ -22,6 +22,8 @@ uint32_t cros_gralloc_convert_format(int32_t format);
 
 cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle);
 
+int32_t cros_gralloc_sync_wait(int32_t acquire_fence);
+
 __attribute__((format(printf, 4, 5))) void cros_gralloc_log(const char *prefix, const char *file,
                                                            int line, const char *format, ...);
 
index 484763e..ec897be 100644 (file)
@@ -185,33 +185,22 @@ static int gralloc0_unregister_buffer(struct gralloc_module_t const *module, buf
 static int gralloc0_lock(struct gralloc_module_t const *module, buffer_handle_t handle, int usage,
                         int l, int t, int w, int h, void **vaddr)
 {
-       int32_t ret, fence;
-       uint64_t flags;
-       uint8_t *addr[DRV_MAX_PLANES];
-       auto mod = (struct gralloc0_module *)module;
-
-       auto hnd = cros_gralloc_convert_handle(handle);
-       if (!hnd) {
-               cros_gralloc_error("Invalid handle.");
-               return -EINVAL;
-       }
-
-       if ((hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888)) {
-               cros_gralloc_error("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.");
-               return -EINVAL;
-       }
-
-       fence = -1;
-       flags = gralloc0_convert_flags(usage);
-       ret = mod->driver->lock(handle, fence, flags, addr);
-       *vaddr = addr[0];
-       return ret;
+       return module->lockAsync(module, handle, usage, l, t, w, h, vaddr, -1);
 }
 
 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;
-       return mod->driver->unlock(handle);
+       ret = mod->driver->unlock(handle, &fence_fd);
+       if (ret)
+               return ret;
+
+       ret = cros_gralloc_sync_wait(fence_fd);
+       if (ret)
+               return ret;
+
+       return 0;
 }
 
 static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
@@ -274,8 +263,47 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
 static int gralloc0_lock_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle,
                               int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr)
 {
+       return module->lockAsync_ycbcr(module, handle, usage, l, t, w, h, ycbcr, -1);
+}
+
+static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_handle_t handle,
+                              int usage, int l, int t, int w, int h, void **vaddr, int fence_fd)
+{
+       int32_t ret;
+       uint64_t flags;
+       uint8_t *addr[DRV_MAX_PLANES];
+       auto mod = (struct gralloc0_module *)module;
+
+       auto hnd = cros_gralloc_convert_handle(handle);
+       if (!hnd) {
+               cros_gralloc_error("Invalid handle.");
+               return -EINVAL;
+       }
+
+       if (hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+               cros_gralloc_error("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.");
+               return -EINVAL;
+       }
+
+       flags = gralloc0_convert_flags(usage);
+       ret = mod->driver->lock(handle, fence_fd, flags, addr);
+       *vaddr = addr[0];
+       return ret;
+}
+
+static int gralloc0_unlock_async(struct gralloc_module_t const *module, buffer_handle_t handle,
+                                int *fence_fd)
+{
+       auto mod = (struct gralloc0_module *)module;
+       return mod->driver->unlock(handle, fence_fd);
+}
+
+static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle,
+                                    int usage, int l, int t, int w, int h,
+                                    struct android_ycbcr *ycbcr, int fence_fd)
+{
        uint64_t flags;
-       int32_t fence, ret;
+       int32_t ret;
        uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr };
        auto mod = (struct gralloc0_module *)module;
 
@@ -292,9 +320,8 @@ static int gralloc0_lock_ycbcr(struct gralloc_module_t const *module, buffer_han
                return -EINVAL;
        }
 
-       fence = -1;
        flags = gralloc0_convert_flags(usage);
-       ret = mod->driver->lock(handle, fence, flags, addr);
+       ret = mod->driver->lock(handle, fence_fd, flags, addr);
        if (ret)
                return ret;
 
@@ -317,7 +344,7 @@ static int gralloc0_lock_ycbcr(struct gralloc_module_t const *module, buffer_han
                ycbcr->chroma_step = 1;
                break;
        default:
-               mod->driver->unlock(handle);
+               module->unlock(module, handle);
                return -EINVAL;
        }
 
@@ -332,7 +359,7 @@ struct gralloc0_module HAL_MODULE_INFO_SYM = {
                .common =
                    {
                        .tag = HARDWARE_MODULE_TAG,
-                       .module_api_version = GRALLOC_MODULE_API_VERSION_0_2,
+                       .module_api_version = GRALLOC_MODULE_API_VERSION_0_3,
                        .hal_api_version = 0,
                        .id = GRALLOC_HARDWARE_MODULE_ID,
                        .name = "CrOS Gralloc",
@@ -346,6 +373,9 @@ struct gralloc0_module HAL_MODULE_INFO_SYM = {
                .unlock = gralloc0_unlock,
                .perform = gralloc0_perform,
                .lock_ycbcr = gralloc0_lock_ycbcr,
+               .lockAsync = gralloc0_lock_async,
+               .unlockAsync = gralloc0_unlock_async,
+               .lockAsync_ycbcr = gralloc0_lock_async_ycbcr,
            },
 
        .alloc = nullptr,