Skip to content

Commit 5a11904

Browse files
authored
Relands "Wide gamut framework gradient test (flutter#153976)" (flutter#157643)
This was reverted because it failed to run. Colors were getting clamped in the dithering fragment shader. One change was made when relanding, i increased the epsilon for the radial and conical gradients. They don't appear to give back the exact color you asked for. Do not land until flutter/engine#56140 is rolled into the framework. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent 9327c24 commit 5a11904

File tree

2 files changed

+175
-21
lines changed

2 files changed

+175
-21
lines changed

dev/integration_tests/wide_gamut_test/integration_test/app_test.dart

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ bool _isAlmost(double x, double y, double epsilon) {
4444
List<double> _deepRed = <double>[1.0931, -0.2268, -0.1501];
4545

4646
bool _findRGBAF16Color(
47-
Uint8List bytes, int width, int height, List<double> color) {
47+
Uint8List bytes, int width, int height, List<double> color,
48+
{required double epsilon}) {
4849
final ByteData byteData = ByteData.sublistView(bytes);
4950
expect(bytes.lengthInBytes, width * height * 8);
5051
expect(bytes.lengthInBytes, byteData.lengthInBytes);
@@ -54,17 +55,18 @@ bool _findRGBAF16Color(
5455
final double blue = _decodeHalf((pixel >> 32) & 0xffff);
5556
final double green = _decodeHalf((pixel >> 16) & 0xffff);
5657
final double red = _decodeHalf((pixel >> 0) & 0xffff);
57-
if (_isAlmost(red, color[0], 0.01) &&
58-
_isAlmost(green, color[1], 0.01) &&
59-
_isAlmost(blue, color[2], 0.01)) {
58+
if (_isAlmost(red, color[0], epsilon) &&
59+
_isAlmost(green, color[1], epsilon) &&
60+
_isAlmost(blue, color[2], epsilon)) {
6061
foundDeepRed = true;
6162
}
6263
}
6364
return foundDeepRed;
6465
}
6566

6667
bool _findBGRA10Color(
67-
Uint8List bytes, int width, int height, List<double> color) {
68+
Uint8List bytes, int width, int height, List<double> color,
69+
{required double epsilon}) {
6870
final ByteData byteData = ByteData.sublistView(bytes);
6971
expect(bytes.lengthInBytes, width * height * 8);
7072
expect(bytes.lengthInBytes, byteData.lengthInBytes);
@@ -74,17 +76,17 @@ bool _findBGRA10Color(
7476
final double blue = _decodeBGR10((pixel >> 6) & 0x3ff);
7577
final double green = _decodeBGR10((pixel >> 22) & 0x3ff);
7678
final double red = _decodeBGR10((pixel >> 38) & 0x3ff);
77-
if (_isAlmost(red, color[0], 0.01) &&
78-
_isAlmost(green, color[1], 0.01) &&
79-
_isAlmost(blue, color[2], 0.01)) {
79+
if (_isAlmost(red, color[0], epsilon) &&
80+
_isAlmost(green, color[1], epsilon) &&
81+
_isAlmost(blue, color[2], epsilon)) {
8082
foundDeepRed = true;
8183
}
8284
}
8385
return foundDeepRed;
8486
}
8587

86-
bool _findBGR10Color(
87-
Uint8List bytes, int width, int height, List<double> color) {
88+
bool _findBGR10Color(Uint8List bytes, int width, int height, List<double> color,
89+
{required double epsilon}) {
8890
final ByteData byteData = ByteData.sublistView(bytes);
8991
expect(bytes.lengthInBytes, width * height * 4);
9092
expect(bytes.lengthInBytes, byteData.lengthInBytes);
@@ -94,23 +96,27 @@ bool _findBGR10Color(
9496
final double blue = _decodeBGR10(pixel & 0x3ff);
9597
final double green = _decodeBGR10((pixel >> 10) & 0x3ff);
9698
final double red = _decodeBGR10((pixel >> 20) & 0x3ff);
97-
if (_isAlmost(red, color[0], 0.01) &&
98-
_isAlmost(green, color[1], 0.01) &&
99-
_isAlmost(blue, color[2], 0.01)) {
99+
if (_isAlmost(red, color[0], epsilon) &&
100+
_isAlmost(green, color[1], epsilon) &&
101+
_isAlmost(blue, color[2], epsilon)) {
100102
foundDeepRed = true;
101103
}
102104
}
103105
return foundDeepRed;
104106
}
105107

106-
bool _findColor(List<dynamic> result, List<double> color) {
108+
bool _findColor(List<dynamic> result, List<double> color,
109+
{double epsilon = 0.01}) {
107110
expect(result, isNotNull);
108111
expect(result.length, 4);
109112
final [int width, int height, String format, Uint8List bytes] = result;
110113
return switch (format) {
111-
'MTLPixelFormatBGR10_XR' => _findBGR10Color(bytes, width, height, color),
112-
'MTLPixelFormatBGRA10_XR' => _findBGRA10Color(bytes, width, height, color),
113-
'MTLPixelFormatRGBA16Float' => _findRGBAF16Color(bytes, width, height, color),
114+
'MTLPixelFormatBGR10_XR' =>
115+
_findBGR10Color(bytes, width, height, color, epsilon: epsilon),
116+
'MTLPixelFormatBGRA10_XR' =>
117+
_findBGRA10Color(bytes, width, height, color, epsilon: epsilon),
118+
'MTLPixelFormatRGBA16Float' =>
119+
_findRGBAF16Color(bytes, width, height, color, epsilon: epsilon),
114120
_ => fail('Unsupported pixel format: $format'),
115121
};
116122
}
@@ -157,7 +163,8 @@ void main() {
157163
expect(_findColor(result, _deepRed), isTrue);
158164
expect(_findColor(result, <double>[0.0, 1.0, 0.0]), isTrue);
159165
});
160-
testWidgets('draw image with wide gamut works', (WidgetTester tester) async {
166+
testWidgets('draw image with wide gamut works',
167+
(WidgetTester tester) async {
161168
app.run(app.Setup.drawnImage);
162169
await tester.pumpAndSettle(const Duration(seconds: 2));
163170

@@ -166,7 +173,8 @@ void main() {
166173
await channel.invokeMethod('test') as List<Object?>;
167174
expect(_findColor(result, <double>[0.0, 1.0, 0.0]), isTrue);
168175
});
169-
testWidgets('draw container with wide gamut works', (WidgetTester tester) async {
176+
testWidgets('draw container with wide gamut works',
177+
(WidgetTester tester) async {
170178
app.run(app.Setup.container);
171179
await tester.pumpAndSettle(const Duration(seconds: 2));
172180

@@ -175,5 +183,49 @@ void main() {
175183
await channel.invokeMethod('test') as List<Object?>;
176184
expect(_findColor(result, _deepRed), isTrue);
177185
});
186+
187+
testWidgets('draw wide gamut linear gradient works',
188+
(WidgetTester tester) async {
189+
app.run(app.Setup.linearGradient);
190+
await tester.pumpAndSettle(const Duration(seconds: 2));
191+
192+
const MethodChannel channel = MethodChannel('flutter/screenshot');
193+
final List<Object?> result =
194+
await channel.invokeMethod('test') as List<Object?>;
195+
expect(_findColor(result, _deepRed), isTrue);
196+
});
197+
198+
testWidgets('draw wide gamut radial gradient works',
199+
(WidgetTester tester) async {
200+
app.run(app.Setup.radialGradient);
201+
await tester.pumpAndSettle(const Duration(seconds: 2));
202+
203+
const MethodChannel channel = MethodChannel('flutter/screenshot');
204+
final List<Object?> result =
205+
await channel.invokeMethod('test') as List<Object?>;
206+
expect(_findColor(result, _deepRed, epsilon: 0.05), isTrue);
207+
});
208+
209+
testWidgets('draw wide gamut conical gradient works',
210+
(WidgetTester tester) async {
211+
app.run(app.Setup.conicalGradient);
212+
await tester.pumpAndSettle(const Duration(seconds: 2));
213+
214+
const MethodChannel channel = MethodChannel('flutter/screenshot');
215+
final List<Object?> result =
216+
await channel.invokeMethod('test') as List<Object?>;
217+
expect(_findColor(result, _deepRed, epsilon: 0.05), isTrue);
218+
});
219+
220+
testWidgets('draw wide gamut sweep gradient works',
221+
(WidgetTester tester) async {
222+
app.run(app.Setup.sweepGradient);
223+
await tester.pumpAndSettle(const Duration(seconds: 2));
224+
225+
const MethodChannel channel = MethodChannel('flutter/screenshot');
226+
final List<Object?> result =
227+
await channel.invokeMethod('test') as List<Object?>;
228+
expect(_findColor(result, _deepRed), isTrue);
229+
});
178230
});
179231
}

dev/integration_tests/wide_gamut_test/lib/main.dart

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ const String _displayP3Logo =
137137
'gr3yrjmlwqXLjmWw1O2I5Wmp9Xxjyh+AVIZ6ADIAqcwClakzeMgApDILVKbO4CED'
138138
'kMosUJk6g4dUBuRfvf1am9VRqzYAAAAASUVORK5CYII=';
139139

140-
void main() => run(Setup.container);
140+
void main() => run(Setup.sweepGradient);
141141

142142
enum Setup {
143143
none,
@@ -146,6 +146,10 @@ enum Setup {
146146
blur,
147147
drawnImage,
148148
container,
149+
linearGradient,
150+
radialGradient,
151+
conicalGradient,
152+
sweepGradient,
149153
}
150154

151155
void run(Setup setup) {
@@ -265,7 +269,14 @@ class _MyHomePageState extends State<MyHomePage> {
265269
_loadImage().then((ui.Image? value) => setState(() { _image = value; }));
266270
case Setup.drawnImage:
267271
_drawImage().then((ui.Image? value) => setState(() { _image = value; }));
268-
case Setup.image || Setup.blur || Setup.none || Setup.container:
272+
case Setup.image ||
273+
Setup.blur ||
274+
Setup.none ||
275+
Setup.container ||
276+
Setup.linearGradient ||
277+
Setup.radialGradient ||
278+
Setup.conicalGradient ||
279+
Setup.sweepGradient:
269280
break;
270281
}
271282
super.initState();
@@ -308,6 +319,97 @@ class _MyHomePageState extends State<MyHomePage> {
308319
green: 0,
309320
blue: 0,
310321
colorSpace: ui.ColorSpace.displayP3));
322+
case Setup.linearGradient:
323+
imageWidget = Container(
324+
width: 100,
325+
height: 100,
326+
decoration: const BoxDecoration(
327+
gradient: LinearGradient(
328+
begin: Alignment.topLeft,
329+
end: Alignment.bottomRight,
330+
colors: <Color>[
331+
Color.from(
332+
alpha: 1,
333+
red: 1,
334+
green: 0,
335+
blue: 0,
336+
colorSpace: ui.ColorSpace.displayP3),
337+
Color.from(
338+
alpha: 1,
339+
red: 0,
340+
green: 1,
341+
blue: 0,
342+
colorSpace: ui.ColorSpace.displayP3)],
343+
),
344+
),
345+
);
346+
case Setup.radialGradient:
347+
imageWidget = Container(
348+
width: 100,
349+
height: 100,
350+
decoration: const BoxDecoration(
351+
gradient: RadialGradient(
352+
colors: <Color>[
353+
Color.from(
354+
alpha: 1,
355+
red: 1,
356+
green: 0,
357+
blue: 0,
358+
colorSpace: ui.ColorSpace.displayP3),
359+
Color.from(
360+
alpha: 1,
361+
red: 0,
362+
green: 1,
363+
blue: 0,
364+
colorSpace: ui.ColorSpace.displayP3)],
365+
),
366+
),
367+
);
368+
case Setup.conicalGradient:
369+
imageWidget = Container(
370+
width: 100,
371+
height: 100,
372+
decoration: const BoxDecoration(
373+
gradient: RadialGradient(
374+
focal: Alignment(0.2, 0.2),
375+
colors: <Color>[
376+
Color.from(
377+
alpha: 1,
378+
red: 1,
379+
green: 0,
380+
blue: 0,
381+
colorSpace: ui.ColorSpace.displayP3),
382+
Color.from(
383+
alpha: 1,
384+
red: 0,
385+
green: 1,
386+
blue: 0,
387+
colorSpace: ui.ColorSpace.displayP3)],
388+
),
389+
),
390+
);
391+
case Setup.sweepGradient:
392+
imageWidget = Container(
393+
width: 100,
394+
height: 100,
395+
decoration: const BoxDecoration(
396+
gradient: SweepGradient(
397+
colors: <Color>[
398+
Color.from(
399+
alpha: 1,
400+
red: 1,
401+
green: 0,
402+
blue: 0,
403+
colorSpace: ui.ColorSpace.displayP3),
404+
Color.from(
405+
alpha: 1,
406+
red: 0,
407+
green: 1,
408+
blue: 0,
409+
colorSpace: ui.ColorSpace.displayP3)],
410+
),
411+
),
412+
);
311413
}
312414

313415
return Scaffold(

0 commit comments

Comments
 (0)