perf(mornye): reuse exact luminance contributions for contrast sampling

Use 6 KiB of lookup tables to avoid repeated Color allocations and exponentiation during frame sampling. Exhaustively verify exact Flutter luminance parity for every 8-bit RGB value.
This commit is contained in:
zarzet
2026-09-20 17:20:52 +07:00
parent 6038ce5777
commit 5053ed93ee
2 changed files with 47 additions and 3 deletions
+28 -3
View File
@@ -1,9 +1,35 @@
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
// Readback uses 8-bit sRGB. Cache each channel's exact Flutter luminance
// contribution (6 KiB total), avoiding three powers and a Color per pixel.
final _redLuminance = Float64List.fromList(
List.generate(
256,
(value) => Color.fromARGB(255, value, 0, 0).computeLuminance(),
),
);
final _greenLuminance = Float64List.fromList(
List.generate(
256,
(value) => Color.fromARGB(255, 0, value, 0).computeLuminance(),
),
);
final _blueLuminance = Float64List.fromList(
List.generate(
256,
(value) => Color.fromARGB(255, 0, 0, value).computeLuminance(),
),
);
/// Matches [Color.computeLuminance] for an RGB pixel from an 8-bit readback.
double artworkPixelLuminance(int red, int green, int blue) =>
_redLuminance[red] + _greenLuminance[green] + _blueLuminance[blue];
/// Samples rendered video and its fade, rather than a static album palette.
/// Read back only 48 pixels across, at most three times a second when visible.
class MornyeArtworkContrast extends StatefulWidget {
@@ -95,12 +121,11 @@ class _MornyeArtworkContrastState extends State<MornyeArtworkContrast> {
for (var y = top; y < bottom; y++) {
for (var x = left; x < right; x++) {
final index = (y * image.width + x) * 4;
luminance += Color.fromARGB(
255,
luminance += artworkPixelLuminance(
pixels.getUint8(index),
pixels.getUint8(index + 1),
pixels.getUint8(index + 2),
).computeLuminance();
);
count++;
}
}
+19
View File
@@ -3,6 +3,25 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:spotiflac_android/widgets/mornye_artwork_contrast.dart';
void main() {
test('readback luminance matches Flutter exactly for every RGB pixel', () {
for (var red = 0; red < 256; red++) {
for (var green = 0; green < 256; green++) {
for (var blue = 0; blue < 256; blue++) {
final expected = Color.fromARGB(
255,
red,
green,
blue,
).computeLuminance();
final actual = artworkPixelLuminance(red, green, blue);
if (actual != expected) {
fail('RGB($red, $green, $blue): $actual != $expected');
}
}
}
}
});
testWidgets('foreground follows changing frames separately for each region', (
tester,
) async {