From 15ffffa835f343aae640bd12319a904ffac07c19 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 15 Dec 2019 16:45:00 +0100 Subject: [PATCH] Android/Vulkan: Recreate swapchain on orientation change. ANativeWindow getWidth/Height does not detect any changes when using Vulkan, so use the old onContentRectChanged callback to get notified when size changed. Use those values instead when figuring out how large swapchain to create. Tested trivially on Galaxy S9+ Exynos model. --- frontend/drivers/platform_unix.c | 13 +++++++++++++ frontend/drivers/platform_unix.h | 6 ++++++ gfx/drivers_context/android_ctx.c | 18 ++++++++++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 185fdc2947..ff21203013 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -377,6 +377,18 @@ static void onInputQueueDestroyed(ANativeActivity* activity, android_app_set_input((struct android_app*)activity->instance, NULL); } +static void onContentRectChanged(ANativeActivity *activity, + const ARect *rect) +{ + struct android_app *instance = (struct android_app*)activity->instance; + unsigned width = rect->right - rect->left; + unsigned height = rect->bottom - rect->top; + RARCH_LOG("Content rect changed: %u x %u\n", width, height); + instance->content_rect.changed = true; + instance->content_rect.width = width; + instance->content_rect.height = height; +} + JNIEnv *jni_thread_getenv(void) { JNIEnv *env; @@ -486,6 +498,7 @@ void ANativeActivity_onCreate(ANativeActivity* activity, activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; activity->callbacks->onInputQueueCreated = onInputQueueCreated; activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; + activity->callbacks->onContentRectChanged = onContentRectChanged; /* These are set only for the native activity, * and are reset when it ends. */ diff --git a/frontend/drivers/platform_unix.h b/frontend/drivers/platform_unix.h index 75f5578967..8a0485e6bc 100644 --- a/frontend/drivers/platform_unix.h +++ b/frontend/drivers/platform_unix.h @@ -165,6 +165,12 @@ struct android_app jmethodID setScreenOrientation; jmethodID getUserLanguageString; jmethodID doVibrate; + + struct + { + unsigned width, height; + bool changed; + } content_rect; }; enum diff --git a/gfx/drivers_context/android_ctx.c b/gfx/drivers_context/android_ctx.c index aeb6ed5f87..d48ae81f6a 100644 --- a/gfx/drivers_context/android_ctx.c +++ b/gfx/drivers_context/android_ctx.c @@ -218,6 +218,10 @@ static void android_gfx_ctx_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height, bool is_shutdown) { +#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; @@ -234,11 +238,17 @@ static void android_gfx_ctx_check_window(void *data, bool *quit, 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 = and->width; - new_height = and->height; + new_width = android_app->content_rect.width; + new_height = android_app->content_rect.height; #endif break; case GFX_CTX_NONE: @@ -276,8 +286,8 @@ static bool android_gfx_ctx_set_resize(void *data, { case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN - and->width = ANativeWindow_getWidth(android_app->window); - and->height = ANativeWindow_getHeight(android_app->window); + 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)) {