Android Vulkan: Don't trust a stale surface extent after a rotation

Since rotation is handled in place, the swapchain is recreated right
after surfaceChanged, and the surface can still report the previous
orientation's extent. On a Galaxy S8+ this happened in about one in four
rotations, leaving a portrait swapchain on a landscape window or the
other way around, squashed into half the screen until the next rotation.

If the extent is exactly the window size transposed, use the window size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-12 17:22:41 +02:00
1 parent 08649f0f15
commit f7ec86c5d5
1 file changed
+13
+13
View File
@@ -1532,6 +1532,19 @@ bool VulkanContext::InitSwapchain(VkPresentModeKHR desiredPresentMode) {
}
}
#if PPSSPP_PLATFORM(ANDROID)
// Right after an in-place rotation, the surface can still report the previous orientation's extent (seen
// on a Mali Galaxy S8+, when queried within a few ms of surfaceChanged). That leaves a portrait swapchain
// on a landscape window or the other way around, until the next rotation. The window size we were told
// about is current, so if the extent is exactly that transposed, it's stale.
if (g_display.pixel_xres > 0 && g_display.pixel_yres > 0 && g_display.pixel_xres != g_display.pixel_yres &&
currentExtent.width == (uint32_t)g_display.pixel_yres && currentExtent.height == (uint32_t)g_display.pixel_xres) {
WARN_LOG(Log::G3D, "Surface extent %dx%d is the window transposed, probably stale after a rotation. Using %dx%d.",
currentExtent.width, currentExtent.height, g_display.pixel_xres, g_display.pixel_yres);
std::swap(currentExtent.width, currentExtent.height);
}
#endif
swapChainExtent_.width = clamp(currentExtent.width, surfCapabilities_.minImageExtent.width, surfCapabilities_.maxImageExtent.width);
swapChainExtent_.height = clamp(currentExtent.height, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.height);