Class RenderAggregator

java.lang.Object
eu.svjatoslav.sixth.e3d.renderer.raster.RenderAggregator

public class RenderAggregator extends Object
Collects transformed shapes during a render frame and paints them in depth-sorted order.

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 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

      public void paint(RenderingContext renderBuffer)
      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

      public void sort(ExecutorService executor)
      Sorts the queue by (Z, shapeId), using an instrumented parallel merge sort on the given executor for large queues. Unlike Arrays.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

      public void paintSorted(RenderingContext renderBuffer)
      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 after sort() 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 / onScreenMaxX bounds, 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 viewport
      tilesY - tile rows down the viewport
      originX - X origin of the tiled viewport (eye offset in stereo)
      width - tiled viewport width in pixels
      height - full render height in pixels
      executor - executor for parallel binning, or null for serial
    • size

      public int size()
      Returns the number of shapes currently queued.
      Returns:
      the shape count
    • queueShapeForRendering

      public void queueShapeForRendering(AbstractCoordinateShape shape)
      Queues a shape for rendering. Called during the transform phase.
      Parameters:
      shape - the shape to queue
    • mergeFrom

      public void mergeFrom(RenderAggregator other)
      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

      public void mergeAllParallel(List<RenderAggregator> parts, ExecutorService executor)
      Merges many chunk aggregators into this one, producing a flat array that sort() consumes directly. The per-chunk lists are copied into the merged array by parallel copy tasks on the given executor — the old per-chunk addAll chain (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 merge
      executor - executor for the parallel copy, or null for serial
    • reset

      public void reset()
      Clears all queued shapes, preparing for a new render frame.