refactor(srp): tighten renderer feature lifecycle invalidation

This commit is contained in:
2026-04-21 19:43:45 +08:00
parent 97bd990b12
commit ffe4717d8f
7 changed files with 243 additions and 5 deletions

View File

@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
using XCEngine;
using XCEngine.Rendering;
@@ -11,6 +12,8 @@ namespace XCEngine.Rendering.Universal
private ScriptableRenderer m_rendererInstance;
private bool m_rendererInvalidated;
private int m_runtimeStateVersion = 1;
private int m_rendererFeatureCollectionHash;
private bool m_rendererFeatureCollectionHashResolved;
protected ScriptableRendererData()
{
@@ -59,8 +62,19 @@ namespace XCEngine.Rendering.Universal
SetDirty();
}
internal void InvalidateRendererFeaturesInstance()
{
m_rendererFeatureCollectionHash =
ComputeRendererFeatureCollectionHash(
rendererFeatures ??
Array.Empty<ScriptableRendererFeature>());
m_rendererFeatureCollectionHashResolved = true;
SetDirty();
}
internal int GetRuntimeStateVersionInstance()
{
SynchronizeRendererFeatureCollectionState();
return m_runtimeStateVersion;
}
@@ -339,9 +353,92 @@ namespace XCEngine.Rendering.Universal
Array.Empty<ScriptableRendererFeature>();
}
BindRendererFeatureOwners(m_rendererFeatures);
return m_rendererFeatures;
}
private void SynchronizeRendererFeatureCollectionState()
{
ScriptableRendererFeature[] configuredRendererFeatures =
rendererFeatures ??
Array.Empty<ScriptableRendererFeature>();
BindRendererFeatureOwners(configuredRendererFeatures);
int collectionHash =
ComputeRendererFeatureCollectionHash(
configuredRendererFeatures);
if (!m_rendererFeatureCollectionHashResolved)
{
m_rendererFeatureCollectionHash = collectionHash;
m_rendererFeatureCollectionHashResolved = true;
return;
}
if (collectionHash == m_rendererFeatureCollectionHash)
{
return;
}
m_rendererFeatureCollectionHash = collectionHash;
SetDirty();
}
private void BindRendererFeatureOwners(
ScriptableRendererFeature[] rendererFeatureCollection)
{
if (rendererFeatureCollection == null)
{
return;
}
for (int i = 0; i < rendererFeatureCollection.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatureCollection[i];
if (rendererFeature != null)
{
rendererFeature.BindOwnerInstance(this);
}
}
}
private static int ComputeRendererFeatureCollectionHash(
ScriptableRendererFeature[] rendererFeatureCollection)
{
unchecked
{
int hash = 17;
if (rendererFeatureCollection == null)
{
return hash;
}
hash =
(hash * 31) +
rendererFeatureCollection.Length;
for (int i = 0; i < rendererFeatureCollection.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatureCollection[i];
if (rendererFeature == null)
{
hash = (hash * 31) + 1;
continue;
}
hash =
(hash * 31) +
RuntimeHelpers.GetHashCode(rendererFeature);
hash =
(hash * 31) +
rendererFeature
.GetRuntimeStateVersionInstance();
}
return hash;
}
}
private void ReleaseRendererSetupCache()
{
if (m_rendererInstance != null)