AI 修复横竖屏的问题

This commit is contained in:
xsl
2026-04-23 23:43:48 +08:00
parent 27b7075818
commit 2066b3b124
5 changed files with 127 additions and 18 deletions
+63 -10
View File
@@ -112,9 +112,12 @@ void Application::initVulkan()
createSyncObjects(); // 创建同步对象
_lastDrawFrameTime = getCurrentTimeMillis();
_applicationInited = true;
// The first branch above already built all of the window-dependent
// objects. Mark _sceondInited so we don't fall into the recovery
// branch below and leak a second copy of surface/swapChain/etc.
_sceondInited = true;
}
if (!_sceondInited) {
else if (!_sceondInited) {
createSurface();
createSwapChain();
createImageViews();
@@ -155,8 +158,14 @@ void Application::cleanupForWindowLost()
(int)_applicationInited, (int)_sceondInited);
return;
}
FACE_DBG_LOG("cleanupForWindowLost: begin (imageCount=%zu MAX_FRAMES_IN_FLIGHT=%d)",
swapChainImages.size(), MAX_FRAMES_IN_FLIGHT);
FACE_DBG_LOG("cleanupForWindowLost: begin (imageCount=%zu MAX_FRAMES_IN_FLIGHT=%d extent=%ux%u format=%d)",
swapChainImages.size(), MAX_FRAMES_IN_FLIGHT,
swapChainExtent.width, swapChainExtent.height, (int)swapChainImageFormat);
// Snapshot before we destroy the swapchain so reinitForNewWindow() can
// decide whether the new swapchain needs renderPass / pipelines rebuilt.
_prevSwapChainExtent = swapChainExtent;
_prevSwapChainImageFormat = swapChainImageFormat;
// Block until GPU is no longer using any of the resources we are about
// to destroy. Anything weaker than this risks hitting VK_ERROR_DEVICE_LOST
@@ -222,29 +231,73 @@ void Application::cleanupForWindowLost()
FACE_DBG_LOG("cleanupForWindowLost: done");
}
void Application::reinitForNewWindow()
bool Application::reinitForNewWindow()
{
if (!_applicationInited) {
FACE_DBG_LOG("reinitForNewWindow: skip, _applicationInited=0 (must go through initVulkan first)");
return;
return false;
}
if (_sceondInited) {
FACE_DBG_LOG("reinitForNewWindow: skip, already _sceondInited=1");
return;
return false;
}
FACE_DBG_LOG("reinitForNewWindow: begin");
FACE_DBG_LOG("reinitForNewWindow: begin (prev extent=%ux%u format=%d)",
_prevSwapChainExtent.width, _prevSwapChainExtent.height,
(int)_prevSwapChainImageFormat);
createSurface();
createSwapChain();
const bool extentChanged = (swapChainExtent.width != _prevSwapChainExtent.width) ||
(swapChainExtent.height != _prevSwapChainExtent.height);
const bool formatChanged = (swapChainImageFormat != _prevSwapChainImageFormat);
const bool swapchainIncompatible = extentChanged || formatChanged;
if (formatChanged) {
// renderPass bakes in swapChainImageFormat, so it must be rebuilt
// when the surface chose a different format. The old Application
// graphicsPipeline is tied to the old renderPass, so destroy it
// first to make the handle invalidation explicit.
FACE_DBG_LOG("reinitForNewWindow: format changed (%d -> %d), rebuilding renderPass",
(int)_prevSwapChainImageFormat, (int)swapChainImageFormat);
if (graphicsPipeline != VK_NULL_HANDLE) {
vkDestroyPipeline(device, graphicsPipeline, nullptr);
graphicsPipeline = VK_NULL_HANDLE;
}
if (pipelineLayout != VK_NULL_HANDLE) {
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
pipelineLayout = VK_NULL_HANDLE;
}
if (renderPass != VK_NULL_HANDLE) {
vkDestroyRenderPass(device, renderPass, nullptr);
renderPass = VK_NULL_HANDLE;
}
createRenderPass();
createPipelineLayout();
createGraphicsPipeline();
} else if (extentChanged) {
// renderPass is still fine, but the Application pipeline has a static
// viewport baked to the old extent and must be rebuilt.
FACE_DBG_LOG("reinitForNewWindow: extent changed (%ux%u -> %ux%u), rebuilding graphicsPipeline",
_prevSwapChainExtent.width, _prevSwapChainExtent.height,
swapChainExtent.width, swapChainExtent.height);
if (graphicsPipeline != VK_NULL_HANDLE) {
vkDestroyPipeline(device, graphicsPipeline, nullptr);
graphicsPipeline = VK_NULL_HANDLE;
}
createGraphicsPipeline();
}
createImageViews();
createFramebuffers();
createCommandBuffer();
createSyncObjects();
_sceondInited = true;
FACE_DBG_LOG("reinitForNewWindow: done (imageCount=%zu extent=%ux%u MAX_FRAMES_IN_FLIGHT=%d)",
FACE_DBG_LOG("reinitForNewWindow: done (imageCount=%zu extent=%ux%u format=%d MAX_FRAMES_IN_FLIGHT=%d swapchainIncompatible=%d)",
swapChainImages.size(), swapChainExtent.width, swapChainExtent.height,
MAX_FRAMES_IN_FLIGHT);
(int)swapChainImageFormat, MAX_FRAMES_IN_FLIGHT, (int)swapchainIncompatible);
return swapchainIncompatible;
}