Split XCUI hosted preview ImGui presenter seam
This commit is contained in:
@@ -56,6 +56,7 @@ Current gap:
|
|||||||
|
|
||||||
- `new_editor` remains the isolated XCUI sandbox.
|
- `new_editor` remains the isolated XCUI sandbox.
|
||||||
- Native hosted preview is working as `RHI offscreen surface -> ImGui shell texture embed`.
|
- Native hosted preview is working as `RHI offscreen surface -> ImGui shell texture embed`.
|
||||||
|
- Hosted preview surface descriptors now stay on XCUI-owned value types (`UITextureHandle`, `UIPoint`, `UIRect`) instead of exposing ImGui texture/UV types through the generic preview contract.
|
||||||
- `XCUI Demo` remains the long-lived effect and behavior testbed.
|
- `XCUI Demo` remains the long-lived effect and behavior testbed.
|
||||||
- `XCUI Demo` now covers both single-line and multiline text authoring behavior, including click caret placement, delete/backspace, tab indentation, and optional text-area line numbers.
|
- `XCUI Demo` now covers both single-line and multiline text authoring behavior, including click caret placement, delete/backspace, tab indentation, and optional text-area line numbers.
|
||||||
- `XCUI Demo` now consumes the shared `UITextInputController` path for text editing instead of carrying a private key-handling state machine.
|
- `XCUI Demo` now consumes the shared `UITextInputController` path for text editing instead of carrying a private key-handling state machine.
|
||||||
@@ -64,11 +65,13 @@ Current gap:
|
|||||||
- Panel diagnostics were expanded to clearly separate preview/runtime/input state and native vs legacy paths.
|
- Panel diagnostics were expanded to clearly separate preview/runtime/input state and native vs legacy paths.
|
||||||
- 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.
|
||||||
- `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.
|
||||||
- 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
|
||||||
@@ -77,6 +80,7 @@ Current gap:
|
|||||||
- `new_editor_xcui_layout_lab_runtime_tests`: `6/6`
|
- `new_editor_xcui_layout_lab_runtime_tests`: `6/6`
|
||||||
- `new_editor_xcui_rhi_command_compiler_tests`: `6/6`
|
- `new_editor_xcui_rhi_command_compiler_tests`: `6/6`
|
||||||
- `new_editor_xcui_rhi_render_backend_tests`: `5/5`
|
- `new_editor_xcui_rhi_render_backend_tests`: `5/5`
|
||||||
|
- `new_editor_xcui_hosted_preview_presenter_tests`: `12/12`
|
||||||
- `XCNewEditor` Debug target builds successfully
|
- `XCNewEditor` Debug target builds successfully
|
||||||
- `core_ui_tests`: `26/26`
|
- `core_ui_tests`: `26/26`
|
||||||
- `core_ui_style_tests`: `5/5`
|
- `core_ui_style_tests`: `5/5`
|
||||||
@@ -129,6 +133,10 @@ Current gap:
|
|||||||
- `IEditorHostCompositor`
|
- `IEditorHostCompositor`
|
||||||
- `ImGuiHostCompositor`
|
- `ImGuiHostCompositor`
|
||||||
- `Application` frame/present flow routed through the compositor instead of direct `m_imguiBackend` ownership
|
- `Application` frame/present flow routed through the compositor instead of direct `m_imguiBackend` ownership
|
||||||
|
- Hosted preview contracts were tightened again:
|
||||||
|
- generic preview surface metadata stays on XCUI-owned value types
|
||||||
|
- `ImGuiTransitionBackend` moved behind `ImGuiXCUIHostedPreviewPresenter`
|
||||||
|
- 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.
|
||||||
- `UIDocumentCompiler.cpp` repaired enough to restore full local builds after the duplicated schema-helper regression.
|
- `UIDocumentCompiler.cpp` repaired enough to restore full local builds after the duplicated schema-helper regression.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
||||||
|
#include "XCUIBackend/ImGuiXCUIHostedPreviewPresenter.h"
|
||||||
#include "XCUIBackend/ImGuiWindowUICompositor.h"
|
#include "XCUIBackend/ImGuiWindowUICompositor.h"
|
||||||
|
|
||||||
#include <XCEngine/Core/Asset/ResourceManager.h>
|
#include <XCEngine/Core/Asset/ResourceManager.h>
|
||||||
@@ -848,11 +849,14 @@ void Application::RenderQueuedHostedPreviews(
|
|||||||
drainStats.renderedDrawListCount += overlayStats.drawListCount;
|
drainStats.renderedDrawListCount += overlayStats.drawListCount;
|
||||||
drainStats.renderedCommandCount += overlayStats.renderedCommandCount;
|
drainStats.renderedCommandCount += overlayStats.renderedCommandCount;
|
||||||
drainStats.skippedCommandCount += overlayStats.skippedCommandCount;
|
drainStats.skippedCommandCount += overlayStats.skippedCommandCount;
|
||||||
|
::XCEngine::UI::UITextureHandle previewTexture = {};
|
||||||
|
previewTexture.nativeHandle = static_cast<std::uintptr_t>(previewSurface.imguiTextureId);
|
||||||
|
previewTexture.width = previewSurface.width;
|
||||||
|
previewTexture.height = previewSurface.height;
|
||||||
|
previewTexture.kind = ::XCEngine::UI::UITextureHandleKind::ImGuiDescriptor;
|
||||||
m_hostedPreviewSurfaceRegistry.UpdateSurface(
|
m_hostedPreviewSurfaceRegistry.UpdateSurface(
|
||||||
queuedFrame.debugName,
|
queuedFrame.debugName,
|
||||||
previewSurface.imguiTextureId,
|
previewTexture,
|
||||||
previewSurface.width,
|
|
||||||
previewSurface.height,
|
|
||||||
::XCEngine::UI::UIRect(
|
::XCEngine::UI::UIRect(
|
||||||
0.0f,
|
0.0f,
|
||||||
0.0f,
|
0.0f,
|
||||||
|
|||||||
45
new_editor/src/XCUIBackend/ImGuiXCUIHostedPreviewPresenter.h
Normal file
45
new_editor/src/XCUIBackend/ImGuiXCUIHostedPreviewPresenter.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "XCUIBackend/ImGuiTransitionBackend.h"
|
||||||
|
#include "XCUIBackend/XCUIHostedPreviewPresenter.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace Editor {
|
||||||
|
namespace XCUIBackend {
|
||||||
|
|
||||||
|
class ImGuiXCUIHostedPreviewPresenter final : public IXCUIHostedPreviewPresenter {
|
||||||
|
public:
|
||||||
|
bool Present(const XCUIHostedPreviewFrame& frame) override {
|
||||||
|
m_lastStats = {};
|
||||||
|
if (frame.drawData == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_backend.BeginFrame();
|
||||||
|
m_backend.Submit(*frame.drawData);
|
||||||
|
m_lastStats.submittedDrawListCount = m_backend.GetPendingDrawListCount();
|
||||||
|
m_lastStats.submittedCommandCount = m_backend.GetPendingCommandCount();
|
||||||
|
m_lastStats.presented = m_backend.EndFrame(frame.targetDrawList);
|
||||||
|
m_lastStats.flushedDrawListCount = m_backend.GetLastFlushedDrawListCount();
|
||||||
|
m_lastStats.flushedCommandCount = m_backend.GetLastFlushedCommandCount();
|
||||||
|
return m_lastStats.presented;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XCUIHostedPreviewStats& GetLastStats() const override {
|
||||||
|
return m_lastStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImGuiTransitionBackend m_backend = {};
|
||||||
|
XCUIHostedPreviewStats m_lastStats = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::unique_ptr<IXCUIHostedPreviewPresenter> CreateImGuiXCUIHostedPreviewPresenter() {
|
||||||
|
return std::make_unique<ImGuiXCUIHostedPreviewPresenter>();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace XCUIBackend
|
||||||
|
} // namespace Editor
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "XCUIBackend/ImGuiTransitionBackend.h"
|
|
||||||
|
|
||||||
#include <XCEngine/UI/DrawData.h>
|
#include <XCEngine/UI/DrawData.h>
|
||||||
#include <XCEngine/UI/Types.h>
|
#include <XCEngine/UI/Types.h>
|
||||||
|
|
||||||
@@ -45,15 +43,15 @@ struct XCUIHostedPreviewQueuedFrame {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct XCUIHostedPreviewSurfaceImage {
|
struct XCUIHostedPreviewSurfaceImage {
|
||||||
ImTextureID textureId = {};
|
::XCEngine::UI::UITextureHandle texture = {};
|
||||||
ImVec2 uvMin = ImVec2(0.0f, 0.0f);
|
::XCEngine::UI::UIPoint uvMin = {};
|
||||||
ImVec2 uvMax = ImVec2(1.0f, 1.0f);
|
::XCEngine::UI::UIPoint uvMax = ::XCEngine::UI::UIPoint(1.0f, 1.0f);
|
||||||
::XCEngine::UI::UIRect renderedCanvasRect = {};
|
::XCEngine::UI::UIRect renderedCanvasRect = {};
|
||||||
std::uint32_t surfaceWidth = 0;
|
std::uint32_t surfaceWidth = 0;
|
||||||
std::uint32_t surfaceHeight = 0;
|
std::uint32_t surfaceHeight = 0;
|
||||||
|
|
||||||
bool IsValid() const {
|
bool IsValid() const {
|
||||||
return textureId != ImTextureID{} && surfaceWidth > 0u && surfaceHeight > 0u;
|
return texture.IsValid() && surfaceWidth > 0u && surfaceHeight > 0u;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,11 +112,9 @@ public:
|
|||||||
|
|
||||||
void UpdateSurface(
|
void UpdateSurface(
|
||||||
const std::string& debugName,
|
const std::string& debugName,
|
||||||
ImTextureID textureId,
|
const ::XCEngine::UI::UITextureHandle& texture,
|
||||||
std::uint32_t surfaceWidth,
|
|
||||||
std::uint32_t surfaceHeight,
|
|
||||||
const ::XCEngine::UI::UIRect& renderedCanvasRect) {
|
const ::XCEngine::UI::UIRect& renderedCanvasRect) {
|
||||||
if (debugName.empty() || textureId == ImTextureID{} || surfaceWidth == 0u || surfaceHeight == 0u) {
|
if (debugName.empty() || !texture.IsValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,16 +126,16 @@ public:
|
|||||||
descriptor = &m_descriptors.back();
|
descriptor = &m_descriptors.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptor->image.textureId = textureId;
|
descriptor->image.texture = texture;
|
||||||
descriptor->image.surfaceWidth = surfaceWidth;
|
descriptor->image.surfaceWidth = texture.width;
|
||||||
descriptor->image.surfaceHeight = surfaceHeight;
|
descriptor->image.surfaceHeight = texture.height;
|
||||||
descriptor->image.renderedCanvasRect = renderedCanvasRect;
|
descriptor->image.renderedCanvasRect = renderedCanvasRect;
|
||||||
descriptor->image.uvMin = ImVec2(
|
descriptor->image.uvMin = ::XCEngine::UI::UIPoint(
|
||||||
renderedCanvasRect.x / static_cast<float>(surfaceWidth),
|
renderedCanvasRect.x / static_cast<float>(texture.width),
|
||||||
renderedCanvasRect.y / static_cast<float>(surfaceHeight));
|
renderedCanvasRect.y / static_cast<float>(texture.height));
|
||||||
descriptor->image.uvMax = ImVec2(
|
descriptor->image.uvMax = ::XCEngine::UI::UIPoint(
|
||||||
(renderedCanvasRect.x + renderedCanvasRect.width) / static_cast<float>(surfaceWidth),
|
(renderedCanvasRect.x + renderedCanvasRect.width) / static_cast<float>(texture.width),
|
||||||
(renderedCanvasRect.y + renderedCanvasRect.height) / static_cast<float>(surfaceHeight));
|
(renderedCanvasRect.y + renderedCanvasRect.height) / static_cast<float>(texture.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TryGetSurfaceDescriptor(
|
bool TryGetSurfaceDescriptor(
|
||||||
@@ -267,33 +263,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImGuiXCUIHostedPreviewPresenter final : public IXCUIHostedPreviewPresenter {
|
|
||||||
public:
|
|
||||||
bool Present(const XCUIHostedPreviewFrame& frame) override {
|
|
||||||
m_lastStats = {};
|
|
||||||
if (frame.drawData == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_backend.BeginFrame();
|
|
||||||
m_backend.Submit(*frame.drawData);
|
|
||||||
m_lastStats.submittedDrawListCount = m_backend.GetPendingDrawListCount();
|
|
||||||
m_lastStats.submittedCommandCount = m_backend.GetPendingCommandCount();
|
|
||||||
m_lastStats.presented = m_backend.EndFrame(frame.targetDrawList);
|
|
||||||
m_lastStats.flushedDrawListCount = m_backend.GetLastFlushedDrawListCount();
|
|
||||||
m_lastStats.flushedCommandCount = m_backend.GetLastFlushedCommandCount();
|
|
||||||
return m_lastStats.presented;
|
|
||||||
}
|
|
||||||
|
|
||||||
const XCUIHostedPreviewStats& GetLastStats() const override {
|
|
||||||
return m_lastStats;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ImGuiTransitionBackend m_backend = {};
|
|
||||||
XCUIHostedPreviewStats m_lastStats = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
class QueuedNativeXCUIHostedPreviewPresenter final : public IXCUIHostedPreviewPresenter {
|
class QueuedNativeXCUIHostedPreviewPresenter final : public IXCUIHostedPreviewPresenter {
|
||||||
public:
|
public:
|
||||||
QueuedNativeXCUIHostedPreviewPresenter(
|
QueuedNativeXCUIHostedPreviewPresenter(
|
||||||
@@ -334,9 +303,7 @@ private:
|
|||||||
XCUIHostedPreviewStats m_lastStats = {};
|
XCUIHostedPreviewStats m_lastStats = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<IXCUIHostedPreviewPresenter> CreateImGuiXCUIHostedPreviewPresenter() {
|
std::unique_ptr<IXCUIHostedPreviewPresenter> CreateImGuiXCUIHostedPreviewPresenter();
|
||||||
return std::make_unique<ImGuiXCUIHostedPreviewPresenter>();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::unique_ptr<IXCUIHostedPreviewPresenter> CreateQueuedNativeXCUIHostedPreviewPresenter(
|
inline std::unique_ptr<IXCUIHostedPreviewPresenter> CreateQueuedNativeXCUIHostedPreviewPresenter(
|
||||||
XCUIHostedPreviewQueue& queue,
|
XCUIHostedPreviewQueue& queue,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "XCUIDemoPanel.h"
|
#include "XCUIDemoPanel.h"
|
||||||
|
|
||||||
|
#include "XCUIBackend/ImGuiXCUIHostedPreviewPresenter.h"
|
||||||
#include "XCUIBackend/ImGuiXCUIInputAdapter.h"
|
#include "XCUIBackend/ImGuiXCUIInputAdapter.h"
|
||||||
|
|
||||||
#include <XCEngine/UI/Types.h>
|
#include <XCEngine/UI/Types.h>
|
||||||
@@ -30,6 +31,16 @@ UI::UIRect ToUIRect(const ImVec2& minPoint, const ImVec2& size) {
|
|||||||
return UI::UIRect(minPoint.x, minPoint.y, size.x, size.y);
|
return UI::UIRect(minPoint.x, minPoint.y, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImTextureID ToImTextureId(const UI::UITextureHandle& texture) {
|
||||||
|
return texture.IsValid()
|
||||||
|
? static_cast<ImTextureID>(texture.nativeHandle)
|
||||||
|
: ImTextureID{};
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 ToImVec2(const UI::UIPoint& point) {
|
||||||
|
return ImVec2(point.x, point.y);
|
||||||
|
}
|
||||||
|
|
||||||
bool ContainsPoint(const UI::UIRect& rect, const UI::UIPoint& point) {
|
bool ContainsPoint(const UI::UIRect& rect, const UI::UIPoint& point) {
|
||||||
return point.x >= rect.x &&
|
return point.x >= rect.x &&
|
||||||
point.y >= rect.y &&
|
point.y >= rect.y &&
|
||||||
@@ -216,7 +227,11 @@ void XCUIDemoPanel::Render() {
|
|||||||
if (validCanvas) {
|
if (validCanvas) {
|
||||||
ImGui::SetCursorScreenPos(canvasMin);
|
ImGui::SetCursorScreenPos(canvasMin);
|
||||||
if (showHostedSurfaceImage) {
|
if (showHostedSurfaceImage) {
|
||||||
ImGui::Image(hostedSurfaceImage.textureId, canvasSize, hostedSurfaceImage.uvMin, hostedSurfaceImage.uvMax);
|
ImGui::Image(
|
||||||
|
ToImTextureId(hostedSurfaceImage.texture),
|
||||||
|
canvasSize,
|
||||||
|
ToImVec2(hostedSurfaceImage.uvMin),
|
||||||
|
ToImVec2(hostedSurfaceImage.uvMax));
|
||||||
DrawHostedPreviewFrame(drawList, canvasMin, canvasSize);
|
DrawHostedPreviewFrame(drawList, canvasMin, canvasSize);
|
||||||
} else {
|
} else {
|
||||||
ImGui::InvisibleButton("##XCUIDemoCanvas", canvasSize);
|
ImGui::InvisibleButton("##XCUIDemoCanvas", canvasSize);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "XCUILayoutLabPanel.h"
|
#include "XCUILayoutLabPanel.h"
|
||||||
|
|
||||||
|
#include "XCUIBackend/ImGuiXCUIHostedPreviewPresenter.h"
|
||||||
#include <XCEngine/UI/Types.h>
|
#include <XCEngine/UI/Types.h>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
@@ -23,6 +24,16 @@ UI::UIRect ToUIRect(const ImVec2& minPoint, const ImVec2& size) {
|
|||||||
return UI::UIRect(minPoint.x, minPoint.y, size.x, size.y);
|
return UI::UIRect(minPoint.x, minPoint.y, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImTextureID ToImTextureId(const UI::UITextureHandle& texture) {
|
||||||
|
return texture.IsValid()
|
||||||
|
? static_cast<ImTextureID>(texture.nativeHandle)
|
||||||
|
: ImTextureID{};
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 ToImVec2(const UI::UIPoint& point) {
|
||||||
|
return ImVec2(point.x, point.y);
|
||||||
|
}
|
||||||
|
|
||||||
bool ContainsPoint(const UI::UIRect& rect, const UI::UIPoint& point) {
|
bool ContainsPoint(const UI::UIRect& rect, const UI::UIPoint& point) {
|
||||||
return point.x >= rect.x &&
|
return point.x >= rect.x &&
|
||||||
point.y >= rect.y &&
|
point.y >= rect.y &&
|
||||||
@@ -197,7 +208,11 @@ void XCUILayoutLabPanel::Render() {
|
|||||||
if (validCanvas) {
|
if (validCanvas) {
|
||||||
ImGui::SetCursorScreenPos(canvasMin);
|
ImGui::SetCursorScreenPos(canvasMin);
|
||||||
if (showHostedSurfaceImage) {
|
if (showHostedSurfaceImage) {
|
||||||
ImGui::Image(hostedSurfaceImage.textureId, canvasSize, hostedSurfaceImage.uvMin, hostedSurfaceImage.uvMax);
|
ImGui::Image(
|
||||||
|
ToImTextureId(hostedSurfaceImage.texture),
|
||||||
|
canvasSize,
|
||||||
|
ToImVec2(hostedSurfaceImage.uvMin),
|
||||||
|
ToImVec2(hostedSurfaceImage.uvMax));
|
||||||
DrawHostedPreviewFrame(drawList, canvasMin, canvasSize);
|
DrawHostedPreviewFrame(drawList, canvasMin, canvasSize);
|
||||||
} else {
|
} else {
|
||||||
ImGui::InvisibleButton("##XCUILayoutLabCanvas", canvasSize);
|
ImGui::InvisibleButton("##XCUILayoutLabCanvas", canvasSize);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "XCUIBackend/ImGuiXCUIHostedPreviewPresenter.h"
|
||||||
#include "XCUIBackend/XCUIHostedPreviewPresenter.h"
|
#include "XCUIBackend/XCUIHostedPreviewPresenter.h"
|
||||||
|
|
||||||
#include <XCEngine/UI/DrawData.h>
|
#include <XCEngine/UI/DrawData.h>
|
||||||
@@ -46,6 +47,18 @@ void PrepareImGui(float width = 1024.0f, float height = 768.0f) {
|
|||||||
io.Fonts->SetTexID(static_cast<ImTextureID>(1));
|
io.Fonts->SetTexID(static_cast<ImTextureID>(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XCEngine::UI::UITextureHandle MakeHostedPreviewTextureHandle(
|
||||||
|
std::uintptr_t nativeHandle,
|
||||||
|
std::uint32_t width,
|
||||||
|
std::uint32_t height) {
|
||||||
|
XCEngine::UI::UITextureHandle texture = {};
|
||||||
|
texture.nativeHandle = nativeHandle;
|
||||||
|
texture.width = width;
|
||||||
|
texture.height = height;
|
||||||
|
texture.kind = XCEngine::UI::UITextureHandleKind::ImGuiDescriptor;
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
TEST(XCUIHostedPreviewPresenterTest, PresentReturnsFalseAndClearsStatsWhenFrameHasNoDrawData) {
|
TEST(XCUIHostedPreviewPresenterTest, PresentReturnsFalseAndClearsStatsWhenFrameHasNoDrawData) {
|
||||||
ImGuiContextScope contextScope;
|
ImGuiContextScope contextScope;
|
||||||
PrepareImGui();
|
PrepareImGui();
|
||||||
@@ -216,14 +229,14 @@ TEST(XCUIHostedPreviewPresenterTest, QueuedNativePresenterFallsBackLogicalSizeTo
|
|||||||
|
|
||||||
surfaceRegistry.UpdateSurface(
|
surfaceRegistry.UpdateSurface(
|
||||||
"XCUI Demo",
|
"XCUI Demo",
|
||||||
static_cast<ImTextureID>(static_cast<intptr_t>(11)),
|
MakeHostedPreviewTextureHandle(11u, 640u, 360u),
|
||||||
640u,
|
|
||||||
360u,
|
|
||||||
XCEngine::UI::UIRect(0.0f, 0.0f, 320.0f, 180.0f));
|
XCEngine::UI::UIRect(0.0f, 0.0f, 320.0f, 180.0f));
|
||||||
|
|
||||||
ASSERT_TRUE(presenter->TryGetSurfaceImage("XCUI Demo", image));
|
ASSERT_TRUE(presenter->TryGetSurfaceImage("XCUI Demo", image));
|
||||||
EXPECT_TRUE(image.IsValid());
|
EXPECT_TRUE(image.IsValid());
|
||||||
EXPECT_EQ(image.textureId, static_cast<ImTextureID>(static_cast<intptr_t>(11)));
|
EXPECT_EQ(image.texture.nativeHandle, 11u);
|
||||||
|
EXPECT_EQ(image.texture.width, 640u);
|
||||||
|
EXPECT_EQ(image.texture.height, 360u);
|
||||||
EXPECT_FLOAT_EQ(image.uvMin.x, 0.0f);
|
EXPECT_FLOAT_EQ(image.uvMin.x, 0.0f);
|
||||||
EXPECT_FLOAT_EQ(image.uvMin.y, 0.0f);
|
EXPECT_FLOAT_EQ(image.uvMin.y, 0.0f);
|
||||||
EXPECT_FLOAT_EQ(image.uvMax.x, 0.5f);
|
EXPECT_FLOAT_EQ(image.uvMax.x, 0.5f);
|
||||||
@@ -324,9 +337,7 @@ TEST(XCUIHostedPreviewPresenterTest, SurfaceRegistryIgnoresUnnamedQueuedFramesAn
|
|||||||
|
|
||||||
surfaceRegistry.UpdateSurface(
|
surfaceRegistry.UpdateSurface(
|
||||||
"XCUI Demo",
|
"XCUI Demo",
|
||||||
static_cast<ImTextureID>(static_cast<intptr_t>(13)),
|
MakeHostedPreviewTextureHandle(13u, 800u, 600u),
|
||||||
800u,
|
|
||||||
600u,
|
|
||||||
XCEngine::UI::UIRect(0.0f, 0.0f, 400.0f, 300.0f));
|
XCEngine::UI::UIRect(0.0f, 0.0f, 400.0f, 300.0f));
|
||||||
ASSERT_EQ(surfaceRegistry.GetDescriptors().size(), 1u);
|
ASSERT_EQ(surfaceRegistry.GetDescriptors().size(), 1u);
|
||||||
|
|
||||||
@@ -342,14 +353,14 @@ TEST(XCUIHostedPreviewPresenterTest, SurfaceRegistryExposesImageUvForRenderedCan
|
|||||||
|
|
||||||
surfaceRegistry.UpdateSurface(
|
surfaceRegistry.UpdateSurface(
|
||||||
"XCUI Demo",
|
"XCUI Demo",
|
||||||
static_cast<ImTextureID>(static_cast<intptr_t>(7)),
|
MakeHostedPreviewTextureHandle(7u, 1024u, 768u),
|
||||||
1024u,
|
|
||||||
768u,
|
|
||||||
XCEngine::UI::UIRect(128.0f, 96.0f, 512.0f, 384.0f));
|
XCEngine::UI::UIRect(128.0f, 96.0f, 512.0f, 384.0f));
|
||||||
|
|
||||||
ASSERT_TRUE(surfaceRegistry.TryGetSurfaceImage("XCUI Demo", image));
|
ASSERT_TRUE(surfaceRegistry.TryGetSurfaceImage("XCUI Demo", image));
|
||||||
EXPECT_TRUE(image.IsValid());
|
EXPECT_TRUE(image.IsValid());
|
||||||
EXPECT_EQ(image.textureId, static_cast<ImTextureID>(static_cast<intptr_t>(7)));
|
EXPECT_EQ(image.texture.nativeHandle, 7u);
|
||||||
|
EXPECT_EQ(image.texture.width, 1024u);
|
||||||
|
EXPECT_EQ(image.texture.height, 768u);
|
||||||
EXPECT_EQ(image.surfaceWidth, 1024u);
|
EXPECT_EQ(image.surfaceWidth, 1024u);
|
||||||
EXPECT_EQ(image.surfaceHeight, 768u);
|
EXPECT_EQ(image.surfaceHeight, 768u);
|
||||||
EXPECT_FLOAT_EQ(image.uvMin.x, 0.125f);
|
EXPECT_FLOAT_EQ(image.uvMin.x, 0.125f);
|
||||||
@@ -400,15 +411,15 @@ TEST(XCUIHostedPreviewPresenterTest, SurfaceRegistryTracksQueuedFrameMetadataAlo
|
|||||||
|
|
||||||
surfaceRegistry.UpdateSurface(
|
surfaceRegistry.UpdateSurface(
|
||||||
"XCUI Demo",
|
"XCUI Demo",
|
||||||
static_cast<ImTextureID>(static_cast<intptr_t>(9)),
|
MakeHostedPreviewTextureHandle(9u, 1024u, 512u),
|
||||||
1024u,
|
|
||||||
512u,
|
|
||||||
XCEngine::UI::UIRect(128.0f, 64.0f, 320.0f, 160.0f));
|
XCEngine::UI::UIRect(128.0f, 64.0f, 320.0f, 160.0f));
|
||||||
|
|
||||||
ASSERT_TRUE(surfaceRegistry.TryGetSurfaceDescriptor("XCUI Demo", descriptor));
|
ASSERT_TRUE(surfaceRegistry.TryGetSurfaceDescriptor("XCUI Demo", descriptor));
|
||||||
EXPECT_TRUE(descriptor.queuedThisFrame);
|
EXPECT_TRUE(descriptor.queuedThisFrame);
|
||||||
EXPECT_TRUE(descriptor.image.IsValid());
|
EXPECT_TRUE(descriptor.image.IsValid());
|
||||||
EXPECT_EQ(descriptor.image.textureId, static_cast<ImTextureID>(static_cast<intptr_t>(9)));
|
EXPECT_EQ(descriptor.image.texture.nativeHandle, 9u);
|
||||||
|
EXPECT_EQ(descriptor.image.texture.width, 1024u);
|
||||||
|
EXPECT_EQ(descriptor.image.texture.height, 512u);
|
||||||
EXPECT_FLOAT_EQ(descriptor.image.uvMin.x, 0.125f);
|
EXPECT_FLOAT_EQ(descriptor.image.uvMin.x, 0.125f);
|
||||||
EXPECT_FLOAT_EQ(descriptor.image.uvMin.y, 0.125f);
|
EXPECT_FLOAT_EQ(descriptor.image.uvMin.y, 0.125f);
|
||||||
EXPECT_FLOAT_EQ(descriptor.image.uvMax.x, 0.4375f);
|
EXPECT_FLOAT_EQ(descriptor.image.uvMax.x, 0.4375f);
|
||||||
@@ -427,9 +438,7 @@ TEST(XCUIHostedPreviewPresenterTest, SurfaceRegistryRejectsInvalidSurfaceUpdates
|
|||||||
|
|
||||||
surfaceRegistry.UpdateSurface(
|
surfaceRegistry.UpdateSurface(
|
||||||
"XCUI Demo",
|
"XCUI Demo",
|
||||||
static_cast<ImTextureID>(static_cast<intptr_t>(17)),
|
MakeHostedPreviewTextureHandle(17u, 512u, 256u),
|
||||||
512u,
|
|
||||||
256u,
|
|
||||||
XCEngine::UI::UIRect(64.0f, 32.0f, 256.0f, 128.0f));
|
XCEngine::UI::UIRect(64.0f, 32.0f, 256.0f, 128.0f));
|
||||||
|
|
||||||
ASSERT_TRUE(surfaceRegistry.TryGetSurfaceDescriptor("XCUI Demo", descriptor));
|
ASSERT_TRUE(surfaceRegistry.TryGetSurfaceDescriptor("XCUI Demo", descriptor));
|
||||||
@@ -438,25 +447,21 @@ TEST(XCUIHostedPreviewPresenterTest, SurfaceRegistryRejectsInvalidSurfaceUpdates
|
|||||||
|
|
||||||
surfaceRegistry.UpdateSurface(
|
surfaceRegistry.UpdateSurface(
|
||||||
"XCUI Demo",
|
"XCUI Demo",
|
||||||
ImTextureID{},
|
XCEngine::UI::UITextureHandle{},
|
||||||
512u,
|
|
||||||
256u,
|
|
||||||
XCEngine::UI::UIRect(0.0f, 0.0f, 128.0f, 64.0f));
|
XCEngine::UI::UIRect(0.0f, 0.0f, 128.0f, 64.0f));
|
||||||
surfaceRegistry.UpdateSurface(
|
surfaceRegistry.UpdateSurface(
|
||||||
"",
|
"",
|
||||||
static_cast<ImTextureID>(static_cast<intptr_t>(19)),
|
MakeHostedPreviewTextureHandle(19u, 512u, 256u),
|
||||||
512u,
|
|
||||||
256u,
|
|
||||||
XCEngine::UI::UIRect(0.0f, 0.0f, 128.0f, 64.0f));
|
XCEngine::UI::UIRect(0.0f, 0.0f, 128.0f, 64.0f));
|
||||||
surfaceRegistry.UpdateSurface(
|
surfaceRegistry.UpdateSurface(
|
||||||
"XCUI Demo",
|
"XCUI Demo",
|
||||||
static_cast<ImTextureID>(static_cast<intptr_t>(21)),
|
MakeHostedPreviewTextureHandle(21u, 0u, 256u),
|
||||||
0u,
|
|
||||||
256u,
|
|
||||||
XCEngine::UI::UIRect(0.0f, 0.0f, 128.0f, 64.0f));
|
XCEngine::UI::UIRect(0.0f, 0.0f, 128.0f, 64.0f));
|
||||||
|
|
||||||
ASSERT_TRUE(surfaceRegistry.TryGetSurfaceDescriptor("XCUI Demo", descriptor));
|
ASSERT_TRUE(surfaceRegistry.TryGetSurfaceDescriptor("XCUI Demo", descriptor));
|
||||||
EXPECT_EQ(descriptor.image.textureId, originalImage.textureId);
|
EXPECT_EQ(descriptor.image.texture.nativeHandle, originalImage.texture.nativeHandle);
|
||||||
|
EXPECT_EQ(descriptor.image.texture.width, originalImage.texture.width);
|
||||||
|
EXPECT_EQ(descriptor.image.texture.height, originalImage.texture.height);
|
||||||
EXPECT_EQ(descriptor.image.surfaceWidth, originalImage.surfaceWidth);
|
EXPECT_EQ(descriptor.image.surfaceWidth, originalImage.surfaceWidth);
|
||||||
EXPECT_EQ(descriptor.image.surfaceHeight, originalImage.surfaceHeight);
|
EXPECT_EQ(descriptor.image.surfaceHeight, originalImage.surfaceHeight);
|
||||||
EXPECT_FLOAT_EQ(descriptor.image.uvMin.x, originalImage.uvMin.x);
|
EXPECT_FLOAT_EQ(descriptor.image.uvMin.x, originalImage.uvMin.x);
|
||||||
@@ -504,7 +509,7 @@ TEST(XCUIHostedPreviewPresenterTest, SurfaceRegistryQueriesClearOutputForMissing
|
|||||||
descriptor.queuedThisFrame = true;
|
descriptor.queuedThisFrame = true;
|
||||||
|
|
||||||
XCUIHostedPreviewSurfaceImage image = {};
|
XCUIHostedPreviewSurfaceImage image = {};
|
||||||
image.textureId = static_cast<ImTextureID>(static_cast<intptr_t>(23));
|
image.texture = MakeHostedPreviewTextureHandle(23u, 64u, 64u);
|
||||||
image.surfaceWidth = 64u;
|
image.surfaceWidth = 64u;
|
||||||
image.surfaceHeight = 64u;
|
image.surfaceHeight = 64u;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user