refactor(srp): unify managed pipeline instance ownership
Move shared managed ScriptableRenderPipeline instance ownership into MonoManagedRenderPipelineAssetRuntime. Make stage recorders borrow the runtime-owned pipeline instead of creating and destroying private handles. Add a regression test that locks one CreatePipeline call across multiple stage recorders.
This commit is contained in:
@@ -731,10 +731,11 @@ public:
|
||||
m_runtime->m_initialized;
|
||||
}
|
||||
|
||||
bool CreateManagedPipeline(uint32_t& outPipelineHandle) const;
|
||||
bool AcquireManagedPipelineHandle(uint32_t& outPipelineHandle) const;
|
||||
|
||||
private:
|
||||
bool EnsureManagedAsset() const;
|
||||
void ReleaseManagedPipeline() const;
|
||||
void ReleaseManagedAsset() const;
|
||||
MonoObject* GetManagedAssetObject() const;
|
||||
MonoMethod* ResolveCreatePipelineMethod(MonoObject* assetObject) const;
|
||||
@@ -755,6 +756,8 @@ private:
|
||||
mutable MonoMethod* m_getPipelineRendererAssetKeyMethod = nullptr;
|
||||
mutable bool m_ownsManagedAssetHandle = false;
|
||||
mutable bool m_assetCreationAttempted = false;
|
||||
mutable uint32_t m_pipelineHandle = 0;
|
||||
mutable bool m_pipelineCreationAttempted = false;
|
||||
mutable bool m_pipelineRendererAssetResolved = false;
|
||||
mutable std::shared_ptr<const Rendering::RenderPipelineAsset>
|
||||
m_pipelineRendererAsset = nullptr;
|
||||
@@ -777,7 +780,7 @@ public:
|
||||
}
|
||||
|
||||
bool Initialize(const Rendering::RenderContext&) override {
|
||||
return EnsureManagedPipeline();
|
||||
return GetManagedPipelineObject() != nullptr;
|
||||
}
|
||||
|
||||
void Shutdown() override {
|
||||
@@ -791,10 +794,8 @@ public:
|
||||
if (m_ownedSceneRenderer != nullptr) {
|
||||
m_ownedSceneRenderer->Shutdown();
|
||||
}
|
||||
ReleaseManagedObjects();
|
||||
m_supportsStageMethod = nullptr;
|
||||
m_recordStageMethod = nullptr;
|
||||
m_pipelineCreationAttempted = false;
|
||||
m_boundSceneRenderer = nullptr;
|
||||
}
|
||||
|
||||
@@ -806,12 +807,11 @@ public:
|
||||
|
||||
bool SupportsStageRenderGraph(Rendering::CameraFrameStage stage) const override {
|
||||
if (!SupportsManagedRenderPipelineStageGraphRecording(stage) ||
|
||||
!EnsureManagedPipeline()) {
|
||||
!IsRuntimeAlive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MonoObject* const pipelineObject =
|
||||
m_runtime->GetManagedObject(m_pipelineHandle);
|
||||
MonoObject* const pipelineObject = GetManagedPipelineObject();
|
||||
MonoMethod* const method = ResolveSupportsStageMethod(pipelineObject);
|
||||
if (!pipelineObject || !method) {
|
||||
return false;
|
||||
@@ -834,12 +834,11 @@ public:
|
||||
|
||||
bool RecordStageRenderGraph(
|
||||
const Rendering::RenderPipelineStageRenderGraphContext& context) override {
|
||||
if (!EnsureManagedPipeline()) {
|
||||
if (!IsRuntimeAlive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MonoObject* const pipelineObject =
|
||||
m_runtime->GetManagedObject(m_pipelineHandle);
|
||||
MonoObject* const pipelineObject = GetManagedPipelineObject();
|
||||
MonoMethod* const method = ResolveRecordStageMethod(pipelineObject);
|
||||
if (!pipelineObject || !method) {
|
||||
return false;
|
||||
@@ -895,30 +894,18 @@ private:
|
||||
m_runtime != nullptr;
|
||||
}
|
||||
|
||||
bool EnsureManagedPipeline() const {
|
||||
if (m_pipelineHandle != 0) {
|
||||
return true;
|
||||
}
|
||||
if (m_pipelineCreationAttempted || !IsRuntimeAlive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pipelineCreationAttempted = true;
|
||||
|
||||
return m_assetRuntime->CreateManagedPipeline(m_pipelineHandle) &&
|
||||
m_pipelineHandle != 0;
|
||||
}
|
||||
|
||||
void ReleaseManagedObjects() {
|
||||
MonoObject* GetManagedPipelineObject() const {
|
||||
if (!IsRuntimeAlive()) {
|
||||
m_pipelineHandle = 0;
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (m_pipelineHandle != 0) {
|
||||
m_runtime->DestroyExternalManagedObject(m_pipelineHandle);
|
||||
m_pipelineHandle = 0;
|
||||
uint32_t pipelineHandle = 0;
|
||||
if (!m_assetRuntime->AcquireManagedPipelineHandle(pipelineHandle) ||
|
||||
pipelineHandle == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_runtime->GetManagedObject(pipelineHandle);
|
||||
}
|
||||
|
||||
MonoMethod* ResolveSupportsStageMethod(MonoObject* pipelineObject) const {
|
||||
@@ -998,10 +985,8 @@ private:
|
||||
|
||||
std::shared_ptr<const MonoManagedRenderPipelineAssetRuntime> m_assetRuntime;
|
||||
MonoScriptRuntime* m_runtime = nullptr;
|
||||
mutable uint32_t m_pipelineHandle = 0;
|
||||
mutable MonoMethod* m_supportsStageMethod = nullptr;
|
||||
mutable MonoMethod* m_recordStageMethod = nullptr;
|
||||
mutable bool m_pipelineCreationAttempted = false;
|
||||
std::vector<std::unique_ptr<Rendering::RenderPass>> m_fullscreenPassPool = {};
|
||||
Rendering::NativeSceneRenderer* m_boundSceneRenderer = nullptr;
|
||||
std::unique_ptr<Rendering::NativeSceneRenderer> m_ownedSceneRenderer =
|
||||
@@ -1131,17 +1116,28 @@ MonoManagedRenderPipelineAssetRuntime::GetPipelineRendererAsset() const {
|
||||
return m_pipelineRendererAsset;
|
||||
}
|
||||
|
||||
bool MonoManagedRenderPipelineAssetRuntime::CreateManagedPipeline(
|
||||
bool MonoManagedRenderPipelineAssetRuntime::AcquireManagedPipelineHandle(
|
||||
uint32_t& outPipelineHandle) const {
|
||||
outPipelineHandle = 0;
|
||||
if (!EnsureManagedAsset()) {
|
||||
if (m_pipelineHandle != 0) {
|
||||
outPipelineHandle = m_pipelineHandle;
|
||||
return true;
|
||||
}
|
||||
if (m_pipelineCreationAttempted) {
|
||||
outPipelineHandle = 0;
|
||||
return false;
|
||||
}
|
||||
if (!EnsureManagedAsset()) {
|
||||
outPipelineHandle = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pipelineCreationAttempted = true;
|
||||
|
||||
MonoObject* const assetObject = GetManagedAssetObject();
|
||||
MonoMethod* const createPipelineMethod =
|
||||
ResolveCreatePipelineMethod(assetObject);
|
||||
if (assetObject == nullptr || createPipelineMethod == nullptr) {
|
||||
outPipelineHandle = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1152,6 +1148,7 @@ bool MonoManagedRenderPipelineAssetRuntime::CreateManagedPipeline(
|
||||
nullptr,
|
||||
&pipelineObject) ||
|
||||
pipelineObject == nullptr) {
|
||||
outPipelineHandle = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1161,11 +1158,13 @@ bool MonoManagedRenderPipelineAssetRuntime::CreateManagedPipeline(
|
||||
m_runtime->SetError(
|
||||
"Managed render pipeline asset returned a non-ScriptableRenderPipeline instance: " +
|
||||
m_descriptor.GetFullName() + ".");
|
||||
outPipelineHandle = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
outPipelineHandle = m_runtime->RetainExternalManagedObject(pipelineObject);
|
||||
return outPipelineHandle != 0;
|
||||
m_pipelineHandle = m_runtime->RetainExternalManagedObject(pipelineObject);
|
||||
outPipelineHandle = m_pipelineHandle;
|
||||
return m_pipelineHandle != 0;
|
||||
}
|
||||
|
||||
bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const {
|
||||
@@ -1232,7 +1231,22 @@ bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const {
|
||||
return m_ownsManagedAssetHandle;
|
||||
}
|
||||
|
||||
void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedPipeline() const {
|
||||
m_pipelineCreationAttempted = false;
|
||||
|
||||
if (!IsRuntimeAlive()) {
|
||||
m_pipelineHandle = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pipelineHandle != 0) {
|
||||
m_runtime->DestroyExternalManagedObject(m_pipelineHandle);
|
||||
m_pipelineHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
|
||||
ReleaseManagedPipeline();
|
||||
m_createPipelineMethod = nullptr;
|
||||
m_configureCameraRenderRequestMethod = nullptr;
|
||||
m_getDefaultFinalColorSettingsMethod = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user