Files
XCEngine/tests/NewEditor/test_xcui_rhi_command_support.cpp

203 lines
7.8 KiB
C++
Raw Normal View History

2026-04-05 04:55:25 +08:00
#include <gtest/gtest.h>
#include "XCUIBackend/XCUIRHICommandSupport.h"
#include <string>
namespace {
using XCEngine::Editor::XCUIBackend::AccumulateXCUIRHICommandSupport;
using XCEngine::Editor::XCUIBackend::AnalyzeXCUIRHICommandSupport;
using XCEngine::Editor::XCUIBackend::BuildXCUIRHICommandSupportDiagnostic;
using XCEngine::Editor::XCUIBackend::ClassifyXCUIRHICommandSupport;
using XCEngine::Editor::XCUIBackend::SummarizeXCUIRHICommandSupport;
using XCEngine::Editor::XCUIBackend::XCUIRHICommandCategory;
using XCEngine::Editor::XCUIBackend::XCUIRHICommandDiagnosticOptions;
using XCEngine::Editor::XCUIBackend::XCUIRHICommandSupportReason;
using XCEngine::Editor::XCUIBackend::XCUIRHICommandSupportStats;
using XCEngine::UI::UIColor;
using XCEngine::UI::UIDrawCommand;
using XCEngine::UI::UIDrawCommandType;
using XCEngine::UI::UIDrawData;
using XCEngine::UI::UIDrawList;
using XCEngine::UI::UIPoint;
using XCEngine::UI::UIRect;
using XCEngine::UI::UITextureHandle;
using XCEngine::UI::UITextureHandleKind;
UITextureHandle MakeShaderResourceTexture() {
UITextureHandle texture = {};
texture.nativeHandle = 42u;
texture.width = 64u;
texture.height = 64u;
texture.kind = UITextureHandleKind::ShaderResourceView;
return texture;
}
UIDrawCommand MakeUnknownCommand() {
UIDrawCommand command = {};
command.type = static_cast<UIDrawCommandType>(255);
return command;
}
} // namespace
TEST(XCUIRHICommandSupportTest, ClassifySupportedCommandTypes) {
UIDrawList drawList("Supported");
drawList.AddFilledRect(UIRect(0.0f, 0.0f, 12.0f, 10.0f), UIColor(1.0f, 0.0f, 0.0f, 1.0f));
drawList.AddRectOutline(
UIRect(1.0f, 2.0f, 8.0f, 5.0f),
UIColor(0.0f, 1.0f, 0.0f, 1.0f),
2.0f,
1.0f);
drawList.AddText(UIPoint(4.0f, 5.0f), "label", UIColor(1.0f, 1.0f, 1.0f, 1.0f), 14.0f);
drawList.AddImage(
UIRect(2.0f, 3.0f, 18.0f, 14.0f),
MakeShaderResourceTexture(),
UIColor(1.0f, 1.0f, 1.0f, 1.0f));
drawList.PushClipRect(UIRect(0.0f, 0.0f, 24.0f, 20.0f));
drawList.PopClipRect();
const auto& commands = drawList.GetCommands();
EXPECT_EQ(
ClassifyXCUIRHICommandSupport(commands[0]).category,
XCUIRHICommandCategory::FilledRect);
EXPECT_EQ(
ClassifyXCUIRHICommandSupport(commands[1]).category,
XCUIRHICommandCategory::RectOutline);
EXPECT_EQ(
ClassifyXCUIRHICommandSupport(commands[2]).category,
XCUIRHICommandCategory::Text);
EXPECT_EQ(
ClassifyXCUIRHICommandSupport(commands[3]).category,
XCUIRHICommandCategory::Image);
EXPECT_EQ(
ClassifyXCUIRHICommandSupport(commands[4]).category,
XCUIRHICommandCategory::PushClipRect);
EXPECT_EQ(
ClassifyXCUIRHICommandSupport(commands[5]).category,
XCUIRHICommandCategory::PopClipRect);
for (const UIDrawCommand& command : commands) {
EXPECT_TRUE(ClassifyXCUIRHICommandSupport(command).IsSupported());
}
}
TEST(XCUIRHICommandSupportTest, InvalidImageCommandIsClassifiedAsUnsupportedTexture) {
UIDrawCommand command = {};
command.type = UIDrawCommandType::Image;
command.rect = UIRect(0.0f, 0.0f, 12.0f, 12.0f);
command.texture.nativeHandle = 7u;
command.texture.width = 32u;
command.texture.height = 32u;
command.texture.kind = UITextureHandleKind::ImGuiDescriptor;
const auto classification = ClassifyXCUIRHICommandSupport(command);
EXPECT_EQ(classification.category, XCUIRHICommandCategory::Image);
EXPECT_EQ(
classification.supportReason,
XCUIRHICommandSupportReason::UnsupportedImageTexture);
EXPECT_FALSE(classification.IsSupported());
}
TEST(XCUIRHICommandSupportTest, UnknownCommandTypeIsClassifiedSeparately) {
const auto classification = ClassifyXCUIRHICommandSupport(MakeUnknownCommand());
EXPECT_EQ(classification.category, XCUIRHICommandCategory::Unknown);
EXPECT_EQ(
classification.supportReason,
XCUIRHICommandSupportReason::UnsupportedUnknownCommand);
EXPECT_FALSE(classification.IsSupported());
}
TEST(XCUIRHICommandSupportTest, AnalyzeDrawDataAggregatesSupportedAndUnsupportedCounts) {
UIDrawData drawData = {};
UIDrawList& firstDrawList = drawData.EmplaceDrawList("First");
firstDrawList.AddFilledRect(
UIRect(0.0f, 0.0f, 8.0f, 8.0f),
UIColor(1.0f, 0.0f, 0.0f, 1.0f));
firstDrawList.AddImage(
UIRect(2.0f, 2.0f, 12.0f, 10.0f),
MakeShaderResourceTexture(),
UIColor(1.0f, 1.0f, 1.0f, 1.0f));
UIDrawList& secondDrawList = drawData.EmplaceDrawList("Second");
secondDrawList.PushClipRect(UIRect(0.0f, 0.0f, 100.0f, 60.0f));
secondDrawList.AddText(
UIPoint(5.0f, 6.0f),
"status",
UIColor(1.0f, 1.0f, 1.0f, 1.0f),
12.0f);
UITextureHandle invalidTexture = {};
invalidTexture.nativeHandle = 9u;
invalidTexture.width = 32u;
invalidTexture.height = 32u;
invalidTexture.kind = UITextureHandleKind::ImGuiDescriptor;
secondDrawList.AddImage(
UIRect(1.0f, 1.0f, 6.0f, 6.0f),
invalidTexture,
UIColor(1.0f, 1.0f, 1.0f, 1.0f));
const auto stats = AnalyzeXCUIRHICommandSupport(drawData);
EXPECT_EQ(stats.drawListCount, 2u);
EXPECT_EQ(stats.commandCount, 5u);
EXPECT_EQ(stats.filledRectCommandCount, 1u);
EXPECT_EQ(stats.textCommandCount, 1u);
EXPECT_EQ(stats.imageCommandCount, 2u);
EXPECT_EQ(stats.clipPushCommandCount, 1u);
EXPECT_EQ(stats.clipPopCommandCount, 0u);
EXPECT_EQ(stats.supportedCommandCount, 4u);
EXPECT_EQ(stats.unsupportedCommandCount, 1u);
EXPECT_EQ(stats.unsupportedImageCommandCount, 1u);
EXPECT_EQ(stats.unsupportedUnknownCommandCount, 0u);
EXPECT_FALSE(stats.SupportsAllCommands());
}
TEST(XCUIRHICommandSupportTest, DiagnosticIncludesUnsupportedReasonsAndCanBeCustomized) {
XCUIRHICommandSupportStats stats = {};
AccumulateXCUIRHICommandSupport(MakeUnknownCommand(), stats);
UIDrawCommand invalidImage = {};
invalidImage.type = UIDrawCommandType::Image;
invalidImage.texture.nativeHandle = 11u;
invalidImage.texture.width = 16u;
invalidImage.texture.height = 16u;
invalidImage.texture.kind = UITextureHandleKind::ImGuiDescriptor;
AccumulateXCUIRHICommandSupport(invalidImage, stats);
const std::string defaultDiagnostic = BuildXCUIRHICommandSupportDiagnostic(stats);
EXPECT_NE(defaultDiagnostic.find("2 command(s) will be skipped by native overlay: "), std::string::npos);
EXPECT_NE(defaultDiagnostic.find("1 image command(s) missing valid ShaderResourceView textures"), std::string::npos);
EXPECT_NE(defaultDiagnostic.find("1 unknown command type(s)"), std::string::npos);
XCUIRHICommandDiagnosticOptions options = {};
options.noCommandsMessage = "No overlay commands.";
options.allSupportedMessage = "Everything supported.";
options.unsupportedPrefix = "command(s) rejected:";
const std::string customDiagnostic = BuildXCUIRHICommandSupportDiagnostic(stats, options);
EXPECT_NE(customDiagnostic.find("2 command(s) rejected:"), std::string::npos);
}
TEST(XCUIRHICommandSupportTest, SummaryReturnsNoCommandAndAllSupportedMessages) {
const auto emptySummary = SummarizeXCUIRHICommandSupport(UIDrawData());
EXPECT_EQ(emptySummary.stats.commandCount, 0u);
EXPECT_EQ(emptySummary.diagnostic, "Overlay runtime produced no commands.");
UIDrawData drawData = {};
UIDrawList& drawList = drawData.EmplaceDrawList("Supported");
drawList.AddFilledRect(
UIRect(0.0f, 0.0f, 4.0f, 4.0f),
UIColor(0.2f, 0.4f, 0.8f, 1.0f));
const auto supportedSummary = SummarizeXCUIRHICommandSupport(drawData);
EXPECT_EQ(supportedSummary.stats.supportedCommandCount, 1u);
EXPECT_TRUE(supportedSummary.stats.SupportsAllCommands());
EXPECT_EQ(supportedSummary.diagnostic, "All commands preflight for native overlay.");
}