Tighten XCUI hosted preview frame contract

This commit is contained in:
2026-04-05 06:38:34 +08:00
parent 585575a738
commit c6e0973fe7
6 changed files with 6 additions and 9 deletions

View File

@@ -68,12 +68,13 @@ Current gap:
- The editor bridge layer now has smoke coverage for swapchain after-UI rendering hooks and SRV-backed ImGui texture descriptor registration. - The editor bridge layer now has smoke coverage for swapchain after-UI rendering hooks and SRV-backed ImGui texture descriptor registration.
- `Application` no longer owns the ImGui backend directly; window presentation now routes through `IWindowUICompositor` with an `ImGuiWindowUICompositor` implementation, which currently delegates to `IEditorHostCompositor` / `ImGuiHostCompositor`. - `Application` no longer owns the ImGui backend directly; window presentation now routes through `IWindowUICompositor` with an `ImGuiWindowUICompositor` implementation, which currently delegates to `IEditorHostCompositor` / `ImGuiHostCompositor`.
- The generic hosted-preview presenter contract no longer owns `ImGuiTransitionBackend`; the ImGui presenter now sits in a separate `ImGuiXCUIHostedPreviewPresenter` header while the native queue/surface registry remains XCUI-generic. - The generic hosted-preview presenter contract no longer owns `ImGuiTransitionBackend`; the ImGui presenter now sits in a separate `ImGuiXCUIHostedPreviewPresenter` header while the native queue/surface registry remains XCUI-generic.
- The generic hosted-preview frame contract no longer carries an ImGui draw-list pointer; the legacy ImGui presenter resolves its inline draw target from the active ImGui window context instead of pushing that type through the XCUI contract.
- `XCNewEditor` builds successfully to `build/new_editor/bin/Debug/XCNewEditor.exe`. - `XCNewEditor` builds successfully to `build/new_editor/bin/Debug/XCNewEditor.exe`.
Current gap: Current gap:
- The shell is still ImGui-hosted. - The shell is still ImGui-hosted.
- The hosted-preview frame submission contract still carries an ImGui draw-list target for the legacy inline presenter path. - Legacy hosted preview still depends on an active ImGui window context for inline presentation.
- Editor-specialized widgets are still incomplete at the shared-module level: the authored prototypes exist, but virtualization, selection models, command routing, property editing models, toolbar/menu chrome, and icon-atlas widgets are not yet extracted into reusable XCUI modules. - Editor-specialized widgets are still incomplete at the shared-module level: the authored prototypes exist, but virtualization, selection models, command routing, property editing models, toolbar/menu chrome, and icon-atlas widgets are not yet extracted into reusable XCUI modules.
## Validated This Phase ## Validated This Phase
@@ -140,6 +141,7 @@ Current gap:
- Hosted preview contracts were tightened again: - Hosted preview contracts were tightened again:
- generic preview surface metadata stays on XCUI-owned value types - generic preview surface metadata stays on XCUI-owned value types
- `ImGuiTransitionBackend` moved behind `ImGuiXCUIHostedPreviewPresenter` - `ImGuiTransitionBackend` moved behind `ImGuiXCUIHostedPreviewPresenter`
- generic preview frame submission no longer carries an ImGui draw-list pointer
- panel/runtime callers still preserve the same legacy and native-preview behavior - panel/runtime callers still preserve the same legacy and native-preview behavior
- `new_editor` panel/shell diagnostics improvements for hosted preview state. - `new_editor` panel/shell diagnostics improvements for hosted preview state.
- XCUI asset document loading changed to prefer direct source compilation before `ResourceManager` fallback for the sandbox path, fixing the LayoutLab crash. - XCUI asset document loading changed to prefer direct source compilation before `ResourceManager` fallback for the sandbox path, fixing the LayoutLab crash.

View File

@@ -3,6 +3,8 @@
#include "XCUIBackend/ImGuiTransitionBackend.h" #include "XCUIBackend/ImGuiTransitionBackend.h"
#include "XCUIBackend/XCUIHostedPreviewPresenter.h" #include "XCUIBackend/XCUIHostedPreviewPresenter.h"
#include <imgui.h>
#include <memory> #include <memory>
namespace XCEngine { namespace XCEngine {
@@ -21,7 +23,7 @@ public:
m_backend.Submit(*frame.drawData); m_backend.Submit(*frame.drawData);
m_lastStats.submittedDrawListCount = m_backend.GetPendingDrawListCount(); m_lastStats.submittedDrawListCount = m_backend.GetPendingDrawListCount();
m_lastStats.submittedCommandCount = m_backend.GetPendingCommandCount(); m_lastStats.submittedCommandCount = m_backend.GetPendingCommandCount();
m_lastStats.presented = m_backend.EndFrame(frame.targetDrawList); m_lastStats.presented = m_backend.EndFrame(ImGui::GetWindowDrawList());
m_lastStats.flushedDrawListCount = m_backend.GetLastFlushedDrawListCount(); m_lastStats.flushedDrawListCount = m_backend.GetLastFlushedDrawListCount();
m_lastStats.flushedCommandCount = m_backend.GetLastFlushedCommandCount(); m_lastStats.flushedCommandCount = m_backend.GetLastFlushedCommandCount();
return m_lastStats.presented; return m_lastStats.presented;

View File

@@ -10,15 +10,12 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
struct ImDrawList;
namespace XCEngine { namespace XCEngine {
namespace Editor { namespace Editor {
namespace XCUIBackend { namespace XCUIBackend {
struct XCUIHostedPreviewFrame { struct XCUIHostedPreviewFrame {
const ::XCEngine::UI::UIDrawData* drawData = nullptr; const ::XCEngine::UI::UIDrawData* drawData = nullptr;
ImDrawList* targetDrawList = nullptr;
::XCEngine::UI::UIRect canvasRect = {}; ::XCEngine::UI::UIRect canvasRect = {};
::XCEngine::UI::UISize logicalSize = {}; ::XCEngine::UI::UISize logicalSize = {};
const char* debugName = nullptr; const char* debugName = nullptr;

View File

@@ -298,7 +298,6 @@ void XCUIDemoPanel::Render() {
if (m_hostedPreviewEnabled && m_previewPresenter != nullptr) { if (m_hostedPreviewEnabled && m_previewPresenter != nullptr) {
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewFrame previewFrame = {}; ::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewFrame previewFrame = {};
previewFrame.drawData = &frame.drawData; previewFrame.drawData = &frame.drawData;
previewFrame.targetDrawList = drawList;
previewFrame.canvasRect = canvasRect; previewFrame.canvasRect = canvasRect;
previewFrame.logicalSize = UI::UISize(canvasRect.width, canvasRect.height); previewFrame.logicalSize = UI::UISize(canvasRect.width, canvasRect.height);
previewFrame.debugName = kPreviewDebugName; previewFrame.debugName = kPreviewDebugName;

View File

@@ -247,7 +247,6 @@ void XCUILayoutLabPanel::Render() {
if (m_hostedPreviewEnabled && m_previewPresenter != nullptr) { if (m_hostedPreviewEnabled && m_previewPresenter != nullptr) {
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewFrame previewFrame = {}; ::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewFrame previewFrame = {};
previewFrame.drawData = &frame.drawData; previewFrame.drawData = &frame.drawData;
previewFrame.targetDrawList = ImGui::GetWindowDrawList();
previewFrame.canvasRect = input.canvasRect; previewFrame.canvasRect = input.canvasRect;
previewFrame.logicalSize = UI::UISize(input.canvasRect.width, input.canvasRect.height); previewFrame.logicalSize = UI::UISize(input.canvasRect.width, input.canvasRect.height);
previewFrame.debugName = kPreviewDebugName; previewFrame.debugName = kPreviewDebugName;

View File

@@ -103,7 +103,6 @@ TEST(XCUIHostedPreviewPresenterTest, PresentFlushesDrawDataIntoProvidedImGuiDraw
XCUIHostedPreviewFrame frame = {}; XCUIHostedPreviewFrame frame = {};
frame.drawData = &drawData; frame.drawData = &drawData;
frame.targetDrawList = targetDrawList;
const bool presented = presenter->Present(frame); const bool presented = presenter->Present(frame);
const XCUIHostedPreviewStats& stats = presenter->GetLastStats(); const XCUIHostedPreviewStats& stats = presenter->GetLastStats();
@@ -254,7 +253,6 @@ TEST(XCUIHostedPreviewPresenterTest, QueuedNativePresenterRejectsMissingDrawData
XCUIHostedPreviewFrame frame = {}; XCUIHostedPreviewFrame frame = {};
frame.debugName = "Missing DrawData"; frame.debugName = "Missing DrawData";
frame.targetDrawList = reinterpret_cast<ImDrawList*>(1);
EXPECT_FALSE(presenter->Present(frame)); EXPECT_FALSE(presenter->Present(frame));