contributionBetween function
Differences two RGBA frames of width by height.
Alpha is deliberately not compared. Every frame this engine hands back is opaque, so a difference there would be a bug in the readback rather than a contribution from a pass, and counting it would put a constant under every measurement.
Implementation
PassContribution contributionBetween(
ByteData without,
ByteData with_, {
required int width,
required int height,
}) {
final pixels = width * height;
if (without.lengthInBytes != pixels * 4 ||
with_.lengthInBytes != pixels * 4) {
throw ArgumentError(
'the two frames must both be $width x $height RGBA — got '
'${without.lengthInBytes} and ${with_.lengthInBytes} bytes, and a '
'difference between frames of different sizes is not a contribution',
);
}
var changed = 0;
var worst = 0;
var sum = 0;
var left = width;
var top = height;
var right = -1;
var bottom = -1;
for (var i = 0; i < pixels; i++) {
final at = i * 4;
var most = 0;
for (var c = 0; c < 3; c++) {
final delta = (without.getUint8(at + c) - with_.getUint8(at + c)).abs();
if (delta > most) most = delta;
}
if (most == 0) continue;
changed++;
sum += most;
if (most > worst) worst = most;
final x = i % width;
final y = i ~/ width;
if (x < left) left = x;
if (x > right) right = x;
if (y < top) top = y;
if (y > bottom) bottom = y;
}
return PassContribution(
changedPixels: changed,
totalPixels: pixels,
worstChannelDelta: worst,
meanChannelDelta: changed == 0 ? 0.0 : sum / changed,
bounds: changed == 0
? null
: (left: left, top: top, right: right, bottom: bottom),
);
}