mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
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 https://github.com/flutter/engine/pull/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
This commit is contained in:
parent
9327c24d80
commit
5a11904383
@ -44,7 +44,8 @@ bool _isAlmost(double x, double y, double epsilon) {
|
||||
List<double> _deepRed = <double>[1.0931, -0.2268, -0.1501];
|
||||
|
||||
bool _findRGBAF16Color(
|
||||
Uint8List bytes, int width, int height, List<double> color) {
|
||||
Uint8List bytes, int width, int height, List<double> color,
|
||||
{required double epsilon}) {
|
||||
final ByteData byteData = ByteData.sublistView(bytes);
|
||||
expect(bytes.lengthInBytes, width * height * 8);
|
||||
expect(bytes.lengthInBytes, byteData.lengthInBytes);
|
||||
@ -54,9 +55,9 @@ bool _findRGBAF16Color(
|
||||
final double blue = _decodeHalf((pixel >> 32) & 0xffff);
|
||||
final double green = _decodeHalf((pixel >> 16) & 0xffff);
|
||||
final double red = _decodeHalf((pixel >> 0) & 0xffff);
|
||||
if (_isAlmost(red, color[0], 0.01) &&
|
||||
_isAlmost(green, color[1], 0.01) &&
|
||||
_isAlmost(blue, color[2], 0.01)) {
|
||||
if (_isAlmost(red, color[0], epsilon) &&
|
||||
_isAlmost(green, color[1], epsilon) &&
|
||||
_isAlmost(blue, color[2], epsilon)) {
|
||||
foundDeepRed = true;
|
||||
}
|
||||
}
|
||||
@ -64,7 +65,8 @@ bool _findRGBAF16Color(
|
||||
}
|
||||
|
||||
bool _findBGRA10Color(
|
||||
Uint8List bytes, int width, int height, List<double> color) {
|
||||
Uint8List bytes, int width, int height, List<double> color,
|
||||
{required double epsilon}) {
|
||||
final ByteData byteData = ByteData.sublistView(bytes);
|
||||
expect(bytes.lengthInBytes, width * height * 8);
|
||||
expect(bytes.lengthInBytes, byteData.lengthInBytes);
|
||||
@ -74,17 +76,17 @@ bool _findBGRA10Color(
|
||||
final double blue = _decodeBGR10((pixel >> 6) & 0x3ff);
|
||||
final double green = _decodeBGR10((pixel >> 22) & 0x3ff);
|
||||
final double red = _decodeBGR10((pixel >> 38) & 0x3ff);
|
||||
if (_isAlmost(red, color[0], 0.01) &&
|
||||
_isAlmost(green, color[1], 0.01) &&
|
||||
_isAlmost(blue, color[2], 0.01)) {
|
||||
if (_isAlmost(red, color[0], epsilon) &&
|
||||
_isAlmost(green, color[1], epsilon) &&
|
||||
_isAlmost(blue, color[2], epsilon)) {
|
||||
foundDeepRed = true;
|
||||
}
|
||||
}
|
||||
return foundDeepRed;
|
||||
}
|
||||
|
||||
bool _findBGR10Color(
|
||||
Uint8List bytes, int width, int height, List<double> color) {
|
||||
bool _findBGR10Color(Uint8List bytes, int width, int height, List<double> color,
|
||||
{required double epsilon}) {
|
||||
final ByteData byteData = ByteData.sublistView(bytes);
|
||||
expect(bytes.lengthInBytes, width * height * 4);
|
||||
expect(bytes.lengthInBytes, byteData.lengthInBytes);
|
||||
@ -94,23 +96,27 @@ bool _findBGR10Color(
|
||||
final double blue = _decodeBGR10(pixel & 0x3ff);
|
||||
final double green = _decodeBGR10((pixel >> 10) & 0x3ff);
|
||||
final double red = _decodeBGR10((pixel >> 20) & 0x3ff);
|
||||
if (_isAlmost(red, color[0], 0.01) &&
|
||||
_isAlmost(green, color[1], 0.01) &&
|
||||
_isAlmost(blue, color[2], 0.01)) {
|
||||
if (_isAlmost(red, color[0], epsilon) &&
|
||||
_isAlmost(green, color[1], epsilon) &&
|
||||
_isAlmost(blue, color[2], epsilon)) {
|
||||
foundDeepRed = true;
|
||||
}
|
||||
}
|
||||
return foundDeepRed;
|
||||
}
|
||||
|
||||
bool _findColor(List<dynamic> result, List<double> color) {
|
||||
bool _findColor(List<dynamic> result, List<double> color,
|
||||
{double epsilon = 0.01}) {
|
||||
expect(result, isNotNull);
|
||||
expect(result.length, 4);
|
||||
final [int width, int height, String format, Uint8List bytes] = result;
|
||||
return switch (format) {
|
||||
'MTLPixelFormatBGR10_XR' => _findBGR10Color(bytes, width, height, color),
|
||||
'MTLPixelFormatBGRA10_XR' => _findBGRA10Color(bytes, width, height, color),
|
||||
'MTLPixelFormatRGBA16Float' => _findRGBAF16Color(bytes, width, height, color),
|
||||
'MTLPixelFormatBGR10_XR' =>
|
||||
_findBGR10Color(bytes, width, height, color, epsilon: epsilon),
|
||||
'MTLPixelFormatBGRA10_XR' =>
|
||||
_findBGRA10Color(bytes, width, height, color, epsilon: epsilon),
|
||||
'MTLPixelFormatRGBA16Float' =>
|
||||
_findRGBAF16Color(bytes, width, height, color, epsilon: epsilon),
|
||||
_ => fail('Unsupported pixel format: $format'),
|
||||
};
|
||||
}
|
||||
@ -157,7 +163,8 @@ void main() {
|
||||
expect(_findColor(result, _deepRed), isTrue);
|
||||
expect(_findColor(result, <double>[0.0, 1.0, 0.0]), isTrue);
|
||||
});
|
||||
testWidgets('draw image with wide gamut works', (WidgetTester tester) async {
|
||||
testWidgets('draw image with wide gamut works',
|
||||
(WidgetTester tester) async {
|
||||
app.run(app.Setup.drawnImage);
|
||||
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||
|
||||
@ -166,7 +173,8 @@ void main() {
|
||||
await channel.invokeMethod('test') as List<Object?>;
|
||||
expect(_findColor(result, <double>[0.0, 1.0, 0.0]), isTrue);
|
||||
});
|
||||
testWidgets('draw container with wide gamut works', (WidgetTester tester) async {
|
||||
testWidgets('draw container with wide gamut works',
|
||||
(WidgetTester tester) async {
|
||||
app.run(app.Setup.container);
|
||||
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||
|
||||
@ -175,5 +183,49 @@ void main() {
|
||||
await channel.invokeMethod('test') as List<Object?>;
|
||||
expect(_findColor(result, _deepRed), isTrue);
|
||||
});
|
||||
|
||||
testWidgets('draw wide gamut linear gradient works',
|
||||
(WidgetTester tester) async {
|
||||
app.run(app.Setup.linearGradient);
|
||||
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||
|
||||
const MethodChannel channel = MethodChannel('flutter/screenshot');
|
||||
final List<Object?> result =
|
||||
await channel.invokeMethod('test') as List<Object?>;
|
||||
expect(_findColor(result, _deepRed), isTrue);
|
||||
});
|
||||
|
||||
testWidgets('draw wide gamut radial gradient works',
|
||||
(WidgetTester tester) async {
|
||||
app.run(app.Setup.radialGradient);
|
||||
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||
|
||||
const MethodChannel channel = MethodChannel('flutter/screenshot');
|
||||
final List<Object?> result =
|
||||
await channel.invokeMethod('test') as List<Object?>;
|
||||
expect(_findColor(result, _deepRed, epsilon: 0.05), isTrue);
|
||||
});
|
||||
|
||||
testWidgets('draw wide gamut conical gradient works',
|
||||
(WidgetTester tester) async {
|
||||
app.run(app.Setup.conicalGradient);
|
||||
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||
|
||||
const MethodChannel channel = MethodChannel('flutter/screenshot');
|
||||
final List<Object?> result =
|
||||
await channel.invokeMethod('test') as List<Object?>;
|
||||
expect(_findColor(result, _deepRed, epsilon: 0.05), isTrue);
|
||||
});
|
||||
|
||||
testWidgets('draw wide gamut sweep gradient works',
|
||||
(WidgetTester tester) async {
|
||||
app.run(app.Setup.sweepGradient);
|
||||
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||
|
||||
const MethodChannel channel = MethodChannel('flutter/screenshot');
|
||||
final List<Object?> result =
|
||||
await channel.invokeMethod('test') as List<Object?>;
|
||||
expect(_findColor(result, _deepRed), isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ const String _displayP3Logo =
|
||||
'gr3yrjmlwqXLjmWw1O2I5Wmp9Xxjyh+AVIZ6ADIAqcwClakzeMgApDILVKbO4CED'
|
||||
'kMosUJk6g4dUBuRfvf1am9VRqzYAAAAASUVORK5CYII=';
|
||||
|
||||
void main() => run(Setup.container);
|
||||
void main() => run(Setup.sweepGradient);
|
||||
|
||||
enum Setup {
|
||||
none,
|
||||
@ -146,6 +146,10 @@ enum Setup {
|
||||
blur,
|
||||
drawnImage,
|
||||
container,
|
||||
linearGradient,
|
||||
radialGradient,
|
||||
conicalGradient,
|
||||
sweepGradient,
|
||||
}
|
||||
|
||||
void run(Setup setup) {
|
||||
@ -265,7 +269,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
_loadImage().then((ui.Image? value) => setState(() { _image = value; }));
|
||||
case Setup.drawnImage:
|
||||
_drawImage().then((ui.Image? value) => setState(() { _image = value; }));
|
||||
case Setup.image || Setup.blur || Setup.none || Setup.container:
|
||||
case Setup.image ||
|
||||
Setup.blur ||
|
||||
Setup.none ||
|
||||
Setup.container ||
|
||||
Setup.linearGradient ||
|
||||
Setup.radialGradient ||
|
||||
Setup.conicalGradient ||
|
||||
Setup.sweepGradient:
|
||||
break;
|
||||
}
|
||||
super.initState();
|
||||
@ -308,6 +319,97 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
green: 0,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3));
|
||||
case Setup.linearGradient:
|
||||
imageWidget = Container(
|
||||
width: 100,
|
||||
height: 100,
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: <Color>[
|
||||
Color.from(
|
||||
alpha: 1,
|
||||
red: 1,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3),
|
||||
Color.from(
|
||||
alpha: 1,
|
||||
red: 0,
|
||||
green: 1,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3)],
|
||||
),
|
||||
),
|
||||
);
|
||||
case Setup.radialGradient:
|
||||
imageWidget = Container(
|
||||
width: 100,
|
||||
height: 100,
|
||||
decoration: const BoxDecoration(
|
||||
gradient: RadialGradient(
|
||||
colors: <Color>[
|
||||
Color.from(
|
||||
alpha: 1,
|
||||
red: 1,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3),
|
||||
Color.from(
|
||||
alpha: 1,
|
||||
red: 0,
|
||||
green: 1,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3)],
|
||||
),
|
||||
),
|
||||
);
|
||||
case Setup.conicalGradient:
|
||||
imageWidget = Container(
|
||||
width: 100,
|
||||
height: 100,
|
||||
decoration: const BoxDecoration(
|
||||
gradient: RadialGradient(
|
||||
focal: Alignment(0.2, 0.2),
|
||||
colors: <Color>[
|
||||
Color.from(
|
||||
alpha: 1,
|
||||
red: 1,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3),
|
||||
Color.from(
|
||||
alpha: 1,
|
||||
red: 0,
|
||||
green: 1,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3)],
|
||||
),
|
||||
),
|
||||
);
|
||||
case Setup.sweepGradient:
|
||||
imageWidget = Container(
|
||||
width: 100,
|
||||
height: 100,
|
||||
decoration: const BoxDecoration(
|
||||
gradient: SweepGradient(
|
||||
colors: <Color>[
|
||||
Color.from(
|
||||
alpha: 1,
|
||||
red: 1,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3),
|
||||
Color.from(
|
||||
alpha: 1,
|
||||
red: 0,
|
||||
green: 1,
|
||||
blue: 0,
|
||||
colorSpace: ui.ColorSpace.displayP3)],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
|
Loading…
Reference in New Issue
Block a user