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 performance 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 and 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

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

dart
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
In stable release: 3.16

References

#

API documentation:

Relevant issues:

Relevant PRs: