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

Commit 0a3cb0c

Browse files
authored
Further filter/clear <SkPaint>.setDither(true), this time in DlSkPaintDispatchHelper (#44912)
Closes flutter/flutter#132860. - If `setDither(true)` is called, and an existing `setColorSource` is a gradient, it is ignored. - If `setColorSource(...)` is called, and it is a gradient, and dithering was previously set, it is cleared. I'm not sure this is fool proof.
1 parent 97f1ed1 commit 0a3cb0c

File tree

3 files changed

+84
-2
lines changed

3 files changed

+84
-2
lines changed

display_list/skia/dl_sk_paint_dispatcher.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void DlSkPaintDispatchHelper::setAntiAlias(bool aa) {
4141
paint_.setAntiAlias(aa);
4242
}
4343
void DlSkPaintDispatchHelper::setDither(bool dither) {
44-
paint_.setDither(dither);
44+
dither_ = dither;
4545
}
4646
void DlSkPaintDispatchHelper::setInvertColors(bool invert) {
4747
invert_colors_ = invert;
@@ -73,6 +73,7 @@ void DlSkPaintDispatchHelper::setBlendMode(DlBlendMode mode) {
7373
paint_.setBlendMode(ToSk(mode));
7474
}
7575
void DlSkPaintDispatchHelper::setColorSource(const DlColorSource* source) {
76+
color_source_gradient_ = source && source->isGradient();
7677
paint_.setShader(ToSk(source));
7778
}
7879
void DlSkPaintDispatchHelper::setImageFilter(const DlImageFilter* filter) {

display_list/skia/dl_sk_paint_dispatcher.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,17 @@ class DlSkPaintDispatchHelper : public virtual DlOpReceiver {
3737
void setMaskFilter(const DlMaskFilter* filter) override;
3838
void setImageFilter(const DlImageFilter* filter) override;
3939

40-
const SkPaint& paint() { return paint_; }
40+
const SkPaint& paint() {
41+
// On the Impeller backend, we will only support dithering of *gradients*,
42+
// and it will be enabled by default (without the option to disable it).
43+
// Until Skia support is completely removed, we only want to respect the
44+
// dither flag for gradients (otherwise it will also apply to, for
45+
// example, images, which is not supported in Impeller).
46+
//
47+
// See https://github.com/flutter/flutter/issues/112498.
48+
paint_.setDither(color_source_gradient_ && dither_);
49+
return paint_;
50+
}
4151

4252
/// Returns the current opacity attribute which is used to reduce
4353
/// the alpha of all setColor calls encountered in the streeam
@@ -57,6 +67,8 @@ class DlSkPaintDispatchHelper : public virtual DlOpReceiver {
5767

5868
private:
5969
SkPaint paint_;
70+
bool color_source_gradient_ = false;
71+
bool dither_ = false;
6072
bool invert_colors_ = false;
6173
sk_sp<SkColorFilter> sk_color_filter_;
6274

display_list/skia/dl_sk_paint_dispatcher_unittests.cc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
#include "display_list/effects/dl_color_source.h"
56
#include "flutter/display_list/skia/dl_sk_paint_dispatcher.h"
67

78
#include "flutter/display_list/utils/dl_receiver_utils.h"
@@ -21,6 +22,17 @@ class MockDispatchHelper final : public virtual DlOpReceiver,
2122
void restore() override { DlSkPaintDispatchHelper::restore_opacity(); }
2223
};
2324

25+
static const DlColor kTestColors[2] = {0xFF000000, 0xFFFFFFFF};
26+
static const float kTestStops[2] = {0.0f, 1.0f};
27+
static const auto kTestLinearGradient =
28+
DlColorSource::MakeLinear(SkPoint::Make(0.0f, 0.0f),
29+
SkPoint::Make(100.0f, 100.0f),
30+
2,
31+
kTestColors,
32+
kTestStops,
33+
DlTileMode::kClamp,
34+
nullptr);
35+
2436
// Regression test for https://github.com/flutter/flutter/issues/100176.
2537
TEST(DisplayListUtils, OverRestore) {
2638
MockDispatchHelper helper;
@@ -31,5 +43,62 @@ TEST(DisplayListUtils, OverRestore) {
3143
helper.restore();
3244
}
3345

46+
// https://github.com/flutter/flutter/issues/132860.
47+
TEST(DisplayListUtils, SetDitherIgnoredIfColorSourceNotGradient) {
48+
MockDispatchHelper helper;
49+
helper.setDither(true);
50+
EXPECT_FALSE(helper.paint().isDither());
51+
}
52+
53+
// https://github.com/flutter/flutter/issues/132860.
54+
TEST(DisplayListUtils, SetColorSourceClearsDitherIfNotGradient) {
55+
MockDispatchHelper helper;
56+
helper.setDither(true);
57+
helper.setColorSource(nullptr);
58+
EXPECT_FALSE(helper.paint().isDither());
59+
}
60+
61+
// https://github.com/flutter/flutter/issues/132860.
62+
TEST(DisplayListUtils, SetDitherTrueThenSetColorSourceDithersIfGradient) {
63+
MockDispatchHelper helper;
64+
65+
// A naive implementation would ignore the dither flag here since the current
66+
// color source is not a gradient.
67+
helper.setDither(true);
68+
helper.setColorSource(kTestLinearGradient.get());
69+
EXPECT_TRUE(helper.paint().isDither());
70+
}
71+
72+
// https://github.com/flutter/flutter/issues/132860.
73+
TEST(DisplayListUtils, SetDitherTrueThenRenderNonGradientThenRenderGradient) {
74+
MockDispatchHelper helper;
75+
76+
// "Render" a dithered non-gradient.
77+
helper.setDither(true);
78+
EXPECT_FALSE(helper.paint().isDither());
79+
80+
// "Render" a gradient.
81+
helper.setColorSource(kTestLinearGradient.get());
82+
EXPECT_TRUE(helper.paint().isDither());
83+
}
84+
85+
// https://github.com/flutter/flutter/issues/132860.
86+
TEST(DisplayListUtils, SetDitherTrueThenGradientTHenNonGradientThenGradient) {
87+
MockDispatchHelper helper;
88+
89+
// "Render" a dithered gradient.
90+
helper.setDither(true);
91+
helper.setColorSource(kTestLinearGradient.get());
92+
EXPECT_TRUE(helper.paint().isDither());
93+
94+
// "Render" a non-gradient.
95+
helper.setColorSource(nullptr);
96+
EXPECT_FALSE(helper.paint().isDither());
97+
98+
// "Render" a gradient again.
99+
helper.setColorSource(kTestLinearGradient.get());
100+
EXPECT_TRUE(helper.paint().isDither());
101+
}
102+
34103
} // namespace testing
35104
} // namespace flutter

0 commit comments

Comments
 (0)