Files
XCEngine/new_editor/app/Rendering/Viewport/ViewportHostServiceFrame.cpp

140 lines
4.2 KiB
C++
Raw Normal View History

#include "ViewportHostService.h"
#include <XCEngine/RHI/RHICommandList.h>
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<std::uint32_t>(requestedSize.width)
: 0u;
entry.requestedHeight = entry.requestedThisFrame
? static_cast<std::uint32_t>(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<float>(entry.renderTargets.width),
static_cast<float>(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