From b8c1e31c13a116130c6771efbd2681eac59c6d92 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 1 Mar 2016 18:16:22 +0100 Subject: [PATCH] (Android/Vulkan) Start hooking up Vulkan for Android context driver --- gfx/drivers_context/android_ctx.c | 166 +++++++++++++++++++++++------- gfx/drivers_context/wayland_ctx.c | 16 ++- 2 files changed, 134 insertions(+), 48 deletions(-) diff --git a/gfx/drivers_context/android_ctx.c b/gfx/drivers_context/android_ctx.c index e832100e05..8020eb305e 100644 --- a/gfx/drivers_context/android_ctx.c +++ b/gfx/drivers_context/android_ctx.c @@ -32,6 +32,10 @@ #include "../common/gl_common.h" #endif +#ifdef HAVE_VULKAN +#include "../common/vulkan_common.h" +#endif + #include "../../frontend/drivers/platform_linux.h" static enum gfx_ctx_api android_api; @@ -49,10 +53,47 @@ typedef struct egl_ctx_data_t egl; #endif #ifdef HAVE_VULKAN + gfx_ctx_vulkan_data_t vk; + unsigned width; + unsigned height; unsigned swap_interval; #endif } android_ctx_data_t; +static void android_gfx_ctx_destroy(void *data) +{ + android_ctx_data_t *and = (android_ctx_data_t*)data; +#ifdef HAVE_VULKAN + struct android_app *android_app = (struct android_app*)g_android; +#endif + + if (!and) + return; + + switch (android_api) + { + case GFX_CTX_OPENGL_API: + case GFX_CTX_OPENGL_ES_API: +#ifdef HAVE_EGL + egl_destroy(&and->egl); +#endif + break; + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + vulkan_context_destroy(&and->vk, android_app->window); + + if (and->vk.context.queue_lock) + slock_free(and->vk.context.queue_lock); +#endif + break; + case GFX_CTX_NONE: + default: + break; + } + + free(data); +} + static void *android_gfx_ctx_init(void *video_driver) { #ifdef HAVE_OPENGLES @@ -94,6 +135,12 @@ static void *android_gfx_ctx_init(void *video_driver) if (!egl_get_native_visual_id(&and->egl, &format)) goto error; +#endif + break; + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + if (!vulkan_context_init(&and->vk, VULKAN_WSI_ANDROID)) + goto error; #endif break; case GFX_CTX_NONE: @@ -120,6 +167,14 @@ static void *android_gfx_ctx_init(void *video_driver) if (!egl_create_surface(&and->egl, android_app->window)) goto unlock_error; +#endif + break; + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + if (!vulkan_surface_create(&and->vk, VULKAN_WSI_ANDROID, + and->dpy, android_app->window, + and->width, and->height, and->swap_interval)) + goto error; #endif break; case GFX_CTX_NONE: @@ -133,52 +188,57 @@ static void *android_gfx_ctx_init(void *video_driver) unlock_error: slock_unlock(android_app->mutex); error: + android_gfx_ctx_destroy(and); + + return NULL; +} + +static void android_gfx_ctx_get_video_size(void *data, + unsigned *width, unsigned *height) +{ + android_ctx_data_t *and = (android_ctx_data_t*)data; + switch (android_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_EGL - egl_destroy(&and->egl); + egl_get_video_size(&and->egl, width, height); +#endif + break; + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + *width = and->width; + *height = and->height; #endif break; case GFX_CTX_NONE: default: break; } - - return NULL; -} - -static void android_gfx_ctx_destroy(void *data) -{ - android_ctx_data_t *and = (android_ctx_data_t*)data; - - if (!and) - return; - -#ifdef HAVE_OPENGLES - egl_destroy(&and->egl); -#endif - - free(data); } static void android_gfx_ctx_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height, unsigned frame_count) { unsigned new_width, new_height; +#ifdef HAVE_VULKAN android_ctx_data_t *and = (android_ctx_data_t*)data; +#endif (void)frame_count; *quit = false; + android_gfx_ctx_get_video_size(data, &new_width, &new_height); + switch (android_api) { - case GFX_CTX_OPENGL_API: - case GFX_CTX_OPENGL_ES_API: -#ifdef HAVE_OPENGLES - egl_get_video_size(&and->egl, &new_width, &new_height); + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + /* Swapchains are recreated in set_resize as a + * central place, so use that to trigger swapchain reinit. */ + *resize = and->vk.need_new_swapchain; #endif break; case GFX_CTX_NONE: @@ -224,10 +284,27 @@ static bool android_gfx_ctx_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) { - (void)data; +#ifdef HAVE_VULKAN + android_ctx_data_t *and = (android_ctx_data_t*)data; +#endif + (void)width; (void)height; (void)fullscreen; + + switch (android_api) + { + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + and->width = width; + and->height = height; +#endif + break; + case GFX_CTX_NONE: + default: + break; + } + return true; } @@ -351,6 +428,12 @@ static void android_gfx_ctx_swap_buffers(void *data) case GFX_CTX_OPENVG_API: #ifdef HAVE_EGL egl_swap_buffers(&and->egl); +#endif + break; + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + vulkan_present(&and->vk, and->vk.context.current_swapchain_index); + vulkan_acquire_next_image(&and->vk); #endif break; case GFX_CTX_NONE: @@ -371,23 +454,14 @@ static void android_gfx_ctx_set_swap_interval(void *data, unsigned swap_interval egl_set_swap_interval(&and->egl, swap_interval); #endif break; - case GFX_CTX_NONE: - default: - break; - } -} - -static void android_gfx_ctx_get_video_size(void *data, - unsigned *width, unsigned *height) -{ - android_ctx_data_t *and = (android_ctx_data_t*)data; - - switch (android_api) - { - case GFX_CTX_OPENGL_API: - case GFX_CTX_OPENGL_ES_API: -#ifdef HAVE_EGL - egl_get_video_size(&and->egl, width, height); + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + if (and->swap_interval != swap_interval) + { + and->swap_interval = swap_interval; + if (and->vk.swapchain) + and->vk.need_new_swapchain = true; + } #endif break; case GFX_CTX_NONE: @@ -396,6 +470,7 @@ static void android_gfx_ctx_get_video_size(void *data, } } + static gfx_ctx_proc_t android_gfx_ctx_get_proc_address(const char *symbol) { switch (android_api) @@ -433,6 +508,14 @@ static void android_gfx_ctx_bind_hw_render(void *data, bool enable) } } +#ifdef HAVE_VULKAN +static void *android_gfx_ctx_get_context_data(void *data) +{ + android_ctx_data_t *and = (android_ctx_data_t*)data; + return &and->vk.context; +} +#endif + const gfx_ctx_driver_t gfx_ctx_android = { android_gfx_ctx_init, android_gfx_ctx_destroy, @@ -459,4 +542,9 @@ const gfx_ctx_driver_t gfx_ctx_android = { NULL, "android", android_gfx_ctx_bind_hw_render, +#ifdef HAVE_VULKAN + android_gfx_ctx_get_context_data +#else + NULL +#endif }; diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 064273e8d8..3bf79b7b93 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -242,7 +242,13 @@ static const struct wl_registry_listener registry_listener = { }; static void gfx_ctx_wl_get_video_size(void *data, - unsigned *width, unsigned *height); + unsigned *width, unsigned *height) +{ + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + + *width = wl->width; + *height = wl->height; +} static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl) { @@ -422,14 +428,6 @@ static void gfx_ctx_wl_update_window_title(void *data) runloop_msg_queue_push(buf_fps, 1, 1, false); } -static void gfx_ctx_wl_get_video_size(void *data, - unsigned *width, unsigned *height) -{ - gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; - - *width = wl->width; - *height = wl->height; -} static bool gfx_ctx_wl_get_metrics(void *data, enum display_metric_types type, float *value)