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