Alexandre Julliard : wineandroid: Add support for gralloc version 1.

Alexandre Julliard julliard at winehq.org
Mon Nov 19 15:59:38 CST 2018


Module: wine
Branch: master
Commit: 5b16fb9689f668f51f05868158e2d7833843097e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5b16fb9689f668f51f05868158e2d7833843097e

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Nov 19 16:07:48 2018 +0100

wineandroid: Add support for gralloc version 1.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44245
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wineandroid.drv/android_native.h | 83 +++++++++++++++++++++++++++++++++++
 dlls/wineandroid.drv/device.c         | 76 +++++++++++++++++++++++++++++---
 2 files changed, 152 insertions(+), 7 deletions(-)

diff --git a/dlls/wineandroid.drv/android_native.h b/dlls/wineandroid.drv/android_native.h
index 5efd564..fc26beb 100644
--- a/dlls/wineandroid.drv/android_native.h
+++ b/dlls/wineandroid.drv/android_native.h
@@ -230,4 +230,87 @@ enum gralloc_usage
 
 extern int hw_get_module(const char *id, const struct hw_module_t **module);
 
+typedef enum
+{
+    GRALLOC1_CAPABILITY_INVALID = 0,
+    GRALLOC1_CAPABILITY_TEST_ALLOCATE = 1,
+    GRALLOC1_CAPABILITY_LAYERED_BUFFERS = 2,
+    GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE = 3,
+    GRALLOC1_LAST_CAPABILITY = 3,
+} gralloc1_capability_t;
+
+typedef enum
+{
+    GRALLOC1_FUNCTION_INVALID = 0,
+    GRALLOC1_FUNCTION_DUMP = 1,
+    GRALLOC1_FUNCTION_CREATE_DESCRIPTOR = 2,
+    GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR = 3,
+    GRALLOC1_FUNCTION_SET_CONSUMER_USAGE = 4,
+    GRALLOC1_FUNCTION_SET_DIMENSIONS = 5,
+    GRALLOC1_FUNCTION_SET_FORMAT = 6,
+    GRALLOC1_FUNCTION_SET_PRODUCER_USAGE = 7,
+    GRALLOC1_FUNCTION_GET_BACKING_STORE = 8,
+    GRALLOC1_FUNCTION_GET_CONSUMER_USAGE = 9,
+    GRALLOC1_FUNCTION_GET_DIMENSIONS = 10,
+    GRALLOC1_FUNCTION_GET_FORMAT = 11,
+    GRALLOC1_FUNCTION_GET_PRODUCER_USAGE = 12,
+    GRALLOC1_FUNCTION_GET_STRIDE = 13,
+    GRALLOC1_FUNCTION_ALLOCATE = 14,
+    GRALLOC1_FUNCTION_RETAIN = 15,
+    GRALLOC1_FUNCTION_RELEASE = 16,
+    GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES = 17,
+    GRALLOC1_FUNCTION_LOCK = 18,
+    GRALLOC1_FUNCTION_LOCK_FLEX = 19,
+    GRALLOC1_FUNCTION_UNLOCK = 20,
+    GRALLOC1_FUNCTION_SET_LAYER_COUNT = 21,
+    GRALLOC1_FUNCTION_GET_LAYER_COUNT = 22,
+    GRALLOC1_FUNCTION_VALIDATE_BUFFER_SIZE = 23,
+    GRALLOC1_FUNCTION_GET_TRANSPORT_SIZE = 24,
+    GRALLOC1_FUNCTION_IMPORT_BUFFER = 25,
+    GRALLOC1_LAST_FUNCTION = 25,
+} gralloc1_function_descriptor_t;
+
+typedef enum
+{
+    GRALLOC1_ERROR_NONE = 0,
+    GRALLOC1_ERROR_BAD_DESCRIPTOR = 1,
+    GRALLOC1_ERROR_BAD_HANDLE = 2,
+    GRALLOC1_ERROR_BAD_VALUE = 3,
+    GRALLOC1_ERROR_NOT_SHARED = 4,
+    GRALLOC1_ERROR_NO_RESOURCES = 5,
+    GRALLOC1_ERROR_UNDEFINED = 6,
+    GRALLOC1_ERROR_UNSUPPORTED = 7,
+} gralloc1_error_t;
+
+typedef enum
+{
+    GRALLOC1_PRODUCER_USAGE_NONE = 0,
+    GRALLOC1_PRODUCER_USAGE_CPU_READ = 1u << 1,
+    GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN = 1u << 2 | GRALLOC1_PRODUCER_USAGE_CPU_READ,
+    GRALLOC1_PRODUCER_USAGE_CPU_WRITE = 1u << 5,
+    GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN = 1u << 6 | GRALLOC1_PRODUCER_USAGE_CPU_WRITE,
+} gralloc1_producer_usage_t;
+
+typedef enum
+{
+    GRALLOC1_CONSUMER_USAGE_NONE = 0,
+    GRALLOC1_CONSUMER_USAGE_CPU_READ = 1u << 1,
+    GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN = 1u << 2 | GRALLOC1_CONSUMER_USAGE_CPU_READ,
+} gralloc1_consumer_usage_t;
+
+typedef struct gralloc1_device
+{
+    struct hw_device_t common;
+    void (*getCapabilities)(struct gralloc1_device *device, uint32_t *outCount, int32_t *outCapabilities);
+    void* (*getFunction)(struct gralloc1_device *device, int32_t descriptor);
+} gralloc1_device_t;
+
+typedef struct gralloc1_rect
+{
+    int32_t left;
+    int32_t top;
+    int32_t width;
+    int32_t height;
+} gralloc1_rect_t;
+
 #endif /* __WINE_ANDROID_NATIVE_H */
diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c
index a6f2838..c0ff072 100644
--- a/dlls/wineandroid.drv/device.c
+++ b/dlls/wineandroid.drv/device.c
@@ -213,6 +213,17 @@ struct ioctl_android_set_capture
 };
 
 static struct gralloc_module_t *gralloc_module;
+static struct gralloc1_device *gralloc1_device;
+static BOOL gralloc1_caps[GRALLOC1_LAST_CAPABILITY + 1];
+
+static gralloc1_error_t (*gralloc1_retain)( gralloc1_device_t *device, buffer_handle_t buffer );
+static gralloc1_error_t (*gralloc1_release)( gralloc1_device_t *device, buffer_handle_t buffer );
+static gralloc1_error_t (*gralloc1_lock)( gralloc1_device_t *device, buffer_handle_t buffer,
+                                          uint64_t producerUsage, uint64_t consumerUsage,
+                                          const gralloc1_rect_t *accessRegion, void **outData,
+                                          int32_t acquireFence );
+static gralloc1_error_t (*gralloc1_unlock)( gralloc1_device_t *device, buffer_handle_t buffer,
+                                            int32_t *outReleaseFence );
 
 static inline BOOL is_in_desktop_process(void)
 {
@@ -328,7 +339,7 @@ static native_handle_t *unmap_native_handle( const native_handle_t *src )
 
     if (!is_in_desktop_process())
     {
-        dest = HeapAlloc( GetProcessHeap(), 0, size );
+        dest = malloc( size );
         memcpy( dest, src, size );
         /* fetch file descriptors passed from the server process */
         for (i = 0; i < dest->numFds; i++)
@@ -344,7 +355,7 @@ static void close_native_handle( native_handle_t *handle )
     int i;
 
     for (i = 0; i < handle->numFds; i++) close( handle->data[i] );
-    HeapFree( GetProcessHeap(), 0, handle );
+    free( handle );
 }
 
 /* insert a buffer index at the head of the LRU list */
@@ -500,15 +511,49 @@ void register_native_window( HWND hwnd, struct ANativeWindow *win, BOOL opengl )
 
 void init_gralloc( const struct hw_module_t *module )
 {
+    struct hw_device_t *device;
+    int ret;
+
     TRACE( "got module %p ver %u.%u id %s name %s author %s\n",
            module, module->module_api_version >> 8, module->module_api_version & 0xff,
            debugstr_a(module->id), debugstr_a(module->name), debugstr_a(module->author) );
 
-    gralloc_module = (struct gralloc_module_t *)module;
+    switch (module->module_api_version >> 8)
+    {
+    case 0:
+        gralloc_module = (struct gralloc_module_t *)module;
+        break;
+    case 1:
+        if (!(ret = module->methods->open( module, GRALLOC_HARDWARE_MODULE_ID, &device )))
+        {
+            int32_t caps[64];
+            uint32_t i, count = ARRAY_SIZE(caps);
+
+            gralloc1_device = (struct gralloc1_device *)device;
+            gralloc1_retain  = gralloc1_device->getFunction( gralloc1_device, GRALLOC1_FUNCTION_RETAIN );
+            gralloc1_release = gralloc1_device->getFunction( gralloc1_device, GRALLOC1_FUNCTION_RELEASE );
+            gralloc1_lock    = gralloc1_device->getFunction( gralloc1_device, GRALLOC1_FUNCTION_LOCK );
+            gralloc1_unlock  = gralloc1_device->getFunction( gralloc1_device, GRALLOC1_FUNCTION_UNLOCK );
+            TRACE( "got device version %u funcs %p %p %p %p\n", device->version,
+                   gralloc1_retain, gralloc1_release, gralloc1_lock, gralloc1_unlock );
+
+            gralloc1_device->getCapabilities( gralloc1_device, &count, caps );
+            if (count == ARRAY_SIZE(caps)) ERR( "too many gralloc capabilities\n" );
+            for (i = 0; i < count; i++)
+                if (caps[i] < ARRAY_SIZE(gralloc1_caps)) gralloc1_caps[caps[i]] = TRUE;
+        }
+        else ERR( "failed to open gralloc err %d\n", ret );
+        break;
+    default:
+        ERR( "unknown gralloc module version %u\n", module->module_api_version >> 8 );
+        break;
+    }
 }
 
 static int gralloc_grab_buffer( struct ANativeWindowBuffer *buffer )
 {
+    if (gralloc1_device)
+        return gralloc1_retain( gralloc1_device, buffer->handle );
     if (gralloc_module)
         return gralloc_module->registerBuffer( gralloc_module, buffer->handle );
     return -ENODEV;
@@ -516,12 +561,23 @@ static int gralloc_grab_buffer( struct ANativeWindowBuffer *buffer )
 
 static void gralloc_release_buffer( struct ANativeWindowBuffer *buffer )
 {
-    if (gralloc_module) gralloc_module->unregisterBuffer( gralloc_module, buffer->handle );
-    close_native_handle( (native_handle_t *)buffer->handle );
+    if (gralloc1_device) gralloc1_release( gralloc1_device, buffer->handle );
+    else if (gralloc_module) gralloc_module->unregisterBuffer( gralloc_module, buffer->handle );
+
+    if (!gralloc1_caps[GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE])
+        close_native_handle( (native_handle_t *)buffer->handle );
 }
 
 static int gralloc_lock( struct ANativeWindowBuffer *buffer, void **bits )
 {
+    if (gralloc1_device)
+    {
+        gralloc1_rect_t rect = { 0, 0, buffer->width, buffer->height };
+        return gralloc1_lock( gralloc1_device, buffer->handle,
+                              GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN |
+                              GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
+                              GRALLOC1_CONSUMER_USAGE_NONE, &rect, bits, -1 );
+    }
     if (gralloc_module)
         return gralloc_module->lock( gralloc_module, buffer->handle,
                                      GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
@@ -533,7 +589,13 @@ static int gralloc_lock( struct ANativeWindowBuffer *buffer, void **bits )
 
 static void gralloc_unlock( struct ANativeWindowBuffer *buffer )
 {
-    if (gralloc_module) gralloc_module->unlock( gralloc_module, buffer->handle );
+    if (gralloc1_device)
+    {
+        int fence;
+        gralloc1_unlock( gralloc1_device, buffer->handle, &fence );
+        wait_fence_and_close( fence );
+    }
+    else if (gralloc_module) gralloc_module->unlock( gralloc_module, buffer->handle );
 }
 
 /* get the capture window stored in the desktop process */
@@ -1133,7 +1195,7 @@ static int dequeueBuffer( struct ANativeWindow *window, struct ANativeWindowBuff
     struct native_win_wrapper *win = (struct native_win_wrapper *)window;
     struct ioctl_android_dequeueBuffer res;
     DWORD size = sizeof(res);
-    int ret, use_win32 = !gralloc_module;
+    int ret, use_win32 = !gralloc_module && !gralloc1_device;
 
     res.hdr.hwnd = HandleToLong( win->hwnd );
     res.hdr.opengl = win->opengl;




More information about the wine-cvs mailing list