修复切换出现的 clash

This commit is contained in:
xsl
2026-04-26 22:42:10 +08:00
parent c5ec7c7dc5
commit b753fd36a2
2 changed files with 52 additions and 8 deletions
+2
View File
@@ -209,6 +209,8 @@ void android_main(struct android_app *pApp) {
// 头再进 MakeupActivity 时,onWindowInit 看到 _applicationInited=1 走 reinit
// 复用路径,引用悬空的 renderPass 调 vkCreateFramebuffervalidation
// layer 检测出 use-after-free 直接 SEGV。
//application.cleanup();
//g_Application->cleanupSecondInit();
g_Application->clearnSecondFaceApp();
DebugLog::log("android_main: exit");
}
+50 -8
View File
@@ -150,14 +150,55 @@ void Application::initVulkan()
// 这个函数目前只保留给 vulkan/main.cpp 那个独立 desktop 入口的进程退出路径。
void Application::cleanupSecondInit()
{
vkDestroySwapchainKHR(device, swapChain, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr);
vkDestroyPipeline(device, graphicsPipeline, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyRenderPass(device, renderPass, nullptr);
for (auto imageView : swapChainImageViews) {
vkDestroyImageView(device, imageView, nullptr);
// ★ 幂等:销毁后立刻把句柄置 VK_NULL_HANDLE / 清空 vector。
//
// 这个函数过去在 Android 路径 (android_main 退出) 上被错误地调用过;
// 由于销毁后没有清零句柄,紧接着重新进入的 reinitForNewWindow() 在
// extent/format 不变时会跳过重建,让 framebuffer / drawFrame 在
// 已经销毁的 renderPass 上继续工作,最终在
// vkCmdBeginRenderPass 内部 (libGLES_mali) 触发 SIGSEGV。
//
// 现在 android_main 退出路径已经不再调本函数;本函数只剩 Windows
// 路径 (mainLoop → cleanupSecondInit → initVulkan 的"二次 session"
// 复用) 在用。把它写成幂等的可以兜住将来任何对它的误用。
FACE_DBG_LOG("cleanupSecondInit: begin (swapChain=%s surface=%s renderPass=%s pipelineLayout=%s graphicsPipeline=%s imageViews=%zu framebuffers=%zu)",
swapChain == VK_NULL_HANDLE ? "null" : "live",
surface == VK_NULL_HANDLE ? "null" : "live",
renderPass == VK_NULL_HANDLE ? "null" : "live",
pipelineLayout == VK_NULL_HANDLE ? "null" : "live",
graphicsPipeline == VK_NULL_HANDLE ? "null" : "live",
swapChainImageViews.size(), swapChainFramebuffers.size());
if (device != VK_NULL_HANDLE) {
vkDeviceWaitIdle(device);
}
if (swapChain != VK_NULL_HANDLE) {
vkDestroySwapchainKHR(device, swapChain, nullptr);
swapChain = VK_NULL_HANDLE;
}
if (surface != VK_NULL_HANDLE) {
vkDestroySurfaceKHR(instance, surface, nullptr);
surface = VK_NULL_HANDLE;
}
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;
}
for (auto imageView : swapChainImageViews) {
if (imageView != VK_NULL_HANDLE) {
vkDestroyImageView(device, imageView, nullptr);
}
}
swapChainImageViews.clear();
for (auto framebuffer : swapChainFramebuffers)
{
if (framebuffer != VK_NULL_HANDLE)
@@ -166,7 +207,8 @@ void Application::cleanupSecondInit()
}
}
swapChainFramebuffers.clear();
swapChainImages.clear();
_sceondInited = false;
}