Files
XCEngine/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRendererFeatureCollection.cs

263 lines
7.8 KiB
C#

using System;
using System.Runtime.CompilerServices;
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
internal sealed class ScriptableRendererFeatureCollection
{
private readonly ScriptableRendererData m_owner;
private ScriptableRendererFeature[] m_features;
public ScriptableRendererFeatureCollection(
ScriptableRendererData owner)
{
m_owner = owner;
m_features = Array.Empty<ScriptableRendererFeature>();
}
public ScriptableRendererFeature[] GetFeatures(
ref ScriptableRendererFeature[] configuredFeatures)
{
if (m_features == null)
{
ScriptableRendererFeature[] resolvedFeatures =
configuredFeatures ??
Array.Empty<ScriptableRendererFeature>();
configuredFeatures = resolvedFeatures;
m_features = resolvedFeatures;
}
BindOwners(m_features);
return m_features;
}
public void Reset(
ref ScriptableRendererFeature[] configuredFeatures,
ScriptableRendererFeature[] features)
{
configuredFeatures =
features ??
Array.Empty<ScriptableRendererFeature>();
m_features = configuredFeatures;
BindOwners(m_features);
}
public void Invalidate(
ref ScriptableRendererFeature[] configuredFeatures,
ref int collectionHash,
ref bool collectionHashResolved)
{
ScriptableRendererFeature[] features =
ResolveConfiguredFeatures(
ref configuredFeatures);
collectionHash =
ComputeCollectionHash(features);
collectionHashResolved = true;
}
public void Synchronize(
ref ScriptableRendererFeature[] configuredFeatures,
ref int collectionHash,
ref bool collectionHashResolved,
Action onChanged)
{
ScriptableRendererFeature[] features =
ResolveConfiguredFeatures(
ref configuredFeatures);
int resolvedHash =
ComputeCollectionHash(features);
if (!collectionHashResolved)
{
collectionHash = resolvedHash;
collectionHashResolved = true;
return;
}
if (resolvedHash == collectionHash)
{
return;
}
collectionHash = resolvedHash;
onChanged?.Invoke();
}
public void ConfigureCameraRenderRequest(
ref ScriptableRendererFeature[] configuredFeatures,
CameraRenderRequestContext context)
{
ScriptableRendererFeature[] features =
GetFeatures(ref configuredFeatures);
for (int i = 0; i < features.Length; ++i)
{
ScriptableRendererFeature feature =
features[i];
if (feature == null ||
!feature.isActive)
{
continue;
}
feature.ConfigureCameraRenderRequest(
context);
}
}
public void ConfigureCameraFramePlan(
ref ScriptableRendererFeature[] configuredFeatures,
ScriptableRenderPipelinePlanningContext context)
{
ScriptableRendererFeature[] features =
GetFeatures(ref configuredFeatures);
for (int i = 0; i < features.Length; ++i)
{
ScriptableRendererFeature feature =
features[i];
if (feature == null ||
!feature.isActive)
{
continue;
}
feature.ConfigureCameraFramePlan(
context);
}
}
public void ConfigureRenderSceneSetup(
ref ScriptableRendererFeature[] configuredFeatures,
RenderSceneSetupContext context)
{
ScriptableRendererFeature[] features =
GetFeatures(ref configuredFeatures);
for (int i = 0; i < features.Length; ++i)
{
ScriptableRendererFeature feature =
features[i];
if (feature == null ||
!feature.isActive)
{
continue;
}
feature.ConfigureRenderSceneSetup(
context);
}
}
public void ConfigureDirectionalShadowExecutionState(
ref ScriptableRendererFeature[] configuredFeatures,
DirectionalShadowExecutionContext context)
{
ScriptableRendererFeature[] features =
GetFeatures(ref configuredFeatures);
for (int i = 0; i < features.Length; ++i)
{
ScriptableRendererFeature feature =
features[i];
if (feature == null ||
!feature.isActive)
{
continue;
}
feature
.ConfigureDirectionalShadowExecutionState(
context);
}
}
public void ReleaseRuntimeResources()
{
if (m_features == null)
{
return;
}
for (int i = 0; i < m_features.Length; ++i)
{
ScriptableRendererFeature feature =
m_features[i];
if (feature != null)
{
feature.ReleaseRuntimeResourcesInstance();
}
}
m_features = null;
}
public void ResetResolvedCache()
{
m_features = null;
}
private ScriptableRendererFeature[] ResolveConfiguredFeatures(
ref ScriptableRendererFeature[] configuredFeatures)
{
ScriptableRendererFeature[] features =
configuredFeatures ??
Array.Empty<ScriptableRendererFeature>();
configuredFeatures = features;
m_features = features;
BindOwners(features);
return features;
}
private void BindOwners(
ScriptableRendererFeature[] features)
{
if (features == null)
{
return;
}
for (int i = 0; i < features.Length; ++i)
{
ScriptableRendererFeature feature =
features[i];
if (feature != null)
{
feature.BindOwnerInstance(m_owner);
}
}
}
private static int ComputeCollectionHash(
ScriptableRendererFeature[] features)
{
unchecked
{
int hash = 17;
if (features == null)
{
return hash;
}
hash = (hash * 31) + features.Length;
for (int i = 0; i < features.Length; ++i)
{
ScriptableRendererFeature feature =
features[i];
if (feature == null)
{
hash = (hash * 31) + 1;
continue;
}
hash =
(hash * 31) +
RuntimeHelpers.GetHashCode(feature);
hash =
(hash * 31) +
feature.GetRuntimeStateVersionInstance();
}
return hash;
}
}
}
}