Introduce ScriptableRendererData dirty/invalidation support so renderer and feature caches can be released and rebuilt within the same managed asset runtime. Add managed probes and scripting coverage for non-public dirty APIs and for renderer rebuild after invalidation, then archive the completed phase plan.
260 lines
6.9 KiB
C#
260 lines
6.9 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;
|
|
private bool m_rendererInvalidated;
|
|
|
|
protected ScriptableRendererData()
|
|
{
|
|
}
|
|
|
|
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 string GetPipelineRendererAssetKeyInstance()
|
|
{
|
|
return GetPipelineRendererAssetKey();
|
|
}
|
|
|
|
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);
|
|
|
|
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 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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|