refactor(srp): remove managed frame planning hook

- derive fullscreen stage planning from pipeline render-graph support
- trim planning-only APIs from the managed SRP bridge and public surface
- update probes and tests to lock the slimmer SRP API boundary
This commit is contained in:
2026-04-19 13:47:20 +08:00
parent 08e2b38df2
commit 537d7d99fc
19 changed files with 179 additions and 517 deletions

View File

@@ -45,7 +45,10 @@ void RenderPipelineHost::SetPipelineAsset(std::shared_ptr<const RenderPipelineAs
std::vector<CameraFramePlan> RenderPipelineHost::BuildFramePlans(
const std::vector<CameraRenderRequest>& requests) {
return m_framePlanBuilder != nullptr
? m_framePlanBuilder->BuildPlans(requests, GetPipelineAsset())
? m_framePlanBuilder->BuildPlans(
requests,
GetPipelineAsset(),
GetPipeline())
: std::vector<CameraFramePlan>();
}

View File

@@ -89,17 +89,6 @@ FinalColorSettings ManagedScriptableRenderPipelineAsset::GetDefaultFinalColorSet
return m_executionHostAsset.GetDefaultFinalColorSettings();
}
void ManagedScriptableRenderPipelineAsset::ConfigureCameraFramePlan(
CameraFramePlan& plan) const {
RenderPipelineAsset::ConfigureCameraFramePlan(plan);
if (const std::shared_ptr<const ManagedRenderPipelineAssetRuntime> runtime =
ResolveManagedAssetRuntime();
runtime != nullptr) {
runtime->ConfigureCameraFramePlan(plan);
}
}
void SetManagedRenderPipelineBridge(
std::shared_ptr<const ManagedRenderPipelineBridge> bridge) {
GetGraphicsSettingsState().SetManagedRenderPipelineBridge(

View File

@@ -1,15 +1,76 @@
#include "Rendering/Planning/CameraFramePlanBuilder.h"
#include "Rendering/RenderPipeline.h"
#include "Rendering/RenderPipelineAsset.h"
namespace XCEngine {
namespace Rendering {
namespace {
bool UsesExplicitFullscreenSource(
const FullscreenPassRenderRequest& request,
CameraFrameColorSource source) {
return source == CameraFrameColorSource::ExplicitSurface &&
HasValidColorTarget(request.sourceSurface);
}
void ConfigureFullscreenStagesFromPipeline(
CameraFramePlan& plan,
const RenderPipeline* pipeline) {
const bool supportsPostProcess =
pipeline != nullptr &&
pipeline->SupportsStageRenderGraph(
CameraFrameStage::PostProcess);
const bool supportsFinalOutput =
pipeline != nullptr &&
pipeline->SupportsStageRenderGraph(
CameraFrameStage::FinalOutput);
const bool hasPostProcess =
plan.postProcess.IsRequested() ||
supportsPostProcess;
const bool hasFinalOutput =
plan.finalOutput.IsRequested() ||
supportsFinalOutput;
if (hasPostProcess &&
!UsesExplicitFullscreenSource(
plan.postProcess,
plan.ResolveStageColorSource(
CameraFrameStage::PostProcess))) {
plan.RequestFullscreenStage(
CameraFrameStage::PostProcess,
CameraFrameColorSource::MainSceneColor,
hasFinalOutput);
}
const bool canChainFromPostProcess =
hasPostProcess &&
!UsesExplicitFullscreenSource(
plan.postProcess,
plan.ResolveStageColorSource(
CameraFrameStage::PostProcess));
if (hasFinalOutput &&
!UsesExplicitFullscreenSource(
plan.finalOutput,
plan.ResolveStageColorSource(
CameraFrameStage::FinalOutput))) {
plan.RequestFullscreenStage(
CameraFrameStage::FinalOutput,
canChainFromPostProcess
? CameraFrameColorSource::PostProcessColor
: CameraFrameColorSource::MainSceneColor);
}
}
} // namespace
std::vector<CameraFramePlan> CameraFramePlanBuilder::BuildPlans(
const std::vector<CameraRenderRequest>& requests,
const RenderPipelineAsset* pipelineAsset) {
const RenderPipelineAsset* pipelineAsset,
const RenderPipeline* pipeline) {
std::vector<CameraFramePlan> plans = CreatePlansFromRequests(requests);
ConfigurePlans(plans, pipelineAsset);
ConfigurePlans(plans, pipelineAsset, pipeline);
return plans;
}
@@ -26,13 +87,18 @@ std::vector<CameraFramePlan> CameraFramePlanBuilder::CreatePlansFromRequests(
void CameraFramePlanBuilder::ConfigurePlans(
std::vector<CameraFramePlan>& plans,
const RenderPipelineAsset* pipelineAsset) const {
const RenderPipelineAsset* pipelineAsset,
const RenderPipeline* pipeline) const {
for (CameraFramePlan& plan : plans) {
if (pipelineAsset != nullptr) {
pipelineAsset->ConfigureCameraFramePlan(plan);
} else {
ApplyDefaultRenderPipelineAssetCameraFramePlanPolicy(plan);
}
ConfigureFullscreenStagesFromPipeline(
plan,
pipeline);
}
}

View File

@@ -8,6 +8,7 @@ namespace XCEngine {
namespace Rendering {
class RenderPipelineAsset;
class RenderPipeline;
class CameraFramePlanBuilder {
public:
@@ -18,14 +19,16 @@ public:
std::vector<CameraFramePlan> BuildPlans(
const std::vector<CameraRenderRequest>& requests,
const RenderPipelineAsset* pipelineAsset);
const RenderPipelineAsset* pipelineAsset,
const RenderPipeline* pipeline);
private:
std::vector<CameraFramePlan> CreatePlansFromRequests(
const std::vector<CameraRenderRequest>& requests) const;
void ConfigurePlans(
std::vector<CameraFramePlan>& plans,
const RenderPipelineAsset* pipelineAsset) const;
const RenderPipelineAsset* pipelineAsset,
const RenderPipeline* pipeline) const;
};
} // namespace Rendering

View File

@@ -111,11 +111,6 @@ struct ManagedScriptableRenderPipelineCameraRequestContextState {
size_t renderedRequestCount = 0u;
};
struct ManagedScriptableRenderPipelinePlanningContextState {
uint64_t handle = 0;
Rendering::CameraFramePlan* plan = nullptr;
};
uint64_t& GetManagedScriptableRenderContextNextHandle() {
static uint64_t nextHandle = 1;
return nextHandle;
@@ -279,49 +274,6 @@ void UnregisterManagedScriptableRenderPipelineCameraRequestContextState(
GetManagedScriptableRenderPipelineCameraRequestContextRegistry().erase(handle);
}
uint64_t& GetManagedScriptableRenderPipelinePlanningContextNextHandle() {
static uint64_t nextHandle = 1;
return nextHandle;
}
std::unordered_map<uint64_t, ManagedScriptableRenderPipelinePlanningContextState*>&
GetManagedScriptableRenderPipelinePlanningContextRegistry() {
static std::unordered_map<uint64_t, ManagedScriptableRenderPipelinePlanningContextState*>
registry;
return registry;
}
ManagedScriptableRenderPipelinePlanningContextState*
FindManagedScriptableRenderPipelinePlanningContextState(
uint64_t handle) {
const auto it =
GetManagedScriptableRenderPipelinePlanningContextRegistry().find(handle);
return it != GetManagedScriptableRenderPipelinePlanningContextRegistry().end()
? it->second
: nullptr;
}
uint64_t RegisterManagedScriptableRenderPipelinePlanningContextState(
ManagedScriptableRenderPipelinePlanningContextState& state) {
uint64_t handle =
GetManagedScriptableRenderPipelinePlanningContextNextHandle()++;
if (handle == 0) {
handle = GetManagedScriptableRenderPipelinePlanningContextNextHandle()++;
}
state.handle = handle;
GetManagedScriptableRenderPipelinePlanningContextRegistry()[handle] = &state;
return handle;
}
void UnregisterManagedScriptableRenderPipelinePlanningContextState(uint64_t handle) {
if (handle == 0) {
return;
}
GetManagedScriptableRenderPipelinePlanningContextRegistry().erase(handle);
}
void CleanupMonoRootDomainAtExit() {
MonoRootState& rootState = GetMonoRootState();
if (!rootState.rootDomain) {
@@ -764,9 +716,6 @@ public:
const Rendering::DirectionalShadowPlanningSettings&
directionalShadowSettings) const override;
void ConfigureCameraFramePlan(
Rendering::CameraFramePlan& plan) const override;
bool TryGetDefaultFinalColorSettings(
Rendering::FinalColorSettings& settings) const override;
@@ -789,8 +738,6 @@ private:
MonoMethod* ResolveCreatePipelineMethod(MonoObject* assetObject) const;
MonoMethod* ResolveConfigureCameraRenderRequestMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveConfigureCameraFramePlanMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveGetDefaultFinalColorSettingsMethod(
MonoObject* assetObject) const;
@@ -800,7 +747,6 @@ private:
mutable uint32_t m_assetHandle = 0;
mutable MonoMethod* m_createPipelineMethod = nullptr;
mutable MonoMethod* m_configureCameraRenderRequestMethod = nullptr;
mutable MonoMethod* m_configureCameraFramePlanMethod = nullptr;
mutable MonoMethod* m_getDefaultFinalColorSettingsMethod = nullptr;
mutable bool m_ownsManagedAssetHandle = false;
mutable bool m_assetCreationAttempted = false;
@@ -1081,43 +1027,6 @@ void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest(
requestContextHandle);
}
void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraFramePlan(
Rendering::CameraFramePlan& plan) const {
if (!EnsureManagedAsset()) {
return;
}
MonoObject* const assetObject = GetManagedAssetObject();
MonoMethod* const method =
ResolveConfigureCameraFramePlanMethod(assetObject);
if (assetObject == nullptr || method == nullptr) {
return;
}
ManagedScriptableRenderPipelinePlanningContextState planningContextState = {};
planningContextState.plan = &plan;
const uint64_t planningContextHandle =
RegisterManagedScriptableRenderPipelinePlanningContextState(
planningContextState);
MonoObject* const planningContextObject =
m_runtime->CreateManagedScriptableRenderPipelinePlanningContext(
planningContextHandle);
if (planningContextObject == nullptr) {
UnregisterManagedScriptableRenderPipelinePlanningContextState(
planningContextHandle);
return;
}
void* args[1] = { planningContextObject };
m_runtime->InvokeManagedMethod(
assetObject,
method,
args,
nullptr);
UnregisterManagedScriptableRenderPipelinePlanningContextState(
planningContextHandle);
}
bool MonoManagedRenderPipelineAssetRuntime::TryGetDefaultFinalColorSettings(
Rendering::FinalColorSettings& settings) const {
settings = {};
@@ -1252,7 +1161,6 @@ bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const {
void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
m_createPipelineMethod = nullptr;
m_configureCameraRenderRequestMethod = nullptr;
m_configureCameraFramePlanMethod = nullptr;
m_getDefaultFinalColorSettingsMethod = nullptr;
const bool ownsManagedAssetHandle = m_ownsManagedAssetHandle;
m_ownsManagedAssetHandle = false;
@@ -1303,20 +1211,6 @@ MonoManagedRenderPipelineAssetRuntime::ResolveConfigureCameraRenderRequestMethod
return m_configureCameraRenderRequestMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::ResolveConfigureCameraFramePlanMethod(
MonoObject* assetObject) const {
if (m_configureCameraFramePlanMethod == nullptr) {
m_configureCameraFramePlanMethod =
m_runtime->ResolveManagedMethod(
assetObject,
"ConfigureCameraFramePlan",
1);
}
return m_configureCameraFramePlanMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::ResolveGetDefaultFinalColorSettingsMethod(
MonoObject* assetObject) const {
@@ -3747,47 +3641,6 @@ void InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDi
state->request->directionalShadow = {};
}
void InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage(
uint64_t nativeHandle,
int32_t stage) {
ManagedScriptableRenderPipelinePlanningContextState* const state =
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
const Rendering::CameraFrameStage frameStage =
static_cast<Rendering::CameraFrameStage>(stage);
if (state == nullptr ||
state->plan == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(frameStage)) {
return;
}
state->plan->ClearFullscreenStage(frameStage);
}
mono_bool
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage(
uint64_t nativeHandle,
int32_t stage,
int32_t source,
mono_bool usesGraphManagedOutputColor) {
ManagedScriptableRenderPipelinePlanningContextState* const state =
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
const Rendering::CameraFrameStage frameStage =
static_cast<Rendering::CameraFrameStage>(stage);
if (state == nullptr ||
state->plan == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(frameStage) ||
source == static_cast<int32_t>(Rendering::CameraFrameColorSource::ExplicitSurface)) {
return 0;
}
return state->plan->RequestFullscreenStage(
frameStage,
static_cast<Rendering::CameraFrameColorSource>(source),
usesGraphManagedOutputColor != 0)
? 1
: 0;
}
void RegisterInternalCalls() {
if (GetInternalCallRegistrationState()) {
return;
@@ -3975,8 +3828,6 @@ void RegisterInternalCalls() {
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage));
GetInternalCallRegistrationState() = true;
}
@@ -4036,8 +3887,6 @@ void MonoScriptRuntime::Shutdown() {
GetManagedScriptableRenderContextNextHandle() = 1;
GetManagedScriptableRenderPipelineCameraRequestContextRegistry().clear();
GetManagedScriptableRenderPipelineCameraRequestContextNextHandle() = 1;
GetManagedScriptableRenderPipelinePlanningContextRegistry().clear();
GetManagedScriptableRenderPipelinePlanningContextNextHandle() = 1;
ClearManagedInstances();
ClearExternalManagedObjects();
ClearClassCache();
@@ -4055,12 +3904,10 @@ void MonoScriptRuntime::Shutdown() {
m_scriptableRenderPipelineClass = nullptr;
m_scriptableRenderContextClass = nullptr;
m_scriptableRenderPipelineCameraRequestContextClass = nullptr;
m_scriptableRenderPipelinePlanningContextClass = nullptr;
m_serializeFieldAttributeClass = nullptr;
m_gameObjectConstructor = nullptr;
m_scriptableRenderContextConstructor = nullptr;
m_scriptableRenderPipelineCameraRequestContextConstructor = nullptr;
m_scriptableRenderPipelinePlanningContextConstructor = nullptr;
m_managedGameObjectUUIDField = nullptr;
m_gameObjectUUIDField = nullptr;
m_scriptComponentUUIDField = nullptr;
@@ -4854,27 +4701,6 @@ bool MonoScriptRuntime::DiscoverScriptClasses() {
return false;
}
m_scriptableRenderPipelinePlanningContextClass = mono_class_from_name(
m_coreImage,
kManagedRenderingNamespace,
"ScriptableRenderPipelinePlanningContext");
if (!m_scriptableRenderPipelinePlanningContextClass) {
SetError(
"Failed to locate the managed ScriptableRenderPipelinePlanningContext type.");
return false;
}
m_scriptableRenderPipelinePlanningContextConstructor =
mono_class_get_method_from_name(
m_scriptableRenderPipelinePlanningContextClass,
".ctor",
1);
if (!m_scriptableRenderPipelinePlanningContextConstructor) {
SetError(
"Failed to locate the managed ScriptableRenderPipelinePlanningContext constructor.");
return false;
}
m_serializeFieldAttributeClass = mono_class_from_name(
m_coreImage,
m_settings.baseNamespace.c_str(),
@@ -5470,45 +5296,6 @@ MonoScriptRuntime::CreateManagedScriptableRenderPipelineCameraRequestContext(
return contextObject;
}
MonoObject* MonoScriptRuntime::CreateManagedScriptableRenderPipelinePlanningContext(
uint64_t nativeHandle) {
if (!m_initialized ||
nativeHandle == 0 ||
m_scriptableRenderPipelinePlanningContextClass == nullptr ||
m_scriptableRenderPipelinePlanningContextConstructor == nullptr) {
return nullptr;
}
SetCurrentDomain();
MonoObject* const contextObject =
mono_object_new(
m_appDomain,
m_scriptableRenderPipelinePlanningContextClass);
if (contextObject == nullptr) {
SetError(
"Mono failed to allocate a managed ScriptableRenderPipelinePlanningContext.");
return nullptr;
}
void* args[1];
uint64_t nativeHandleArgument = nativeHandle;
args[0] = &nativeHandleArgument;
MonoObject* exception = nullptr;
mono_runtime_invoke(
m_scriptableRenderPipelinePlanningContextConstructor,
contextObject,
args,
&exception);
if (exception != nullptr) {
RecordException(exception);
return nullptr;
}
return contextObject;
}
MonoScriptRuntime::InstanceData* MonoScriptRuntime::FindInstance(const ScriptRuntimeContext& context) {
const auto it = m_instances.find(InstanceKey{context.gameObjectUUID, context.scriptComponentUUID});
return it != m_instances.end() ? &it->second : nullptr;