diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 988f8cbe38..341fce4e87 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -190,6 +190,33 @@ error: /* forward declaration */ bool android_run_events(void *data); +void android_dpi_get_density(char *s, size_t len) +{ + static bool inited_once = false; + static bool inited2_once = false; + static char string[PROP_VALUE_MAX] = {0}; + static char string2[PROP_VALUE_MAX] = {0}; + if (!inited_once) + { + system_property_get("getprop", "ro.sf.lcd_density", string); + inited_once = true; + } + + if (!string_is_empty(string)) + { + strlcpy(s, string, len); + return; + } + + if (!inited2_once) + { + system_property_get("wm", "density", string2); + inited2_once = true; + } + + strlcpy(s, string2, len); +} + void android_app_write_cmd(struct android_app *android_app, int8_t cmd) { if (!android_app) diff --git a/frontend/drivers/platform_unix.h b/frontend/drivers/platform_unix.h index 8a0485e6bc..13d6007b1c 100644 --- a/frontend/drivers/platform_unix.h +++ b/frontend/drivers/platform_unix.h @@ -346,6 +346,8 @@ extern JNIEnv *jni_thread_getenv(void); void android_app_write_cmd(struct android_app *android_app, int8_t cmd); +void android_dpi_get_density(char *s, size_t len); + extern struct android_app *g_android; #endif diff --git a/gfx/drivers_context/android_ctx.c b/gfx/drivers_context/android_ctx.c index a82edda523..d00fa211f2 100644 --- a/gfx/drivers_context/android_ctx.c +++ b/gfx/drivers_context/android_ctx.c @@ -33,10 +33,6 @@ #include "../common/gl_common.h" #endif -#ifdef HAVE_VULKAN -#include "../common/vulkan_common.h" -#endif - #include "../../frontend/frontend_driver.h" #include "../../frontend/drivers/platform_unix.h" #include "../../verbosity.h" @@ -53,18 +49,8 @@ typedef struct #ifdef HAVE_EGL egl_ctx_data_t egl; #endif -#ifdef HAVE_VULKAN - gfx_ctx_vulkan_data_t vk; - unsigned width; - unsigned height; - int swap_interval; -#endif } android_ctx_data_t; - -/* Forward declaration */ -int system_property_get(const char *cmd, const char *args, char *value); - /* TODO/FIXME - static global */ static enum gfx_ctx_api android_api = GFX_CTX_NONE; #ifdef HAVE_OPENGLES @@ -74,33 +60,13 @@ static bool g_es3 = false; 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); + 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); } @@ -126,7 +92,8 @@ static void *android_gfx_ctx_init(void *video_driver) }; #endif struct android_app *android_app = (struct android_app*)g_android; - android_ctx_data_t *and = (android_ctx_data_t*)calloc(1, sizeof(*and)); + android_ctx_data_t *and = (android_ctx_data_t*) + calloc(1, sizeof(*and)); if (!android_app || !and) return false; @@ -136,56 +103,33 @@ static void *android_gfx_ctx_init(void *video_driver) attribs[1] = EGL_OPENGL_ES3_BIT_KHR; #endif - switch (android_api) - { - case GFX_CTX_OPENGL_API: - case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_EGL - RARCH_LOG("Android EGL: GLES version = %d.\n", g_es3 ? 3 : 2); + RARCH_LOG("Android EGL: GLES version = %d.\n", g_es3 ? 3 : 2); - if (!egl_init_context(&and->egl, EGL_NONE, EGL_DEFAULT_DISPLAY, - &major, &minor, &n, attribs, NULL)) - { - egl_report_error(); - goto error; - } - - 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: - default: - break; + if (!egl_init_context(&and->egl, EGL_NONE, EGL_DEFAULT_DISPLAY, + &major, &minor, &n, attribs, NULL)) + { + egl_report_error(); + goto error; } + if (!egl_get_native_visual_id(&and->egl, &format)) + goto error; +#endif + slock_lock(android_app->mutex); if (!android_app->window) - goto unlock_error; - - switch (android_api) { - case GFX_CTX_OPENGL_API: - case GFX_CTX_OPENGL_ES_API: - ANativeWindow_setBuffersGeometry(android_app->window, 0, 0, format); - - break; - case GFX_CTX_NONE: - default: - break; + slock_unlock(android_app->mutex); + android_gfx_ctx_destroy(and); + return NULL; } + ANativeWindow_setBuffersGeometry(android_app->window, 0, 0, format); + slock_unlock(android_app->mutex); return and; -unlock_error: - slock_unlock(android_app->mutex); error: android_gfx_ctx_destroy(and); @@ -197,66 +141,23 @@ static void android_gfx_ctx_get_video_size(void *data, { 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); + 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; - } } static void android_gfx_ctx_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height) { -#ifdef HAVE_VULKAN - struct android_app *android_app = (struct android_app*)g_android; -#endif - unsigned new_width = 0; unsigned new_height = 0; android_ctx_data_t *and = (android_ctx_data_t*)data; - *quit = false; + *quit = false; - switch (android_api) - { - case GFX_CTX_OPENGL_API: - case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_EGL - egl_get_video_size(&and->egl, &new_width, &new_height); + egl_get_video_size(&and->egl, &new_width, &new_height); #endif - break; - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - if (android_app->content_rect.changed) - { - and->vk.need_new_swapchain = true; - android_app->content_rect.changed = false; - } - - /* Swapchains are recreated in set_resize as a - * central place, so use that to trigger swapchain reinit. */ - *resize = and->vk.need_new_swapchain; - new_width = android_app->content_rect.width; - new_height = android_app->content_rect.height; -#endif - break; - case GFX_CTX_NONE: - default: - break; - } if (new_width != *width || new_height != *height) { @@ -270,54 +171,17 @@ static void android_gfx_ctx_check_window(void *data, bool *quit, } static bool android_gfx_ctx_set_resize(void *data, - unsigned width, unsigned height) -{ -#ifdef HAVE_VULKAN - android_ctx_data_t *and = (android_ctx_data_t*)data; - struct android_app *android_app = (struct android_app*)g_android; -#endif - (void)data; - (void)width; - (void)height; - - switch (android_api) - { - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - and->width = android_app->content_rect.width; - and->height = android_app->content_rect.height; - RARCH_LOG("[Android]: Native window size: %u x %u.\n", and->width, and->height); - if (!vulkan_create_swapchain(&and->vk, and->width, and->height, and->swap_interval)) - { - RARCH_ERR("[Android]: Failed to update swapchain.\n"); - return false; - } - - if (and->vk.created_new_swapchain) - vulkan_acquire_next_image(&and->vk); - and->vk.context.invalid_swapchain = true; - and->vk.need_new_swapchain = false; -#endif - break; - - case GFX_CTX_NONE: - default: - break; - } - - return false; -} + unsigned width, unsigned height) { return false; } static bool android_gfx_ctx_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) { -#if defined(HAVE_OPENGLES) || defined(HAVE_VULKAN) +#if defined(HAVE_OPENGLES) struct android_app *android_app = (struct android_app*)g_android; - android_ctx_data_t *and = (android_ctx_data_t*)data; -#endif -#if defined(HAVE_OPENGLES) && defined(HAVE_EGL) - EGLint context_attributes[] = { + android_ctx_data_t *and = (android_ctx_data_t*)data; +#if defined(HAVE_EGL) + EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, g_es3 ? 3 : 2, #if 0 EGL_CONTEXT_FLAGS_KHR, debug ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0, @@ -325,10 +189,7 @@ static bool android_gfx_ctx_set_video_mode(void *data, EGL_NONE }; #endif - - (void)width; - (void)height; - (void)fullscreen; +#endif switch (android_api) { @@ -344,19 +205,6 @@ static bool android_gfx_ctx_set_video_mode(void *data, if (!egl_create_surface(&and->egl, android_app->window)) return false; -#endif - break; - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - and->width = ANativeWindow_getWidth(android_app->window); - and->height = ANativeWindow_getHeight(android_app->window); - RARCH_LOG("[Android]: Native window size: %u x %u.\n", and->width, and->height); - if (!vulkan_surface_create(&and->vk, VULKAN_WSI_ANDROID, NULL, android_app->window, - and->width, and->height, and->swap_interval)) - { - RARCH_ERR("[Android]: Failed to create surface.\n"); - return false; - } #endif break; @@ -387,36 +235,20 @@ static bool android_gfx_ctx_bind_api(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor) { unsigned version; - android_api = api; - switch (api) - { - case GFX_CTX_OPENGL_API: - case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_OPENGLES - version = major * 100 + minor; - if (version > 300) - return false; - if (version < 300) - g_es3 = false; - else if (version == 300) - g_es3 = true; + version = major * 100 + minor; + if (version > 300) + return false; + if (version < 300) + g_es3 = false; + else if (version == 300) + g_es3 = true; - if (api == GFX_CTX_OPENGL_ES_API) - return true; + if (api == GFX_CTX_OPENGL_ES_API) + return true; #endif - break; - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - return true; -#else - break; -#endif - case GFX_CTX_NONE: - default: - break; - } return false; } @@ -435,39 +267,7 @@ static bool android_gfx_ctx_has_focus(void *data) return focused; } -static bool android_gfx_ctx_suppress_screensaver(void *data, bool enable) -{ - (void)data; - (void)enable; - return false; -} - -static void dpi_get_density(char *s, size_t len) -{ - static bool inited_once = false; - static bool inited2_once = false; - static char string[PROP_VALUE_MAX] = {0}; - static char string2[PROP_VALUE_MAX] = {0}; - if (!inited_once) - { - system_property_get("getprop", "ro.sf.lcd_density", string); - inited_once = true; - } - - if (!string_is_empty(string)) - { - strlcpy(s, string, len); - return; - } - - if (!inited2_once) - { - system_property_get("wm", "density", string2); - inited2_once = true; - } - - strlcpy(s, string2, len); -} +static bool android_gfx_ctx_suppress_screensaver(void *data, bool enable) { return false; } static bool android_gfx_ctx_get_metrics(void *data, enum display_metric_types type, float *value) @@ -477,7 +277,6 @@ static bool android_gfx_ctx_get_metrics(void *data, switch (type) { case DISPLAY_METRIC_MM_WIDTH: - return false; case DISPLAY_METRIC_MM_HEIGHT: return false; case DISPLAY_METRIC_DPI: @@ -486,7 +285,7 @@ static bool android_gfx_ctx_get_metrics(void *data, char density[PROP_VALUE_MAX]; density[0] = '\0'; - dpi_get_density(density, sizeof(density)); + android_dpi_get_density(density, sizeof(density)); if (string_is_empty(density)) goto dpi_fallback; dpi = atoi(density); @@ -516,121 +315,44 @@ static void android_gfx_ctx_swap_buffers(void *data) { 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_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 - break; - case GFX_CTX_NONE: - default: - break; - } } static void android_gfx_ctx_set_swap_interval(void *data, int swap_interval) { 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_set_swap_interval(&and->egl, swap_interval); + egl_set_swap_interval(&and->egl, swap_interval); #endif - break; - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - if (and->swap_interval != swap_interval) - { - RARCH_LOG("[Vulkan]: Setting swap interval: %u.\n", swap_interval); - and->swap_interval = swap_interval; - if (and->vk.swapchain) - and->vk.need_new_swapchain = true; - } -#endif - break; - case GFX_CTX_NONE: - default: - break; - } } static gfx_ctx_proc_t android_gfx_ctx_get_proc_address(const char *symbol) { - switch (android_api) - { - case GFX_CTX_OPENGL_API: - case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_EGL - return egl_get_proc_address(symbol); + return egl_get_proc_address(symbol); #else - break; -#endif - case GFX_CTX_NONE: - default: - break; - } - return NULL; +#endif } static void android_gfx_ctx_bind_hw_render(void *data, bool enable) { 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_bind_hw_render(&and->egl, enable); + egl_bind_hw_render(&and->egl, enable); #endif - break; - case GFX_CTX_NONE: - default: - break; - } } -#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 - static uint32_t android_gfx_ctx_get_flags(void *data) { uint32_t flags = 0; - switch (android_api) - { - case GFX_CTX_OPENGL_API: - case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_GLSL - BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_GLSL); + BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_GLSL); #endif - break; - case GFX_CTX_VULKAN_API: -#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) - BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG); -#endif - break; - case GFX_CTX_NONE: - default: - break; - } return flags; } @@ -667,10 +389,6 @@ const gfx_ctx_driver_t gfx_ctx_android = { android_gfx_ctx_get_flags, android_gfx_ctx_set_flags, android_gfx_ctx_bind_hw_render, -#ifdef HAVE_VULKAN - android_gfx_ctx_get_context_data, -#else NULL, -#endif NULL }; diff --git a/gfx/drivers_context/android_vk_ctx.c b/gfx/drivers_context/android_vk_ctx.c new file mode 100644 index 0000000000..d959974a72 --- /dev/null +++ b/gfx/drivers_context/android_vk_ctx.c @@ -0,0 +1,329 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ +#include + +#include + +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include "../common/vulkan_common.h" + +#include "../../frontend/frontend_driver.h" +#include "../../frontend/drivers/platform_unix.h" +#include "../../verbosity.h" +#include "../../configuration.h" + +typedef struct +{ + gfx_ctx_vulkan_data_t vk; + unsigned width; + unsigned height; + int swap_interval; +} android_ctx_data_vk_t; + +static void android_gfx_ctx_vk_destroy(void *data) +{ + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)data; + struct android_app *android_app = (struct android_app*)g_android; + + if (!and) + return; + + vulkan_context_destroy(&and->vk, android_app->window); + + if (and->vk.context.queue_lock) + slock_free(and->vk.context.queue_lock); + + free(data); +} + +static void *android_gfx_ctx_vk_init(void *video_driver) +{ + struct android_app *android_app = (struct android_app*)g_android; + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)calloc(1, sizeof(*and)); + + if (!android_app || !and) + return false; + + if (!vulkan_context_init(&and->vk, VULKAN_WSI_ANDROID)) + goto error; + + slock_lock(android_app->mutex); + if (!android_app->window) + { + slock_unlock(android_app->mutex); + android_gfx_ctx_vk_destroy(and); + return NULL; + } + + slock_unlock(android_app->mutex); + return and; + +error: + android_gfx_ctx_vk_destroy(and); + + return NULL; +} + +static void android_gfx_ctx_vk_get_video_size(void *data, + unsigned *width, unsigned *height) +{ + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)data; + + *width = and->width; + *height = and->height; +} + +static void android_gfx_ctx_vk_check_window(void *data, bool *quit, + bool *resize, unsigned *width, unsigned *height) +{ + struct android_app *android_app = (struct android_app*)g_android; + + unsigned new_width = 0; + unsigned new_height = 0; + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)data; + + *quit = false; + + if (android_app->content_rect.changed) + { + and->vk.need_new_swapchain = true; + android_app->content_rect.changed = false; + } + + /* Swapchains are recreated in set_resize as a + * central place, so use that to trigger swapchain reinit. */ + *resize = and->vk.need_new_swapchain; + new_width = android_app->content_rect.width; + new_height = android_app->content_rect.height; + + if (new_width != *width || new_height != *height) + { + RARCH_LOG("[Android]: Resizing (%u x %u) -> (%u x %u).\n", + *width, *height, new_width, new_height); + + *width = new_width; + *height = new_height; + *resize = true; + } +} + +static bool android_gfx_ctx_vk_set_resize(void *data, + unsigned width, unsigned height) +{ + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)data; + struct android_app *android_app = (struct android_app*)g_android; + + and->width = android_app->content_rect.width; + and->height = android_app->content_rect.height; + RARCH_LOG("[Android]: Native window size: %u x %u.\n", and->width, and->height); + if (!vulkan_create_swapchain(&and->vk, and->width, and->height, and->swap_interval)) + { + RARCH_ERR("[Android]: Failed to update swapchain.\n"); + return false; + } + + if (and->vk.created_new_swapchain) + vulkan_acquire_next_image(&and->vk); + and->vk.context.invalid_swapchain = true; + and->vk.need_new_swapchain = false; + + return false; +} + +static bool android_gfx_ctx_vk_set_video_mode(void *data, + unsigned width, unsigned height, + bool fullscreen) +{ + struct android_app *android_app = (struct android_app*)g_android; + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)data; + + and->width = ANativeWindow_getWidth(android_app->window); + and->height = ANativeWindow_getHeight(android_app->window); + RARCH_LOG("[Android]: Native window size: %u x %u.\n", and->width, and->height); + if (!vulkan_surface_create(&and->vk, VULKAN_WSI_ANDROID, NULL, android_app->window, + and->width, and->height, and->swap_interval)) + { + RARCH_ERR("[Android]: Failed to create surface.\n"); + return false; + } + + return true; +} + +static void android_gfx_ctx_vk_input_driver(void *data, + const char *joypad_name, + input_driver_t **input, void **input_data) +{ + void *androidinput = input_android.init(joypad_name); + + *input = androidinput ? &input_android : NULL; + *input_data = androidinput; +} + +static enum gfx_ctx_api android_gfx_ctx_vk_get_api(void *data) +{ + return GFX_CTX_VULKAN_API; +} + +static bool android_gfx_ctx_vk_bind_api(void *data, + enum gfx_ctx_api api, unsigned major, unsigned minor) +{ + if (api == GFX_CTX_VULKAN_API) + return true; + return false; +} + +static bool android_gfx_ctx_vk_has_focus(void *data) +{ + bool focused = false; + struct android_app *android_app = (struct android_app*)g_android; + if (!android_app) + return true; + + slock_lock(android_app->mutex); + focused = !android_app->unfocused; + slock_unlock(android_app->mutex); + + return focused; +} + +static bool android_gfx_ctx_vk_suppress_screensaver(void *data, bool enable) { return false; } + +static bool android_gfx_ctx_vk_get_metrics(void *data, + enum display_metric_types type, float *value) +{ + static int dpi = -1; + + switch (type) + { + case DISPLAY_METRIC_MM_WIDTH: + case DISPLAY_METRIC_MM_HEIGHT: + return false; + case DISPLAY_METRIC_DPI: + if (dpi == -1) + { + char density[PROP_VALUE_MAX]; + density[0] = '\0'; + + android_dpi_get_density(density, sizeof(density)); + if (string_is_empty(density)) + goto dpi_fallback; + dpi = atoi(density); + + if (dpi <= 0) + goto dpi_fallback; + } + *value = (float)dpi; + break; + case DISPLAY_METRIC_NONE: + default: + *value = 0; + return false; + } + + return true; + +dpi_fallback: + /* add a fallback in case the device doesn't report DPI. + * Hopefully fixes issues with the moto G2. */ + dpi = 90; + *value = (float)dpi; + return true; +} + +static void android_gfx_ctx_vk_swap_buffers(void *data) +{ + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)data; + + vulkan_present(&and->vk, and->vk.context.current_swapchain_index); + vulkan_acquire_next_image(&and->vk); +} + +static void android_gfx_ctx_vk_set_swap_interval(void *data, int swap_interval) +{ + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)data; + + if (and->swap_interval != swap_interval) + { + RARCH_LOG("[Vulkan]: Setting swap interval: %u.\n", swap_interval); + and->swap_interval = swap_interval; + if (and->vk.swapchain) + and->vk.need_new_swapchain = true; + } +} + +static gfx_ctx_proc_t android_gfx_ctx_vk_get_proc_address(const char *symbol) { return NULL; } +static void android_gfx_ctx_vk_bind_hw_render(void *data, bool enable) { } + +static void *android_gfx_ctx_vk_get_context_data(void *data) +{ + android_ctx_data_vk_t *and = (android_ctx_data_vk_t*)data; + return &and->vk.context; +} + +static uint32_t android_gfx_ctx_vk_get_flags(void *data) +{ + uint32_t flags = 0; + +#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) + BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG); +#endif + + return flags; +} + +static void android_gfx_ctx_vk_set_flags(void *data, uint32_t flags) { } + +const gfx_ctx_driver_t gfx_ctx_vk_android = { + android_gfx_ctx_vk_init, + android_gfx_ctx_vk_destroy, + android_gfx_ctx_vk_get_api, + android_gfx_ctx_vk_bind_api, + android_gfx_ctx_vk_set_swap_interval, + android_gfx_ctx_vk_set_video_mode, + android_gfx_ctx_vk_get_video_size, + NULL, /* get_refresh_rate */ + NULL, /* get_video_output_size */ + NULL, /* get_video_output_prev */ + NULL, /* get_video_output_next */ + android_gfx_ctx_vk_get_metrics, + NULL, + NULL, /* update_title */ + android_gfx_ctx_vk_check_window, + android_gfx_ctx_vk_set_resize, + android_gfx_ctx_vk_has_focus, + android_gfx_ctx_vk_suppress_screensaver, + false, /* has_windowed */ + android_gfx_ctx_vk_swap_buffers, + android_gfx_ctx_vk_input_driver, + android_gfx_ctx_vk_get_proc_address, + NULL, + NULL, + NULL, + "android_vk", + android_gfx_ctx_vk_get_flags, + android_gfx_ctx_vk_set_flags, + android_gfx_ctx_vk_bind_hw_render, + android_gfx_ctx_vk_get_context_data, + NULL +}; diff --git a/griffin/griffin.c b/griffin/griffin.c index f5b538f2fc..a926670d47 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -248,6 +248,9 @@ VIDEO CONTEXT #include "../gfx/drivers_context/ps3_ctx.c" #elif defined(ANDROID) #include "../gfx/drivers_context/android_ctx.c" +#if defined(HAVE_VULKAN) +#include "../gfx/drivers_context/android_vk_ctx.c" +#endif #include "../gfx/display_servers/dispserv_android.c" #elif defined(__QNX__) #include "../gfx/drivers_context/qnx_ctx.c" diff --git a/retroarch.c b/retroarch.c index c5c1e9418d..c0074a134d 100644 --- a/retroarch.c +++ b/retroarch.c @@ -580,6 +580,9 @@ static const gfx_ctx_driver_t *gfx_ctx_vk_drivers[] = { #if defined(_WIN32) && !defined(__WINRT__) &gfx_ctx_w_vk, #endif +#if defined(ANDROID) + &gfx_ctx_vk_android, +#endif #if defined(HAVE_VULKAN_DISPLAY) &gfx_ctx_khr_display, #endif diff --git a/retroarch.h b/retroarch.h index a94a65fcc8..ec09d8ffe1 100644 --- a/retroarch.h +++ b/retroarch.h @@ -1892,6 +1892,7 @@ extern const gfx_ctx_driver_t gfx_ctx_go2_drm; extern const gfx_ctx_driver_t gfx_ctx_mali_fbdev; extern const gfx_ctx_driver_t gfx_ctx_vivante_fbdev; extern const gfx_ctx_driver_t gfx_ctx_android; +extern const gfx_ctx_driver_t gfx_ctx_vk_android; extern const gfx_ctx_driver_t gfx_ctx_ps3; extern const gfx_ctx_driver_t gfx_ctx_w_vk; extern const gfx_ctx_driver_t gfx_ctx_wgl;