Paint.enableDithering is now true by default.

Summary

Paint.enableDithering is now true by default (previously, false), and is deprecated pending removal - Flutter no longer supports user-configurable dithering settings.

In addition, the dithering documentation states support is only for gradients.

Background

Paint.enableDithering was added as a global option in PR 13868 as a response to Issue 44134, which reported that gradients in Flutter had visible banding artifacts:

Gradients currently have a lot of color banding on all devices, and it looks very weird when using the pulse animation too. A solution is to make the gradients opaque, and to use dithered gradients with Skia. Dithered gradients aren’t currently exposed, so adding a dither parameter to dart:ui’s Paint class would be nice. We’d be able to manually draw our gradients with a CustomPainter.

Example of banding

Issue 118073 reported that gradients in our new Impeller backend displayed visible banding artifacts in some gradients. It was later discovered that Impeller didn’t support the (rarely used) Paint.enableDithering property.

After adding dithering support to Impeller (PR 44181, PR 44331, PR 44522), and reviewing the perfomance impact of dithering (negligible), the following observations were made:

  1. Consensus that gradients look good by default: Issue 112498.
  2. Having a global option was intended to be deprecated: PR 13868.

This resulted in the following decisions:

  1. Make dithering enabled by default.
  2. Deprecate the global option.
  3. Remove the global option in a future release.

As part of that process, the ability for dithering to affect anything other than gradients was removed in PR 44730, PR 44912. That was done to ease the process of migrating, because Impeller will never support dithering for anything but gradients.

Migration guide

Most users and libraries will not need to make any changes.

For users that maintain golden tests, you might need to update your golden images to reflect the new default. For example, if you use matchesGoldenFile to test a widget that contains a gradient:

flutter test --update-goldens

Not expected to be a common case, but you can disable dithering temporarily by setting the enableDithering property in your main() method (either in an app or test):

void main() {
+ // TODO: Remove this after XYZ.
+ Paint.enableDithering = false;

  runApp(MyApp());
}

As the plan is to permanently remove the enableDithering property, please provide feedback in Issue 112498 if you have a use case that requires disabling dithering (due to performance, crashes).

If for some reason you must draw gradients without dithering, you’ll need to write your own custom shader. Describing that is out of the scope of this migration guide, but you can find some resources and examples:

NOTE: Flutter web does not support dithering: Issue 134250.

Timeline

Landed in version: 3.14.0-0.1.pre.

Not yet in a stable release.

References

API documentation:

Relevant issues:

Relevant PRs: