refactor(srp): decouple managed pipeline assets from fixed native backend

This commit is contained in:
2026-04-19 21:46:05 +08:00
parent 20e727e882
commit 74e790891c
4 changed files with 283 additions and 3 deletions

View File

@@ -775,11 +775,13 @@ private:
struct MockManagedRenderPipelineAssetRuntimeState {
int createStageRecorderCalls = 0;
int configureCameraRenderRequestCalls = 0;
int getPipelineRendererAssetCalls = 0;
int getDefaultFinalColorSettingsCalls = 0;
bool hasDefaultFinalColorSettings = false;
FinalColorSettings defaultFinalColorSettings = {};
size_t lastRenderedBaseCameraCount = 0u;
size_t lastRenderedRequestCount = 0u;
std::shared_ptr<const RenderPipelineAsset> pipelineRendererAsset = nullptr;
std::shared_ptr<MockStageRecorderState> lastCreatedStageRecorderState;
std::function<void(
CameraRenderRequest&,
@@ -822,6 +824,12 @@ public:
}
}
std::shared_ptr<const RenderPipelineAsset>
GetPipelineRendererAsset() const override {
++m_state->getPipelineRendererAssetCalls;
return m_state->pipelineRendererAsset;
}
bool TryGetDefaultFinalColorSettings(
FinalColorSettings& settings) const override {
++m_state->getDefaultFinalColorSettingsCalls;
@@ -843,6 +851,7 @@ struct MockManagedRenderPipelineBridgeState {
std::shared_ptr<MockManagedRenderPipelineAssetRuntimeState> lastCreatedRuntimeState;
bool hasDefaultFinalColorSettings = false;
FinalColorSettings defaultFinalColorSettings = {};
std::shared_ptr<const RenderPipelineAsset> pipelineRendererAsset = nullptr;
std::function<void(
CameraRenderRequest&,
size_t,
@@ -869,6 +878,8 @@ public:
m_state->hasDefaultFinalColorSettings;
m_state->lastCreatedRuntimeState->defaultFinalColorSettings =
m_state->defaultFinalColorSettings;
m_state->lastCreatedRuntimeState->pipelineRendererAsset =
m_state->pipelineRendererAsset;
m_state->lastCreatedRuntimeState->configureCameraRenderRequest =
m_state->configureCameraRenderRequest;
return std::make_shared<MockManagedRenderPipelineAssetRuntime>(
@@ -4591,6 +4602,9 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, CreatesHostWithStageRecorderFrom
EXPECT_EQ(bridgeState->lastDescriptor.className, "ManagedRenderPipelineProbeAsset");
ASSERT_NE(bridgeState->lastCreatedRuntimeState, nullptr);
EXPECT_EQ(
bridgeState->lastCreatedRuntimeState->getPipelineRendererAssetCalls,
1);
ASSERT_NE(
bridgeState->lastCreatedRuntimeState->lastCreatedStageRecorderState,
nullptr);
@@ -4602,6 +4616,42 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, CreatesHostWithStageRecorderFrom
Pipelines::ClearManagedRenderPipelineBridge();
}
TEST(
ManagedScriptableRenderPipelineAsset_Test,
UsesRuntimeProvidedPipelineRendererAssetForHostComposition) {
Pipelines::ClearManagedRenderPipelineBridge();
const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
"GameScripts",
"Gameplay",
"ManagedRenderPipelineProbeAsset"
};
auto bridgeState = std::make_shared<MockManagedRenderPipelineBridgeState>();
auto rendererAssetState = std::make_shared<MockPipelineAssetState>();
auto rendererAsset = std::make_shared<MockPipelineAsset>(rendererAssetState);
bridgeState->pipelineRendererAsset = rendererAsset;
Pipelines::SetManagedRenderPipelineBridge(
std::make_shared<MockManagedRenderPipelineBridge>(bridgeState));
Pipelines::ManagedScriptableRenderPipelineAsset asset(descriptor);
std::unique_ptr<RenderPipeline> pipeline = asset.CreatePipeline();
ASSERT_NE(pipeline, nullptr);
auto* host =
dynamic_cast<Pipelines::ScriptableRenderPipelineHost*>(pipeline.get());
ASSERT_NE(host, nullptr);
EXPECT_EQ(host->GetPipelineRendererAsset(), rendererAsset.get());
EXPECT_NE(host->GetPipelineRenderer(), nullptr);
EXPECT_NE(host->GetStageRecorder(), nullptr);
EXPECT_EQ(rendererAssetState->createCalls, 1);
ASSERT_NE(bridgeState->lastCreatedRuntimeState, nullptr);
EXPECT_EQ(
bridgeState->lastCreatedRuntimeState->getPipelineRendererAssetCalls,
1);
Pipelines::ClearManagedRenderPipelineBridge();
}
TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeConfigureCameraRenderRequests) {
Pipelines::ClearManagedRenderPipelineBridge();
@@ -4714,6 +4764,58 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeProvideDefaultF
Pipelines::ClearManagedRenderPipelineBridge();
}
TEST(
ManagedScriptableRenderPipelineAsset_Test,
FallsBackToRuntimeProvidedPipelineRendererAssetDefaultFinalColorSettings) {
Pipelines::ClearManagedRenderPipelineBridge();
const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
"GameScripts",
"Gameplay",
"ManagedFinalColorRenderPipelineProbeAsset"
};
auto bridgeState = std::make_shared<MockManagedRenderPipelineBridgeState>();
auto rendererAssetState = std::make_shared<MockPipelineAssetState>();
rendererAssetState->defaultFinalColorSettings.outputTransferMode =
FinalColorOutputTransferMode::LinearToSRGB;
rendererAssetState->defaultFinalColorSettings.exposureMode =
FinalColorExposureMode::Fixed;
rendererAssetState->defaultFinalColorSettings.exposureValue = 2.25f;
rendererAssetState->defaultFinalColorSettings.toneMappingMode =
FinalColorToneMappingMode::ACES;
rendererAssetState->defaultFinalColorSettings.finalColorScale =
XCEngine::Math::Vector4(1.02f, 0.97f, 0.93f, 1.0f);
bridgeState->pipelineRendererAsset =
std::make_shared<MockPipelineAsset>(rendererAssetState);
Pipelines::SetManagedRenderPipelineBridge(
std::make_shared<MockManagedRenderPipelineBridge>(bridgeState));
Pipelines::ManagedScriptableRenderPipelineAsset asset(descriptor);
const FinalColorSettings settings = asset.GetDefaultFinalColorSettings();
EXPECT_EQ(bridgeState->createAssetRuntimeCalls, 1);
ASSERT_NE(bridgeState->lastCreatedRuntimeState, nullptr);
EXPECT_EQ(
bridgeState->lastCreatedRuntimeState->getDefaultFinalColorSettingsCalls,
1);
EXPECT_EQ(
bridgeState->lastCreatedRuntimeState->getPipelineRendererAssetCalls,
1);
EXPECT_EQ(rendererAssetState->createCalls, 0);
EXPECT_EQ(
settings.outputTransferMode,
FinalColorOutputTransferMode::LinearToSRGB);
EXPECT_EQ(settings.exposureMode, FinalColorExposureMode::Fixed);
EXPECT_FLOAT_EQ(settings.exposureValue, 2.25f);
EXPECT_EQ(settings.toneMappingMode, FinalColorToneMappingMode::ACES);
EXPECT_FLOAT_EQ(settings.finalColorScale.x, 1.02f);
EXPECT_FLOAT_EQ(settings.finalColorScale.y, 0.97f);
EXPECT_FLOAT_EQ(settings.finalColorScale.z, 0.93f);
EXPECT_FLOAT_EQ(settings.finalColorScale.w, 1.0f);
Pipelines::ClearManagedRenderPipelineBridge();
}
TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossPipelineAndRequestCalls) {
Pipelines::ClearManagedRenderPipelineBridge();