diff --git a/new_editor/app/Application.cpp b/new_editor/app/Application.cpp index 873f9756..ed459a06 100644 --- a/new_editor/app/Application.cpp +++ b/new_editor/app/Application.cpp @@ -464,8 +464,18 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { LogRuntimeTrace("app", "renderer initialization failed"); return false; } + RECT clientRect = {}; + GetClientRect(m_hwnd, &clientRect); + const int clientWidth = (std::max)(clientRect.right - clientRect.left, 1L); + const int clientHeight = (std::max)(clientRect.bottom - clientRect.top, 1L); + if (!m_windowRenderer.Initialize(m_hwnd, clientWidth, clientHeight)) { + LogRuntimeTrace("app", "d3d12 window renderer initialization failed"); + return false; + } m_editorContext.AttachTextMeasurer(m_renderer); m_editorWorkspace.Initialize(repoRoot, m_renderer); + m_editorWorkspace.AttachViewportWindowRenderer(m_windowRenderer); + m_editorWorkspace.SetViewportSurfacePresentationEnabled(false); if (!m_editorWorkspace.GetBuiltInIconError().empty()) { LogRuntimeTrace("icons", m_editorWorkspace.GetBuiltInIconError()); } @@ -494,6 +504,7 @@ void Application::Shutdown() { m_autoScreenshot.Shutdown(); m_editorWorkspace.Shutdown(); + m_windowRenderer.Shutdown(); m_renderer.Shutdown(); if (m_hwnd != nullptr && IsWindow(m_hwnd)) { @@ -541,11 +552,22 @@ void Application::RenderFrame() { m_editorWorkspace.GetShellInteractionState())); } + const bool d3d12FrameBegun = m_windowRenderer.BeginFrame(); + if (!d3d12FrameBegun) { + LogRuntimeTrace("viewport", "d3d12 frame begin failed"); + } + m_editorWorkspace.Update( m_editorContext, UIRect(0.0f, 0.0f, width, height), frameEvents, BuildCaptureStatusText()); + if (d3d12FrameBegun) { + m_editorWorkspace.RenderRequestedViewports(m_windowRenderer.GetRenderContext()); + if (!m_windowRenderer.SubmitFrame(false)) { + LogRuntimeTrace("viewport", "d3d12 offscreen frame submit failed"); + } + } const UIEditorShellInteractionFrame& shellFrame = m_editorWorkspace.GetShellFrame(); if (!frameEvents.empty() || @@ -710,6 +732,7 @@ void Application::OnResize(UINT width, UINT height) { } m_renderer.Resize(width, height); + m_windowRenderer.Resize(static_cast(width), static_cast(height)); } void Application::OnDpiChanged(UINT dpi, const RECT& suggestedRect) { diff --git a/new_editor/app/Application.h b/new_editor/app/Application.h index 0dd45634..fe29a522 100644 --- a/new_editor/app/Application.h +++ b/new_editor/app/Application.h @@ -5,6 +5,7 @@ #endif #include +#include #include #include @@ -68,6 +69,7 @@ private: HINSTANCE m_hInstance = nullptr; ATOM m_windowClassAtom = 0; ::XCEngine::UI::Editor::Host::NativeRenderer m_renderer = {}; + ::XCEngine::UI::Editor::Host::D3D12WindowRenderer m_windowRenderer = {}; ::XCEngine::UI::Editor::Host::AutoScreenshotController m_autoScreenshot = {}; ::XCEngine::UI::Editor::Host::InputModifierTracker m_inputModifierTracker = {}; App::ProductEditorContext m_editorContext = {}; diff --git a/new_editor/app/Host/D3D12WindowRenderLoop.cpp b/new_editor/app/Host/D3D12WindowRenderLoop.cpp index 1bb501af..eadd1c62 100644 --- a/new_editor/app/Host/D3D12WindowRenderLoop.cpp +++ b/new_editor/app/Host/D3D12WindowRenderLoop.cpp @@ -52,12 +52,7 @@ bool RenderD3D12WindowFrame( renderTargetView, ::XCEngine::RHI::ResourceStates::RenderTarget, ::XCEngine::RHI::ResourceStates::Present); - renderContext.commandList->Close(); - - void* commandLists[] = { renderContext.commandList }; - renderContext.commandQueue->ExecuteCommandLists(1, commandLists); - windowRenderer.GetSwapChain()->Present(1, 0); - return true; + return windowRenderer.SubmitFrame(true); } } // namespace XCEngine::UI::Editor::Host diff --git a/new_editor/app/Host/D3D12WindowRenderer.cpp b/new_editor/app/Host/D3D12WindowRenderer.cpp index 6ea01af0..fd0cfa5d 100644 --- a/new_editor/app/Host/D3D12WindowRenderer.cpp +++ b/new_editor/app/Host/D3D12WindowRenderer.cpp @@ -174,6 +174,24 @@ bool D3D12WindowRenderer::BeginFrame() { return true; } +bool D3D12WindowRenderer::SubmitFrame(bool presentSwapChain) { + if (m_commandList == nullptr || m_commandQueue == nullptr) { + return false; + } + + if (presentSwapChain && m_swapChain == nullptr) { + return false; + } + + m_commandList->Close(); + void* commandLists[] = { m_commandList }; + m_commandQueue->ExecuteCommandLists(1, commandLists); + if (presentSwapChain) { + m_swapChain->Present(1, 0); + } + return true; +} + ID3D12Device* D3D12WindowRenderer::GetDevice() const { const D3D12Device* device = GetD3D12Device(); return device != nullptr ? device->GetDevice() : nullptr; diff --git a/new_editor/app/Host/D3D12WindowRenderer.h b/new_editor/app/Host/D3D12WindowRenderer.h index 6ee6af38..7ae7acba 100644 --- a/new_editor/app/Host/D3D12WindowRenderer.h +++ b/new_editor/app/Host/D3D12WindowRenderer.h @@ -36,6 +36,7 @@ public: void Shutdown(); void Resize(int width, int height); bool BeginFrame(); + bool SubmitFrame(bool presentSwapChain); ID3D12Device* GetDevice() const; ID3D12DescriptorHeap* GetSrvHeap() const; diff --git a/new_editor/app/Workspace/ProductEditorWorkspace.cpp b/new_editor/app/Workspace/ProductEditorWorkspace.cpp index e42902dd..670d16a4 100644 --- a/new_editor/app/Workspace/ProductEditorWorkspace.cpp +++ b/new_editor/app/Workspace/ProductEditorWorkspace.cpp @@ -138,6 +138,18 @@ void ProductEditorWorkspace::Initialize( m_projectPanel.Initialize(repoRoot); } +void ProductEditorWorkspace::AttachViewportWindowRenderer(Host::D3D12WindowRenderer& renderer) { + m_viewportHostService.AttachWindowRenderer(renderer); +} + +void ProductEditorWorkspace::DetachViewportWindowRenderer() { + m_viewportHostService.DetachWindowRenderer(); +} + +void ProductEditorWorkspace::SetViewportSurfacePresentationEnabled(bool enabled) { + m_viewportHostService.SetSurfacePresentationEnabled(enabled); +} + void ProductEditorWorkspace::Shutdown() { m_shellFrame = {}; m_shellInteractionState = {}; @@ -206,6 +218,11 @@ void ProductEditorWorkspace::Update( m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame); } +void ProductEditorWorkspace::RenderRequestedViewports( + const ::XCEngine::Rendering::RenderContext& renderContext) { + m_viewportHostService.RenderRequestedViewports(renderContext); +} + void ProductEditorWorkspace::Append(UIDrawList& drawList) const { const auto& metrics = ResolveUIEditorShellInteractionMetrics(); const auto& palette = ResolveUIEditorShellInteractionPalette(); diff --git a/new_editor/app/Workspace/ProductEditorWorkspace.h b/new_editor/app/Workspace/ProductEditorWorkspace.h index edc759d5..ebd61752 100644 --- a/new_editor/app/Workspace/ProductEditorWorkspace.h +++ b/new_editor/app/Workspace/ProductEditorWorkspace.h @@ -9,10 +9,12 @@ #include "Viewport/ProductViewportHostService.h" #include "Workspace/ProductEditorWorkspaceEventRouter.h" +#include #include #include +#include #include #include @@ -27,12 +29,17 @@ public: const std::filesystem::path& repoRoot, Host::NativeRenderer& renderer); void Shutdown(); + void AttachViewportWindowRenderer(Host::D3D12WindowRenderer& renderer); + void DetachViewportWindowRenderer(); + void SetViewportSurfacePresentationEnabled(bool enabled); void Update( ProductEditorContext& context, const ::XCEngine::UI::UIRect& bounds, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, std::string_view captureText); + void RenderRequestedViewports( + const ::XCEngine::Rendering::RenderContext& renderContext); void Append(::XCEngine::UI::UIDrawList& drawList) const; const UIEditorShellInteractionFrame& GetShellFrame() const;