Default new_editor to native XCUI shell host
This commit is contained in:
218
new_editor/src/XCUIBackend/NativeWindowUICompositor.cpp
Normal file
218
new_editor/src/XCUIBackend/NativeWindowUICompositor.cpp
Normal file
@@ -0,0 +1,218 @@
|
||||
#include "XCUIBackend/NativeWindowUICompositor.h"
|
||||
|
||||
#include <XCEngine/Rendering/RenderContext.h>
|
||||
#include <XCEngine/Rendering/RenderSurface.h>
|
||||
#include <XCEngine/RHI/RHICommandList.h>
|
||||
#include <XCEngine/RHI/RHICommandQueue.h>
|
||||
#include <XCEngine/RHI/RHIResourceView.h>
|
||||
#include <XCEngine/RHI/RHISwapChain.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
namespace XCUIBackend {
|
||||
|
||||
namespace {
|
||||
|
||||
bool PrepareSwapChainRender(
|
||||
::XCEngine::Editor::Platform::D3D12WindowRenderer& windowRenderer,
|
||||
const float clearColor[4],
|
||||
::XCEngine::Rendering::RenderContext& outRenderContext,
|
||||
const ::XCEngine::Rendering::RenderSurface*& outRenderSurface,
|
||||
::XCEngine::RHI::RHIResourceView*& outRenderTargetView) {
|
||||
outRenderContext = windowRenderer.GetRenderContext();
|
||||
outRenderSurface = windowRenderer.GetCurrentRenderSurface();
|
||||
outRenderTargetView = nullptr;
|
||||
|
||||
if (!outRenderContext.IsValid() ||
|
||||
outRenderSurface == nullptr ||
|
||||
outRenderContext.commandList == nullptr ||
|
||||
windowRenderer.GetSwapChain() == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& colorAttachments = outRenderSurface->GetColorAttachments();
|
||||
if (colorAttachments.empty() || colorAttachments[0] == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outRenderTargetView = colorAttachments[0];
|
||||
outRenderContext.commandList->TransitionBarrier(
|
||||
outRenderTargetView,
|
||||
::XCEngine::RHI::ResourceStates::Present,
|
||||
::XCEngine::RHI::ResourceStates::RenderTarget);
|
||||
outRenderContext.commandList->SetRenderTargets(1, &outRenderTargetView, nullptr);
|
||||
outRenderContext.commandList->ClearRenderTarget(outRenderTargetView, clearColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RebindSwapChainRenderTarget(
|
||||
::XCEngine::Rendering::RenderContext& renderContext,
|
||||
::XCEngine::RHI::RHIResourceView* renderTargetView) {
|
||||
if (renderContext.commandList == nullptr || renderTargetView == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderContext.commandList->SetRenderTargets(1, &renderTargetView, nullptr);
|
||||
}
|
||||
|
||||
void PresentSwapChainRender(
|
||||
::XCEngine::Editor::Platform::D3D12WindowRenderer& windowRenderer,
|
||||
::XCEngine::Rendering::RenderContext& renderContext,
|
||||
::XCEngine::RHI::RHIResourceView* renderTargetView) {
|
||||
if (renderContext.commandList == nullptr ||
|
||||
renderContext.commandQueue == nullptr ||
|
||||
renderTargetView == nullptr ||
|
||||
windowRenderer.GetSwapChain() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderContext.commandList->TransitionBarrier(
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool NativeWindowUICompositor::Initialize(
|
||||
HWND hwnd,
|
||||
::XCEngine::Editor::Platform::D3D12WindowRenderer& windowRenderer,
|
||||
const ConfigureFontsCallback& configureFonts) {
|
||||
(void)configureFonts;
|
||||
|
||||
m_hwnd = hwnd;
|
||||
m_windowRenderer = hwnd != nullptr ? &windowRenderer : nullptr;
|
||||
m_renderBackend.Shutdown();
|
||||
m_renderBackend.ResetStats();
|
||||
m_pendingRenderPacket.Clear();
|
||||
m_lastPresentStats = {};
|
||||
return m_windowRenderer != nullptr;
|
||||
}
|
||||
|
||||
void NativeWindowUICompositor::Shutdown() {
|
||||
m_renderBackend.Shutdown();
|
||||
m_pendingRenderPacket.Clear();
|
||||
m_lastPresentStats = {};
|
||||
m_windowRenderer = nullptr;
|
||||
m_hwnd = nullptr;
|
||||
}
|
||||
|
||||
bool NativeWindowUICompositor::HandleWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
(void)hwnd;
|
||||
(void)message;
|
||||
(void)wParam;
|
||||
(void)lParam;
|
||||
return false;
|
||||
}
|
||||
|
||||
void NativeWindowUICompositor::RenderFrame(
|
||||
const float clearColor[4],
|
||||
const UiRenderCallback& renderUi,
|
||||
const RenderCallback& beforeUiRender,
|
||||
const RenderCallback& afterUiRender) {
|
||||
(void)renderUi;
|
||||
|
||||
m_lastPresentStats = {};
|
||||
if (m_windowRenderer == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
::XCEngine::Rendering::RenderContext renderContext = {};
|
||||
const ::XCEngine::Rendering::RenderSurface* renderSurface = nullptr;
|
||||
::XCEngine::RHI::RHIResourceView* renderTargetView = nullptr;
|
||||
if (!PrepareSwapChainRender(
|
||||
*m_windowRenderer,
|
||||
clearColor,
|
||||
renderContext,
|
||||
renderSurface,
|
||||
renderTargetView)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (beforeUiRender) {
|
||||
beforeUiRender(renderContext, *renderSurface);
|
||||
RebindSwapChainRenderTarget(renderContext, renderTargetView);
|
||||
}
|
||||
|
||||
m_lastPresentStats.hadPendingPacket = m_pendingRenderPacket.HasDrawData();
|
||||
m_lastPresentStats.submittedDrawListCount = m_pendingRenderPacket.drawData.GetDrawListCount();
|
||||
m_lastPresentStats.submittedCommandCount = m_pendingRenderPacket.drawData.GetTotalCommandCount();
|
||||
|
||||
if (m_pendingRenderPacket.textAtlasProvider != nullptr) {
|
||||
m_renderBackend.SetTextAtlasProvider(m_pendingRenderPacket.textAtlasProvider);
|
||||
} else {
|
||||
m_renderBackend.SetTextAtlasProvider(nullptr);
|
||||
}
|
||||
|
||||
if (m_lastPresentStats.hadPendingPacket) {
|
||||
m_lastPresentStats.renderedNativeOverlay =
|
||||
m_renderBackend.Render(renderContext, *renderSurface, m_pendingRenderPacket.drawData);
|
||||
m_lastPresentStats.overlayStats = m_renderBackend.GetLastOverlayStats();
|
||||
} else {
|
||||
m_renderBackend.ResetStats();
|
||||
m_lastPresentStats.overlayStats = m_renderBackend.GetLastOverlayStats();
|
||||
}
|
||||
|
||||
m_pendingRenderPacket.Clear();
|
||||
|
||||
if (afterUiRender) {
|
||||
RebindSwapChainRenderTarget(renderContext, renderTargetView);
|
||||
afterUiRender(renderContext, *renderSurface);
|
||||
}
|
||||
|
||||
PresentSwapChainRender(*m_windowRenderer, renderContext, renderTargetView);
|
||||
}
|
||||
|
||||
bool NativeWindowUICompositor::CreateTextureDescriptor(
|
||||
::XCEngine::RHI::RHIDevice* device,
|
||||
::XCEngine::RHI::RHITexture* texture,
|
||||
UITextureRegistration& outRegistration) {
|
||||
(void)device;
|
||||
(void)texture;
|
||||
outRegistration = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
void NativeWindowUICompositor::FreeTextureDescriptor(const UITextureRegistration& registration) {
|
||||
(void)registration;
|
||||
}
|
||||
|
||||
void NativeWindowUICompositor::SubmitRenderPacket(const XCUINativeWindowRenderPacket& packet) {
|
||||
m_pendingRenderPacket = packet;
|
||||
}
|
||||
|
||||
void NativeWindowUICompositor::SubmitRenderPacket(
|
||||
const ::XCEngine::UI::UIDrawData& drawData,
|
||||
const IXCUITextAtlasProvider* textAtlasProvider) {
|
||||
m_pendingRenderPacket.drawData = drawData;
|
||||
m_pendingRenderPacket.textAtlasProvider = textAtlasProvider;
|
||||
}
|
||||
|
||||
void NativeWindowUICompositor::ClearPendingRenderPacket() {
|
||||
m_pendingRenderPacket.Clear();
|
||||
}
|
||||
|
||||
bool NativeWindowUICompositor::HasPendingRenderPacket() const {
|
||||
return m_pendingRenderPacket.HasDrawData();
|
||||
}
|
||||
|
||||
const XCUINativeWindowRenderPacket& NativeWindowUICompositor::GetPendingRenderPacket() const {
|
||||
return m_pendingRenderPacket;
|
||||
}
|
||||
|
||||
const XCUINativeWindowPresentStats& NativeWindowUICompositor::GetLastPresentStats() const {
|
||||
return m_lastPresentStats;
|
||||
}
|
||||
|
||||
std::unique_ptr<IWindowUICompositor> CreateNativeWindowUICompositor() {
|
||||
return std::make_unique<NativeWindowUICompositor>();
|
||||
}
|
||||
|
||||
} // namespace XCUIBackend
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user