#include "ViewportHostService.h" #include namespace XCEngine::UI::Editor::App { namespace { using ::XCEngine::RHI::ResourceStates; } // namespace ViewportFrame ViewportHostService::RequestViewport( ViewportKind kind, const ::XCEngine::UI::UISize& requestedSize) { ViewportEntry& entry = GetEntry(kind); entry.requestedThisFrame = requestedSize.width > 1.0f && requestedSize.height > 1.0f; entry.requestedWidth = entry.requestedThisFrame ? static_cast(requestedSize.width) : 0u; entry.requestedHeight = entry.requestedThisFrame ? static_cast(requestedSize.height) : 0u; if (!entry.requestedThisFrame) { return BuildFrame(entry, requestedSize); } if (m_windowRenderer == nullptr || m_device == nullptr) { return BuildFrame(entry, requestedSize); } if (!EnsureViewportResources(entry)) { return BuildFrame(entry, requestedSize); } return BuildFrame(entry, requestedSize); } void ViewportHostService::RenderRequestedViewports( const ::XCEngine::Rendering::RenderContext& renderContext) { if (m_windowRenderer == nullptr || m_device == nullptr || !renderContext.IsValid()) { return; } for (ViewportEntry& entry : m_entries) { if (!entry.requestedThisFrame || !EnsureViewportResources(entry)) { continue; } if (entry.kind == ViewportKind::Scene) { ClearViewport(entry, renderContext, 0.09f, 0.09f, 0.09f, 1.0f); } else { ClearViewport(entry, renderContext, 0.09f, 0.09f, 0.09f, 1.0f); } entry.renderedThisFrame = true; } } bool ViewportHostService::EnsureViewportResources(ViewportEntry& entry) { const ViewportResourceReuseQuery reuseQuery = BuildViewportRenderTargetsReuseQuery( entry.kind, entry.renderTargets, entry.requestedWidth, entry.requestedHeight); if (CanReuseViewportResources(reuseQuery)) { return true; } if (m_windowRenderer == nullptr || m_device == nullptr || entry.requestedWidth == 0u || entry.requestedHeight == 0u) { return false; } return m_renderTargetManager.EnsureTargets( entry.kind, entry.requestedWidth, entry.requestedHeight, *m_device, m_textureDescriptorAllocator, entry.renderTargets); } void ViewportHostService::ClearViewport( ViewportEntry& entry, const ::XCEngine::Rendering::RenderContext& renderContext, float r, float g, float b, float a) { if (renderContext.commandList == nullptr || entry.renderTargets.colorView == nullptr || entry.renderTargets.depthView == nullptr) { return; } auto* commandList = renderContext.commandList; auto* colorView = entry.renderTargets.colorView; const float clearColor[4] = { r, g, b, a }; commandList->TransitionBarrier( colorView, entry.renderTargets.colorState, ResourceStates::RenderTarget); commandList->SetRenderTargets(1, &colorView, entry.renderTargets.depthView); commandList->ClearRenderTarget(colorView, clearColor); commandList->ClearDepthStencil(entry.renderTargets.depthView, 1.0f, 0); commandList->TransitionBarrier( colorView, ResourceStates::RenderTarget, ResourceStates::PixelShaderResource); entry.renderTargets.colorState = ResourceStates::PixelShaderResource; entry.renderTargets.hasValidObjectIdFrame = false; } ViewportFrame ViewportHostService::BuildFrame( const ViewportEntry& entry, const ::XCEngine::UI::UISize& requestedSize) const { ViewportFrame frame = {}; frame.requestedSize = requestedSize; frame.renderSize = ::XCEngine::UI::UISize( static_cast(entry.renderTargets.width), static_cast(entry.renderTargets.height)); frame.wasRequested = entry.requestedThisFrame; frame.statusText = entry.statusText; if (m_surfacePresentationEnabled && entry.renderTargets.textureHandle.IsValid()) { frame.texture = entry.renderTargets.textureHandle; frame.hasTexture = true; } return frame; } } // namespace XCEngine::UI::Editor::App