修复切换出现的 clash

This commit is contained in:
xsl
2026-04-26 12:42:32 +08:00
parent 36d7d65a0a
commit 6535a2c26a
2 changed files with 81 additions and 9 deletions
+31 -1
View File
@@ -191,8 +191,38 @@ void android_main(struct android_app *pApp) {
}
} while (!pApp->destroyRequested);
DebugLog::log("android_main: destroyRequested, running cleanup");
// ⚠️ 不要在这里调 cleanupSecondInit()。
//
// 在 Android 上,Activity 销毁(APP_CMD_DESTROY) 之前已经先收到了
// APP_CMD_TERM_WINDOWhandle_cmd 里走的是 onWindowLost()
// → Application::cleanupForWindowLost():销毁 swapChain / surface /
// framebuffers / imageViews / commandBuffers / 同步对象,但故意保留
// renderPass / pipelineLayout / graphicsPipeline,以便下一次进入
// Activity 时 reinitForNewWindow() 在 extent/format 不变的情况下
// 直接复用,省下重建 RenderPass / 重新编译 Pipeline 的开销。
//
// 而 cleanupSecondInit() 是 Windows 路径
// (mainLoop → cleanupSecondInit → initVulkan → mainLoop) 的对偶——
// 它会把 renderPass / pipelineLayout / graphicsPipeline 全部销毁。
// 又因为 g_Application 是一个跨 Activity 存活的全局 FaceApp 实例
// (android_main 入口处只在 g_Application == nullptr 时才 new)
// _applicationInited 也不会被复位;
// 下一次同一进程内进入另一个继承自 FaceActivity 的 Activity 时,
// onWindowInit() 看到 _applicationInited=1 走恢复分支调用
// reinitForNewWindow()extent/format 与上次相同(480x480 / 同 format)
// 时**不会**重建 renderPass / pipelineLayout / graphicsPipeline——
// 用着已经被销毁的 renderPass 句柄继续 createFramebuffers() →
// recordCommandBuffer() → vkCmdBeginRenderPass()
// Mali 驱动 (libGLES_mali) 在校验层后解引用已释放的 RenderPass 内部
// 数据,触发 SIGSEGV / si_addr=0x4
// (recordCommandBuffer + 0xBC,正好是 vkCmdBeginRenderPass)。
//
// 解决办法:android_main 退出时只信任 cleanupForWindowLost 已经做的
// 那部分清理,不再额外调 cleanupSecondInit(),让 renderPass /
// pipelineLayout / graphicsPipeline / FaceApp 的 m_graphicsPipeline*
// 都能存活到下一次 android_main 重新进来被复用。
//application.cleanup();
g_Application->cleanupSecondInit();
//g_Application->cleanupSecondInit();
g_Application->clearnSecondFaceApp();
DebugLog::log("android_main: exit");
}