-
Notifications
You must be signed in to change notification settings - Fork 6k
Add ability to control dithering on Paint #13868
Conversation
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. ℹ️ Googlers: Go here for more info. |
1 similar comment
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. ℹ️ Googlers: Go here for more info. |
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
1 similar comment
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
I'd rather we didn't expose this. We should just make the gradients look good regardless. We shouldn't need the developer to control this. |
lib/web_ui/lib/src/ui/painting.dart
Outdated
/// Some implementations may choose to ignore this completely, if they're | ||
/// unable to control dithering. | ||
bool get dither => false; // Not implemented on web | ||
set dither(bool value) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we do expose this, we should implement it on web.
if we do expose this and don't implement it on web, we should still make the property mutable, so that code that relies on it mutating doesn't randomly break on web.
I agree, however it might be a large change to do. It doesn't seem to break hard-stop gradients (like those used for the overflow indicator).
I somewhat agree, but maybe the name of the property should be changed to If not supporting it on web is fine, I can add the backing field to web_ui Paint. The documentation already explains that the hint may be ignored. |
After some discussion I've moved over to a static field so it can be enabled and disabled globally. The dither property has been made private for now, and it defaults to the value of Still isn't enabled by default, but enabling it by default shouldn't have noticeable performance impacts. Most of the concern comes from whether having non-dithered gradients is a valid usecase. |
This will need tests. I assume the new global is temporary? Can we mark it as deprecated? What's the timeframe by which we plan to flip the default and remove it? |
Haven't added tests to the engine repository before. Where should the test live? I was browsing around for paint related tests, but I didn't see any.
The global value is temporary, since you would either want to opt in entirely or opt out entirely. However, we don't know if this is the right default behavior to have. Initially, it would be great to initialize this to true in But as of right now, the whole issue is finding out if apps rely on non-dithered gradients, and giving their developers an avenue to reach out if a default behavior change (which is a breaking change) needs a better, more permanent, escape hatch. This may also have a very very slight performance impact for gradients heavy apps on less-powerful devices, if used by default. It isn't a big deal for low-end Android devices, but there might be smaller near-embedded devices (like Raspberry Pi) that might be affected by the change. |
@liyuqian @cbracken can you help @ds84182 with writing tests for this? Thanks!
Seems reasonable.
Presumably gradient-heavy apps are the ones most likely to want dithering... I wouldn't worry about the lower-end devices, we don't support those anyway. The Nest Home Hub is basically the lowest-end device I would worry about, as far as this feature goes. |
@ds84182 : maybe put your test in https://github.com/flutter/engine/blob/master/testing/dart/canvas_test.dart ? There's already some Dart code that exercises |
Added two image comparison tests, PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! The dithered gradient golden image looks great to me. Can't wait to actually see them in the Flutter app on my phone. Currently the circular gradient animation of loading images does look quite banded. Any ETA on when I can see them in your app? 😃
/// Constructs an empty [Paint] object with all fields initialized to | ||
/// their defaults. | ||
Paint(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be unnecessary, FWIW. The constructor is normally implied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When it was omitted one of the web UI lints complained
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the one in lib/ui/painting.dart
too and the lint should go away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That constructor can't be removed because its used to set _dither
to true if enableDithering
is true. I could use cascade syntax on _data
's initializer, but readability suffers a little.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Ping @jonahwilliams and @yjbanov to see if the web tools (the lint) can be relaxed in this case. If not, I'm Ok with just having this dummy constructor. My experience is that there's already a lot of dummy/duplicate code in lib/web_ui
. The ideal future would be that we don't need any duplicate code in lib/web_ui
, and this issue would go away naturally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep this one. We are splitting the implementation between HTML and CanvasKit (#14320), and this constructor is becoming a factory
, which we cannot omit.
* fb9dfe0 [fuchsia] Move async_get_default_dispatcher include to the header (flutter/engine#14351) * 3ebb7b4 Roll src/third_party/skia 75799967be60..3517aa7b14ad (3 commits) (flutter/engine#14345) * 2713225 Remove duplicate and outdated src/third_party/dart/tools/sdks entry from DEPS. (flutter/engine#14340) * 80d80ff Add ability to control dithering on Paint (flutter/engine#13868) * 8595361 Conditionally use offscreen root surface only when needed * 0a40f3d Assert that arc end caps on canvases with root surface transformations are drawn correctly. (flutter/engine#14359) * d698d96 Fix missing timeline event of flutter engine's startup time (flutter/engine#14319) * 9dc23b8 Fix missing API stream when record event in systrace (flutter/engine#14323) * 9e4c6ad Fix CGMutablePathRef memory leaks when the path is invalid. (flutter/engine#14275) * fc8cafb objcdoc fix for some ambiguity (flutter/engine#14367) * 9bafb3c [tests] Use distinct begin and end times (flutter/engine#14361) * 897ce34 Roll src/third_party/skia 3517aa7b14ad..826484f2631f (18 commits) (flutter/engine#14375) * 1ce85be [flutter_runner] Enable Skia tracing by default on Fuchsia (flutter/engine#13457) * a7b6ee5 Smart quote/dash configuration support in iOS (flutter/engine#13863) * 48ba39c Roll fuchsia/sdk/core/mac-amd64 from otkJA... to SlgE8... (flutter/engine#14407) * 0081e8c Remove unused _TypeNone enum field. (flutter/engine#14440) * d8edfea Roll src/third_party/dart d9fa37e85d5c..45db29709547 (48 commits) (flutter/engine#14453) * f650bca Refactoring text editing. Strategy pattern is used to handle different browser/operating system and a11y behavior. (flutter/engine#14131) * 4275b49 Fix type in build_fuchsia_artifacts (flutter/engine#14452) * 0c24f3d Roll src/third_party/skia 51b99659ed82..c514e7d9be6e (13 commits) (flutter/engine#14457) * ffbe2a4 [testing] Move test vsync waiters to their own TUs (flutter/engine#14456) * 181ad4e Use futures to images used for comparison with fixtures in embedder unit-tests. (flutter/engine#14465) * e0e0ac0 [testing] Make vsync waiters pluggable in shell_unittests (flutter/engine#14463)
What’s the status of this PR? I’m having banding issues on an app I’m working on. It’s very noticeable when you start dealing with gradients based on blacks. I agree that gradients should just look good from the start but they clearly don’t and so dithering would be an ideal shim especially since it appears to be low hanging fruit. |
@lukepighetti : this has been rolled into Flutter framework on flutter/flutter@bcacd06. It has not made to the last stable release, but it's in our beta (v1.14.6) and master branches. |
Closes flutter/flutter#44134
web_ui does not implement dithering, since it's more of a hint to the underlying renderer.
Can test with the following code snippet:
Without dithering, the banding is very obvious on all devices. With dithering, the banding disappears completely.