Decouple editor windowing from D3D12 runtime
This commit is contained in:
158
editor/app/Rendering/D3D12/D3D12EditorWindowRenderRuntime.cpp
Normal file
158
editor/app/Rendering/D3D12/D3D12EditorWindowRenderRuntime.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
#include "Rendering/D3D12/D3D12EditorWindowRenderRuntime.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace XCEngine::UI::Editor::Host {
|
||||
|
||||
namespace {
|
||||
|
||||
using Rendering::Host::EditorWindowRenderRuntimeFrameContext;
|
||||
using Rendering::Host::EditorWindowRenderRuntimeInitializeResult;
|
||||
using Rendering::Host::EditorWindowRenderRuntimePresentResult;
|
||||
using Rendering::Host::EditorWindowRenderRuntimeResizeResult;
|
||||
using Rendering::Host::EditorWindowRenderRuntimeSurface;
|
||||
|
||||
} // namespace
|
||||
|
||||
D3D12EditorWindowRenderRuntime::~D3D12EditorWindowRenderRuntime() = default;
|
||||
|
||||
bool D3D12EditorWindowRenderRuntime::IsReady() const {
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
void D3D12EditorWindowRenderRuntime::SetDpiScale(float dpiScale) {
|
||||
m_dpiScale = dpiScale > 0.0f ? dpiScale : 1.0f;
|
||||
m_textSystem.SetDpiScale(m_dpiScale);
|
||||
m_uiRenderer.SetDpiScale(m_dpiScale);
|
||||
}
|
||||
|
||||
UIEditorTextMeasurer& D3D12EditorWindowRenderRuntime::GetTextMeasurer() {
|
||||
return m_textSystem;
|
||||
}
|
||||
|
||||
const UIEditorTextMeasurer& D3D12EditorWindowRenderRuntime::GetTextMeasurer() const {
|
||||
return m_textSystem;
|
||||
}
|
||||
|
||||
Rendering::Host::UiTextureHost& D3D12EditorWindowRenderRuntime::GetTextureHost() {
|
||||
return m_textureHost;
|
||||
}
|
||||
|
||||
Rendering::Host::ViewportRenderHost& D3D12EditorWindowRenderRuntime::GetViewportRenderHost() {
|
||||
return m_windowRenderer;
|
||||
}
|
||||
|
||||
EditorWindowRenderRuntimeInitializeResult D3D12EditorWindowRenderRuntime::Initialize(
|
||||
const EditorWindowRenderRuntimeSurface& surface) {
|
||||
EditorWindowRenderRuntimeInitializeResult result = {};
|
||||
|
||||
HWND hwnd = static_cast<HWND>(surface.nativeWindowHandle);
|
||||
if (hwnd == nullptr) {
|
||||
result.errorMessage = "window initialize skipped: hwnd is null";
|
||||
return result;
|
||||
}
|
||||
|
||||
const int clientWidth = (std::max)(static_cast<int>(surface.widthPixels), 1);
|
||||
const int clientHeight = (std::max)(static_cast<int>(surface.heightPixels), 1);
|
||||
if (!m_windowRenderer.Initialize(hwnd, clientWidth, clientHeight)) {
|
||||
result.errorMessage = "d3d12 window renderer initialization failed";
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!m_textureHost.Initialize(m_windowRenderer)) {
|
||||
result.errorMessage = "d3d12 ui texture host initialization failed";
|
||||
m_windowRenderer.Shutdown();
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!m_textSystem.Initialize()) {
|
||||
result.errorMessage = "d3d12 ui text system initialization failed";
|
||||
m_textureHost.Shutdown();
|
||||
m_windowRenderer.Shutdown();
|
||||
return result;
|
||||
}
|
||||
m_textSystem.SetDpiScale(m_dpiScale);
|
||||
|
||||
if (!m_uiRenderer.Initialize(m_windowRenderer, m_textureHost, m_textSystem)) {
|
||||
result.errorMessage = "d3d12 ui renderer initialization failed";
|
||||
m_textSystem.Shutdown();
|
||||
m_textureHost.Shutdown();
|
||||
m_windowRenderer.Shutdown();
|
||||
return result;
|
||||
}
|
||||
m_uiRenderer.SetDpiScale(m_dpiScale);
|
||||
|
||||
const D3D12WindowRenderLoopAttachResult attachResult =
|
||||
m_windowRenderLoop.Attach(m_uiRenderer, m_windowRenderer);
|
||||
result.success = true;
|
||||
result.hasViewportSurfacePresentation = attachResult.hasViewportSurfacePresentation;
|
||||
result.warning = attachResult.warning;
|
||||
m_ready = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void D3D12EditorWindowRenderRuntime::WaitForGpuIdle() {
|
||||
m_windowRenderer.WaitForGpuIdle();
|
||||
}
|
||||
|
||||
void D3D12EditorWindowRenderRuntime::Shutdown() {
|
||||
m_ready = false;
|
||||
m_windowRenderLoop.Detach();
|
||||
m_uiRenderer.Shutdown();
|
||||
m_textSystem.Shutdown();
|
||||
m_textureHost.Shutdown();
|
||||
m_windowRenderer.Shutdown();
|
||||
m_dpiScale = 1.0f;
|
||||
}
|
||||
|
||||
EditorWindowRenderRuntimeResizeResult D3D12EditorWindowRenderRuntime::ApplyResize(
|
||||
std::uint32_t width,
|
||||
std::uint32_t height) {
|
||||
EditorWindowRenderRuntimeResizeResult result = {};
|
||||
if (!m_ready || width == 0u || height == 0u) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const D3D12WindowRenderLoopResizeResult resizeResult =
|
||||
m_windowRenderLoop.ApplyResize(
|
||||
static_cast<UINT>(width),
|
||||
static_cast<UINT>(height));
|
||||
result.hasViewportSurfacePresentation = resizeResult.hasViewportSurfacePresentation;
|
||||
result.warning = resizeResult.windowRendererWarning;
|
||||
return result;
|
||||
}
|
||||
|
||||
EditorWindowRenderRuntimeFrameContext D3D12EditorWindowRenderRuntime::BeginFrame() {
|
||||
EditorWindowRenderRuntimeFrameContext result = {};
|
||||
if (!m_ready) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const D3D12WindowRenderLoopFrameContext frameContext = m_windowRenderLoop.BeginFrame();
|
||||
result.canRenderViewports = frameContext.canRenderViewports;
|
||||
result.renderContext = frameContext.renderContext;
|
||||
result.warning = frameContext.warning;
|
||||
return result;
|
||||
}
|
||||
|
||||
EditorWindowRenderRuntimePresentResult D3D12EditorWindowRenderRuntime::Present(
|
||||
const ::XCEngine::UI::UIDrawData& drawData,
|
||||
const std::filesystem::path* captureOutputPath) {
|
||||
EditorWindowRenderRuntimePresentResult result = {};
|
||||
if (!m_ready) {
|
||||
result.warning = "window render runtime is not ready.";
|
||||
return result;
|
||||
}
|
||||
|
||||
const D3D12WindowRenderLoopPresentResult presentResult =
|
||||
m_windowRenderLoop.Present(drawData, captureOutputPath);
|
||||
result.framePresented = presentResult.framePresented;
|
||||
result.captureSucceeded = presentResult.captureSucceeded;
|
||||
result.captureError = presentResult.captureError;
|
||||
result.warning = presentResult.warning;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::Host
|
||||
Reference in New Issue
Block a user