fusedDrawTiles function

List<GlassFusedTile>? fusedDrawTiles({
  1. required List<Rect> boxes,
  2. required double reach,
  3. required double cullMargin,
  4. int maxTiles = kMaxFusedTiles,
})

Splits a fused draw into disjoint rectangles, each carrying only the shapes that can change a pixel inside it.

Returns null when the split is refused as too fine (maxTiles); the caller then draws the one quad it always could. An empty list means there was nothing to draw.

Why the area can shrink at all. The fold is bounded below by min_i d_i - delta(n) * k (_foldDepression), so the silhouette lies inside the union of the members' own boxes each grown by reach — not inside the bounding box of all of them grown by the same. On a clustered layout the two are nearly the same rectangle; on a scattered one the second is the screen and the first is twelve panels' worth of it.

Why a shape can be dropped from a tile, exactly. A shape farther than (1 + 2 * delta(n)) * k from the tile — cullMargin — cannot change one bit of any fragment in it, and that is arithmetic rather than a tolerance. Run the fold in the order the uniforms are in. Before the first near shape is folded the running d is at least min_far - delta(n) * k, which that margin puts at (1 + delta(n)) * k or more; a near shape sits at delta(n) * k or less wherever the draw is not already transparent, so |d_i - d| >= k, h is exactly zero, and the fold leaves min(d_i, d) with mix(n, n_i, 0) — the near shape's own distance and its own normal, which is what it would have found had the far ones never been there. After that first near shape d <= delta(n) * k, so every later far one is k away or more and is skipped for the same reason. The shader's own uCullK branch is this same identity spent on speed, which is why the two are independent: dropping a shape here is exact whether or not the branch runs.

Why the rectangles must not overlap. The draw is translucent (vec4(col, 1) * coverage), so a pixel covered twice composites twice and the seam is visible. The decomposition below is a partition by construction — vertical slabs at every box edge, disjoint y-intervals inside each — and the draws go out with antialiasing off, so the rasterizer's own rule gives each device pixel to exactly one of two tiles that share an edge.

Implementation

List<GlassFusedTile>? fusedDrawTiles({
  required List<Rect> boxes,
  required double reach,
  required double cullMargin,
  int maxTiles = kMaxFusedTiles,
}) {
  final int n = boxes.length;
  if (n == 0) {
    return const <GlassFusedTile>[];
  }
  final covers = <Rect>[for (final Rect b in boxes) b.inflate(reach)];

  // One decomposition per connected run of overlapping boxes, and that is the
  // difference between a dozen rectangles and forty. A single sweep over all of
  // them splits every box at every other box's edges — including the edges of
  // one on the far side of the screen, which shares no pixel with it and cannot
  // change what is drawn there. Boxes that do not overlap are already disjoint
  // rectangles, so their decompositions cannot collide and each can be taken on
  // its own. Measured on the corpus: twelve scattered panels fall into 14-21
  // rectangles this way and into 39-55 without it, for the same area.
  final rects = <Rect>[];
  for (final List<int> part in _overlapping(covers)) {
    final slice = <Rect>[for (final int i in part) covers[i]];
    // Every x where the set of boxes in force can change, so a slab between two
    // of them is spanned by the same boxes from top to bottom.
    final xs = <double>{
      for (final Rect r in slice) ...<double>[r.left, r.right],
    }.toList(growable: false)..sort();

    // The run of slabs whose y-intervals are identical, so a single box comes
    // back as a single rectangle rather than as one per edge in the layout.
    List<double>? run;
    double runLeft = 0;
    for (var j = 0; j + 1 < xs.length; j++) {
      final List<double> intervals = _slabIntervals(slice, xs[j], xs[j + 1]);
      if (run != null && _sameSpans(run, intervals)) {
        continue;
      }
      if (run != null) {
        _emitSpans(rects, runLeft, xs[j], run);
      }
      run = intervals.isEmpty ? null : intervals;
      runLeft = xs[j];
    }
    if (run != null) {
      _emitSpans(rects, runLeft, xs.last, run);
    }
    if (rects.length > maxTiles) {
      return null;
    }
  }
  return <GlassFusedTile>[
    for (final Rect rect in rects)
      GlassFusedTile(rect, <int>[
        for (var i = 0; i < n; i++)
          if (_within(boxes[i], cullMargin, rect)) i,
      ]),
  ];
}