Reuse panel frame composition in native XCUI shell
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
#include "Application.h"
|
||||
#include "XCUIBackend/XCUINativeShellLayout.h"
|
||||
#include "XCUIBackend/NativeWindowUICompositor.h"
|
||||
#include "XCUIBackend/XCUIPanelCanvasHost.h"
|
||||
#include "panels/XCUIDemoPanel.h"
|
||||
#include "panels/XCUILayoutLabPanel.h"
|
||||
|
||||
#include <XCEngine/Core/Asset/ResourceManager.h>
|
||||
#include <XCEngine/UI/DrawData.h>
|
||||
@@ -41,54 +44,64 @@ std::uint64_t MakeFrameTimestampNanoseconds() {
|
||||
.count());
|
||||
}
|
||||
|
||||
class ForwardingNativePanelCanvasHost final : public ::XCEngine::Editor::XCUIBackend::IXCUIPanelCanvasHost {
|
||||
public:
|
||||
explicit ForwardingNativePanelCanvasHost(::XCEngine::Editor::XCUIBackend::NativeXCUIPanelCanvasHost& host)
|
||||
: m_host(host) {}
|
||||
|
||||
const char* GetDebugName() const override {
|
||||
return m_host.GetDebugName();
|
||||
}
|
||||
|
||||
auto BeginCanvas(
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUIPanelCanvasRequest& request)
|
||||
-> decltype(std::declval<::XCEngine::Editor::XCUIBackend::NativeXCUIPanelCanvasHost&>().BeginCanvas(request))
|
||||
override {
|
||||
return m_host.BeginCanvas(request);
|
||||
}
|
||||
|
||||
void DrawFilledRect(
|
||||
const ::XCEngine::UI::UIRect& rect,
|
||||
const ::XCEngine::UI::UIColor& color,
|
||||
float rounding) override {
|
||||
m_host.DrawFilledRect(rect, color, rounding);
|
||||
}
|
||||
|
||||
void DrawOutlineRect(
|
||||
const ::XCEngine::UI::UIRect& rect,
|
||||
const ::XCEngine::UI::UIColor& color,
|
||||
float thickness,
|
||||
float rounding) override {
|
||||
m_host.DrawOutlineRect(rect, color, thickness, rounding);
|
||||
}
|
||||
|
||||
void DrawText(
|
||||
const ::XCEngine::UI::UIPoint& position,
|
||||
std::string_view text,
|
||||
const ::XCEngine::UI::UIColor& color,
|
||||
float fontSize) override {
|
||||
m_host.DrawText(position, text, color, fontSize);
|
||||
}
|
||||
|
||||
void EndCanvas() override {
|
||||
m_host.EndCanvas();
|
||||
}
|
||||
|
||||
bool TryGetLatestFrameSnapshot(
|
||||
::XCEngine::Editor::XCUIBackend::XCUIPanelCanvasFrameSnapshot& outSnapshot) const override {
|
||||
return m_host.TryGetLatestFrameSnapshot(outSnapshot);
|
||||
}
|
||||
|
||||
private:
|
||||
::XCEngine::Editor::XCUIBackend::NativeXCUIPanelCanvasHost& m_host;
|
||||
};
|
||||
|
||||
void AppendDrawData(::XCEngine::UI::UIDrawData& destination, const ::XCEngine::UI::UIDrawData& source) {
|
||||
for (const ::XCEngine::UI::UIDrawList& drawList : source.GetDrawLists()) {
|
||||
destination.AddDrawList(drawList);
|
||||
}
|
||||
}
|
||||
|
||||
bool ContainsKeyTransition(
|
||||
const std::vector<std::int32_t>& keys,
|
||||
std::int32_t keyCode) {
|
||||
return std::find(keys.begin(), keys.end(), keyCode) != keys.end();
|
||||
}
|
||||
|
||||
bool ShouldCaptureKeyboardNavigation(
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUIPanelCanvasSession& canvasSession,
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUILayoutLabFrameResult& previousFrame) {
|
||||
if (!canvasSession.validCanvas) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return canvasSession.hovered ||
|
||||
(canvasSession.windowFocused &&
|
||||
!previousFrame.stats.selectedElementId.empty());
|
||||
}
|
||||
|
||||
void PopulateKeyboardNavigationInput(
|
||||
::XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState& input,
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta& frameDelta,
|
||||
bool captureKeyboardNavigation) {
|
||||
if (!captureKeyboardNavigation) {
|
||||
return;
|
||||
}
|
||||
|
||||
using ::XCEngine::Input::KeyCode;
|
||||
const auto pressedThisFrame =
|
||||
[&frameDelta](KeyCode keyCode) {
|
||||
const std::int32_t code = static_cast<std::int32_t>(keyCode);
|
||||
return ContainsKeyTransition(frameDelta.keyboard.pressedKeys, code) ||
|
||||
ContainsKeyTransition(frameDelta.keyboard.repeatedKeys, code);
|
||||
};
|
||||
|
||||
input.navigatePrevious = pressedThisFrame(KeyCode::Up);
|
||||
input.navigateNext = pressedThisFrame(KeyCode::Down);
|
||||
input.navigateHome = pressedThisFrame(KeyCode::Home);
|
||||
input.navigateEnd = pressedThisFrame(KeyCode::End);
|
||||
input.navigateCollapse = pressedThisFrame(KeyCode::Left);
|
||||
input.navigateExpand = pressedThisFrame(KeyCode::Right);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool Application::IsNativeWindowHostEnabled() const {
|
||||
@@ -99,12 +112,35 @@ void Application::InitializeNativeShell() {
|
||||
m_nativeActivePanel = m_shellChromeState.IsPanelVisible(ShellPanelId::XCUIDemo)
|
||||
? ShellPanelId::XCUIDemo
|
||||
: ShellPanelId::XCUILayoutLab;
|
||||
m_nativeDemoInputBridge.Reset();
|
||||
m_nativeLayoutInputBridge.Reset();
|
||||
m_nativeDemoCanvasHost.ClearCanvasSession();
|
||||
m_nativeLayoutCanvasHost.ClearCanvasSession();
|
||||
m_nativeDemoReloadSucceeded = m_nativeDemoRuntime.ReloadDocuments();
|
||||
m_nativeLayoutReloadSucceeded = m_nativeLayoutRuntime.ReloadDocuments();
|
||||
|
||||
const auto buildNativePreviewPresenter =
|
||||
[this](ShellPanelId panelId, bool hostedPreviewEnabled) {
|
||||
if (!hostedPreviewEnabled || !IsNativeHostedPreviewEnabled(panelId)) {
|
||||
return std::unique_ptr<::XCEngine::Editor::XCUIBackend::IXCUIHostedPreviewPresenter>();
|
||||
}
|
||||
|
||||
return CreateHostedPreviewPresenter(true);
|
||||
};
|
||||
|
||||
const ShellPanelChromeState* demoState = TryGetShellPanelState(ShellPanelId::XCUIDemo);
|
||||
const bool demoHostedPreviewEnabled = demoState == nullptr || demoState->hostedPreviewEnabled;
|
||||
m_demoPanel = std::make_unique<XCUIDemoPanel>(
|
||||
&m_xcuiInputSource,
|
||||
buildNativePreviewPresenter(ShellPanelId::XCUIDemo, demoHostedPreviewEnabled),
|
||||
std::make_unique<ForwardingNativePanelCanvasHost>(m_nativeDemoCanvasHost));
|
||||
m_demoPanel->SetVisible(demoState != nullptr && demoState->visible);
|
||||
m_demoPanel->SetHostedPreviewEnabled(demoHostedPreviewEnabled);
|
||||
|
||||
const ShellPanelChromeState* layoutState = TryGetShellPanelState(ShellPanelId::XCUILayoutLab);
|
||||
const bool layoutHostedPreviewEnabled = layoutState == nullptr || layoutState->hostedPreviewEnabled;
|
||||
m_layoutLabPanel = std::make_unique<XCUILayoutLabPanel>(
|
||||
&m_xcuiInputSource,
|
||||
buildNativePreviewPresenter(ShellPanelId::XCUILayoutLab, layoutHostedPreviewEnabled),
|
||||
std::make_unique<ForwardingNativePanelCanvasHost>(m_nativeLayoutCanvasHost));
|
||||
m_layoutLabPanel->SetVisible(layoutState != nullptr && layoutState->visible);
|
||||
m_layoutLabPanel->SetHostedPreviewEnabled(layoutHostedPreviewEnabled);
|
||||
}
|
||||
|
||||
const Application::ShellPanelChromeState* Application::TryGetShellPanelState(ShellPanelId panelId) const {
|
||||
@@ -683,33 +719,10 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
for (const NativeShellPanelLayout& panelLayout : panelLayouts) {
|
||||
if (panelLayout.panelId == ShellPanelId::XCUIDemo) {
|
||||
const ShellPanelChromeState* panelState = TryGetShellPanelState(ShellPanelId::XCUIDemo);
|
||||
const bool nativeHostedPreview =
|
||||
const bool nativeHostedPreviewRequested =
|
||||
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 Application::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;
|
||||
@@ -720,63 +733,54 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
canvasSession.windowFocused = shellSnapshot.windowFocused;
|
||||
m_nativeDemoCanvasHost.SetCanvasSession(canvasSession);
|
||||
|
||||
::XCEngine::Editor::XCUIBackend::XCUIPanelCanvasRequest canvasRequest = {};
|
||||
canvasRequest.childId = "XCUIDemo.NativeCanvas";
|
||||
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);
|
||||
|
||||
const bool wantsKeyboard = panelLayout.active;
|
||||
const auto panelSnapshot = capturePanelSnapshot(panelLayout, wantsKeyboard);
|
||||
if (!m_nativeDemoInputBridge.HasBaseline()) {
|
||||
m_nativeDemoInputBridge.Prime(panelSnapshot);
|
||||
}
|
||||
const auto panelFrameDelta = m_nativeDemoInputBridge.Translate(panelSnapshot);
|
||||
const bool showPanelHud = IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud);
|
||||
|
||||
::XCEngine::Editor::XCUIBackend::XCUIDemoInputState input = {};
|
||||
input.canvasRect = resolvedSession.canvasRect;
|
||||
input.pointerPosition = panelSnapshot.pointerPosition;
|
||||
input.pointerInside = panelSnapshot.pointerInside;
|
||||
input.pointerPressed = panelFrameDelta.pointer.pressed[0];
|
||||
input.pointerReleased = panelFrameDelta.pointer.released[0];
|
||||
input.pointerDown = panelSnapshot.pointerButtonsDown[0];
|
||||
input.windowFocused = panelSnapshot.windowFocused;
|
||||
input.wantCaptureMouse = panelSnapshot.wantCaptureMouse;
|
||||
input.wantCaptureKeyboard = panelSnapshot.wantCaptureKeyboard;
|
||||
input.wantTextInput = panelSnapshot.wantTextInput;
|
||||
input.events = panelFrameDelta.events;
|
||||
|
||||
const auto& frame = m_nativeDemoRuntime.Update(input);
|
||||
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);
|
||||
const XCUIDemoPanelFrameComposition* composition = nullptr;
|
||||
if (m_demoPanel != nullptr) {
|
||||
composition = &m_demoPanel->ComposeFrame(
|
||||
XCUIDemoPanelFrameComposeOptions{
|
||||
panelLayout.panelRect.height,
|
||||
panelLayout.canvasRect.y - panelLayout.panelRect.y,
|
||||
panelState == nullptr || panelState->hostedPreviewEnabled,
|
||||
showPanelHud,
|
||||
showPanelHud,
|
||||
panelSnapshot.timestampNanoseconds,
|
||||
"XCUIDemo.NativeCanvas",
|
||||
&panelSnapshot,
|
||||
false,
|
||||
nativeHostedPreviewRequested ? "Native XCUI preview pending" : nullptr,
|
||||
nativeHostedPreviewRequested
|
||||
? "Waiting for queued native preview output to publish into the shell card."
|
||||
: nullptr,
|
||||
false,
|
||||
nullptr,
|
||||
nullptr,
|
||||
});
|
||||
}
|
||||
|
||||
if (IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud)) {
|
||||
const auto& stats = frame.stats;
|
||||
const Application::NativeHostedPreviewConsumption previewConsumption =
|
||||
composition != nullptr
|
||||
? Application::ResolveNativeHostedPreviewConsumption(
|
||||
composition->nativeHostedPreview,
|
||||
composition->hasHostedSurfaceDescriptor,
|
||||
composition->showHostedSurfaceImage,
|
||||
"Native XCUI preview pending",
|
||||
"Waiting for queued native preview output to publish into the shell card.")
|
||||
: Application::NativeHostedPreviewConsumption{};
|
||||
if (composition != nullptr &&
|
||||
composition->frame != nullptr &&
|
||||
previewConsumption.appendRuntimeDrawDataToShell) {
|
||||
AppendDrawData(composedDrawData, composition->frame->drawData);
|
||||
}
|
||||
|
||||
if (showPanelHud && composition != nullptr && composition->frame != nullptr) {
|
||||
const auto& stats = composition->frame->stats;
|
||||
const UI::UIRect hudRect(
|
||||
resolvedSession.canvasRect.x + 10.0f,
|
||||
resolvedSession.canvasRect.y + 10.0f,
|
||||
(std::min)(resolvedSession.canvasRect.width - 20.0f, 360.0f),
|
||||
composition->canvasSession.canvasRect.x + 10.0f,
|
||||
composition->canvasSession.canvasRect.y + 10.0f,
|
||||
(std::min)(composition->canvasSession.canvasRect.width - 20.0f, 360.0f),
|
||||
62.0f);
|
||||
if (hudRect.width > 40.0f && hudRect.height > 20.0f) {
|
||||
m_nativeDemoCanvasHost.DrawFilledRect(
|
||||
@@ -799,49 +803,28 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
stats.statusMessage,
|
||||
textMuted);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
NativePanelFrameSummary summary = {};
|
||||
summary.layout = panelLayout;
|
||||
summary.lineA = m_nativeDemoReloadSucceeded
|
||||
summary.lineA =
|
||||
m_demoPanel != nullptr && m_demoPanel->GetLastReloadSucceeded()
|
||||
? Application::ComposeNativeHostedPreviewStatusLine(
|
||||
previewConsumption,
|
||||
frame.stats.statusMessage)
|
||||
composition != nullptr && composition->frame != nullptr
|
||||
? composition->frame->stats.statusMessage
|
||||
: std::string_view("XCUI demo frame unavailable"))
|
||||
: "Document reload failed; showing last retained runtime state.";
|
||||
summary.lineB =
|
||||
std::string(panelLayout.active ? "Active" : "Passive") +
|
||||
" | " + std::to_string(frame.stats.elementCount) +
|
||||
" elements | " + std::to_string(frame.stats.commandCount) +
|
||||
" | " + std::to_string(
|
||||
composition != nullptr && composition->frame != nullptr
|
||||
? composition->frame->stats.elementCount
|
||||
: 0u) +
|
||||
" elements | " + std::to_string(
|
||||
composition != nullptr && composition->frame != nullptr
|
||||
? composition->frame->stats.commandCount
|
||||
: 0u) +
|
||||
" cmds";
|
||||
summary.overlay = extractCanvasOverlay(m_nativeDemoCanvasHost);
|
||||
panelSummaries.push_back(std::move(summary));
|
||||
@@ -850,21 +833,22 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
}
|
||||
|
||||
const ShellPanelChromeState* panelState = TryGetShellPanelState(ShellPanelId::XCUILayoutLab);
|
||||
const bool nativeHostedPreview =
|
||||
const bool nativeHostedPreviewRequested =
|
||||
panelState != nullptr &&
|
||||
panelState->hostedPreviewEnabled &&
|
||||
IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab);
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceDescriptor hostedSurfaceDescriptor = {};
|
||||
const bool hasHostedSurfaceDescriptor =
|
||||
nativeHostedPreview &&
|
||||
nativeHostedPreviewRequested &&
|
||||
panelState != nullptr &&
|
||||
!panelState->previewDebugName.empty() &&
|
||||
m_hostedPreviewSurfaceRegistry.TryGetSurfaceDescriptor(
|
||||
panelState->previewDebugName.data(),
|
||||
hostedSurfaceDescriptor);
|
||||
|
||||
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceImage hostedSurfaceImage = {};
|
||||
const bool showHostedSurfaceImage =
|
||||
nativeHostedPreview &&
|
||||
nativeHostedPreviewRequested &&
|
||||
panelState != nullptr &&
|
||||
!panelState->previewDebugName.empty() &&
|
||||
m_hostedPreviewSurfaceRegistry.TryGetSurfaceImage(
|
||||
@@ -872,7 +856,7 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
hostedSurfaceImage);
|
||||
const Application::NativeHostedPreviewConsumption previewConsumption =
|
||||
Application::ResolveNativeHostedPreviewConsumption(
|
||||
nativeHostedPreview,
|
||||
nativeHostedPreviewRequested,
|
||||
hasHostedSurfaceDescriptor,
|
||||
showHostedSurfaceImage,
|
||||
"Native layout preview pending",
|
||||
@@ -902,50 +886,53 @@ bool Application::RenderHostedPreviewOffscreenSurface(
|
||||
|
||||
const bool wantsKeyboard = panelLayout.active;
|
||||
const auto panelSnapshot = capturePanelSnapshot(panelLayout, wantsKeyboard);
|
||||
if (!m_nativeLayoutInputBridge.HasBaseline()) {
|
||||
m_nativeLayoutInputBridge.Prime(panelSnapshot);
|
||||
}
|
||||
const auto panelFrameDelta = m_nativeLayoutInputBridge.Translate(panelSnapshot);
|
||||
|
||||
::XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState input = {};
|
||||
input.canvasRect = resolvedSession.canvasRect;
|
||||
input.pointerPosition = panelSnapshot.pointerPosition;
|
||||
input.pointerInside = panelSnapshot.pointerInside;
|
||||
input.pointerPressed = input.pointerInside && panelFrameDelta.pointer.pressed[0];
|
||||
PopulateKeyboardNavigationInput(
|
||||
input,
|
||||
panelFrameDelta,
|
||||
panelLayout.active && ShouldCaptureKeyboardNavigation(resolvedSession, m_nativeLayoutRuntime.GetFrameResult()));
|
||||
|
||||
const auto& frame = m_nativeLayoutRuntime.Update(input);
|
||||
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);
|
||||
const XCUILayoutLabFrameComposition* composition = nullptr;
|
||||
if (m_layoutLabPanel != nullptr) {
|
||||
composition = &m_layoutLabPanel->ComposeFrame(
|
||||
XCUILayoutLabFrameCompositionRequest{
|
||||
resolvedSession,
|
||||
panelSnapshot });
|
||||
}
|
||||
m_nativeLayoutCanvasHost.EndCanvas();
|
||||
|
||||
const Application::NativeHostedPreviewConsumption composedPreviewConsumption =
|
||||
composition != nullptr
|
||||
? Application::ResolveNativeHostedPreviewConsumption(
|
||||
composition->nativeHostedPreview,
|
||||
composition->hasHostedSurfaceDescriptor,
|
||||
composition->showHostedSurfaceImage,
|
||||
"Native layout preview pending",
|
||||
"Waiting for queued native preview output to publish into the layout card.")
|
||||
: previewConsumption;
|
||||
if (composition != nullptr &&
|
||||
composition->frameResult != nullptr &&
|
||||
composedPreviewConsumption.appendRuntimeDrawDataToShell) {
|
||||
AppendDrawData(composedDrawData, composition->frameResult->drawData);
|
||||
}
|
||||
|
||||
NativePanelFrameSummary summary = {};
|
||||
summary.layout = panelLayout;
|
||||
summary.lineA = m_nativeLayoutReloadSucceeded
|
||||
summary.lineA =
|
||||
m_layoutLabPanel != nullptr && m_layoutLabPanel->GetLastReloadSucceeded()
|
||||
? Application::ComposeNativeHostedPreviewStatusLine(
|
||||
previewConsumption,
|
||||
frame.stats.statusMessage)
|
||||
composedPreviewConsumption,
|
||||
composition != nullptr && composition->frameResult != nullptr
|
||||
? composition->frameResult->stats.statusMessage
|
||||
: std::string_view("XCUI layout frame unavailable"))
|
||||
: "Layout lab reload failed; showing last retained runtime state.";
|
||||
summary.lineB =
|
||||
std::to_string(frame.stats.rowCount) + " rows | " +
|
||||
std::to_string(frame.stats.columnCount) + " cols | " +
|
||||
std::to_string(frame.stats.commandCount) + " cmds";
|
||||
std::to_string(
|
||||
composition != nullptr && composition->frameResult != nullptr
|
||||
? composition->frameResult->stats.rowCount
|
||||
: 0u) + " rows | " +
|
||||
std::to_string(
|
||||
composition != nullptr && composition->frameResult != nullptr
|
||||
? composition->frameResult->stats.columnCount
|
||||
: 0u) + " cols | " +
|
||||
std::to_string(
|
||||
composition != nullptr && composition->frameResult != nullptr
|
||||
? composition->frameResult->stats.commandCount
|
||||
: 0u) + " cmds";
|
||||
summary.overlay = extractCanvasOverlay(m_nativeLayoutCanvasHost);
|
||||
panelSummaries.push_back(std::move(summary));
|
||||
m_nativeLayoutCanvasHost.ClearCanvasSession();
|
||||
|
||||
Reference in New Issue
Block a user