Class RenderAggregator
The RenderAggregator implements the painter's algorithm: shapes are sorted
from back to front (highest Z-depth first) and then painted sequentially. This ensures
that closer shapes correctly occlude those behind them.
When two shapes have the same Z-depth, their unique AbstractCoordinateShape.shapeId
is used as a tiebreaker to guarantee deterministic rendering order.
This class is used internally by ShapeCollection during the render pipeline.
You typically do not need to interact with it directly.
- See Also:
-
Constructor Summary
ConstructorsConstructorDescriptionCreates a new render aggregator.RenderAggregator(int slot) Creates an aggregator bound to a projection buffer slot. -
Method Summary
Modifier and TypeMethodDescriptionvoidbinForTiles(int tilesX, int tilesY, int originX, int width, int height, ExecutorService executor) Bins the sorted queue per rectangular paint tile by screen-space overlap.voidmergeAllParallel(List<RenderAggregator> parts, ExecutorService executor) Merges many chunk aggregators into this one, producing a flat array thatsort()consumes directly.voidmergeFrom(RenderAggregator other) Merges all shapes queued in another aggregator into this one.voidpaint(RenderingContext renderBuffer) Sorts all queued shapes by Z-depth (back to front) and paints them.voidpaintSorted(RenderingContext renderBuffer) Paints all shapes that have already been sorted.voidQueues a shape for rendering.voidreset()Clears all queued shapes, preparing for a new render frame.intsize()Returns the number of shapes currently queued.voidsort()Sorts all queued shapes by Z-depth (back to front).voidsort(ExecutorService executor) Sorts the queue by (Z, shapeId), using an instrumented parallel merge sort on the given executor for large queues.
-
Constructor Details
-
RenderAggregator
public RenderAggregator()Creates a new render aggregator. -
RenderAggregator
public RenderAggregator(int slot) Creates an aggregator bound to a projection buffer slot. Sorting and tile binning read the shapes' screen state for this slot, so the double-buffered pipeline can fill one slot's aggregator while the other slot's aggregator is still being painted.- Parameters:
slot- the buffer slot (0 or 1) this aggregator serves
-
-
Method Details
-
paint
Sorts all queued shapes by Z-depth (back to front) and paints them.- Parameters:
renderBuffer- the rendering context to paint shapes into
-
sort
public void sort()Sorts all queued shapes by Z-depth (back to front). Must be called after all shapes are queued and before paintSorted. Uses a parallel sort for large queues. -
sort
Sorts the queue by (Z, shapeId), using an instrumented parallel merge sort on the given executor for large queues. UnlikeArrays.parallelSort, every subtask is recorded on the thread-activity timeline, so the sort does not appear as phantom idle time on the worker rows. Deterministic: (Z, shapeId) is a total order, so any merge schedule yields the same result.- Parameters:
executor- executor for parallel sorting, or null for serial
-
paintSorted
Paints all shapes that have already been sorted. This method can be called multiple times with different segment contexts for multi-threaded rendering.If
binForTiles(int, int, int, int, int, java.util.concurrent.ExecutorService)was called and the given context's bounds exactly match one tile, only that tile's bin is iterated — shapes that cannot touch the tile are skipped entirely. Otherwise the full sorted queue is iterated (every shape clips itself to the context bounds, so the painted result is identical).- Parameters:
renderBuffer- the rendering context to paint shapes into
-
binForTiles
public void binForTiles(int tilesX, int tilesY, int originX, int width, int height, ExecutorService executor) Bins the sorted queue per rectangular paint tile by screen-space overlap. Must be called aftersort()and before tile painting. Built once per frame (per eye, in stereo) on the render thread; the bins are read-only during parallel painting.Each bin preserves the global (Z, shapeId) sort order, so painting a bin produces exactly the same pixels as painting the full queue into that tile. Shapes are assigned with their
AbstractCoordinateShape.onScreenMinY(int)/onScreenMaxY/onScreenMinX/onScreenMaxXbounds, which include a per-shape margin for paint output extending past the vertices (thick lines, billboards, text glyphs).Mouse hit detection is unaffected: a hit requires the cursor to be inside the shape, so the shape always overlaps the tile containing the cursor.
When an executor is given and the queue is large, the sorted list is scanned in per-core chunks concurrently and the per-chunk bins are concatenated in chunk order, preserving the global sort order.
- Parameters:
tilesX- tile columns across the viewporttilesY- tile rows down the viewportoriginX- X origin of the tiled viewport (eye offset in stereo)width- tiled viewport width in pixelsheight- full render height in pixelsexecutor- executor for parallel binning, or null for serial
-
size
public int size()Returns the number of shapes currently queued.- Returns:
- the shape count
-
queueShapeForRendering
Queues a shape for rendering. Called during the transform phase.- Parameters:
shape- the shape to queue
-
mergeFrom
Merges all shapes queued in another aggregator into this one. Used to combine the per-task queues produced by the parallel transform phase. Merge order does not affect the final render order:sort()is deterministic on (Z, shapeId).- Parameters:
other- the aggregator whose queued shapes are moved into this one
-
mergeAllParallel
Merges many chunk aggregators into this one, producing a flat array thatsort()consumes directly. The per-chunk lists are copied into the merged array by parallel copy tasks on the given executor — the old per-chunkaddAllchain (reallocating the target list serially) is gone. Merge order is irrelevant: the following sort re-establishes deterministic (Z, shapeId) order.- Parameters:
parts- chunk aggregators to mergeexecutor- executor for the parallel copy, or null for serial
-
reset
public void reset()Clears all queued shapes, preparing for a new render frame.
-