wineandroid: Add support for gralloc version 1.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44245
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Alexandre Julliard 2018-11-19 16:07:48 +01:00
parent 18ac6bf41a
commit 5b16fb9689
2 changed files with 152 additions and 7 deletions

View File

@ -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 */

View File

@ -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;