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

424 lines
12 KiB
C#

using System;
using System.Runtime.CompilerServices;
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class RendererBackedRenderPipelineAsset
: ScriptableRenderPipelineAsset
{
public ScriptableRendererData[] rendererDataList =
Array.Empty<ScriptableRendererData>();
public int defaultRendererIndex = 0;
private int m_rendererDataRuntimeStateHash;
private bool m_rendererDataRuntimeStateHashResolved;
protected RendererBackedRenderPipelineAsset()
{
}
protected override ScriptableRenderPipeline CreatePipeline()
{
return CreateRendererBackedPipeline();
}
protected override void ConfigureCameraRenderRequest(
CameraRenderRequestContext context)
{
ApplyResolvedRendererIndex(
context,
ResolveRendererIndex(context));
ConfigureRendererCameraRequest(
new RendererCameraRequestContext(context));
ApplyResolvedRendererIndex(
context,
context != null
? context.rendererIndex
: -1);
ScriptableRendererData resolvedRendererData =
ResolveRendererData(context);
if (resolvedRendererData != null)
{
resolvedRendererData
.ConfigureCameraRenderRequestInstance(
context);
}
}
protected override void ConfigureCameraFramePlan(
ScriptableRenderPipelinePlanningContext context)
{
if (UsesExplicitFullscreenStagePlanning() &&
context != null)
{
// Renderer-backed SRP owns fullscreen stage planning explicitly.
context.ClearFullscreenStage(
CameraFrameStage.PostProcess);
context.ClearFullscreenStage(
CameraFrameStage.FinalOutput);
}
ScriptableRendererData resolvedRendererData =
ResolveRendererData(context);
if (resolvedRendererData != null)
{
resolvedRendererData
.ConfigureCameraFramePlanInstance(
context);
}
}
protected override bool ConfigureDirectionalShadowExecutionState(
DirectionalShadowExecutionContext context)
{
ScriptableRendererData resolvedRendererData =
ResolveRendererData(context);
return resolvedRendererData != null &&
resolvedRendererData
.ConfigureDirectionalShadowExecutionStateInstance(
context);
}
protected override bool ConfigureRenderSceneSetup(
RenderSceneSetupContext context)
{
ScriptableRendererData resolvedRendererData =
ResolveRendererData(context);
return resolvedRendererData != null &&
resolvedRendererData
.ConfigureRenderSceneSetupInstance(
context);
}
protected override void ReleaseRuntimeResources()
{
ReleaseRendererDataRuntimeResources();
}
protected override void SynchronizeRuntimeResourceVersion()
{
int runtimeStateHash =
ComputeRendererDataRuntimeStateHash();
if (!m_rendererDataRuntimeStateHashResolved)
{
m_rendererDataRuntimeStateHash =
runtimeStateHash;
m_rendererDataRuntimeStateHashResolved = true;
return;
}
if (runtimeStateHash ==
m_rendererDataRuntimeStateHash)
{
return;
}
m_rendererDataRuntimeStateHash =
runtimeStateHash;
SetDirty();
}
protected virtual ScriptableRenderPipeline
CreateRendererBackedPipeline()
{
return new RendererBackedRenderPipeline(this);
}
protected virtual void ConfigureRendererCameraRequest(
RendererCameraRequestContext context)
{
}
protected virtual int ResolveRendererIndex(
CameraRenderRequestContext context)
{
return ResolveSelectedRendererIndex();
}
protected virtual ScriptableRendererData
CreateDefaultRendererData()
{
return null;
}
protected virtual bool UsesExplicitFullscreenStagePlanning()
{
return true;
}
internal ScriptableRendererData GetDefaultRendererData()
{
return ResolveSelectedRendererData();
}
internal ScriptableRenderer GetDefaultRenderer()
{
return ResolveSelectedRenderer();
}
internal ScriptableRendererData ResolveSelectedRendererData()
{
return ResolveRendererDataByResolvedIndex(
ResolveSelectedRendererIndex());
}
internal ScriptableRenderer ResolveSelectedRenderer()
{
ScriptableRendererData rendererData =
ResolveSelectedRendererData();
return rendererData != null
? rendererData.GetRendererInstance()
: null;
}
internal ScriptableRendererData GetRendererData(
int rendererIndex)
{
return ResolveRendererDataByResolvedIndex(
ResolveRendererIndexWithFallback(
rendererIndex));
}
internal ScriptableRenderer ResolveRenderer(
int rendererIndex)
{
ScriptableRendererData rendererData =
GetRendererData(rendererIndex);
return rendererData != null
? rendererData.GetRendererInstance()
: null;
}
protected internal void ReleaseRendererDataRuntimeResources()
{
EnsureRendererDataList();
for (int i = 0; i < rendererDataList.Length; ++i)
{
ScriptableRendererData rendererData =
rendererDataList[i];
if (rendererData == null ||
WasRendererDataReleasedEarlier(i))
{
continue;
}
rendererData.ReleaseRuntimeResourcesInstance();
}
}
private void EnsureRendererDataList()
{
if (rendererDataList != null &&
rendererDataList.Length > 0)
{
return;
}
ScriptableRendererData defaultRendererData =
CreateDefaultRendererData();
rendererDataList =
defaultRendererData != null
? new ScriptableRendererData[]
{
defaultRendererData
}
: Array.Empty<ScriptableRendererData>();
defaultRendererIndex = 0;
}
private bool WasRendererDataReleasedEarlier(
int rendererDataIndex)
{
ScriptableRendererData rendererData =
rendererDataList[rendererDataIndex];
for (int i = 0; i < rendererDataIndex; ++i)
{
if (object.ReferenceEquals(
rendererDataList[i],
rendererData))
{
return true;
}
}
return false;
}
private int ComputeRendererDataRuntimeStateHash()
{
unchecked
{
int hash = 17;
hash =
(hash * 31) +
ResolveSelectedRendererIndex();
if (rendererDataList == null)
{
return hash;
}
hash = (hash * 31) + rendererDataList.Length;
for (int i = 0; i < rendererDataList.Length; ++i)
{
ScriptableRendererData rendererData =
rendererDataList[i];
if (rendererData != null)
{
hash =
(hash * 31) +
RuntimeHelpers.GetHashCode(
rendererData);
hash =
(hash * 31) +
rendererData
.GetRuntimeStateVersionInstance();
}
}
return hash;
}
}
private ScriptableRendererData ResolveRendererDataByResolvedIndex(
int resolvedRendererIndex)
{
EnsureRendererDataList();
if (resolvedRendererIndex < 0)
{
return null;
}
return rendererDataList[resolvedRendererIndex];
}
private int ResolveSelectedRendererIndex()
{
return ResolveRendererIndexWithFallback(
defaultRendererIndex);
}
private ScriptableRendererData ResolveRendererData(
CameraRenderRequestContext context)
{
return GetRendererData(
context != null
? context.rendererIndex
: -1);
}
private ScriptableRendererData ResolveRendererData(
ScriptableRenderPipelinePlanningContext context)
{
return GetRendererData(
context != null
? context.rendererIndex
: -1);
}
private ScriptableRendererData ResolveRendererData(
RenderSceneSetupContext context)
{
return GetRendererData(
context != null
? context.rendererIndex
: -1);
}
private ScriptableRendererData ResolveRendererData(
DirectionalShadowExecutionContext context)
{
return GetRendererData(
context != null
? context.rendererIndex
: -1);
}
private void ApplyResolvedRendererIndex(
CameraRenderRequestContext context,
int rendererIndex)
{
if (context == null)
{
return;
}
context.rendererIndex =
ResolveRendererIndexWithFallback(
rendererIndex);
}
private int ResolveRendererIndexWithFallback(
int rendererIndex)
{
EnsureRendererDataList();
if (rendererDataList.Length == 0)
{
return -1;
}
if (rendererIndex < 0 ||
rendererIndex >= rendererDataList.Length)
{
return ResolveDefaultRendererIndex();
}
if (rendererDataList[rendererIndex] == null)
{
return ResolveDefaultRendererIndex();
}
return rendererIndex;
}
private int ResolveDefaultRendererIndex()
{
EnsureRendererDataList();
if (rendererDataList.Length == 0)
{
return -1;
}
if (defaultRendererIndex < 0 ||
defaultRendererIndex >= rendererDataList.Length)
{
defaultRendererIndex = 0;
}
if (rendererDataList[defaultRendererIndex] != null)
{
return defaultRendererIndex;
}
int firstValidRendererIndex =
FindFirstValidRendererIndex();
if (firstValidRendererIndex >= 0)
{
defaultRendererIndex = firstValidRendererIndex;
return defaultRendererIndex;
}
rendererDataList[defaultRendererIndex] =
CreateDefaultRendererData();
return defaultRendererIndex;
}
private int FindFirstValidRendererIndex()
{
for (int i = 0; i < rendererDataList.Length; ++i)
{
if (rendererDataList[i] != null)
{
return i;
}
}
return -1;
}
}
}