refactor(srp): formalize renderer feature collections

This commit is contained in:
2026-04-22 02:31:07 +08:00
parent 6950bd15c2
commit 3187ccbfe1
6 changed files with 394 additions and 193 deletions

View File

@@ -9,7 +9,8 @@ namespace XCEngine.Rendering.Universal
: ScriptableObject
{
public ScriptableRendererFeature[] rendererFeatures;
private ScriptableRendererFeature[] m_rendererFeatures;
private readonly ScriptableRendererFeatureCollection
m_featureCollection;
private ScriptableRenderer m_rendererInstance;
private bool m_rendererInvalidated;
private int m_runtimeStateVersion = 1;
@@ -20,6 +21,8 @@ namespace XCEngine.Rendering.Universal
{
rendererFeatures =
Array.Empty<ScriptableRendererFeature>();
m_featureCollection =
new ScriptableRendererFeatureCollection(this);
}
internal ScriptableRenderer CreateRendererInstance()
@@ -60,11 +63,10 @@ namespace XCEngine.Rendering.Universal
internal void InvalidateRendererFeaturesInstance()
{
m_rendererFeatureCollectionHash =
ComputeRendererFeatureCollectionHash(
rendererFeatures ??
Array.Empty<ScriptableRendererFeature>());
m_rendererFeatureCollectionHashResolved = true;
m_featureCollection.Invalidate(
ref rendererFeatures,
ref m_rendererFeatureCollectionHash,
ref m_rendererFeatureCollectionHashResolved);
SetDirty();
}
@@ -85,22 +87,9 @@ namespace XCEngine.Rendering.Universal
CameraRenderRequestContext context)
{
ConfigureCameraRenderRequest(context);
ScriptableRendererFeature[] rendererFeatures =
GetRendererFeatures();
for (int i = 0; i < rendererFeatures.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatures[i];
if (rendererFeature == null ||
!rendererFeature.isActive)
{
continue;
}
rendererFeature.ConfigureCameraRenderRequest(
context);
}
m_featureCollection.ConfigureCameraRenderRequest(
ref rendererFeatures,
context);
}
internal void ConfigureCameraFramePlanInstance(
@@ -116,21 +105,9 @@ namespace XCEngine.Rendering.Universal
context);
}
ScriptableRendererFeature[] rendererFeatures =
GetRendererFeatures();
for (int i = 0; i < rendererFeatures.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatures[i];
if (rendererFeature == null ||
!rendererFeature.isActive)
{
continue;
}
rendererFeature.ConfigureCameraFramePlan(
context);
}
m_featureCollection.ConfigureCameraFramePlan(
ref rendererFeatures,
context);
if (renderer != null)
{
@@ -152,21 +129,9 @@ namespace XCEngine.Rendering.Universal
context);
}
ScriptableRendererFeature[] rendererFeatures =
GetRendererFeatures();
for (int i = 0; i < rendererFeatures.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatures[i];
if (rendererFeature == null ||
!rendererFeature.isActive)
{
continue;
}
rendererFeature.ConfigureRenderSceneSetup(
context);
}
m_featureCollection.ConfigureRenderSceneSetup(
ref rendererFeatures,
context);
return context != null &&
context.isConfigured;
@@ -187,22 +152,10 @@ namespace XCEngine.Rendering.Universal
context);
}
ScriptableRendererFeature[] rendererFeatures =
GetRendererFeatures();
for (int i = 0; i < rendererFeatures.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatures[i];
if (rendererFeature == null ||
!rendererFeature.isActive)
{
continue;
}
rendererFeature
.ConfigureDirectionalShadowExecutionState(
context);
}
m_featureCollection
.ConfigureDirectionalShadowExecutionState(
ref rendererFeatures,
context);
return context != null &&
context.isConfigured;
@@ -329,110 +282,25 @@ namespace XCEngine.Rendering.Universal
protected void ResetRendererFeaturesToDefault()
{
rendererFeatures =
m_featureCollection.Reset(
ref rendererFeatures,
CreateDefaultRendererFeatures() ??
Array.Empty<ScriptableRendererFeature>();
BindRendererFeatureOwners(rendererFeatures);
Array.Empty<ScriptableRendererFeature>());
}
private ScriptableRendererFeature[] GetRendererFeatures()
{
if (m_rendererFeatures == null)
{
ScriptableRendererFeature[]
configuredRendererFeatures =
rendererFeatures ??
Array.Empty<ScriptableRendererFeature>();
rendererFeatures =
configuredRendererFeatures;
m_rendererFeatures =
configuredRendererFeatures;
}
BindRendererFeatureOwners(m_rendererFeatures);
return m_rendererFeatures;
return m_featureCollection.GetFeatures(
ref 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;
}
m_featureCollection.Synchronize(
ref rendererFeatures,
ref m_rendererFeatureCollectionHash,
ref m_rendererFeatureCollectionHashResolved,
SetDirty);
}
private void ReleaseRendererSetupCache()
@@ -441,26 +309,11 @@ namespace XCEngine.Rendering.Universal
{
m_rendererInstance.ReleaseRuntimeResourcesInstance();
m_rendererInstance = null;
m_rendererFeatures = null;
m_featureCollection.ResetResolvedCache();
return;
}
if (m_rendererFeatures == null)
{
return;
}
for (int i = 0; i < m_rendererFeatures.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
m_rendererFeatures[i];
if (rendererFeature != null)
{
rendererFeature.ReleaseRuntimeResourcesInstance();
}
}
m_rendererFeatures = null;
m_featureCollection.ReleaseRuntimeResources();
}
}
}