159 lines
5.2 KiB
C++
159 lines
5.2 KiB
C++
#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
|