Default new_editor to native XCUI shell host

This commit is contained in:
2026-04-05 14:05:46 +08:00
parent e22d7d7f3d
commit 551eefbaa1
11 changed files with 1772 additions and 98 deletions

View 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