(Android/Vulkan) Start hooking up Vulkan for Android context driver

This commit is contained in:
twinaphex 2016-03-01 18:16:22 +01:00
parent cbc575eec0
commit b8c1e31c13
2 changed files with 134 additions and 48 deletions

View File

@ -32,6 +32,10 @@
#include "../common/gl_common.h" #include "../common/gl_common.h"
#endif #endif
#ifdef HAVE_VULKAN
#include "../common/vulkan_common.h"
#endif
#include "../../frontend/drivers/platform_linux.h" #include "../../frontend/drivers/platform_linux.h"
static enum gfx_ctx_api android_api; static enum gfx_ctx_api android_api;
@ -49,10 +53,47 @@ typedef struct
egl_ctx_data_t egl; egl_ctx_data_t egl;
#endif #endif
#ifdef HAVE_VULKAN #ifdef HAVE_VULKAN
gfx_ctx_vulkan_data_t vk;
unsigned width;
unsigned height;
unsigned swap_interval; unsigned swap_interval;
#endif #endif
} android_ctx_data_t; } 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) static void *android_gfx_ctx_init(void *video_driver)
{ {
#ifdef HAVE_OPENGLES #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)) if (!egl_get_native_visual_id(&and->egl, &format))
goto error; goto error;
#endif
break;
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
if (!vulkan_context_init(&and->vk, VULKAN_WSI_ANDROID))
goto error;
#endif #endif
break; break;
case GFX_CTX_NONE: 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)) if (!egl_create_surface(&and->egl, android_app->window))
goto unlock_error; 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 #endif
break; break;
case GFX_CTX_NONE: case GFX_CTX_NONE:
@ -133,52 +188,57 @@ static void *android_gfx_ctx_init(void *video_driver)
unlock_error: unlock_error:
slock_unlock(android_app->mutex); slock_unlock(android_app->mutex);
error: 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) switch (android_api)
{ {
case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENGL_ES_API:
#ifdef HAVE_EGL #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 #endif
break; break;
case GFX_CTX_NONE: case GFX_CTX_NONE:
default: default:
break; 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, static void android_gfx_ctx_check_window(void *data, bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count) bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
{ {
unsigned new_width, new_height; unsigned new_width, new_height;
#ifdef HAVE_VULKAN
android_ctx_data_t *and = (android_ctx_data_t*)data; android_ctx_data_t *and = (android_ctx_data_t*)data;
#endif
(void)frame_count; (void)frame_count;
*quit = false; *quit = false;
android_gfx_ctx_get_video_size(data, &new_width, &new_height);
switch (android_api) switch (android_api)
{ {
case GFX_CTX_OPENGL_API: case GFX_CTX_VULKAN_API:
case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_VULKAN
#ifdef HAVE_OPENGLES /* Swapchains are recreated in set_resize as a
egl_get_video_size(&and->egl, &new_width, &new_height); * central place, so use that to trigger swapchain reinit. */
*resize = and->vk.need_new_swapchain;
#endif #endif
break; break;
case GFX_CTX_NONE: case GFX_CTX_NONE:
@ -224,10 +284,27 @@ static bool android_gfx_ctx_set_video_mode(void *data,
unsigned width, unsigned height, unsigned width, unsigned height,
bool fullscreen) bool fullscreen)
{ {
(void)data; #ifdef HAVE_VULKAN
android_ctx_data_t *and = (android_ctx_data_t*)data;
#endif
(void)width; (void)width;
(void)height; (void)height;
(void)fullscreen; (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; return true;
} }
@ -351,6 +428,12 @@ static void android_gfx_ctx_swap_buffers(void *data)
case GFX_CTX_OPENVG_API: case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL #ifdef HAVE_EGL
egl_swap_buffers(&and->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 #endif
break; break;
case GFX_CTX_NONE: 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); egl_set_swap_interval(&and->egl, swap_interval);
#endif #endif
break; break;
case GFX_CTX_NONE: case GFX_CTX_VULKAN_API:
default: #ifdef HAVE_VULKAN
break; if (and->swap_interval != swap_interval)
} {
} and->swap_interval = swap_interval;
if (and->vk.swapchain)
static void android_gfx_ctx_get_video_size(void *data, and->vk.need_new_swapchain = true;
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);
#endif #endif
break; break;
case GFX_CTX_NONE: 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) static gfx_ctx_proc_t android_gfx_ctx_get_proc_address(const char *symbol)
{ {
switch (android_api) 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 = { const gfx_ctx_driver_t gfx_ctx_android = {
android_gfx_ctx_init, android_gfx_ctx_init,
android_gfx_ctx_destroy, android_gfx_ctx_destroy,
@ -459,4 +542,9 @@ const gfx_ctx_driver_t gfx_ctx_android = {
NULL, NULL,
"android", "android",
android_gfx_ctx_bind_hw_render, android_gfx_ctx_bind_hw_render,
#ifdef HAVE_VULKAN
android_gfx_ctx_get_context_data
#else
NULL
#endif
}; };

View File

@ -242,7 +242,13 @@ static const struct wl_registry_listener registry_listener = {
}; };
static void gfx_ctx_wl_get_video_size(void *data, 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) 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); 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, static bool gfx_ctx_wl_get_metrics(void *data,
enum display_metric_types type, float *value) enum display_metric_types type, float *value)