composite method
Flattens layers onto target in descending Z-index order (topmost first).
Uses a bit-packed Uint32List occlusion map to prevent redundant writes and supports early exit if all destination cells are covered by opaque cells.
Implementation
void composite({
required Buffer target,
required List<LayeredBuffer> layers,
}) {
Tracer.record(_traceCompositeId, Phase.begin, TraceCategory.compositor);
try {
if (layers.isEmpty) return;
// Stable sort in descending order (highest zIndex first)
final indexedLayers = List.generate(layers.length, (i) => (i, layers[i]));
indexedLayers.sort((a, b) {
final cmp = b.$2.zIndex.compareTo(a.$2.zIndex);
if (cmp != 0) return cmp;
return b.$1.compareTo(a.$1);
});
final sortedLayers = List.generate(
indexedLayers.length,
(i) => indexedLayers[i].$2,
);
_poolIndex = 0;
_compositeRecursive(target, sortedLayers, 0);
// Premultiply final alpha against black for any remaining transparent pixels.
final attrs = target.attributes;
final len = attrs.length;
for (var i = 0; i < len; i += 3) {
final fg = attrs[i];
if (fg != 0 && ((fg >> 24) & 0xFF) != 255) {
attrs[i] = _premultiplyBlack(fg);
}
final bg = attrs[i + 1];
if (bg != 0 && ((bg >> 24) & 0xFF) != 255) {
attrs[i + 1] = _premultiplyBlack(bg);
}
}
} finally {
Tracer.record(_traceCompositeId, Phase.end, TraceCategory.compositor);
}
}