Publish native hosted preview textures through XCUI compositor
This commit is contained in:
@@ -591,7 +591,7 @@ void Application::ShutdownRenderer() {
|
||||
|
||||
void Application::DestroyHostedPreviewSurfaces() {
|
||||
for (HostedPreviewOffscreenSurface& previewSurface : m_hostedPreviewSurfaces) {
|
||||
if (previewSurface.textureRegistration.cpuHandle.ptr != 0) {
|
||||
if (Application::HasHostedPreviewTextureRegistration(previewSurface.textureRegistration)) {
|
||||
if (m_windowCompositor != nullptr) {
|
||||
m_windowCompositor->FreeTextureDescriptor(previewSurface.textureRegistration);
|
||||
}
|
||||
@@ -698,7 +698,7 @@ bool Application::EnsureHostedPreviewSurface(
|
||||
return true;
|
||||
}
|
||||
|
||||
if (previewSurface.textureRegistration.cpuHandle.ptr != 0) {
|
||||
if (Application::HasHostedPreviewTextureRegistration(previewSurface.textureRegistration)) {
|
||||
if (m_windowCompositor != nullptr) {
|
||||
m_windowCompositor->FreeTextureDescriptor(previewSurface.textureRegistration);
|
||||
}
|
||||
@@ -980,6 +980,35 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
|
||||
for (const NativeShellPanelLayout& panelLayout : panelLayouts) {
|
||||
if (panelLayout.panelId == ShellPanelId::XCUIDemo) {
|
||||
const ShellPanelChromeState* panelState = TryGetShellPanelState(ShellPanelId::XCUIDemo);
|
||||
const bool nativeHostedPreview =
|
||||
panelState != nullptr &&
|
||||
panelState->hostedPreviewEnabled &&
|
||||
IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo);
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceDescriptor hostedSurfaceDescriptor = {};
|
||||
const bool hasHostedSurfaceDescriptor =
|
||||
nativeHostedPreview &&
|
||||
panelState != nullptr &&
|
||||
!panelState->previewDebugName.empty() &&
|
||||
m_hostedPreviewSurfaceRegistry.TryGetSurfaceDescriptor(
|
||||
panelState->previewDebugName.data(),
|
||||
hostedSurfaceDescriptor);
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceImage hostedSurfaceImage = {};
|
||||
const bool showHostedSurfaceImage =
|
||||
nativeHostedPreview &&
|
||||
panelState != nullptr &&
|
||||
!panelState->previewDebugName.empty() &&
|
||||
m_hostedPreviewSurfaceRegistry.TryGetSurfaceImage(
|
||||
panelState->previewDebugName.data(),
|
||||
hostedSurfaceImage);
|
||||
const NativeHostedPreviewConsumption previewConsumption =
|
||||
Application::ResolveNativeHostedPreviewConsumption(
|
||||
nativeHostedPreview,
|
||||
hasHostedSurfaceDescriptor,
|
||||
showHostedSurfaceImage,
|
||||
"Native XCUI preview pending",
|
||||
"Waiting for queued native preview output to publish into the shell card.");
|
||||
|
||||
::XCEngine::Editor::XCUIBackend::XCUIPanelCanvasSession canvasSession = {};
|
||||
canvasSession.hostRect = panelLayout.panelRect;
|
||||
canvasSession.canvasRect = panelLayout.canvasRect;
|
||||
@@ -994,6 +1023,12 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
canvasRequest.height = panelLayout.panelRect.height;
|
||||
canvasRequest.topInset = panelLayout.canvasRect.y - panelLayout.panelRect.y;
|
||||
canvasRequest.drawPreviewFrame = false;
|
||||
canvasRequest.showSurfaceImage = previewConsumption.showSurfaceImage;
|
||||
canvasRequest.surfaceImage = hostedSurfaceImage;
|
||||
canvasRequest.placeholderTitle =
|
||||
previewConsumption.placeholderTitle.empty() ? nullptr : previewConsumption.placeholderTitle.data();
|
||||
canvasRequest.placeholderSubtitle =
|
||||
previewConsumption.placeholderSubtitle.empty() ? nullptr : previewConsumption.placeholderSubtitle.data();
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUIPanelCanvasSession resolvedSession =
|
||||
m_nativeDemoCanvasHost.BeginCanvas(canvasRequest);
|
||||
|
||||
@@ -1018,7 +1053,21 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
input.events = panelFrameDelta.events;
|
||||
|
||||
const auto& frame = m_nativeDemoRuntime.Update(input);
|
||||
AppendDrawData(composedDrawData, frame.drawData);
|
||||
if (previewConsumption.queueRuntimeFrame) {
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewFrame previewFrame = {};
|
||||
previewFrame.drawData = &frame.drawData;
|
||||
previewFrame.canvasRect = resolvedSession.canvasRect;
|
||||
previewFrame.logicalSize = UI::UISize(
|
||||
resolvedSession.canvasRect.width,
|
||||
resolvedSession.canvasRect.height);
|
||||
previewFrame.debugName =
|
||||
panelState != nullptr ? panelState->previewDebugName.data() : nullptr;
|
||||
previewFrame.debugSource =
|
||||
panelState != nullptr ? panelState->previewDebugSource.data() : nullptr;
|
||||
m_hostedPreviewQueue.Submit(previewFrame);
|
||||
} else if (previewConsumption.appendRuntimeDrawDataToShell) {
|
||||
AppendDrawData(composedDrawData, frame.drawData);
|
||||
}
|
||||
|
||||
if (IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud)) {
|
||||
const auto& stats = frame.stats;
|
||||
@@ -1049,22 +1098,33 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
textMuted);
|
||||
}
|
||||
|
||||
const auto drawDebugRect =
|
||||
[this, &stats](const std::string& elementId, const UI::UIColor& color, const char* label) {
|
||||
if (elementId.empty()) {
|
||||
return;
|
||||
}
|
||||
UI::UIRect rect = {};
|
||||
if (!m_nativeDemoRuntime.TryGetElementRect(elementId, rect)) {
|
||||
return;
|
||||
}
|
||||
m_nativeDemoCanvasHost.DrawOutlineRect(rect, color, 2.0f, 6.0f);
|
||||
if (label != nullptr && label[0] != '\0') {
|
||||
m_nativeDemoCanvasHost.DrawText(UI::UIPoint(rect.x + 4.0f, rect.y + 4.0f), label, color);
|
||||
}
|
||||
};
|
||||
drawDebugRect(stats.hoveredElementId, UI::UIColor(1.0f, 195.0f / 255.0f, 64.0f / 255.0f, 1.0f), "hover");
|
||||
drawDebugRect(stats.focusedElementId, UI::UIColor(64.0f / 255.0f, 214.0f / 255.0f, 1.0f, 1.0f), "focus");
|
||||
if (previewConsumption.drawRuntimeDebugRects) {
|
||||
const auto drawDebugRect =
|
||||
[this](const std::string& elementId, const UI::UIColor& color, const char* label) {
|
||||
if (elementId.empty()) {
|
||||
return;
|
||||
}
|
||||
UI::UIRect rect = {};
|
||||
if (!m_nativeDemoRuntime.TryGetElementRect(elementId, rect)) {
|
||||
return;
|
||||
}
|
||||
m_nativeDemoCanvasHost.DrawOutlineRect(rect, color, 2.0f, 6.0f);
|
||||
if (label != nullptr && label[0] != '\0') {
|
||||
m_nativeDemoCanvasHost.DrawText(
|
||||
UI::UIPoint(rect.x + 4.0f, rect.y + 4.0f),
|
||||
label,
|
||||
color);
|
||||
}
|
||||
};
|
||||
drawDebugRect(
|
||||
stats.hoveredElementId,
|
||||
UI::UIColor(1.0f, 195.0f / 255.0f, 64.0f / 255.0f, 1.0f),
|
||||
"hover");
|
||||
drawDebugRect(
|
||||
stats.focusedElementId,
|
||||
UI::UIColor(64.0f / 255.0f, 214.0f / 255.0f, 1.0f, 1.0f),
|
||||
"focus");
|
||||
}
|
||||
}
|
||||
|
||||
m_nativeDemoCanvasHost.EndCanvas();
|
||||
@@ -1072,7 +1132,9 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
NativePanelFrameSummary summary = {};
|
||||
summary.layout = panelLayout;
|
||||
summary.lineA = m_nativeDemoReloadSucceeded
|
||||
? frame.stats.statusMessage
|
||||
? Application::ComposeNativeHostedPreviewStatusLine(
|
||||
previewConsumption,
|
||||
frame.stats.statusMessage)
|
||||
: "Document reload failed; showing last retained runtime state.";
|
||||
summary.lineB =
|
||||
std::string(panelLayout.active ? "Active" : "Passive") +
|
||||
@@ -1085,6 +1147,35 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
continue;
|
||||
}
|
||||
|
||||
const ShellPanelChromeState* panelState = TryGetShellPanelState(ShellPanelId::XCUILayoutLab);
|
||||
const bool nativeHostedPreview =
|
||||
panelState != nullptr &&
|
||||
panelState->hostedPreviewEnabled &&
|
||||
IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab);
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceDescriptor hostedSurfaceDescriptor = {};
|
||||
const bool hasHostedSurfaceDescriptor =
|
||||
nativeHostedPreview &&
|
||||
panelState != nullptr &&
|
||||
!panelState->previewDebugName.empty() &&
|
||||
m_hostedPreviewSurfaceRegistry.TryGetSurfaceDescriptor(
|
||||
panelState->previewDebugName.data(),
|
||||
hostedSurfaceDescriptor);
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceImage hostedSurfaceImage = {};
|
||||
const bool showHostedSurfaceImage =
|
||||
nativeHostedPreview &&
|
||||
panelState != nullptr &&
|
||||
!panelState->previewDebugName.empty() &&
|
||||
m_hostedPreviewSurfaceRegistry.TryGetSurfaceImage(
|
||||
panelState->previewDebugName.data(),
|
||||
hostedSurfaceImage);
|
||||
const NativeHostedPreviewConsumption previewConsumption =
|
||||
Application::ResolveNativeHostedPreviewConsumption(
|
||||
nativeHostedPreview,
|
||||
hasHostedSurfaceDescriptor,
|
||||
showHostedSurfaceImage,
|
||||
"Native layout preview pending",
|
||||
"Waiting for queued native preview output to publish into the layout card.");
|
||||
|
||||
::XCEngine::Editor::XCUIBackend::XCUIPanelCanvasSession canvasSession = {};
|
||||
canvasSession.hostRect = panelLayout.panelRect;
|
||||
canvasSession.canvasRect = panelLayout.canvasRect;
|
||||
@@ -1099,6 +1190,12 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
canvasRequest.height = panelLayout.panelRect.height;
|
||||
canvasRequest.topInset = panelLayout.canvasRect.y - panelLayout.panelRect.y;
|
||||
canvasRequest.drawPreviewFrame = false;
|
||||
canvasRequest.showSurfaceImage = previewConsumption.showSurfaceImage;
|
||||
canvasRequest.surfaceImage = hostedSurfaceImage;
|
||||
canvasRequest.placeholderTitle =
|
||||
previewConsumption.placeholderTitle.empty() ? nullptr : previewConsumption.placeholderTitle.data();
|
||||
canvasRequest.placeholderSubtitle =
|
||||
previewConsumption.placeholderSubtitle.empty() ? nullptr : previewConsumption.placeholderSubtitle.data();
|
||||
const auto resolvedSession = m_nativeLayoutCanvasHost.BeginCanvas(canvasRequest);
|
||||
|
||||
const bool wantsKeyboard = panelLayout.active;
|
||||
@@ -1119,13 +1216,29 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
panelLayout.active && ShouldCaptureKeyboardNavigation(resolvedSession, m_nativeLayoutRuntime.GetFrameResult()));
|
||||
|
||||
const auto& frame = m_nativeLayoutRuntime.Update(input);
|
||||
AppendDrawData(composedDrawData, frame.drawData);
|
||||
if (previewConsumption.queueRuntimeFrame) {
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewFrame previewFrame = {};
|
||||
previewFrame.drawData = &frame.drawData;
|
||||
previewFrame.canvasRect = resolvedSession.canvasRect;
|
||||
previewFrame.logicalSize = UI::UISize(
|
||||
resolvedSession.canvasRect.width,
|
||||
resolvedSession.canvasRect.height);
|
||||
previewFrame.debugName =
|
||||
panelState != nullptr ? panelState->previewDebugName.data() : nullptr;
|
||||
previewFrame.debugSource =
|
||||
panelState != nullptr ? panelState->previewDebugSource.data() : nullptr;
|
||||
m_hostedPreviewQueue.Submit(previewFrame);
|
||||
} else if (previewConsumption.appendRuntimeDrawDataToShell) {
|
||||
AppendDrawData(composedDrawData, frame.drawData);
|
||||
}
|
||||
m_nativeLayoutCanvasHost.EndCanvas();
|
||||
|
||||
NativePanelFrameSummary summary = {};
|
||||
summary.layout = panelLayout;
|
||||
summary.lineA = m_nativeLayoutReloadSucceeded
|
||||
? frame.stats.statusMessage
|
||||
? Application::ComposeNativeHostedPreviewStatusLine(
|
||||
previewConsumption,
|
||||
frame.stats.statusMessage)
|
||||
: "Layout lab reload failed; showing last retained runtime state.";
|
||||
summary.lineB =
|
||||
std::to_string(frame.stats.rowCount) + " rows | " +
|
||||
@@ -1197,8 +1310,9 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
}
|
||||
|
||||
void Application::FrameLegacyImGuiHost() {
|
||||
m_hostedPreviewQueue.BeginFrame();
|
||||
m_hostedPreviewSurfaceRegistry.BeginFrame();
|
||||
Application::BeginHostedPreviewFrameLifecycle(
|
||||
m_hostedPreviewQueue,
|
||||
m_hostedPreviewSurfaceRegistry);
|
||||
SyncHostedPreviewSurfaces();
|
||||
if (m_windowCompositor == nullptr) {
|
||||
m_xcuiInputSource.ClearFrameTransients();
|
||||
@@ -1273,6 +1387,11 @@ void Application::FrameLegacyImGuiHost() {
|
||||
}
|
||||
|
||||
void Application::FrameNativeXCUIHost() {
|
||||
Application::BeginHostedPreviewFrameLifecycle(
|
||||
m_hostedPreviewQueue,
|
||||
m_hostedPreviewSurfaceRegistry);
|
||||
SyncHostedPreviewSurfaces();
|
||||
|
||||
auto* nativeCompositor =
|
||||
dynamic_cast<::XCEngine::Editor::XCUIBackend::NativeWindowUICompositor*>(m_windowCompositor.get());
|
||||
if (nativeCompositor == nullptr) {
|
||||
@@ -1287,6 +1406,7 @@ void Application::FrameNativeXCUIHost() {
|
||||
const auto shellFrameDelta = DispatchShellShortcuts(shellSnapshot);
|
||||
::XCEngine::UI::UIDrawData nativeShellDrawData = BuildNativeShellDrawData(shellSnapshot, shellFrameDelta);
|
||||
nativeCompositor->SubmitRenderPacket(nativeShellDrawData, &m_hostedPreviewTextAtlasProvider);
|
||||
SyncHostedPreviewSurfaces();
|
||||
|
||||
m_windowCompositor->RenderFrame(
|
||||
kClearColor,
|
||||
@@ -1294,6 +1414,8 @@ void Application::FrameNativeXCUIHost() {
|
||||
[this](
|
||||
const ::XCEngine::Rendering::RenderContext& renderContext,
|
||||
const ::XCEngine::Rendering::RenderSurface& surface) {
|
||||
RenderQueuedHostedPreviews(renderContext, surface);
|
||||
|
||||
MainWindowNativeBackdropRenderer::FrameState frameState = {};
|
||||
frameState.elapsedSeconds = static_cast<float>(
|
||||
std::chrono::duration<double>(std::chrono::steady_clock::now() - m_startTime).count());
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
@@ -86,6 +87,23 @@ public:
|
||||
std::function<void()> onHostedPreviewModeChanged = {};
|
||||
};
|
||||
|
||||
enum class NativeHostedPreviewSurfaceState : std::uint8_t {
|
||||
Disabled = 0,
|
||||
AwaitingSubmit,
|
||||
Warming,
|
||||
Live
|
||||
};
|
||||
|
||||
struct NativeHostedPreviewConsumption {
|
||||
NativeHostedPreviewSurfaceState surfaceState = NativeHostedPreviewSurfaceState::Disabled;
|
||||
bool queueRuntimeFrame = false;
|
||||
bool appendRuntimeDrawDataToShell = true;
|
||||
bool showSurfaceImage = false;
|
||||
bool drawRuntimeDebugRects = true;
|
||||
std::string_view placeholderTitle = {};
|
||||
std::string_view placeholderSubtitle = {};
|
||||
};
|
||||
|
||||
static ::XCEngine::Editor::XCUIBackend::XCUIEditorCommandInputSnapshot BuildShellShortcutSnapshot(
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta& frameDelta) {
|
||||
::XCEngine::Editor::XCUIBackend::XCUIEditorCommandInputSnapshot snapshot = {};
|
||||
@@ -251,6 +269,69 @@ public:
|
||||
bindings.onHostedPreviewModeChanged);
|
||||
}
|
||||
|
||||
static void BeginHostedPreviewFrameLifecycle(
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewQueue& previewQueue,
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceRegistry& surfaceRegistry) {
|
||||
previewQueue.BeginFrame();
|
||||
surfaceRegistry.BeginFrame();
|
||||
}
|
||||
|
||||
static bool HasHostedPreviewTextureRegistration(
|
||||
const ::XCEngine::Editor::XCUIBackend::UITextureRegistration& registration) {
|
||||
return registration.texture.IsValid() ||
|
||||
registration.cpuHandle.ptr != 0u ||
|
||||
registration.gpuHandle.ptr != 0u;
|
||||
}
|
||||
|
||||
static bool HasHostedPreviewPublishedTexture(
|
||||
const ::XCEngine::Editor::XCUIBackend::UITextureRegistration& registration) {
|
||||
return registration.texture.IsValid();
|
||||
}
|
||||
|
||||
static NativeHostedPreviewConsumption ResolveNativeHostedPreviewConsumption(
|
||||
bool nativeHostedPreview,
|
||||
bool hasHostedSurfaceDescriptor,
|
||||
bool showHostedSurfaceImage,
|
||||
std::string_view pendingTitle = {},
|
||||
std::string_view pendingSubtitle = {}) {
|
||||
NativeHostedPreviewConsumption consumption = {};
|
||||
if (!nativeHostedPreview) {
|
||||
return consumption;
|
||||
}
|
||||
|
||||
consumption.queueRuntimeFrame = true;
|
||||
consumption.appendRuntimeDrawDataToShell = false;
|
||||
consumption.showSurfaceImage = showHostedSurfaceImage;
|
||||
consumption.drawRuntimeDebugRects = showHostedSurfaceImage;
|
||||
consumption.surfaceState = showHostedSurfaceImage
|
||||
? NativeHostedPreviewSurfaceState::Live
|
||||
: (hasHostedSurfaceDescriptor
|
||||
? NativeHostedPreviewSurfaceState::Warming
|
||||
: NativeHostedPreviewSurfaceState::AwaitingSubmit);
|
||||
if (!showHostedSurfaceImage) {
|
||||
consumption.placeholderTitle = pendingTitle;
|
||||
consumption.placeholderSubtitle = pendingSubtitle;
|
||||
}
|
||||
|
||||
return consumption;
|
||||
}
|
||||
|
||||
static std::string ComposeNativeHostedPreviewStatusLine(
|
||||
const NativeHostedPreviewConsumption& consumption,
|
||||
std::string_view status) {
|
||||
switch (consumption.surfaceState) {
|
||||
case NativeHostedPreviewSurfaceState::AwaitingSubmit:
|
||||
return std::string("Native surface awaiting submit | ") + std::string(status);
|
||||
case NativeHostedPreviewSurfaceState::Warming:
|
||||
return std::string("Native surface warming | ") + std::string(status);
|
||||
case NativeHostedPreviewSurfaceState::Live:
|
||||
return std::string("Native surface live | ") + std::string(status);
|
||||
case NativeHostedPreviewSurfaceState::Disabled:
|
||||
default:
|
||||
return std::string(status);
|
||||
}
|
||||
}
|
||||
|
||||
int Run(HINSTANCE instance, int nCmdShow);
|
||||
|
||||
private:
|
||||
@@ -291,7 +372,7 @@ private:
|
||||
return !debugName.empty() &&
|
||||
colorTexture != nullptr &&
|
||||
colorView != nullptr &&
|
||||
textureRegistration.IsValid() &&
|
||||
Application::HasHostedPreviewPublishedTexture(textureRegistration) &&
|
||||
width > 0u &&
|
||||
height > 0u;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,26 @@ namespace XCUIBackend {
|
||||
|
||||
namespace {
|
||||
|
||||
::XCEngine::RHI::ResourceViewDimension ResolveShaderResourceDimension(
|
||||
::XCEngine::RHI::TextureType textureType) {
|
||||
switch (textureType) {
|
||||
case ::XCEngine::RHI::TextureType::Texture1D:
|
||||
return ::XCEngine::RHI::ResourceViewDimension::Texture1D;
|
||||
case ::XCEngine::RHI::TextureType::Texture2D:
|
||||
return ::XCEngine::RHI::ResourceViewDimension::Texture2D;
|
||||
case ::XCEngine::RHI::TextureType::Texture2DArray:
|
||||
return ::XCEngine::RHI::ResourceViewDimension::Texture2DArray;
|
||||
case ::XCEngine::RHI::TextureType::Texture3D:
|
||||
return ::XCEngine::RHI::ResourceViewDimension::Texture3D;
|
||||
case ::XCEngine::RHI::TextureType::TextureCube:
|
||||
return ::XCEngine::RHI::ResourceViewDimension::TextureCube;
|
||||
case ::XCEngine::RHI::TextureType::TextureCubeArray:
|
||||
return ::XCEngine::RHI::ResourceViewDimension::TextureCubeArray;
|
||||
default:
|
||||
return ::XCEngine::RHI::ResourceViewDimension::Texture2D;
|
||||
}
|
||||
}
|
||||
|
||||
bool PrepareSwapChainRender(
|
||||
::XCEngine::Editor::Platform::D3D12WindowRenderer& windowRenderer,
|
||||
const float clearColor[4],
|
||||
@@ -172,14 +192,56 @@ bool NativeWindowUICompositor::CreateTextureDescriptor(
|
||||
::XCEngine::RHI::RHIDevice* device,
|
||||
::XCEngine::RHI::RHITexture* texture,
|
||||
UITextureRegistration& outRegistration) {
|
||||
(void)device;
|
||||
(void)texture;
|
||||
outRegistration = {};
|
||||
return false;
|
||||
if (device == nullptr || texture == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::XCEngine::RHI::ResourceViewDesc viewDesc = {};
|
||||
viewDesc.format = static_cast<std::uint32_t>(texture->GetFormat());
|
||||
viewDesc.dimension = ResolveShaderResourceDimension(texture->GetTextureType());
|
||||
viewDesc.mipLevel = 0u;
|
||||
|
||||
::XCEngine::RHI::RHIResourceView* shaderResourceView = device->CreateShaderResourceView(texture, viewDesc);
|
||||
if (shaderResourceView == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!shaderResourceView->IsValid() ||
|
||||
shaderResourceView->GetViewType() != ::XCEngine::RHI::ResourceViewType::ShaderResource) {
|
||||
shaderResourceView->Shutdown();
|
||||
delete shaderResourceView;
|
||||
return false;
|
||||
}
|
||||
|
||||
outRegistration.cpuHandle.ptr =
|
||||
reinterpret_cast<std::uintptr_t>(shaderResourceView->GetNativeHandle());
|
||||
outRegistration.texture.nativeHandle =
|
||||
reinterpret_cast<std::uintptr_t>(shaderResourceView);
|
||||
outRegistration.texture.width = texture->GetWidth();
|
||||
outRegistration.texture.height = texture->GetHeight();
|
||||
outRegistration.texture.kind = ::XCEngine::UI::UITextureHandleKind::ShaderResourceView;
|
||||
|
||||
if (!outRegistration.IsValid()) {
|
||||
shaderResourceView->Shutdown();
|
||||
delete shaderResourceView;
|
||||
outRegistration = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NativeWindowUICompositor::FreeTextureDescriptor(const UITextureRegistration& registration) {
|
||||
(void)registration;
|
||||
if (registration.texture.kind != ::XCEngine::UI::UITextureHandleKind::ShaderResourceView ||
|
||||
registration.texture.nativeHandle == 0u) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* shaderResourceView =
|
||||
reinterpret_cast<::XCEngine::RHI::RHIResourceView*>(registration.texture.nativeHandle);
|
||||
shaderResourceView->Shutdown();
|
||||
delete shaderResourceView;
|
||||
}
|
||||
|
||||
void NativeWindowUICompositor::SubmitRenderPacket(const XCUINativeWindowRenderPacket& packet) {
|
||||
|
||||
@@ -14,7 +14,15 @@ struct UITextureRegistration {
|
||||
::XCEngine::UI::UITextureHandle texture = {};
|
||||
|
||||
bool IsValid() const {
|
||||
return cpuHandle.ptr != 0u && gpuHandle.ptr != 0u && texture.IsValid();
|
||||
if (!texture.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (texture.kind == ::XCEngine::UI::UITextureHandleKind::ShaderResourceView) {
|
||||
return cpuHandle.ptr != 0u;
|
||||
}
|
||||
|
||||
return cpuHandle.ptr != 0u && gpuHandle.ptr != 0u;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user