debugGlassFusedSplit top-level property
Whether a fused group is drawn as several rectangles instead of one.
The split changes no pixel — fusedDrawTiles carries the proof — so it can only be seen as a price, and what it trades runs both ways: fewer fragments, each folding fewer shapes, against more draw calls. On by default except on desktop, because what a draw costs is decided by whether the engine runs SDFs, and Dart can tell that only by the platform. Where it does not — Android always, iOS unless the app opts in — both GPUs that have been timed charge for the fragments. On Adreno 830 eleven rectangles cost 0.91x the one quad's frame and twenty cost 0.52x it, the glass over its floor 0.83x and 0.35x (D192). On the M2 iPad Pro the same two scenes cost 0.71-0.76x and 0.40-0.42x in GPU time, the glass over its floor 0.61-0.67x and 0.30-0.32x, two seeds (D194).
For a day the default was keyed on the declared hardware — the quad on Apple, from D190: on an Apple-silicon Mac eleven rectangles cost 3.2x the one quad and fifteen 5.8-6.3x. That run had one instrument, the raster thread's wall time, because a desktop's GPU tracer dies with its uptime; on the iPad, where both instruments read the same arms, the raster thread says +8-25% for the split while the GPU says -24…-60%, and the GPU is where the frame is spent (3-7 ms of 8.3 against 0.5-0.6). So D190 priced the raster thread, and the key answered the same for every declaration once the GPU had been asked — it was removed rather than kept as a switch that switches nothing.
It came back keyed on the platform for a day (D199): on an M3 Max in Metal
System Trace eleven rectangles cost 1.88x the quad's frame and fifteen
1.39x, because every shader rectangle there was three offscreen passes — a
white SDF mask, the shader and a kSrcIn blend (canvas.cc:2185-2209,
flutter/flutter#192994). The tiles asked for isAntiAlias = false, which
keeps a draw off that path, and the flag never arrived: it opened the
picture, where the recorder does not write a false it already holds and
Impeller starts from true (primeAliasedDraw). Primed, a tile is one
draw on macOS as well, and the split costs 0.94-0.95x the quad's frame on
the cluster and 0.70-0.75x on the scatter, two seeds (D200). So it ships on
every platform again, and nothing keys it.
Set null to return to the default.
Independent of debugGlassFoldCull: dropping a shape from a tile is exact whether or not the shader's own skip runs, so the arm that prices one does not silently price the other.
Set it before the tree mounts, and restore it afterwards. Setting it repaints every group already mounted, for the reason the cull's setter does: a retained layer would go on drawing the old way and the run would report the split as free.
Implementation
bool get debugGlassFusedSplit => _fusedSplit ?? debugGlassFusedSplitDefault;
Implementation
set debugGlassFusedSplit(bool? value) {
final bool was = debugGlassFusedSplit;
_fusedSplit = value;
if (debugGlassFusedSplit == was) {
return;
}
for (final RenderGlassGroup group in RenderGlassGroup._live) {
group.markNeedsPaint();
}
}