117 lines
4.1 KiB
C++
117 lines
4.1 KiB
C++
#include "D3D12WindowRenderLoop.h"
|
|
|
|
namespace XCEngine::UI::Editor::Host {
|
|
|
|
D3D12WindowRenderLoopAttachResult D3D12WindowRenderLoop::Attach(
|
|
NativeRenderer& uiRenderer,
|
|
D3D12WindowRenderer& windowRenderer) {
|
|
m_uiRenderer = &uiRenderer;
|
|
m_windowRenderer = &windowRenderer;
|
|
|
|
D3D12WindowRenderLoopAttachResult result = {};
|
|
result.hasViewportSurfacePresentation = m_uiRenderer->AttachWindowRenderer(*m_windowRenderer);
|
|
if (!result.hasViewportSurfacePresentation) {
|
|
const std::string& interopError = m_uiRenderer->GetLastRenderError();
|
|
result.interopWarning = interopError.empty()
|
|
? "native renderer d3d12 interop unavailable; falling back to hwnd renderer."
|
|
: "native renderer d3d12 interop unavailable; falling back to hwnd renderer: " +
|
|
interopError;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void D3D12WindowRenderLoop::Detach() {
|
|
if (m_uiRenderer != nullptr) {
|
|
m_uiRenderer->DetachWindowRenderer();
|
|
}
|
|
|
|
m_uiRenderer = nullptr;
|
|
m_windowRenderer = nullptr;
|
|
}
|
|
|
|
D3D12WindowRenderLoopFrameContext D3D12WindowRenderLoop::BeginFrame() const {
|
|
D3D12WindowRenderLoopFrameContext context = {};
|
|
if (!HasViewportSurfacePresentation()) {
|
|
return context;
|
|
}
|
|
|
|
if (!m_windowRenderer->BeginFrame()) {
|
|
const std::string& frameError = m_windowRenderer->GetLastError();
|
|
context.warning = frameError.empty()
|
|
? "d3d12 frame begin failed"
|
|
: "d3d12 frame begin failed: " + frameError;
|
|
return context;
|
|
}
|
|
|
|
context.canRenderViewports = true;
|
|
context.renderContext = m_windowRenderer->GetRenderContext();
|
|
return context;
|
|
}
|
|
|
|
D3D12WindowRenderLoopResizeResult D3D12WindowRenderLoop::ApplyResize(UINT width, UINT height) {
|
|
D3D12WindowRenderLoopResizeResult result = {};
|
|
if (m_uiRenderer == nullptr || m_windowRenderer == nullptr) {
|
|
result.interopWarning = "window render loop is detached.";
|
|
return result;
|
|
}
|
|
|
|
m_uiRenderer->Resize(width, height);
|
|
m_uiRenderer->DetachWindowRenderer();
|
|
|
|
const bool resizedWindowRenderer =
|
|
m_windowRenderer->Resize(static_cast<int>(width), static_cast<int>(height));
|
|
if (!resizedWindowRenderer || !m_windowRenderer->GetLastError().empty()) {
|
|
const std::string& resizeError = m_windowRenderer->GetLastError();
|
|
result.windowRendererWarning = resizeError.empty()
|
|
? "window renderer resize warning."
|
|
: "window renderer resize warning: " + resizeError;
|
|
}
|
|
|
|
if (!resizedWindowRenderer) {
|
|
return result;
|
|
}
|
|
|
|
const D3D12WindowRenderLoopAttachResult attachResult =
|
|
Attach(*m_uiRenderer, *m_windowRenderer);
|
|
result.hasViewportSurfacePresentation = attachResult.hasViewportSurfacePresentation;
|
|
result.interopWarning = attachResult.interopWarning;
|
|
return result;
|
|
}
|
|
|
|
D3D12WindowRenderLoopPresentResult D3D12WindowRenderLoop::Present(
|
|
const ::XCEngine::UI::UIDrawData& drawData) const {
|
|
D3D12WindowRenderLoopPresentResult result = {};
|
|
if (m_uiRenderer == nullptr) {
|
|
result.warning = "window render loop has no ui renderer.";
|
|
return result;
|
|
}
|
|
|
|
if (HasViewportSurfacePresentation()) {
|
|
result.framePresented = m_uiRenderer->RenderToWindowRenderer(drawData);
|
|
if (!result.framePresented) {
|
|
const std::string& composeError = m_uiRenderer->GetLastRenderError();
|
|
result.warning = composeError.empty()
|
|
? "d3d12 window composition failed, falling back to hwnd renderer."
|
|
: "d3d12 window composition failed, falling back to hwnd renderer: " +
|
|
composeError;
|
|
}
|
|
}
|
|
|
|
if (!result.framePresented) {
|
|
result.framePresented = m_uiRenderer->Render(drawData);
|
|
if (!result.framePresented && result.warning.empty()) {
|
|
result.warning = m_uiRenderer->GetLastRenderError();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool D3D12WindowRenderLoop::HasViewportSurfacePresentation() const {
|
|
return m_uiRenderer != nullptr &&
|
|
m_windowRenderer != nullptr &&
|
|
m_uiRenderer->HasAttachedWindowRenderer();
|
|
}
|
|
|
|
} // namespace XCEngine::UI::Editor::Host
|