Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Surgically remove .*dither.* from the Engine #46750

Merged
merged 12 commits into from
Oct 31, 2023

Conversation

matanlurey
Copy link
Contributor

@matanlurey matanlurey commented Oct 11, 2023

Closes flutter/flutter#112498.

We no longer support any user-visible configuration around dithering. It is unconditionally applied for gradients (in both the Skia and Impeller backends), and never applied elsewhere. After this change, I'll update https://docs.flutter.dev/release/breaking-changes/paint-enableDithering accordingly.


Requires #46746 to land successfully Done.

Alright, this appears ready to review!

@matanlurey matanlurey marked this pull request as ready for review October 30, 2023 21:08
@matanlurey matanlurey changed the title Surgically remove .*dither.* from non-fragment code in the Engine Surgically remove .*dither.* from the Engine Oct 30, 2023
Copy link
Member

@jonahwilliams jonahwilliams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@flar flar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra credit - the dither flags in dl_op_flags.[h,cc] can be deleted.

@@ -387,7 +386,6 @@ TEST_F(DisplayListTest, BuildRestoresAttributes) {
builder.Build();
check_defaults(builder, cull_rect);

receiver.setDither(true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two lines following that should also be removed. They have nothing to check if the receiver wasn't modified.

@@ -61,12 +61,6 @@ class DlPaint {
return *this;
}

bool isDither() const { return is_dither_; }
DlPaint& setDither(bool isDither) {
is_dither_ = isDither;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field can be deleted as well.

sk_paint.setShader(ToSk(color_source));
} else {
sk_paint.setDither(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sk_paint is a brand new object allocated above with defaults (dither is false by default).

//
// See https://github.com/flutter/flutter/issues/112498.
paint_.setDither(color_source_gradient_ && dither_);
paint_.setDither(color_source_gradient_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be handled in setColorSource directly now without having to pass a flag to this method. (color_source_gradient_ field is obsolete compared to just setting the dither flag on the paint_ object)

@flar
Copy link
Contributor

flar commented Oct 30, 2023

The failures in the rendering tests are likely due to setting up an sk_paint with a gradient, but not setting its dither flag (look for calls to setShader and make sure they set the dither flag appropriately).

The entire if (testP.uses_gradient()) { block which used to test the difference between dither and non-dither is likely obsolete now that the parameterization is not any different between the env.init_ref and the RenderWith calls.

@matanlurey
Copy link
Contributor Author

Thanks @jonahwilliams and especially @flar!

I'm working on some MSAA stuff for the rest of the day, and I'll address feedback tomorrow AM.

@matanlurey matanlurey requested a review from flar October 31, 2023 17:20
Copy link
Contributor

@flar flar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest changes look good. The failures are likely due to setting a gradient in the Skia code in the rendering tests without setting the dithering flag on the SkPaint. For example:

ctx.paint.setShader(sk_gradient);

I don't think any tests outside of the dl_rendering_unittests.cc will run into this, but these tests are measuring "DL output vs the equivalent SK commands" so any time a gradient is set, it has to also include setting the dither flag in the Sk version. There are a number of calls to setShader in this file, but it's not clear which ones are setting gradients or some other color source (the one I linked above is definitely setting a gradient).

Note that you can run the rendering tests manually to make sure you've caught all of these cases using out/<build>/display_list_rendertests

@matanlurey
Copy link
Contributor Author

The latest changes look good. The failures are likely due to setting a gradient in the Skia code in the rendering tests without setting the dithering flag on the SkPaint. For example:

ctx.paint.setShader(sk_gradient);

I don't think any tests outside of the dl_rendering_unittests.cc will run into this, but these tests are measuring "DL output vs the equivalent SK commands" so any time a gradient is set, it has to also include setting the dither flag in the Sk version. There are a number of calls to setShader in this file, but it's not clear which ones are setting gradients or some other color source (the one I linked above is definitely setting a gradient).

Note that you can run the rendering tests manually to make sure you've caught all of these cases using out/<build>/display_list_rendertests

It looks like the failures are because of this change:

if (color_source) {
// On the Impeller backend, we will only support dithering of *gradients*,
// and it will be enabled by default (without the option to disable it).
// Until Skia support is completely removed, we only want to respect the
// dither flag for gradients (otherwise it will also apply to, for example,
// images, which is not supported in Impeller).
//
// See https://github.com/flutter/flutter/issues/112498.
sk_paint.setDither(color_source->isGradient());
sk_paint.setShader(ToSk(color_source));
}

... we're not checking for a requested dither before setting dithering (which is intended by this PR).

The part I'm confused on is what exactly to do about it given all of the wrapping in these tests. By adding some logging, I've observed that the following test case:

TEST_F(DisplayListRendering, DrawImageRectLinear) {
SkRect src = SkRect::MakeIWH(kRenderWidth, kRenderHeight).makeInset(5, 5);
SkRect dst = kRenderBounds.makeInset(10.5, 10.5);
CanvasCompareTester::RenderAll( //
TestParameters(
[=](const SkRenderContext& ctx) {
ctx.canvas->drawImageRect(
ctx.image, src, dst, SkImageSampling::kLinear, //
&ctx.paint, SkCanvas::kFast_SrcRectConstraint);
},
[=](const DlRenderContext& ctx) { //
ctx.canvas->DrawImageRect(
ctx.image, src, dst, DlImageSampling::kLinear, //
&ctx.paint, DlCanvas::SrcRectConstraint::kFast);
},
kDrawImageRectWithPaintFlags));
}

... only ends up setting the isGradient branch once:

$ ../out/host_debug_unopt_arm64/display_list_rendertests --gtest_filter="*ImageRectLinear"

INFO:test_timeout_listener.cc(76)] Test timeout of 300 seconds per test case will be enforced.
Note: Google Test filter = *ImageRectLinear
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from DisplayListRendering
[INFO:dl_rendering_unittests.cc(2822)] Running tests on [ Software ]
[ RUN      ] DisplayListRendering.DrawImageRectLinear
[INFO:dl_rendering_unittests.cc(213)] No Impeller output tests on Software
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 1
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] e020bf00 != e01fbf00
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] d828af00 != d827af00
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] 97692f00 != 97682f00
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] e817cf00 != e818cf00
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] a7584f00 != a7594f00
../../flutter/display_list/testing/dl_rendering_unittests.cc:2626: Failure
Expected equality of these values:
  pixels_different
    Which is: 992
  0
Software: DrawImageRectLinear (LinearGradient GYB) (DlCanvas output matches SkCanvas)
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] e020bf00 != e01fbf00
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] d828af00 != d827af00
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] 97692f00 != 97682f00
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] e817cf00 != e818cf00
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(2619)] a7584f00 != a7594f00
../../flutter/display_list/testing/dl_rendering_unittests.cc:2626: Failure
Expected equality of these values:
  pixels_different
    Which is: 992
  0
Software: DrawImageRectLinear (LinearGradient GYB) (DlCanvas DL output matches Builder Dl output)
../../flutter/display_list/testing/dl_rendering_unittests.cc:2702: Failure
Expected equality of these values:
  pixels_different
    Which is: 992
  0
Software: DrawImageRectLinear (LinearGradient GYB) (DisplayList built directly -> surface)
[  FAILED  ] DisplayListRendering.DrawImageRectLinear (2668 ms)
[----------] 1 test from DisplayListRendering (2668 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (2668 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] DisplayListRendering.DrawImageRectLinear

That means in order to be consistent, I'd have to set ctx.paint.setDither(true) exactly once, but I'm not sure how to do that because of the wrapped invocations. I'm guessing it's one of these inner calls:

SkSetup sk_backdrop_setup = [=](const SkSetupContext& ctx) {
SkPaint setup_p;
setup_p.setShader(MakeColorSource(ctx.image));
ctx.canvas->drawPaint(setup_p);
};
DlSetup dl_backdrop_setup = [=](const DlSetupContext& ctx) {
DlPaint setup_p;
setup_p.setColorSource(MakeColorSource(ctx.image));
ctx.canvas->DrawPaint(setup_p);
};

... but I'm not sure which one, yet.

@matanlurey
Copy link
Contributor Author

matanlurey commented Oct 31, 2023

... but I'm not sure which one, yet.

I assumed it was "LinearGradient GYB", I'm not familiar with this test suite though:

        RenderWith(testP, env, tolerance,
                   CaseParameters(
                       "LinearGradient GYB",
                       [=](const SkSetupContext& ctx) {
+                        ctx.paint.setDither(true);
                         ctx.paint.setShader(sk_gradient);
                       },
                       [=](const DlSetupContext& ctx) {
                         ctx.paint.setColorSource(dl_gradient);
                       }));

This didn't actually fix the failure, though commenting out the { ... } clause does show this is the offending case. I'll keep digging/playing around.

@matanlurey
Copy link
Contributor Author

Added some more logging:

[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 0
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(1782)] dl.setColorSource(gradient)
[ERROR:flutter/display_list/skia/dl_sk_conversions.cc(50)] color_source->isGradient() = 1
[ERROR:flutter/display_list/testing/dl_rendering_unittests.cc(1782)] dl.setColorSource(gradient)

It appears that isGradient() either isn't covering a case, or there is something I misunderstand.

@flar
Copy link
Contributor

flar commented Oct 31, 2023

I'll bring over the branch and look.

@matanlurey
Copy link
Contributor Author

Note that the following patch also fails, so maybe it's something else:

        RenderWith(testP, env, tolerance,
                   CaseParameters(
                       "LinearGradient GYB",
                       [=](const SkSetupContext& ctx) {
+                        ctx.paint.setDither(dl_gradient->isGradient());
                         ctx.paint.setShader(sk_gradient);
                       },
                       [=](const DlSetupContext& ctx) {
                         ctx.paint.setColorSource(dl_gradient);
                       }));

@flar
Copy link
Contributor

flar commented Oct 31, 2023

Ah, I see the problem. Just because we set a gradient in the sk_paint doesn't mean the operation will draw a gradient. The drawImage family of rendering calls ignores the shader so the dither flag will affect it even though it is not drawing a gradient - thus causing a difference. Let me look at a better solution here.

@matanlurey
Copy link
Contributor Author

Ah, I see the problem. Just because we set a gradient in the sk_paint doesn't mean the operation will draw a gradient. The drawImage family of rendering calls ignores the shader so the dither flag will affect it even though it is not drawing a gradient - thus causing a difference. Let me look at a better solution here.

Sounds good, let me know how I can help!

// and it will be enabled by default (without the option to disable it).
// Until Skia support is completely removed, we only want to respect the
// dither flag for gradients (otherwise it will also apply to, for
// example, image ops and image sources, which are not supported in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, should probably say "not dithered in" otherwise it looks like we don't implement drawImage...

@matanlurey matanlurey added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 31, 2023
@auto-submit auto-submit bot merged commit fe3882e into flutter:main Oct 31, 2023
@matanlurey matanlurey deleted the engine-removeSetDither branch October 31, 2023 22:44
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 1, 2023
@jonahwilliams
Copy link
Member

There were some golden diffs on an engine roll that I suspect were due to this change. i accepted them to unblock the roll, but they can be seen here:

https://flutter-gold.skia.org/search?crs=github&issue=137651&patchsets=5&positive=true

auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Nov 1, 2023
…137651)

flutter/engine@406b7d7...db06c2e

2023-10-31 skia-flutter-autoroll@skia.org Roll Fuchsia Mac SDK from rg_Ici1tgAVF93cn9... to x2NzYMNhyodIwDl0I... (flutter/engine#47528)
2023-10-31 30870216+gaaclarke@users.noreply.github.com [Impeller] updated ios benchmark link (flutter/engine#47515)
2023-10-31 30870216+gaaclarke@users.noreply.github.com Made clang tidy use arm64 if on an arm64 mac. (flutter/engine#47494)
2023-10-31 bdero@google.com [Impeller] Allow 3D scenes to render when MSAA is not supported. (flutter/engine#47217)
2023-10-31 matanlurey@users.noreply.github.com Surgically remove `.*dither.*` from the Engine (flutter/engine#46750)

Also rolling transitive DEPS:
  fuchsia/sdk/core/mac-amd64 from rg_Ici1tgAVF to x2NzYMNhyodI

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC rmistry@google.com,zra@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
autosubmit Merge PR when tree becomes green via auto submit App e: impeller
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

No-op set Paint.enableDithering (it's deprecated)
4 participants