Introduce a formal ScriptableRendererData setup seam so renderer feature attachment is owned by renderer data instead of renderer constructors pulling feature caches. Route lifecycle and reuse probes through the new setup path, lock the non-public setup seam in the API surface probe, and update scripting expectations accordingly.
233 lines
6.4 KiB
C#
233 lines
6.4 KiB
C#
using System;
|
|
using XCEngine;
|
|
using XCEngine.Rendering;
|
|
|
|
namespace XCEngine.Rendering.Universal
|
|
{
|
|
public abstract class ScriptableRendererData : Object
|
|
{
|
|
private ScriptableRendererFeature[] m_rendererFeatures;
|
|
private ScriptableRenderer m_rendererInstance;
|
|
|
|
protected ScriptableRendererData()
|
|
{
|
|
}
|
|
|
|
internal ScriptableRenderer CreateRendererInstance()
|
|
{
|
|
return GetRendererInstance();
|
|
}
|
|
|
|
internal ScriptableRenderer GetRendererInstance()
|
|
{
|
|
if (m_rendererInstance == null)
|
|
{
|
|
m_rendererInstance = CreateRenderer();
|
|
if (m_rendererInstance != null)
|
|
{
|
|
SetupRendererInstance(m_rendererInstance);
|
|
}
|
|
}
|
|
|
|
return m_rendererInstance;
|
|
}
|
|
|
|
internal ScriptableRendererFeature[] CreateRendererFeaturesInstance()
|
|
{
|
|
return GetRendererFeatures();
|
|
}
|
|
|
|
internal void SetupRendererInstance(
|
|
ScriptableRenderer renderer)
|
|
{
|
|
if (renderer == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetupRenderer(renderer);
|
|
}
|
|
|
|
internal string GetPipelineRendererAssetKeyInstance()
|
|
{
|
|
return GetPipelineRendererAssetKey();
|
|
}
|
|
|
|
internal void ReleaseRuntimeResourcesInstance()
|
|
{
|
|
if (m_rendererInstance != null)
|
|
{
|
|
m_rendererInstance.ReleaseRuntimeResourcesInstance();
|
|
m_rendererInstance = null;
|
|
m_rendererFeatures = null;
|
|
ReleaseRuntimeResources();
|
|
return;
|
|
}
|
|
|
|
if (m_rendererFeatures != null)
|
|
{
|
|
for (int i = 0; i < m_rendererFeatures.Length; ++i)
|
|
{
|
|
ScriptableRendererFeature rendererFeature =
|
|
m_rendererFeatures[i];
|
|
if (rendererFeature != null)
|
|
{
|
|
rendererFeature.ReleaseRuntimeResourcesInstance();
|
|
}
|
|
}
|
|
|
|
m_rendererFeatures = null;
|
|
}
|
|
|
|
ReleaseRuntimeResources();
|
|
}
|
|
|
|
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);
|
|
|
|
ScriptableRendererFeature[] rendererFeatures =
|
|
GetRendererFeatures();
|
|
for (int i = 0; i < rendererFeatures.Length; ++i)
|
|
{
|
|
ScriptableRendererFeature rendererFeature =
|
|
rendererFeatures[i];
|
|
if (rendererFeature == null ||
|
|
!rendererFeature.isActive)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
rendererFeature.ConfigureCameraFramePlan(
|
|
context);
|
|
}
|
|
}
|
|
|
|
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 string GetPipelineRendererAssetKey()
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
protected virtual ScriptableRendererFeature[] CreateRendererFeatures()
|
|
{
|
|
return Array.Empty<ScriptableRendererFeature>();
|
|
}
|
|
|
|
protected virtual void ReleaseRuntimeResources()
|
|
{
|
|
}
|
|
|
|
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 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]);
|
|
}
|
|
}
|
|
|
|
private ScriptableRendererFeature[] GetRendererFeatures()
|
|
{
|
|
if (m_rendererFeatures == null)
|
|
{
|
|
m_rendererFeatures =
|
|
CreateRendererFeatures() ??
|
|
Array.Empty<ScriptableRendererFeature>();
|
|
}
|
|
|
|
return m_rendererFeatures;
|
|
}
|
|
}
|
|
}
|
|
|