refactor(srp): bind managed native scene renderers per renderer selection

This commit is contained in:
2026-04-21 01:34:13 +08:00
parent c60f3db80d
commit 383d1e9c73
6 changed files with 277 additions and 49 deletions

View File

@@ -1272,6 +1272,8 @@ public:
Rendering::FinalColorSettings& settings) const override;
std::shared_ptr<const Rendering::RenderPipelineAsset>
GetPipelineRendererAsset() const override;
std::shared_ptr<const Rendering::RenderPipelineAsset>
GetPipelineRendererAsset(int32_t rendererIndex) const override;
MonoScriptRuntime* GetRuntime() const {
return m_runtime;
@@ -1304,6 +1306,8 @@ private:
MonoObject* assetObject) const;
MonoMethod* ResolveGetPipelineRendererAssetKeyMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveGetPipelineRendererAssetKeyContextualMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveReleaseRuntimeResourcesMethod(
MonoObject* assetObject) const;
@@ -1318,6 +1322,8 @@ private:
mutable MonoMethod* m_getDefaultFinalColorSettingsMethod = nullptr;
mutable MonoMethod* m_getRuntimeResourceVersionMethod = nullptr;
mutable MonoMethod* m_getPipelineRendererAssetKeyMethod = nullptr;
mutable MonoMethod* m_getPipelineRendererAssetKeyContextualMethod =
nullptr;
mutable MonoMethod* m_releaseRuntimeResourcesMethod = nullptr;
mutable bool m_ownsManagedAssetHandle = false;
mutable bool m_assetCreationAttempted = false;
@@ -1328,6 +1334,10 @@ private:
mutable bool m_pipelineRendererAssetResolved = false;
mutable std::shared_ptr<const Rendering::RenderPipelineAsset>
m_pipelineRendererAsset = nullptr;
mutable std::unordered_map<
int32_t,
std::shared_ptr<const Rendering::RenderPipelineAsset>>
m_contextualPipelineRendererAssets = {};
};
class MonoManagedRenderPipelineStageRecorder final
@@ -1472,7 +1482,7 @@ public:
managedContextState.stage = context.stage;
managedContextState.graphContext = &context;
Rendering::NativeSceneRenderer* const sceneRenderer =
ResolveSceneRenderer();
ResolveSceneRenderer(context.rendererIndex);
if (sceneRenderer == nullptr) {
return false;
}
@@ -1658,25 +1668,40 @@ private:
return true;
}
Rendering::NativeSceneRenderer* ResolveSceneRenderer() {
if (m_boundSceneRenderer != nullptr) {
return m_boundSceneRenderer;
}
Rendering::NativeSceneRenderer* ResolveSceneRenderer(
int32_t rendererIndex) {
const std::shared_ptr<const Rendering::RenderPipelineAsset>
pipelineRendererAsset =
contextualPipelineRendererAsset =
m_assetRuntime != nullptr
? m_assetRuntime->GetPipelineRendererAsset(
rendererIndex)
: nullptr;
const std::shared_ptr<const Rendering::RenderPipelineAsset>
defaultPipelineRendererAsset =
m_assetRuntime != nullptr
? m_assetRuntime->GetPipelineRendererAsset()
: nullptr;
if (m_boundSceneRenderer != nullptr &&
contextualPipelineRendererAsset != nullptr &&
contextualPipelineRendererAsset ==
defaultPipelineRendererAsset) {
return m_boundSceneRenderer;
}
if (contextualPipelineRendererAsset == nullptr) {
return nullptr;
}
if (m_ownedSceneRenderer == nullptr ||
pipelineRendererAsset != m_ownedPipelineRendererAsset) {
contextualPipelineRendererAsset != m_ownedPipelineRendererAsset) {
if (m_ownedSceneRenderer != nullptr) {
m_ownedSceneRenderer->Shutdown();
}
m_ownedSceneRenderer =
Rendering::Internal::CreateNativeSceneRendererFromAsset(
pipelineRendererAsset);
m_ownedPipelineRendererAsset = pipelineRendererAsset;
contextualPipelineRendererAsset);
m_ownedPipelineRendererAsset =
contextualPipelineRendererAsset;
}
return m_ownedSceneRenderer.get();
@@ -1819,41 +1844,102 @@ bool MonoManagedRenderPipelineAssetRuntime::TryGetDefaultFinalColorSettings(
std::shared_ptr<const Rendering::RenderPipelineAsset>
MonoManagedRenderPipelineAssetRuntime::GetPipelineRendererAsset() const {
return GetPipelineRendererAsset(-1);
}
std::shared_ptr<const Rendering::RenderPipelineAsset>
MonoManagedRenderPipelineAssetRuntime::GetPipelineRendererAsset(
int32_t rendererIndex) const {
if (!SyncManagedAssetRuntimeState()) {
return nullptr;
}
if (rendererIndex >= 0) {
const auto contextualIt =
m_contextualPipelineRendererAssets.find(rendererIndex);
if (contextualIt != m_contextualPipelineRendererAssets.end()) {
return contextualIt->second;
}
}
if (m_pipelineRendererAssetResolved) {
return m_pipelineRendererAsset;
if (rendererIndex < 0) {
return m_pipelineRendererAsset;
}
}
MonoObject* const assetObject = GetManagedAssetObject();
if (assetObject == nullptr) {
return nullptr;
}
std::string pipelineRendererAssetKey = {};
MonoMethod* const contextualMethod =
ResolveGetPipelineRendererAssetKeyContextualMethod(assetObject);
if (contextualMethod != nullptr) {
void* args[1] = { &rendererIndex };
MonoObject* managedKeyObject = nullptr;
if (!m_runtime->InvokeManagedMethod(
assetObject,
contextualMethod,
args,
&managedKeyObject)) {
return nullptr;
}
pipelineRendererAssetKey =
MonoStringToUtf8(
reinterpret_cast<MonoString*>(managedKeyObject));
} else {
if (rendererIndex >= 0) {
if (m_pipelineRendererAssetResolved) {
return m_pipelineRendererAsset;
}
}
MonoMethod* const method =
ResolveGetPipelineRendererAssetKeyMethod(assetObject);
if (method == nullptr) {
return nullptr;
}
MonoObject* managedKeyObject = nullptr;
if (!m_runtime->InvokeManagedMethod(
assetObject,
method,
nullptr,
&managedKeyObject)) {
return nullptr;
}
pipelineRendererAssetKey =
MonoStringToUtf8(
reinterpret_cast<MonoString*>(managedKeyObject));
}
std::shared_ptr<const Rendering::RenderPipelineAsset>
pipelineRendererAsset = nullptr;
if (pipelineRendererAssetKey.empty()) {
if (rendererIndex >= 0) {
m_contextualPipelineRendererAssets[rendererIndex] = nullptr;
} else {
m_pipelineRendererAssetResolved = true;
m_pipelineRendererAsset.reset();
}
return nullptr;
}
pipelineRendererAsset =
Rendering::Internal::CreatePipelineRendererAssetByKey(
pipelineRendererAssetKey);
if (rendererIndex >= 0) {
m_contextualPipelineRendererAssets[rendererIndex] =
pipelineRendererAsset;
return pipelineRendererAsset;
}
m_pipelineRendererAssetResolved = true;
m_pipelineRendererAsset.reset();
MonoObject* const assetObject = GetManagedAssetObject();
MonoMethod* const method =
ResolveGetPipelineRendererAssetKeyMethod(assetObject);
if (assetObject == nullptr || method == nullptr) {
return nullptr;
}
MonoObject* managedKeyObject = nullptr;
if (!m_runtime->InvokeManagedMethod(
assetObject,
method,
nullptr,
&managedKeyObject)) {
return nullptr;
}
const std::string pipelineRendererAssetKey =
MonoStringToUtf8(reinterpret_cast<MonoString*>(managedKeyObject));
if (pipelineRendererAssetKey.empty()) {
return nullptr;
}
m_pipelineRendererAsset =
Rendering::Internal::CreatePipelineRendererAssetByKey(
pipelineRendererAssetKey);
m_pipelineRendererAsset = pipelineRendererAsset;
return m_pipelineRendererAsset;
}
@@ -1996,6 +2082,7 @@ bool MonoManagedRenderPipelineAssetRuntime::SyncManagedAssetRuntimeState() const
ReleaseManagedPipeline();
m_pipelineRendererAsset.reset();
m_pipelineRendererAssetResolved = false;
m_contextualPipelineRendererAssets.clear();
m_runtimeResourceVersion = runtimeResourceVersion;
return true;
}
@@ -2062,8 +2149,10 @@ void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
m_getDefaultFinalColorSettingsMethod = nullptr;
m_getRuntimeResourceVersionMethod = nullptr;
m_getPipelineRendererAssetKeyMethod = nullptr;
m_getPipelineRendererAssetKeyContextualMethod = nullptr;
m_pipelineRendererAsset.reset();
m_pipelineRendererAssetResolved = false;
m_contextualPipelineRendererAssets.clear();
m_runtimeResourceVersionResolved = false;
m_runtimeResourceVersion = 0;
const bool ownsManagedAssetHandle = m_ownsManagedAssetHandle;
@@ -2195,6 +2284,20 @@ MonoManagedRenderPipelineAssetRuntime::ResolveGetPipelineRendererAssetKeyMethod(
return m_getPipelineRendererAssetKeyMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::ResolveGetPipelineRendererAssetKeyContextualMethod(
MonoObject* assetObject) const {
if (m_getPipelineRendererAssetKeyContextualMethod == nullptr) {
m_getPipelineRendererAssetKeyContextualMethod =
m_runtime->ResolveManagedMethod(
assetObject,
"GetPipelineRendererAssetKeyContextual",
1);
}
return m_getPipelineRendererAssetKeyContextualMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::ResolveReleaseRuntimeResourcesMethod(
MonoObject* assetObject) const {