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

472 lines
14 KiB
C#

using System;
using System.Runtime.CompilerServices;
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class ScriptableRendererData : Object
{
public ScriptableRendererFeature[] rendererFeatures;
private ScriptableRendererFeature[] m_rendererFeatures;
private ScriptableRenderer m_rendererInstance;
private bool m_rendererInvalidated;
private int m_runtimeStateVersion = 1;
private int m_rendererFeatureCollectionHash;
private bool m_rendererFeatureCollectionHashResolved;
protected ScriptableRendererData()
{
rendererFeatures =
Array.Empty<ScriptableRendererFeature>();
}
internal ScriptableRenderer CreateRendererInstance()
{
return GetRendererInstance();
}
internal ScriptableRenderer GetRendererInstance()
{
if (m_rendererInstance == null)
{
m_rendererInstance = CreateRenderer();
if (m_rendererInstance != null)
{
SetupRendererInstance(m_rendererInstance);
m_rendererInvalidated = false;
}
}
return m_rendererInstance;
}
internal ScriptableRendererFeature[] CreateRendererFeaturesInstance()
{
return GetRendererFeatures();
}
internal void SetupRendererInstance(
ScriptableRenderer renderer)
{
if (renderer == null)
{
return;
}
SetupRenderer(renderer);
}
internal void SetDirtyInstance()
{
SetDirty();
}
internal void InvalidateRendererFeaturesInstance()
{
m_rendererFeatureCollectionHash =
ComputeRendererFeatureCollectionHash(
rendererFeatures ??
Array.Empty<ScriptableRendererFeature>());
m_rendererFeatureCollectionHashResolved = true;
SetDirty();
}
internal int GetRuntimeStateVersionInstance()
{
SynchronizeRendererFeatureCollectionState();
return m_runtimeStateVersion;
}
internal void ReleaseRuntimeResourcesInstance()
{
ReleaseRendererSetupCache();
ReleaseRuntimeResources();
m_rendererInvalidated = false;
}
internal void ConfigureCameraRenderRequestInstance(
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);
}
}
internal void ConfigureCameraFramePlanInstance(
ScriptableRenderPipelinePlanningContext context)
{
ConfigureCameraFramePlan(context);
ScriptableRenderer renderer =
GetRendererInstance();
if (renderer != null)
{
renderer.ConfigureCameraFramePlanInstance(
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);
}
if (renderer != null)
{
renderer.FinalizeCameraFramePlanInstance(
context);
}
}
internal bool ConfigureRenderSceneSetupInstance(
RenderSceneSetupContext context)
{
ConfigureRenderSceneSetup(context);
ScriptableRenderer renderer =
GetRendererInstance();
if (renderer != null)
{
renderer.ConfigureRenderSceneSetupInstance(
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);
}
return context != null &&
context.isConfigured;
}
internal bool ConfigureDirectionalShadowExecutionStateInstance(
DirectionalShadowExecutionContext context)
{
ConfigureDirectionalShadowExecutionState(
context);
ScriptableRenderer renderer =
GetRendererInstance();
if (renderer != null)
{
renderer
.ConfigureDirectionalShadowExecutionStateInstance(
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);
}
return context != null &&
context.isConfigured;
}
protected virtual ScriptableRenderer CreateRenderer()
{
return null;
}
protected virtual void SetupRenderer(
ScriptableRenderer renderer)
{
AddRendererFeatures(
renderer,
GetRendererFeatures());
}
protected virtual void ConfigureCameraRenderRequest(
CameraRenderRequestContext context)
{
}
protected virtual void ConfigureCameraFramePlan(
ScriptableRenderPipelinePlanningContext context)
{
}
protected virtual void ConfigureRenderSceneSetup(
RenderSceneSetupContext context)
{
}
protected virtual void ConfigureDirectionalShadowExecutionState(
DirectionalShadowExecutionContext context)
{
}
protected virtual ScriptableRendererFeature[] CreateRendererFeatures()
{
return rendererFeatures ??
Array.Empty<ScriptableRendererFeature>();
}
protected virtual void ReleaseRuntimeResources()
{
}
protected virtual ScriptableRendererFeature[]
CreateDefaultRendererFeatures()
{
return Array.Empty<ScriptableRendererFeature>();
}
protected bool isInvalidated
{
get
{
return m_rendererInvalidated;
}
}
protected bool HasDirectionalShadow(
CameraRenderRequestContext context)
{
return context != null &&
InternalCalls
.Rendering_CameraRenderRequestContext_GetHasDirectionalShadow(
context.nativeHandle);
}
protected void ClearDirectionalShadow(
CameraRenderRequestContext context)
{
if (context == null)
{
return;
}
InternalCalls
.Rendering_CameraRenderRequestContext_ClearDirectionalShadow(
context.nativeHandle);
}
protected void SetDirty()
{
ReleaseRendererSetupCache();
m_rendererInvalidated = true;
unchecked
{
++m_runtimeStateVersion;
}
if (m_runtimeStateVersion <= 0)
{
m_runtimeStateVersion = 1;
}
}
protected void AddRendererFeature(
ScriptableRenderer renderer,
ScriptableRendererFeature rendererFeature)
{
if (renderer == null ||
rendererFeature == null)
{
return;
}
renderer.AddFeatureInstance(rendererFeature);
}
protected void AddRendererFeatures(
ScriptableRenderer renderer,
ScriptableRendererFeature[] rendererFeatures)
{
if (renderer == null ||
rendererFeatures == null)
{
return;
}
for (int i = 0; i < rendererFeatures.Length; ++i)
{
AddRendererFeature(
renderer,
rendererFeatures[i]);
}
}
protected void ResetRendererFeaturesToDefault()
{
rendererFeatures =
CreateDefaultRendererFeatures() ??
Array.Empty<ScriptableRendererFeature>();
}
private ScriptableRendererFeature[] GetRendererFeatures()
{
if (m_rendererFeatures == null)
{
m_rendererFeatures =
CreateRendererFeatures() ??
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)
{
m_rendererInstance.ReleaseRuntimeResourcesInstance();
m_rendererInstance = null;
m_rendererFeatures = null;
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;
}
}
}