Revert "perf(rendering): draw retained frame product"
This reverts commit ef1d263337.
This commit is contained in:
parent
624e1119ca
commit
2c848d4167
13 changed files with 268 additions and 1334 deletions
|
|
@ -76,6 +76,13 @@ public sealed class RetailPViewRenderer
|
|||
InteriorEntityPartition.IObserver? partitionObserver,
|
||||
RenderScenePViewFrameProductController? sceneFrameProduct = null)
|
||||
{
|
||||
if (sceneFrameProduct is not null
|
||||
&& partitionObserver is not ICurrentRenderPViewObserver)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"The scene frame-product referee requires the current PView observer.",
|
||||
nameof(partitionObserver));
|
||||
}
|
||||
_partitionObserver = partitionObserver;
|
||||
_candidateObserver = partitionObserver as ICurrentRenderPViewObserver;
|
||||
_sceneFrameProduct = sceneFrameProduct;
|
||||
|
|
@ -205,16 +212,6 @@ public sealed class RetailPViewRenderer
|
|||
ctx.ViewProjection,
|
||||
_viewconeScratch);
|
||||
|
||||
IRenderFrameEntityPassExecutor? frameEntityPasses = null;
|
||||
if (_sceneFrameProduct is not null)
|
||||
{
|
||||
frameEntityPasses = passes as IRenderFrameEntityPassExecutor
|
||||
?? throw new InvalidOperationException(
|
||||
"The production frame product requires a packed entity-pass executor.");
|
||||
}
|
||||
RenderFrameView frameView = default;
|
||||
bool frameViewBorrowed = false;
|
||||
bool entityFrameOpen = false;
|
||||
_candidateObserver?.BeginPViewFrame();
|
||||
try
|
||||
{
|
||||
|
|
@ -245,73 +242,32 @@ public sealed class RetailPViewRenderer
|
|||
}
|
||||
}
|
||||
|
||||
if (_sceneFrameProduct is not null)
|
||||
{
|
||||
frameView = _sceneFrameProduct.BuildAndBorrow(
|
||||
pvFrame,
|
||||
clipAssembly,
|
||||
viewcone,
|
||||
_lookInFrames,
|
||||
drawableCells,
|
||||
ctx.Cells,
|
||||
ctx.AnimatedEntityIds,
|
||||
ctx.RootCell.IsOutdoorNode);
|
||||
frameViewBorrowed = true;
|
||||
frameEntityPasses!.BeginEntityFrame(in frameView);
|
||||
entityFrameOpen = true;
|
||||
}
|
||||
|
||||
DrawLandscapeThroughOutsideView(
|
||||
ctx,
|
||||
passes,
|
||||
clipAssembly,
|
||||
partition,
|
||||
viewcone,
|
||||
frameEntityPasses,
|
||||
in frameView);
|
||||
DrawLandscapeThroughOutsideView(ctx, passes, clipAssembly, partition, viewcone);
|
||||
passes.UseIndoorMembershipOnlyRouting();
|
||||
DrawExitPortalMasks(ctx, passes, pvFrame, clipAssembly, drawableCells);
|
||||
DrawEnvCellShells(passes, pvFrame);
|
||||
DrawCellObjectLists(
|
||||
ctx,
|
||||
passes,
|
||||
DrawCellObjectLists(ctx, passes, pvFrame, clipAssembly, drawableCells, partition, viewcone);
|
||||
DrawDynamicsLast(ctx, passes, partition, viewcone, ctx.RootCell.IsOutdoorNode);
|
||||
|
||||
_candidateObserver?.CompletePViewFrame();
|
||||
_sceneFrameProduct?.BuildAndCompare(
|
||||
pvFrame,
|
||||
clipAssembly,
|
||||
viewcone,
|
||||
_lookInFrames,
|
||||
drawableCells,
|
||||
partition,
|
||||
viewcone,
|
||||
frameEntityPasses,
|
||||
in frameView);
|
||||
DrawDynamicsLast(
|
||||
ctx,
|
||||
passes,
|
||||
partition,
|
||||
viewcone,
|
||||
ctx.Cells,
|
||||
ctx.AnimatedEntityIds,
|
||||
ctx.PlayerLandblockId ?? 0,
|
||||
ctx.RootCell.IsOutdoorNode,
|
||||
frameEntityPasses,
|
||||
in frameView);
|
||||
|
||||
if (entityFrameOpen)
|
||||
{
|
||||
frameEntityPasses!.CompleteEntityFrame(in frameView);
|
||||
entityFrameOpen = false;
|
||||
}
|
||||
_candidateObserver?.CompletePViewFrame();
|
||||
_sceneFrameProduct?.CompleteProduction(in frameView);
|
||||
ctx.CameraWorldPosition);
|
||||
return result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (entityFrameOpen)
|
||||
frameEntityPasses!.AbortEntityFrame();
|
||||
_candidateObserver?.AbortPViewFrame();
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (frameViewBorrowed)
|
||||
_sceneFrameProduct!.Release(in frameView);
|
||||
}
|
||||
}
|
||||
|
||||
// R-A2: group the nearby building cells by BuildingId and run one per-building flood per group
|
||||
|
|
@ -441,9 +397,7 @@ public sealed class RetailPViewRenderer
|
|||
RetailPViewFrameInput ctx,
|
||||
IRetailPViewPassExecutor passes,
|
||||
ClipFrameAssembly clipAssembly,
|
||||
InteriorEntityPartition.Result partition,
|
||||
IRenderFrameEntityPassExecutor? frameEntityPasses,
|
||||
in RenderFrameView frameView)
|
||||
InteriorEntityPartition.Result partition)
|
||||
{
|
||||
if (_lookInFrames.Count == 0)
|
||||
return;
|
||||
|
|
@ -521,16 +475,7 @@ public sealed class RetailPViewRenderer
|
|||
i,
|
||||
cellId,
|
||||
_cellStaticScratch);
|
||||
DrawEntityRouteOrLegacy(
|
||||
ctx,
|
||||
passes,
|
||||
frameEntityPasses,
|
||||
in frameView,
|
||||
RenderFrameCandidateRoute.LookInObject,
|
||||
i,
|
||||
cellId,
|
||||
_cellStaticScratch,
|
||||
_oneCell);
|
||||
passes.DrawEntityBucket(ctx, _cellStaticScratch, _oneCell);
|
||||
|
||||
// The cell-particles pass for look-in cells — retail's
|
||||
// nested DrawCells draws objects WITH their emitters.
|
||||
|
|
@ -547,9 +492,7 @@ public sealed class RetailPViewRenderer
|
|||
IRetailPViewPassExecutor passes,
|
||||
ClipFrameAssembly clipAssembly,
|
||||
InteriorEntityPartition.Result partition,
|
||||
ViewconeCuller viewcone,
|
||||
IRenderFrameEntityPassExecutor? frameEntityPasses,
|
||||
in RenderFrameView frameView)
|
||||
ViewconeCuller viewcone)
|
||||
{
|
||||
if (clipAssembly.OutsideViewSlices.Length == 0)
|
||||
return;
|
||||
|
|
@ -591,37 +534,15 @@ public sealed class RetailPViewRenderer
|
|||
probeSliceIndex,
|
||||
0,
|
||||
_outdoorStaticScratch);
|
||||
RenderFrameEntityDrawRequest? entityDraw =
|
||||
frameEntityPasses is null
|
||||
? null
|
||||
: new RenderFrameEntityDrawRequest(
|
||||
frameView,
|
||||
RenderFrameCandidateRoute.LandscapeOutdoorStatic,
|
||||
probeSliceIndex,
|
||||
0,
|
||||
ctx.PlayerLandblockId ?? 0);
|
||||
probeSliceIndex++;
|
||||
passes.DrawLandscapeSlice(
|
||||
ctx,
|
||||
new RetailPViewLandscapeSliceContext(
|
||||
slice,
|
||||
_outdoorStaticScratch)
|
||||
{
|
||||
EntityDraw = entityDraw,
|
||||
});
|
||||
passes.DrawLandscapeSlice(ctx, new RetailPViewLandscapeSliceContext(slice, _outdoorStaticScratch));
|
||||
}
|
||||
|
||||
// #124: far-building look-ins draw HERE — still inside the landscape
|
||||
// stage (their punches mark against the terrain/exterior depth just
|
||||
// drawn), strictly BEFORE the depth clear + seals below, matching
|
||||
// retail's LScape::draw placement (DrawCells pc:432719 vs 432732/432785).
|
||||
DrawBuildingLookIns(
|
||||
ctx,
|
||||
passes,
|
||||
clipAssembly,
|
||||
partition,
|
||||
frameEntityPasses,
|
||||
in frameView);
|
||||
DrawBuildingLookIns(ctx, passes, clipAssembly, partition);
|
||||
|
||||
// LATE phase (per slice): outside-stage dynamics' meshes (#118 — drawn
|
||||
// pre-clear so the seal protects their aperture pixels; AFTER the
|
||||
|
|
@ -670,25 +591,9 @@ public sealed class RetailPViewRenderer
|
|||
probeSliceIndex,
|
||||
0,
|
||||
_outdoorStaticScratch);
|
||||
RenderFrameEntityDrawRequest? entityDraw =
|
||||
frameEntityPasses is null
|
||||
? null
|
||||
: new RenderFrameEntityDrawRequest(
|
||||
frameView,
|
||||
RenderFrameCandidateRoute.LandscapeOutsideDynamic,
|
||||
probeSliceIndex,
|
||||
0,
|
||||
ctx.PlayerLandblockId ?? 0);
|
||||
probeSliceIndex++;
|
||||
passes.DrawLandscapeSliceLate(
|
||||
ctx,
|
||||
new RetailPViewLandscapeLateSliceContext(
|
||||
slice,
|
||||
_outdoorStaticScratch,
|
||||
_lateParticleOwnerScratch)
|
||||
{
|
||||
EntityDraw = entityDraw,
|
||||
});
|
||||
passes.DrawLandscapeSliceLate(ctx, new RetailPViewLandscapeLateSliceContext(
|
||||
slice, _outdoorStaticScratch, _lateParticleOwnerScratch));
|
||||
}
|
||||
|
||||
// #131: UNATTACHED emitters (AttachedObjectId == 0 — portal swirls,
|
||||
|
|
@ -797,9 +702,7 @@ public sealed class RetailPViewRenderer
|
|||
IRetailPViewPassExecutor passes,
|
||||
InteriorEntityPartition.Result partition,
|
||||
ViewconeCuller viewcone,
|
||||
bool rootIsOutdoor,
|
||||
IRenderFrameEntityPassExecutor? frameEntityPasses,
|
||||
in RenderFrameView frameView)
|
||||
bool rootIsOutdoor)
|
||||
{
|
||||
if (partition.Dynamics.Count == 0)
|
||||
return;
|
||||
|
|
@ -846,16 +749,7 @@ public sealed class RetailPViewRenderer
|
|||
0,
|
||||
_dynamicsScratch);
|
||||
passes.UseIndoorMembershipOnlyRouting();
|
||||
DrawEntityRouteOrLegacy(
|
||||
ctx,
|
||||
passes,
|
||||
frameEntityPasses,
|
||||
in frameView,
|
||||
RenderFrameCandidateRoute.DynamicLast,
|
||||
0,
|
||||
0,
|
||||
_dynamicsScratch,
|
||||
visibleCellIds: null);
|
||||
passes.DrawEntityBucket(ctx, _dynamicsScratch, visibleCellIds: null);
|
||||
|
||||
// #121: dynamics' attached emitters (portal swirls, creature effects)
|
||||
// gate through the SAME cone-surviving owner set as their meshes —
|
||||
|
|
@ -882,9 +776,7 @@ public sealed class RetailPViewRenderer
|
|||
ClipFrameAssembly clipAssembly,
|
||||
HashSet<uint> drawableCells,
|
||||
InteriorEntityPartition.Result partition,
|
||||
ViewconeCuller viewcone,
|
||||
IRenderFrameEntityPassExecutor? frameEntityPasses,
|
||||
in RenderFrameView frameView)
|
||||
ViewconeCuller viewcone)
|
||||
{
|
||||
// T1: per-cell STATIC object lists only (dat-baked 0x40 statics) —
|
||||
// dynamics moved to DrawDynamicsLast. Far→near with the cells, after
|
||||
|
|
@ -948,16 +840,7 @@ public sealed class RetailPViewRenderer
|
|||
0,
|
||||
_allCellStatics);
|
||||
passes.UseIndoorMembershipOnlyRouting();
|
||||
DrawEntityRouteOrLegacy(
|
||||
ctx,
|
||||
passes,
|
||||
frameEntityPasses,
|
||||
in frameView,
|
||||
RenderFrameCandidateRoute.CellStatic,
|
||||
0,
|
||||
0,
|
||||
_allCellStatics,
|
||||
_cellObjCells);
|
||||
passes.DrawEntityBucket(ctx, _allCellStatics, _cellObjCells);
|
||||
}
|
||||
|
||||
// Cell-particle pass — consolidated across ALL visible cells into ONE
|
||||
|
|
@ -980,35 +863,6 @@ public sealed class RetailPViewRenderer
|
|||
new RetailPViewCellSliceContext(0u, NoClipSlice, _allCellStatics));
|
||||
}
|
||||
|
||||
private static void DrawEntityRouteOrLegacy(
|
||||
RetailPViewFrameInput frame,
|
||||
IRetailPViewPassExecutor passes,
|
||||
IRenderFrameEntityPassExecutor? frameEntityPasses,
|
||||
in RenderFrameView frameView,
|
||||
RenderFrameCandidateRoute route,
|
||||
int routeIndex,
|
||||
uint cellId,
|
||||
IReadOnlyList<WorldEntity> legacyEntities,
|
||||
HashSet<uint>? visibleCellIds)
|
||||
{
|
||||
if (frameEntityPasses is not null)
|
||||
{
|
||||
frameEntityPasses.DrawEntityRoute(
|
||||
frame.Camera,
|
||||
in frameView,
|
||||
route,
|
||||
routeIndex,
|
||||
cellId,
|
||||
frame.PlayerLandblockId ?? 0);
|
||||
return;
|
||||
}
|
||||
|
||||
passes.DrawEntityBucket(
|
||||
frame,
|
||||
legacyEntities,
|
||||
visibleCellIds);
|
||||
}
|
||||
|
||||
// T3 scratch lists (render thread only; cleared per use).
|
||||
private readonly List<WorldEntity> _outdoorStaticScratch = new();
|
||||
private readonly List<WorldEntity> _cellStaticScratch = new();
|
||||
|
|
@ -1446,10 +1300,7 @@ public sealed class RetailPViewFrameResult
|
|||
|
||||
public readonly record struct RetailPViewLandscapeSliceContext(
|
||||
ClipViewSlice Slice,
|
||||
IReadOnlyList<WorldEntity> OutdoorEntities)
|
||||
{
|
||||
internal RenderFrameEntityDrawRequest? EntityDraw { get; init; }
|
||||
}
|
||||
IReadOnlyList<WorldEntity> OutdoorEntities);
|
||||
|
||||
/// <summary>#131/#132: the late landscape phase's per-slice payload —
|
||||
/// outside-stage dynamics to mesh-draw, plus the full scene-particle owner
|
||||
|
|
@ -1457,10 +1308,7 @@ public readonly record struct RetailPViewLandscapeSliceContext(
|
|||
public readonly record struct RetailPViewLandscapeLateSliceContext(
|
||||
ClipViewSlice Slice,
|
||||
IReadOnlyList<WorldEntity> Dynamics,
|
||||
IReadOnlyList<WorldEntity> ParticleOwners)
|
||||
{
|
||||
internal RenderFrameEntityDrawRequest? EntityDraw { get; init; }
|
||||
}
|
||||
IReadOnlyList<WorldEntity> ParticleOwners);
|
||||
|
||||
public readonly record struct RetailPViewCellSliceContext(
|
||||
uint CellId,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue