Files
XCEngine/tests/NewEditor/test_native_xcui_panel_canvas_host.cpp

182 lines
8.0 KiB
C++

#include <gtest/gtest.h>
#include "XCUIBackend/NativeXCUIPanelCanvasHost.h"
namespace {
using XCEngine::Editor::XCUIBackend::CreateNativeXCUIPanelCanvasHost;
using XCEngine::Editor::XCUIBackend::IXCUIPanelCanvasHost;
using XCEngine::Editor::XCUIBackend::NativeXCUIPanelCanvasHost;
using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasFrameSnapshot;
using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend;
using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostCapabilities;
using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasRequest;
using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasSession;
XCEngine::UI::UITextureHandle MakeSurfaceTextureHandle(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::ShaderResourceView;
return texture;
}
TEST(NativeXCUIPanelCanvasHostTest, FactoryReportsNativeBackendCapabilitiesAndNoSnapshotBeforeBegin) {
std::unique_ptr<IXCUIPanelCanvasHost> host = CreateNativeXCUIPanelCanvasHost();
ASSERT_NE(host, nullptr);
EXPECT_STREQ(host->GetDebugName(), "NativeXCUIPanelCanvasHost");
EXPECT_EQ(host->GetBackend(), XCUIPanelCanvasHostBackend::Native);
const XCUIPanelCanvasHostCapabilities capabilities = host->GetCapabilities();
EXPECT_FALSE(capabilities.supportsPointerHitTesting);
EXPECT_TRUE(capabilities.supportsHostedSurfaceImages);
EXPECT_TRUE(capabilities.supportsPrimitiveOverlays);
EXPECT_TRUE(capabilities.supportsExternallyDrivenSession);
XCUIPanelCanvasFrameSnapshot snapshot = {};
EXPECT_FALSE(host->TryGetLatestFrameSnapshot(snapshot));
EXPECT_TRUE(snapshot.childId.empty());
EXPECT_EQ(snapshot.overlayDrawData.GetDrawListCount(), 0u);
}
TEST(NativeXCUIPanelCanvasHostTest, BeginCanvasWithConfiguredSessionCapturesSnapshotAndOverlayCommands) {
NativeXCUIPanelCanvasHost host = {};
XCUIPanelCanvasSession configuredSession = {};
configuredSession.hostRect = XCEngine::UI::UIRect(20.0f, 30.0f, 640.0f, 360.0f);
configuredSession.canvasRect = XCEngine::UI::UIRect(20.0f, 72.0f, 640.0f, 318.0f);
configuredSession.pointerPosition = XCEngine::UI::UIPoint(128.0f, 144.0f);
configuredSession.validCanvas = true;
configuredSession.hovered = true;
configuredSession.windowFocused = true;
host.SetCanvasSession(configuredSession);
XCUIPanelCanvasRequest request = {};
request.childId = "NativeDemoCanvas";
request.height = 360.0f;
request.topInset = 42.0f;
request.placeholderTitle = "Placeholder";
request.placeholderSubtitle = "Native host placeholder";
request.badgeTitle = "XCUI Demo";
request.badgeSubtitle = "native path";
const XCUIPanelCanvasSession session = host.BeginCanvas(request);
EXPECT_FLOAT_EQ(session.hostRect.x, configuredSession.hostRect.x);
EXPECT_FLOAT_EQ(session.hostRect.y, configuredSession.hostRect.y);
EXPECT_FLOAT_EQ(session.canvasRect.x, configuredSession.canvasRect.x);
EXPECT_FLOAT_EQ(session.canvasRect.y, configuredSession.canvasRect.y);
EXPECT_TRUE(session.validCanvas);
EXPECT_TRUE(session.hovered);
EXPECT_TRUE(session.windowFocused);
host.DrawFilledRect(
XCEngine::UI::UIRect(40.0f, 90.0f, 120.0f, 60.0f),
XCEngine::UI::UIColor(0.8f, 0.2f, 0.1f, 1.0f),
6.0f);
host.DrawOutlineRect(
XCEngine::UI::UIRect(42.0f, 92.0f, 118.0f, 58.0f),
XCEngine::UI::UIColor(0.2f, 0.8f, 0.3f, 1.0f),
2.0f,
4.0f);
host.DrawText(
XCEngine::UI::UIPoint(48.0f, 104.0f),
"hello native",
XCEngine::UI::UIColor(1.0f, 1.0f, 1.0f, 1.0f),
16.0f);
host.EndCanvas();
XCUIPanelCanvasFrameSnapshot snapshot = {};
ASSERT_TRUE(host.TryGetLatestFrameSnapshot(snapshot));
EXPECT_EQ(snapshot.childId, "NativeDemoCanvas");
EXPECT_FALSE(snapshot.showingSurfaceImage);
EXPECT_TRUE(snapshot.drawPreviewFrame);
EXPECT_EQ(snapshot.placeholderTitle, "Placeholder");
EXPECT_EQ(snapshot.placeholderSubtitle, "Native host placeholder");
EXPECT_EQ(snapshot.badgeTitle, "XCUI Demo");
EXPECT_EQ(snapshot.badgeSubtitle, "native path");
EXPECT_TRUE(snapshot.session.validCanvas);
EXPECT_EQ(snapshot.overlayDrawData.GetDrawListCount(), 1u);
EXPECT_EQ(snapshot.overlayDrawData.GetDrawLists().front().GetDebugName(), "NativeDemoCanvas.overlay");
EXPECT_EQ(snapshot.overlayDrawData.GetTotalCommandCount(), 14u);
EXPECT_EQ(
snapshot.overlayDrawData.GetDrawLists().front().GetCommands().front().type,
XCEngine::UI::UIDrawCommandType::PushClipRect);
EXPECT_EQ(
snapshot.overlayDrawData.GetDrawLists().front().GetCommands().back().type,
XCEngine::UI::UIDrawCommandType::PopClipRect);
}
TEST(NativeXCUIPanelCanvasHostTest, SurfaceImagePathCapturesSurfaceAndPreviewFrameWithoutPlaceholder) {
NativeXCUIPanelCanvasHost host = {};
XCUIPanelCanvasSession configuredSession = {};
configuredSession.hostRect = XCEngine::UI::UIRect(0.0f, 0.0f, 800.0f, 480.0f);
configuredSession.canvasRect = XCEngine::UI::UIRect(0.0f, 0.0f, 800.0f, 480.0f);
configuredSession.validCanvas = true;
host.SetCanvasSession(configuredSession);
XCUIPanelCanvasRequest request = {};
request.childId = "NativeSurfaceCanvas";
request.showSurfaceImage = true;
request.drawPreviewFrame = true;
request.surfaceImage.texture = MakeSurfaceTextureHandle(17u, 1024u, 512u);
request.surfaceImage.surfaceWidth = 1024u;
request.surfaceImage.surfaceHeight = 512u;
request.surfaceImage.uvMin = XCEngine::UI::UIPoint(0.0f, 0.0f);
request.surfaceImage.uvMax = XCEngine::UI::UIPoint(1.0f, 1.0f);
const XCUIPanelCanvasSession session = host.BeginCanvas(request);
EXPECT_TRUE(session.validCanvas);
host.EndCanvas();
XCUIPanelCanvasFrameSnapshot snapshot = {};
ASSERT_TRUE(host.TryGetLatestFrameSnapshot(snapshot));
EXPECT_TRUE(snapshot.showingSurfaceImage);
EXPECT_TRUE(snapshot.surfaceImage.IsValid());
EXPECT_EQ(snapshot.surfaceImage.texture.nativeHandle, 17u);
EXPECT_EQ(snapshot.overlayDrawData.GetDrawListCount(), 1u);
EXPECT_EQ(snapshot.overlayDrawData.GetTotalCommandCount(), 4u);
const auto& commands = snapshot.overlayDrawData.GetDrawLists().front().GetCommands();
ASSERT_EQ(commands.size(), 4u);
EXPECT_EQ(commands[0].type, XCEngine::UI::UIDrawCommandType::PushClipRect);
EXPECT_EQ(commands[1].type, XCEngine::UI::UIDrawCommandType::Image);
EXPECT_FLOAT_EQ(commands[1].uvMin.x, 0.0f);
EXPECT_FLOAT_EQ(commands[1].uvMin.y, 0.0f);
EXPECT_FLOAT_EQ(commands[1].uvMax.x, 1.0f);
EXPECT_FLOAT_EQ(commands[1].uvMax.y, 1.0f);
EXPECT_EQ(commands[2].type, XCEngine::UI::UIDrawCommandType::RectOutline);
EXPECT_EQ(commands[3].type, XCEngine::UI::UIDrawCommandType::PopClipRect);
}
TEST(NativeXCUIPanelCanvasHostTest, ClearingConfiguredSessionFallsBackToPassiveSnapshot) {
NativeXCUIPanelCanvasHost host = {};
XCUIPanelCanvasSession configuredSession = {};
configuredSession.hostRect = XCEngine::UI::UIRect(4.0f, 5.0f, 320.0f, 240.0f);
configuredSession.canvasRect = XCEngine::UI::UIRect(4.0f, 25.0f, 320.0f, 220.0f);
configuredSession.validCanvas = true;
host.SetCanvasSession(configuredSession);
ASSERT_TRUE(host.HasConfiguredSession());
host.ClearCanvasSession();
EXPECT_FALSE(host.HasConfiguredSession());
XCUIPanelCanvasRequest request = {};
request.height = 180.0f;
request.topInset = 24.0f;
const XCUIPanelCanvasSession session = host.BeginCanvas(request);
host.EndCanvas();
EXPECT_FALSE(session.validCanvas);
EXPECT_FLOAT_EQ(session.hostRect.height, 180.0f);
EXPECT_FLOAT_EQ(session.canvasRect.y, 24.0f);
EXPECT_FLOAT_EQ(session.canvasRect.height, 156.0f);
XCUIPanelCanvasFrameSnapshot snapshot = {};
ASSERT_TRUE(host.TryGetLatestFrameSnapshot(snapshot));
EXPECT_FALSE(snapshot.session.validCanvas);
EXPECT_EQ(snapshot.overlayDrawData.GetDrawListCount(), 0u);
}
} // namespace