fix: 退出 SIGSEGV 与 VkShaderEXT 泄漏——生命周期三层秩序
- 根因:~Application 体内 Logger::Shutdown() 先于成员析构执行, Device 销毁期间 Vulkan validation 回调仍打日志 → spdlog 悬空调用 - 修复:app 置于 main 独立作用域,所有成员析构完毕后再 Shutdown - 退出序 = waitIdle(~Application 体内)→ 成员析构(shader 等 Device 子对象销毁)→ Logger::Shutdown - 顺带注释掉窗口全透明(调试期遗留)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <Engine/Core/Window.h>
|
||||
#include <Engine/Core/Log.h>
|
||||
#include <Engine/ECS/Scene.h>
|
||||
#include <Engine/Physics/PhysicsWorld.h>
|
||||
#include <Engine/Renderer/Renderer.h>
|
||||
#include <Engine/Assets/AssetManager.h>
|
||||
#include <Engine/Vulkan/Device.h>
|
||||
@@ -22,7 +23,6 @@ namespace Engine {
|
||||
|
||||
Application::Application(const std::string& title, u32 width, u32 height)
|
||||
{
|
||||
Logger::Initialize();
|
||||
|
||||
m_Window = CreateScope<Window>(title, width, height);
|
||||
|
||||
@@ -56,7 +56,10 @@ namespace Engine {
|
||||
|
||||
if (m_ImGuiLayer) m_ImGuiLayer.reset();
|
||||
|
||||
Logger::Shutdown();
|
||||
// 注意:这里不能 Logger::Shutdown()——成员析构(Device 销毁等)
|
||||
// 在函数体之后才执行,期间 Vulkan validation 回调仍会打日志,
|
||||
// logger 先亡会导致悬空调用 SIGSEGV。Shutdown 移到 main 的
|
||||
// app 作用域结束之后(所有成员析构完毕)。
|
||||
}
|
||||
|
||||
void Application::EnableImGui()
|
||||
@@ -94,18 +97,31 @@ namespace Engine {
|
||||
|
||||
OnInit();
|
||||
|
||||
// 物理世界(场景实体搭建完后创建)
|
||||
m_Physics = CreateScope<PhysicsWorld>(*m_Scene, m_Assets.get());
|
||||
// 物理调试图元 → 渲染侧(PhysicsDebugPass 每帧上传绘制)
|
||||
m_Renderer->SetPhysicsDebugSource(&m_Physics->GetDebugFrame());
|
||||
|
||||
while (m_Running) {
|
||||
const auto frameStart = std::chrono::steady_clock::now();
|
||||
|
||||
m_Window->PollEvents();
|
||||
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
f32 dt = std::chrono::duration<f32>(now - m_LastFrameTime).count();
|
||||
// 钳制卡顿(断点/窗口拖动导致的超大 dt),避免物理/动画穿模
|
||||
m_DeltaTime = std::clamp(dt, 0.0f, 0.25f);
|
||||
const f64 dt = std::chrono::duration<f64>(now - m_LastFrameTime).count();
|
||||
// 钳制卡顿(断点/窗口拖动导致的超大 dt),避免物理/动画穿模;
|
||||
// 帧首落定 FrameTime(时间单源),业务当帧只读
|
||||
Time::BeginFrame(std::clamp(dt, 0.0, 0.25), m_FrameCount);
|
||||
const FrameTime& frame = Time::Current();
|
||||
m_LastFrameTime = now;
|
||||
|
||||
OnUpdate(m_DeltaTime);
|
||||
// 物理步进(OnUpdate 之前,Unity FixedUpdate→Update 语义):
|
||||
// 动态体姿态写回 Transform 并标脏,UpdateTransforms 统一重算;
|
||||
// 吃 scaled dt → timeScale=0(编辑器暂停)时 accumulator 冻结,
|
||||
// SyncScene 对账仍跑(拖静态体照常同步)
|
||||
m_Physics->Step(frame.Dt());
|
||||
|
||||
OnUpdate(frame);
|
||||
|
||||
// 延迟销毁在渲染前统一 flush,保证渲染遍历时池结构不变
|
||||
m_Scene->FlushDestroyQueue();
|
||||
@@ -130,7 +146,7 @@ namespace Engine {
|
||||
|
||||
// ---- 主渲染(框架行为):RG 顺序 Forward → ImGui(loadOp=Load) →
|
||||
// Present,draw data 在 ImGui pass 里才真正提交 GPU ----
|
||||
m_Renderer->Render(*m_Scene, *m_Assets, m_DeltaTime);
|
||||
m_Renderer->Render(*m_Scene, *m_Assets, frame.Dt());
|
||||
|
||||
// ---- 帧率控制:vsync 开启时 present 自带节奏;否则按目标限帧 ----
|
||||
// 策略:先 sleep 到剩 ~2ms,再自旋——精度高且不烧 CPU
|
||||
|
||||
Reference in New Issue
Block a user