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

Commit 70c1173

Browse files
authored
Displaylist ColorFilter objects (#31491)
1 parent 01ac6cf commit 70c1173

20 files changed

+861
-124
lines changed

DEPS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ deps = {
110110
'src': 'https://github.com/flutter/buildroot.git' + '@' + '79643299bd052c53631b8b200bb582e8badb2708',
111111

112112
'src/flutter/impeller':
113-
Var('github_git') + '/flutter/impeller' + '@' + 'c55014e747541b9a2cca15e6b2cb1b1ef9123da3',
113+
Var('github_git') + '/flutter/impeller' + '@' + '78bc2a026c554c444b2e67b36fd44cd548341a51',
114114

115115
# Fuchsia compatibility
116116
#

ci/licenses_golden/licenses_flutter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.h
5252
FILE: ../../../flutter/display_list/display_list_canvas_recorder.cc
5353
FILE: ../../../flutter/display_list/display_list_canvas_recorder.h
5454
FILE: ../../../flutter/display_list/display_list_canvas_unittests.cc
55+
FILE: ../../../flutter/display_list/display_list_color_filter.cc
56+
FILE: ../../../flutter/display_list/display_list_color_filter.h
57+
FILE: ../../../flutter/display_list/display_list_color_filter_unittests.cc
5558
FILE: ../../../flutter/display_list/display_list_complexity.cc
5659
FILE: ../../../flutter/display_list/display_list_complexity.h
5760
FILE: ../../../flutter/display_list/display_list_dispatcher.cc

display_list/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ source_set("display_list") {
1414
"display_list_canvas_dispatcher.h",
1515
"display_list_canvas_recorder.cc",
1616
"display_list_canvas_recorder.h",
17+
"display_list_color_filter.cc",
18+
"display_list_color_filter.h",
1719
"display_list_complexity.cc",
1820
"display_list_complexity.h",
1921
"display_list_dispatcher.cc",
@@ -40,6 +42,7 @@ source_set("unittests") {
4042

4143
sources = [
4244
"display_list_canvas_unittests.cc",
45+
"display_list_color_filter_unittests.cc",
4346
"display_list_unittests.cc",
4447
]
4548

display_list/display_list.h

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

5-
#ifndef FLUTTER_FLOW_DISPLAY_LIST_H_
6-
#define FLUTTER_FLOW_DISPLAY_LIST_H_
5+
#ifndef FLUTTER_DISPLAY_LIST_DISPLAY_LIST_H_
6+
#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_H_
77

88
#include <optional>
99

@@ -76,13 +76,15 @@ namespace flutter {
7676
V(ClearBlender) \
7777
V(SetShader) \
7878
V(ClearShader) \
79-
V(SetColorFilter) \
80-
V(ClearColorFilter) \
8179
V(SetImageFilter) \
8280
V(ClearImageFilter) \
8381
V(SetPathEffect) \
8482
V(ClearPathEffect) \
8583
\
84+
V(ClearColorFilter) \
85+
V(SetColorFilter) \
86+
V(SetSkColorFilter) \
87+
\
8688
V(ClearMaskFilter) \
8789
V(SetMaskFilter) \
8890
V(SetMaskBlurFilterNormal) \
@@ -278,4 +280,4 @@ class DisplayList : public SkRefCnt {
278280

279281
} // namespace flutter
280282

281-
#endif // FLUTTER_FLOW_DISPLAY_LIST_H_
283+
#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_H_

display_list/display_list_builder.cc

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,50 @@ void DisplayListBuilder::onSetImageFilter(sk_sp<SkImageFilter> filter) {
134134
? Push<SetImageFilterOp>(0, 0, std::move(filter))
135135
: Push<ClearImageFilterOp>(0, 0);
136136
}
137-
void DisplayListBuilder::onSetColorFilter(sk_sp<SkColorFilter> filter) {
138-
(current_color_filter_ = filter) //
139-
? Push<SetColorFilterOp>(0, 0, std::move(filter))
140-
: Push<ClearColorFilterOp>(0, 0);
137+
void DisplayListBuilder::onSetColorFilter(const DlColorFilter* filter) {
138+
if (filter == nullptr) {
139+
if (!current_color_filter_) {
140+
return;
141+
}
142+
current_color_filter_ = nullptr;
143+
Push<ClearColorFilterOp>(0, 0);
144+
} else {
145+
if (current_color_filter_ && *current_color_filter_ == *filter) {
146+
return;
147+
}
148+
current_color_filter_ = filter->shared();
149+
switch (filter->type()) {
150+
case DlColorFilter::kBlend: {
151+
const DlBlendColorFilter* blend_filter = filter->asBlend();
152+
FML_DCHECK(blend_filter);
153+
void* pod = Push<SetColorFilterOp>(blend_filter->size(), 0);
154+
new (pod) DlBlendColorFilter(blend_filter);
155+
break;
156+
}
157+
case DlColorFilter::kMatrix: {
158+
const DlMatrixColorFilter* matrix_filter = filter->asMatrix();
159+
FML_DCHECK(matrix_filter);
160+
void* pod = Push<SetColorFilterOp>(matrix_filter->size(), 0);
161+
new (pod) DlMatrixColorFilter(matrix_filter);
162+
break;
163+
}
164+
case DlColorFilter::kSrgbToLinearGamma: {
165+
void* pod = Push<SetColorFilterOp>(filter->size(), 0);
166+
new (pod) DlSrgbToLinearGammaColorFilter();
167+
break;
168+
}
169+
case DlColorFilter::kLinearToSrgbGamma: {
170+
void* pod = Push<SetColorFilterOp>(filter->size(), 0);
171+
new (pod) DlLinearToSrgbGammaColorFilter();
172+
break;
173+
}
174+
case DlColorFilter::kUnknown: {
175+
const sk_sp<SkColorFilter> sk_filter = filter->sk_filter();
176+
Push<SetSkColorFilterOp>(0, 0, sk_filter);
177+
break;
178+
}
179+
}
180+
}
141181
UpdateCurrentOpacityCompatibility();
142182
}
143183
void DisplayListBuilder::onSetPathEffect(sk_sp<SkPathEffect> effect) {
@@ -211,7 +251,12 @@ void DisplayListBuilder::setAttributesFromPaint(
211251
// we must clear it because it is a second potential color filter
212252
// that is composed with the paint's color filter.
213253
setInvertColors(false);
214-
setColorFilter(sk_ref_sp(paint.getColorFilter()));
254+
SkColorFilter* color_filter = paint.getColorFilter();
255+
if (color_filter) {
256+
setColorFilter(DlColorFilter::From(color_filter).get());
257+
} else {
258+
setColorFilter(nullptr);
259+
}
215260
}
216261
if (flags.applies_image_filter()) {
217262
setImageFilter(sk_ref_sp(paint.getImageFilter()));

display_list/display_list_builder.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,9 @@ class DisplayListBuilder final : public virtual Dispatcher,
9393
onSetImageFilter(std::move(filter));
9494
}
9595
}
96-
void setColorFilter(sk_sp<SkColorFilter> filter) override {
97-
if (current_color_filter_ != filter) {
98-
onSetColorFilter(std::move(filter));
99-
}
96+
void setColorFilter(const DlColorFilter* filter) override {
97+
// onSetColorFilter will deal with whether the filter is new
98+
onSetColorFilter(filter);
10099
}
101100
void setPathEffect(sk_sp<SkPathEffect> effect) override {
102101
if (current_path_effect_ != effect) {
@@ -128,7 +127,9 @@ class DisplayListBuilder final : public virtual Dispatcher,
128127
SkPaint::Cap getStrokeCap() const { return current_stroke_cap_; }
129128
SkPaint::Join getStrokeJoin() const { return current_stroke_join_; }
130129
sk_sp<SkShader> getShader() const { return current_shader_; }
131-
sk_sp<SkColorFilter> getColorFilter() const { return current_color_filter_; }
130+
sk_sp<SkColorFilter> getColorFilter() const {
131+
return current_color_filter_->sk_filter();
132+
}
132133
bool isInvertColors() const { return current_invert_colors_; }
133134
std::optional<SkBlendMode> getBlendMode() const {
134135
if (current_blender_) {
@@ -390,7 +391,7 @@ class DisplayListBuilder final : public virtual Dispatcher,
390391
void onSetBlender(sk_sp<SkBlender> blender);
391392
void onSetShader(sk_sp<SkShader> shader);
392393
void onSetImageFilter(sk_sp<SkImageFilter> filter);
393-
void onSetColorFilter(sk_sp<SkColorFilter> filter);
394+
void onSetColorFilter(const DlColorFilter* filter);
394395
void onSetPathEffect(sk_sp<SkPathEffect> effect);
395396
void onSetMaskFilter(sk_sp<SkMaskFilter> filter);
396397
void onSetMaskBlurFilter(SkBlurStyle style, SkScalar sigma);
@@ -409,7 +410,7 @@ class DisplayListBuilder final : public virtual Dispatcher,
409410
SkBlendMode current_blend_mode_ = SkBlendMode::kSrcOver;
410411
sk_sp<SkBlender> current_blender_;
411412
sk_sp<SkShader> current_shader_;
412-
sk_sp<SkColorFilter> current_color_filter_;
413+
std::shared_ptr<const DlColorFilter> current_color_filter_;
413414
sk_sp<SkImageFilter> current_image_filter_;
414415
sk_sp<SkPathEffect> current_path_effect_;
415416
sk_sp<SkMaskFilter> current_mask_filter_;

display_list/display_list_canvas_unittests.cc

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -836,48 +836,43 @@ class CanvasCompareTester {
836836
0, 0, 0, 0.5, 0,
837837
};
838838
// clang-format on
839-
sk_sp<SkColorFilter> filter =
840-
SkColorFilters::Matrix(rotate_alpha_color_matrix);
839+
DlMatrixColorFilter filter(rotate_alpha_color_matrix);
841840
{
842841
RenderWith(testP, env, tolerance,
843842
CaseParameters(
844843
"saveLayer ColorFilter, no bounds",
845844
[=](SkCanvas* cv, SkPaint& p) {
846845
SkPaint save_p;
847-
save_p.setColorFilter(filter);
846+
save_p.setColorFilter(filter.sk_filter());
848847
cv->saveLayer(nullptr, &save_p);
849848
p.setStrokeWidth(5.0);
850849
},
851850
[=](DisplayListBuilder& b) {
852-
b.setColorFilter(filter);
851+
b.setColorFilter(&filter);
853852
b.saveLayer(nullptr, true);
854853
b.setColorFilter(nullptr);
855854
b.setStrokeWidth(5.0);
856855
})
857856
.with_restore(cv_safe_restore, dl_safe_restore, true));
858857
}
859-
EXPECT_TRUE(filter->unique())
860-
<< "saveLayer ColorFilter, no bounds Cleanup";
861858
{
862859
RenderWith(testP, env, tolerance,
863860
CaseParameters(
864861
"saveLayer ColorFilter and bounds",
865862
[=](SkCanvas* cv, SkPaint& p) {
866863
SkPaint save_p;
867-
save_p.setColorFilter(filter);
864+
save_p.setColorFilter(filter.sk_filter());
868865
cv->saveLayer(RenderBounds, &save_p);
869866
p.setStrokeWidth(5.0);
870867
},
871868
[=](DisplayListBuilder& b) {
872-
b.setColorFilter(filter);
869+
b.setColorFilter(&filter);
873870
b.saveLayer(&RenderBounds, true);
874871
b.setColorFilter(nullptr);
875872
b.setStrokeWidth(5.0);
876873
})
877874
.with_restore(cv_safe_restore, dl_safe_restore, true));
878875
}
879-
EXPECT_TRUE(filter->unique())
880-
<< "saveLayer ColorFilter and bounds Cleanup";
881876
}
882877
{
883878
sk_sp<SkImageFilter> filter = SkImageFilters::Arithmetic(
@@ -1146,40 +1141,38 @@ class CanvasCompareTester {
11461141
1.0, 1.0, 1.0, 1.0, 0,
11471142
};
11481143
// clang-format on
1149-
sk_sp<SkColorFilter> filter = SkColorFilters::Matrix(rotate_color_matrix);
1144+
DlMatrixColorFilter filter(rotate_color_matrix);
11501145
{
11511146
SkColor bg = SK_ColorWHITE;
11521147
RenderWith(testP, env, tolerance,
11531148
CaseParameters(
11541149
"ColorFilter == RotateRGB",
11551150
[=](SkCanvas*, SkPaint& p) {
11561151
p.setColor(SK_ColorYELLOW);
1157-
p.setColorFilter(filter);
1152+
p.setColorFilter(filter.sk_filter());
11581153
},
11591154
[=](DisplayListBuilder& b) {
11601155
b.setColor(SK_ColorYELLOW);
1161-
b.setColorFilter(filter);
1156+
b.setColorFilter(&filter);
11621157
})
11631158
.with_bg(bg));
11641159
}
1165-
EXPECT_TRUE(filter->unique()) << "ColorFilter == RotateRGB Cleanup";
1166-
filter = SkColorFilters::Matrix(invert_color_matrix);
1160+
filter = DlMatrixColorFilter(invert_color_matrix);
11671161
{
11681162
SkColor bg = SK_ColorWHITE;
11691163
RenderWith(testP, env, tolerance,
11701164
CaseParameters(
11711165
"ColorFilter == Invert",
11721166
[=](SkCanvas*, SkPaint& p) {
11731167
p.setColor(SK_ColorYELLOW);
1174-
p.setColorFilter(filter);
1168+
p.setColorFilter(filter.sk_filter());
11751169
},
11761170
[=](DisplayListBuilder& b) {
11771171
b.setColor(SK_ColorYELLOW);
11781172
b.setInvertColors(true);
11791173
})
11801174
.with_bg(bg));
11811175
}
1182-
EXPECT_TRUE(filter->unique()) << "ColorFilter == Invert Cleanup";
11831176
}
11841177

11851178
{
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/display_list/display_list_color_filter.h"
6+
7+
namespace flutter {
8+
9+
std::shared_ptr<DlColorFilter> DlColorFilter::From(SkColorFilter* sk_filter) {
10+
if (sk_filter == nullptr) {
11+
return nullptr;
12+
}
13+
if (sk_filter == DlSrgbToLinearGammaColorFilter::sk_filter_.get()) {
14+
// Skia implements these filters as a singleton.
15+
return DlSrgbToLinearGammaColorFilter::instance;
16+
}
17+
if (sk_filter == DlLinearToSrgbGammaColorFilter::sk_filter_.get()) {
18+
// Skia implements these filters as a singleton.
19+
return DlLinearToSrgbGammaColorFilter::instance;
20+
}
21+
{
22+
SkColor color;
23+
SkBlendMode mode;
24+
if (sk_filter->asAColorMode(&color, &mode)) {
25+
return std::make_shared<DlBlendColorFilter>(color, mode);
26+
}
27+
}
28+
{
29+
float matrix[20];
30+
if (sk_filter->asAColorMatrix(matrix)) {
31+
return std::make_shared<DlMatrixColorFilter>(matrix);
32+
}
33+
}
34+
return std::make_shared<DlUnknownColorFilter>(sk_ref_sp(sk_filter));
35+
}
36+
37+
const std::shared_ptr<DlSrgbToLinearGammaColorFilter>
38+
DlSrgbToLinearGammaColorFilter::instance =
39+
std::make_shared<DlSrgbToLinearGammaColorFilter>();
40+
const sk_sp<SkColorFilter> DlSrgbToLinearGammaColorFilter::sk_filter_ =
41+
SkColorFilters::SRGBToLinearGamma();
42+
43+
const std::shared_ptr<DlLinearToSrgbGammaColorFilter>
44+
DlLinearToSrgbGammaColorFilter::instance =
45+
std::make_shared<DlLinearToSrgbGammaColorFilter>();
46+
const sk_sp<SkColorFilter> DlLinearToSrgbGammaColorFilter::sk_filter_ =
47+
SkColorFilters::LinearToSRGBGamma();
48+
49+
} // namespace flutter

0 commit comments

Comments
 (0)