472 lines
14 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
|