#include "Application.h" #include "XCUIBackend/LegacyImGuiHostInterop.h" #include "panels/XCUIDemoPanel.h" #include "panels/XCUILayoutLabPanel.h" #include #include #include namespace XCEngine { namespace NewEditor { namespace { constexpr float kLegacyHostClearColor[4] = { 0.08f, 0.09f, 0.11f, 1.0f }; std::uint64_t MakeLegacyHostFrameTimestampNanoseconds() { return static_cast( std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()) .count()); } const char* GetHostedPreviewPathLabel(bool nativeRequested, bool nativePresenterBound) { if (nativeRequested && nativePresenterBound) { return "native queued offscreen surface"; } if (nativeRequested) { return "native requested, hosted presenter bound"; } if (nativePresenterBound) { return "hosted presenter requested, native presenter still bound"; } return "hosted presenter"; } const char* GetHostedPreviewStateLabel( bool hostedPreviewEnabled, bool nativePresenterBound, bool presentedThisFrame, bool queuedToNativePassThisFrame, bool surfaceImageAvailable, bool surfaceAllocated, bool surfaceReady, bool descriptorAvailable) { if (!hostedPreviewEnabled) { return "disabled"; } if (nativePresenterBound) { if (surfaceImageAvailable && surfaceReady) { return "live"; } if (queuedToNativePassThisFrame || surfaceAllocated || descriptorAvailable) { return "warming"; } return "awaiting submit"; } if (presentedThisFrame) { return "live"; } return "idle"; } } // namespace Application::Application() = default; Application::~Application() = default; std::unique_ptr<::XCEngine::Editor::XCUIBackend::IXCUIHostedPreviewPresenter> Application::CreateHostedPreviewPresenter(bool nativePreview) { if (nativePreview) { return ::XCEngine::Editor::XCUIBackend::CreateQueuedNativeXCUIHostedPreviewPresenter( m_hostedPreviewQueue, m_hostedPreviewSurfaceRegistry); } return ::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiHostedPreviewPresenter(); } void Application::InitializePanelsForActiveWindowHost() { if (IsNativeWindowHostEnabled()) { InitializeNativeShell(); return; } InitializeLegacyImGuiPanels(); ConfigureHostedPreviewPresenters(); } void Application::InitializeLegacyImGuiPanels() { m_demoPanel = std::make_unique( &m_xcuiInputSource, CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo)), ::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiPanelCanvasHost()); m_layoutLabPanel = std::make_unique( &m_xcuiInputSource, CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab)), ::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiPanelCanvasHost()); } void Application::ConfigureHostedPreviewPresenters() { const ShellPanelChromeState* demoState = TryGetShellPanelState(ShellPanelId::XCUIDemo); if (m_demoPanel != nullptr) { m_demoPanel->SetVisible(demoState != nullptr && demoState->visible); m_demoPanel->SetHostedPreviewEnabled(demoState == nullptr || demoState->hostedPreviewEnabled); m_demoPanel->SetHostedPreviewPresenter(CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo))); } const ShellPanelChromeState* layoutLabState = TryGetShellPanelState(ShellPanelId::XCUILayoutLab); if (m_layoutLabPanel != nullptr) { m_layoutLabPanel->SetVisible(layoutLabState != nullptr && layoutLabState->visible); m_layoutLabPanel->SetHostedPreviewEnabled(layoutLabState == nullptr || layoutLabState->hostedPreviewEnabled); m_layoutLabPanel->SetHostedPreviewPresenter( CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab))); } } void Application::ResetLegacyPanels() { m_demoPanel.reset(); m_layoutLabPanel.reset(); } void Application::SyncShellChromePanelStateFromPanels() { m_shellChromeState.SetPanelVisible( ShellPanelId::XCUIDemo, m_demoPanel != nullptr && m_demoPanel->IsVisible()); m_shellChromeState.SetPanelVisible( ShellPanelId::XCUILayoutLab, m_layoutLabPanel != nullptr && m_layoutLabPanel->IsVisible()); } void Application::ConfigureShellCommandRouter() { m_shellCommandRouter.Clear(); ShellCommandBindings bindings = {}; bindings.getXCUIDemoPanelVisible = [this]() { return m_shellChromeState.IsPanelVisible(ShellPanelId::XCUIDemo); }; bindings.setXCUIDemoPanelVisible = [this](bool visible) { m_shellChromeState.SetPanelVisible(ShellPanelId::XCUIDemo, visible); if (m_demoPanel != nullptr) { m_demoPanel->SetVisible(visible); } }; bindings.getXCUILayoutLabPanelVisible = [this]() { return m_shellChromeState.IsPanelVisible(ShellPanelId::XCUILayoutLab); }; bindings.setXCUILayoutLabPanelVisible = [this](bool visible) { m_shellChromeState.SetPanelVisible(ShellPanelId::XCUILayoutLab, visible); if (m_layoutLabPanel != nullptr) { m_layoutLabPanel->SetVisible(visible); } }; bindings.getImGuiDemoWindowVisible = [this]() { return IsShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow); }; bindings.setImGuiDemoWindowVisible = [this](bool visible) { SetShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow, visible); }; bindings.getNativeBackdropVisible = [this]() { return IsShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop); }; bindings.setNativeBackdropVisible = [this](bool visible) { SetShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop, visible); }; bindings.getPulseAccentEnabled = [this]() { return IsShellViewToggleEnabled(ShellViewToggleId::PulseAccent); }; bindings.setPulseAccentEnabled = [this](bool enabled) { SetShellViewToggleEnabled(ShellViewToggleId::PulseAccent, enabled); }; bindings.getNativeXCUIOverlayVisible = [this]() { return IsShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay); }; bindings.setNativeXCUIOverlayVisible = [this](bool visible) { SetShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay, visible); }; bindings.getHostedPreviewHudVisible = [this]() { return IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud); }; bindings.setHostedPreviewHudVisible = [this](bool visible) { SetShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud, visible); }; bindings.getNativeDemoPanelPreviewEnabled = [this]() { return IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo); }; bindings.setNativeDemoPanelPreviewEnabled = [this](bool enabled) { m_shellChromeState.SetHostedPreviewMode( ShellPanelId::XCUIDemo, enabled ? ShellHostedPreviewMode::NativeOffscreen : ShellHostedPreviewMode::HostedPresenter); }; bindings.getNativeLayoutLabPreviewEnabled = [this]() { return IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab); }; bindings.setNativeLayoutLabPreviewEnabled = [this](bool enabled) { m_shellChromeState.SetHostedPreviewMode( ShellPanelId::XCUILayoutLab, enabled ? ShellHostedPreviewMode::NativeOffscreen : ShellHostedPreviewMode::HostedPresenter); }; bindings.onHostedPreviewModeChanged = [this]() { ConfigureHostedPreviewPresenters(); }; Application::RegisterShellViewCommands(m_shellCommandRouter, bindings); } ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta Application::DispatchShellShortcuts( const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot& snapshot) { ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot shellSnapshot = snapshot; if (!IsNativeWindowHostEnabled()) { ::XCEngine::Editor::XCUIBackend::ApplyLegacyImGuiHostInputCapture(shellSnapshot); } if (!m_shellInputBridge.HasBaseline()) { m_shellInputBridge.Prime(shellSnapshot); } const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta frameDelta = m_shellInputBridge.Translate(shellSnapshot); const ::XCEngine::Editor::XCUIBackend::XCUIEditorCommandInputSnapshot commandSnapshot = Application::BuildShellShortcutSnapshot(frameDelta); m_shellCommandRouter.InvokeMatchingShortcut({ &commandSnapshot }); return frameDelta; } void Application::InitializeWindowCompositor() { m_windowCompositor = IsNativeWindowHostEnabled() ? ::XCEngine::Editor::XCUIBackend::CreateNativeWindowUICompositor() : ::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiWindowUICompositor(); if (m_windowCompositor != nullptr) { m_windowCompositor->Initialize( m_hwnd, m_windowRenderer, []() { (void)::XCEngine::Editor::XCUIBackend::ConfigureLegacyImGuiHostFonts(); }); } } void Application::FrameLegacyImGuiHost() { Application::BeginHostedPreviewFrameLifecycle( m_hostedPreviewQueue, m_hostedPreviewSurfaceRegistry); SyncHostedPreviewSurfaces(); if (m_windowCompositor == nullptr) { m_xcuiInputSource.ClearFrameTransients(); return; } m_windowCompositor->RenderFrame( kLegacyHostClearColor, [this]() { RenderLegacyImGuiUiFrame(); }, [this]( const ::XCEngine::Rendering::RenderContext& renderContext, const ::XCEngine::Rendering::RenderSurface& surface) { RenderQueuedHostedPreviews(renderContext, surface); if (!IsShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop) && !IsShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay)) { return; } MainWindowNativeBackdropRenderer::FrameState frameState = {}; frameState.elapsedSeconds = static_cast( std::chrono::duration(std::chrono::steady_clock::now() - m_startTime).count()); frameState.pulseAccent = IsShellViewToggleEnabled(ShellViewToggleId::PulseAccent); frameState.drawBackdrop = IsShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop); if (IsShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay)) { const float width = static_cast(surface.GetWidth()); const float height = static_cast(surface.GetHeight()); const float horizontalMargin = (std::min)(width * 0.14f, 128.0f); const float topMargin = (std::min)(height * 0.15f, 132.0f); const float bottomMargin = (std::min)(height * 0.12f, 96.0f); ::XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState overlayInput = {}; overlayInput.canvasRect = ::XCEngine::UI::UIRect( horizontalMargin, topMargin, (std::max)(0.0f, width - horizontalMargin * 2.0f), (std::max)(0.0f, height - topMargin - bottomMargin)); overlayInput.pointerPosition = m_xcuiInputSource.GetPointerPosition(); overlayInput.pointerInside = overlayInput.pointerPosition.x >= overlayInput.canvasRect.x && overlayInput.pointerPosition.y >= overlayInput.canvasRect.y && overlayInput.pointerPosition.x <= overlayInput.canvasRect.x + overlayInput.canvasRect.width && overlayInput.pointerPosition.y <= overlayInput.canvasRect.y + overlayInput.canvasRect.height; const auto& overlayFrame = m_nativeOverlayRuntime.Update(overlayInput); frameState.overlayDrawData = &overlayFrame.drawData; } m_nativeBackdropRenderer.Render(renderContext, surface, frameState); }); m_xcuiInputSource.ClearFrameTransients(); } void Application::RenderLegacyImGuiUiFrame() { ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeCaptureOptions options = {}; options.timestampNanoseconds = MakeLegacyHostFrameTimestampNanoseconds(); options.windowFocused = m_xcuiInputSource.IsWindowFocused(); const auto shellSnapshot = m_xcuiInputSource.CaptureSnapshot(options); DispatchShellShortcuts(shellSnapshot); RenderShellChrome(); if (m_demoPanel != nullptr) { m_demoPanel->RenderIfVisible(); } if (m_layoutLabPanel != nullptr) { m_layoutLabPanel->RenderIfVisible(); } bool showImGuiDemoWindow = IsShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow); if (::XCEngine::Editor::XCUIBackend::RenderLegacyImGuiDemoWindow(showImGuiDemoWindow)) { SetShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow, showImGuiDemoWindow); } SyncShellChromePanelStateFromPanels(); SyncHostedPreviewSurfaces(); } void Application::RenderShellChrome() { SyncShellChromePanelStateFromPanels(); ImGuiViewport* viewport = ImGui::GetMainViewport(); if (viewport == nullptr) { return; } ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_MenuBar; ImGui::SetNextWindowPos(viewport->WorkPos); ImGui::SetNextWindowSize(viewport->WorkSize); ImGui::SetNextWindowViewport(viewport->ID); ImGui::SetNextWindowBgAlpha(0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); const bool opened = ImGui::Begin("XCNewEditorShell", nullptr, windowFlags); ImGui::PopStyleVar(3); if (opened) { if (ImGui::BeginMenuBar()) { if (ImGui::BeginMenu("View")) { const auto drawCommandMenuItem = [this](const char* label, const char* shortcut, bool selected, const char* commandId) { const bool enabled = m_shellCommandRouter.IsCommandEnabled(commandId); if (ImGui::MenuItem(label, shortcut, selected, enabled)) { m_shellCommandRouter.InvokeCommand(commandId); } }; drawCommandMenuItem( "XCUI Demo", "Ctrl+1", TryGetShellPanelState(ShellPanelId::XCUIDemo) != nullptr && TryGetShellPanelState(ShellPanelId::XCUIDemo)->visible, ShellCommandIds::ToggleXCUIDemoPanel); drawCommandMenuItem( "XCUI Layout Lab", "Ctrl+2", TryGetShellPanelState(ShellPanelId::XCUILayoutLab) != nullptr && TryGetShellPanelState(ShellPanelId::XCUILayoutLab)->visible, ShellCommandIds::ToggleXCUILayoutLabPanel); drawCommandMenuItem( "ImGui Demo", "Ctrl+3", IsShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow), ShellCommandIds::ToggleImGuiDemoWindow); ImGui::Separator(); drawCommandMenuItem( "Native Backdrop", "Ctrl+Shift+B", IsShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop), ShellCommandIds::ToggleNativeBackdrop); drawCommandMenuItem( "Pulse Accent", "Ctrl+Shift+P", IsShellViewToggleEnabled(ShellViewToggleId::PulseAccent), ShellCommandIds::TogglePulseAccent); drawCommandMenuItem( "Native XCUI Overlay", "Ctrl+Shift+O", IsShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay), ShellCommandIds::ToggleNativeXCUIOverlay); drawCommandMenuItem( "Hosted Preview HUD", "Ctrl+Shift+H", IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud), ShellCommandIds::ToggleHostedPreviewHud); drawCommandMenuItem( "Native Demo Panel Preview", "Ctrl+Alt+1", IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo), ShellCommandIds::ToggleNativeDemoPanelPreview); drawCommandMenuItem( "Native Layout Lab Preview", "Ctrl+Alt+2", IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab), ShellCommandIds::ToggleNativeLayoutLabPreview); ImGui::EndMenu(); } ImGui::SeparatorText("XCUI Sandbox"); const MainWindowNativeBackdropRenderer::OverlayStats& nativeOverlayStats = m_nativeBackdropRenderer.GetLastOverlayStats(); const ::XCEngine::Editor::XCUIBackend::XCUILayoutLabFrameStats& overlayFrameStats = m_nativeOverlayRuntime.GetFrameResult().stats; const ::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewDrainStats& hostedPreviewStats = m_hostedPreviewQueue.GetLastDrainStats(); if (IsShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay)) { ImGui::TextDisabled( "Native XCUI overlay: %s | runtime %zu cmds (%zu fill, %zu outline, %zu text, %zu image, clips %zu/%zu)", overlayFrameStats.nativeOverlayReady ? "preflight OK" : "preflight issues", overlayFrameStats.commandCount, overlayFrameStats.filledRectCommandCount, overlayFrameStats.rectOutlineCommandCount, overlayFrameStats.textCommandCount, overlayFrameStats.imageCommandCount, overlayFrameStats.clipPushCommandCount, overlayFrameStats.clipPopCommandCount); ImGui::TextDisabled( "%s | supported %zu | unsupported %zu | prev native pass %zu cmds, %zu rendered, %zu skipped", overlayFrameStats.nativeOverlayStatusMessage.empty() ? "Overlay diagnostics unavailable" : overlayFrameStats.nativeOverlayStatusMessage.c_str(), overlayFrameStats.nativeSupportedCommandCount, overlayFrameStats.nativeUnsupportedCommandCount, nativeOverlayStats.commandCount, nativeOverlayStats.renderedCommandCount, nativeOverlayStats.skippedCommandCount); } else { ImGui::TextDisabled( IsShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop) ? "Transition backend + runtime diagnostics + native backbuffer pass" : "Transition backend + runtime diagnostics"); } ImGui::TextDisabled( "Hosted preview queue: %zu frames | queued %zu cmds | rendered %zu cmds | skipped %zu cmds", hostedPreviewStats.queuedFrameCount, hostedPreviewStats.queuedCommandCount, hostedPreviewStats.renderedCommandCount, hostedPreviewStats.skippedCommandCount); std::size_t allocatedSurfaceCount = 0u; std::size_t readySurfaceCount = 0u; for (const HostedPreviewOffscreenSurface& previewSurface : m_hostedPreviewSurfaces) { if (previewSurface.colorTexture != nullptr || previewSurface.colorView != nullptr) { ++allocatedSurfaceCount; } if (previewSurface.IsReady()) { ++readySurfaceCount; } } ImGui::TextDisabled( "Hosted surfaces: %zu registry entries | %zu allocated | %zu ready", m_hostedPreviewSurfaceRegistry.GetDescriptors().size(), allocatedSurfaceCount, readySurfaceCount); if (m_demoPanel != nullptr) { ImGui::TextDisabled( "XCUI Demo preview: %s", IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo) ? "native offscreen preview surface" : "hosted presenter"); } if (m_layoutLabPanel != nullptr) { ImGui::TextDisabled( "Layout Lab preview: %s", IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab) ? "native offscreen preview surface" : "hosted presenter"); } ImGui::EndMenuBar(); } ImGui::DockSpace( ImGui::GetID("XCNewEditorDockSpace"), ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode); } ImGui::End(); if (IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud)) { RenderHostedPreviewHud(); } } void Application::RenderHostedPreviewHud() { ImGuiViewport* viewport = ImGui::GetMainViewport(); if (viewport == nullptr) { return; } const ShellPanelChromeState* demoState = TryGetShellPanelState(ShellPanelId::XCUIDemo); const ShellPanelChromeState* layoutLabState = TryGetShellPanelState(ShellPanelId::XCUILayoutLab); const HostedPreviewPanelDiagnostics demoDiagnostics = BuildHostedPreviewPanelDiagnostics( demoState != nullptr ? demoState->previewDebugName.data() : "XCUI Demo", demoState != nullptr ? demoState->previewDebugSource.data() : "new_editor.panels.xcui_demo", demoState != nullptr && demoState->visible, demoState != nullptr && demoState->hostedPreviewEnabled, IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo), m_demoPanel != nullptr && m_demoPanel->IsUsingNativeHostedPreview(), m_demoPanel != nullptr ? m_demoPanel->GetLastPreviewStats() : ::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewStats{}); const HostedPreviewPanelDiagnostics layoutLabDiagnostics = BuildHostedPreviewPanelDiagnostics( layoutLabState != nullptr ? layoutLabState->previewDebugName.data() : "XCUI Layout Lab", layoutLabState != nullptr ? layoutLabState->previewDebugSource.data() : "new_editor.panels.xcui_layout_lab", layoutLabState != nullptr && layoutLabState->visible, layoutLabState != nullptr && layoutLabState->hostedPreviewEnabled, IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab), m_layoutLabPanel != nullptr && m_layoutLabPanel->IsUsingNativeHostedPreview(), m_layoutLabPanel != nullptr ? m_layoutLabPanel->GetLastPreviewStats() : ::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewStats{}); std::size_t allocatedSurfaceCount = 0u; std::size_t readySurfaceCount = 0u; for (const HostedPreviewOffscreenSurface& previewSurface : m_hostedPreviewSurfaces) { if (previewSurface.colorTexture != nullptr || previewSurface.colorView != nullptr) { ++allocatedSurfaceCount; } if (previewSurface.IsReady()) { ++readySurfaceCount; } } const ::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewDrainStats& drainStats = m_hostedPreviewQueue.GetLastDrainStats(); ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav; ImGui::SetNextWindowViewport(viewport->ID); ImGui::SetNextWindowPos( ImVec2(viewport->WorkPos.x + viewport->WorkSize.x - 18.0f, viewport->WorkPos.y + 42.0f), ImGuiCond_Always, ImVec2(1.0f, 0.0f)); ImGui::SetNextWindowBgAlpha(0.9f); if (!ImGui::Begin("XCUI Hosted Preview HUD", nullptr, windowFlags)) { ImGui::End(); return; } ImGui::TextUnformatted("XCUI Hosted Preview"); ImGui::Text( "Registry %zu | surfaces %zu/%zu ready | last native drain %zu rendered, %zu skipped", m_hostedPreviewSurfaceRegistry.GetDescriptors().size(), readySurfaceCount, allocatedSurfaceCount, drainStats.renderedFrameCount, drainStats.skippedFrameCount); ImGui::Separator(); const auto drawPanelRow = [](const HostedPreviewPanelDiagnostics& diagnostics) { const char* const pathLabel = GetHostedPreviewPathLabel(diagnostics.nativeRequested, diagnostics.nativePresenterBound); const char* const stateLabel = GetHostedPreviewStateLabel( diagnostics.hostedPreviewEnabled, diagnostics.nativePresenterBound, diagnostics.presentedThisFrame, diagnostics.queuedToNativePassThisFrame, diagnostics.surfaceImageAvailable, diagnostics.surfaceAllocated, diagnostics.surfaceReady, diagnostics.descriptorAvailable); ImGui::Text( "%s [%s] %s", diagnostics.debugName.c_str(), diagnostics.visible ? "visible" : "hidden", stateLabel); ImGui::TextDisabled("%s", pathLabel); ImGui::Text( "source %s | submit %zu lists / %zu cmds | flush %zu lists / %zu cmds", diagnostics.debugSource.empty() ? "n/a" : diagnostics.debugSource.c_str(), diagnostics.submittedDrawListCount, diagnostics.submittedCommandCount, diagnostics.flushedDrawListCount, diagnostics.flushedCommandCount); if (diagnostics.nativePresenterBound) { ImGui::Text( "surface %ux%u | logical %.0f x %.0f | descriptor %s | image %s | submit->native %s", diagnostics.surfaceWidth, diagnostics.surfaceHeight, diagnostics.logicalWidth, diagnostics.logicalHeight, diagnostics.descriptorAvailable ? "yes" : "no", diagnostics.surfaceImageAvailable ? "yes" : "no", diagnostics.queuedToNativePassThisFrame ? "yes" : "no"); } else { ImGui::Text( "legacy present %s | cached native surface %s", diagnostics.presentedThisFrame ? "yes" : "no", (diagnostics.surfaceAllocated || diagnostics.surfaceImageAvailable) ? "retained" : "none"); } }; drawPanelRow(demoDiagnostics); ImGui::Separator(); drawPanelRow(layoutLabDiagnostics); ImGui::End(); } } // namespace NewEditor } // namespace XCEngine