263 lines
7.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|