diff --git a/dlls/wineandroid.drv/android_native.h b/dlls/wineandroid.drv/android_native.h index 5efd5649f85..fc26beb6534 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 a6f28385ee4..c0ff072b810 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;