Flutter Engine
The Flutter Engine
dl_sk_conversions_unittests.cc
Go to the documentation of this file.
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/dl_blend_mode.h"
6#include "flutter/display_list/dl_paint.h"
7#include "flutter/display_list/dl_sampling_options.h"
8#include "flutter/display_list/dl_tile_mode.h"
9#include "flutter/display_list/dl_vertices.h"
10#include "flutter/display_list/effects/dl_color_source.h"
11#include "flutter/display_list/skia/dl_sk_conversions.h"
12#include "gtest/gtest.h"
16
17namespace flutter {
18namespace testing {
19
20TEST(DisplayListImageFilter, LocalImageSkiaNull) {
21 auto blur_filter =
22 std::make_shared<DlBlurImageFilter>(0, 0, DlTileMode::kClamp);
23 DlLocalMatrixImageFilter dl_local_matrix_filter(SkMatrix::RotateDeg(45),
24 blur_filter);
25 // With sigmas set to zero on the blur filter, Skia will return a null filter.
26 // The local matrix filter should return nullptr instead of crashing.
27 ASSERT_EQ(ToSk(dl_local_matrix_filter), nullptr);
28}
29
30TEST(DisplayListSkConversions, ToSkColor) {
31 // Red
32 ASSERT_EQ(ToSk(DlColor::kRed()), SK_ColorRED);
33
34 // Green
35 ASSERT_EQ(ToSk(DlColor::kGreen()), SK_ColorGREEN);
36
37 // Blue
38 ASSERT_EQ(ToSk(DlColor::kBlue()), SK_ColorBLUE);
39
40 // Half transparent grey
41 auto const grey_hex_half_opaque = 0x7F999999;
42 ASSERT_EQ(ToSk(DlColor(grey_hex_half_opaque)), SkColor(grey_hex_half_opaque));
43}
44
45TEST(DisplayListSkConversions, ToSkTileMode) {
50}
51
52TEST(DisplayListSkConversions, ToSkBlurStyle) {
57}
58
59TEST(DisplayListSkConversions, ToSkDrawStyle) {
60 ASSERT_EQ(ToSk(DlDrawStyle::kFill), SkPaint::Style::kFill_Style);
61 ASSERT_EQ(ToSk(DlDrawStyle::kStroke), SkPaint::Style::kStroke_Style);
63 SkPaint::Style::kStrokeAndFill_Style);
64}
65
66TEST(DisplayListSkConversions, ToSkStrokeCap) {
67 ASSERT_EQ(ToSk(DlStrokeCap::kButt), SkPaint::Cap::kButt_Cap);
68 ASSERT_EQ(ToSk(DlStrokeCap::kRound), SkPaint::Cap::kRound_Cap);
69 ASSERT_EQ(ToSk(DlStrokeCap::kSquare), SkPaint::Cap::kSquare_Cap);
70}
71
72TEST(DisplayListSkConversions, ToSkStrokeJoin) {
73 ASSERT_EQ(ToSk(DlStrokeJoin::kMiter), SkPaint::Join::kMiter_Join);
74 ASSERT_EQ(ToSk(DlStrokeJoin::kRound), SkPaint::Join::kRound_Join);
75 ASSERT_EQ(ToSk(DlStrokeJoin::kBevel), SkPaint::Join::kBevel_Join);
76}
77
78TEST(DisplayListSkConversions, ToSkVertexMode) {
80 SkVertices::VertexMode::kTriangles_VertexMode);
82 SkVertices::VertexMode::kTriangleStrip_VertexMode);
84 SkVertices::VertexMode::kTriangleFan_VertexMode);
85}
86
87TEST(DisplayListSkConversions, ToSkFilterMode) {
91}
92
93TEST(DisplayListSkConversions, ToSkSrcRectConstraint) {
95 SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint);
97 SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint);
98}
99
100TEST(DisplayListSkConversions, ToSkSamplingOptions) {
107 ASSERT_EQ(ToSk(DlImageSampling::kCubic),
108 SkSamplingOptions(SkCubicResampler{1 / 3.0f, 1 / 3.0f}));
109}
110
111#define FOR_EACH_BLEND_MODE_ENUM(FUNC) \
112 FUNC(kSrc) \
113 FUNC(kClear) \
114 FUNC(kSrc) \
115 FUNC(kDst) \
116 FUNC(kSrcOver) \
117 FUNC(kDstOver) \
118 FUNC(kSrcIn) \
119 FUNC(kDstIn) \
120 FUNC(kSrcOut) \
121 FUNC(kDstOut) \
122 FUNC(kSrcATop) \
123 FUNC(kDstATop) \
124 FUNC(kXor) \
125 FUNC(kPlus) \
126 FUNC(kModulate) \
127 FUNC(kScreen) \
128 FUNC(kOverlay) \
129 FUNC(kDarken) \
130 FUNC(kLighten) \
131 FUNC(kColorDodge) \
132 FUNC(kColorBurn) \
133 FUNC(kHardLight) \
134 FUNC(kSoftLight) \
135 FUNC(kDifference) \
136 FUNC(kExclusion) \
137 FUNC(kMultiply) \
138 FUNC(kHue) \
139 FUNC(kSaturation) \
140 FUNC(kColor) \
141 FUNC(kLuminosity) \
142 FUNC(kLastCoeffMode) \
143 FUNC(kLastSeparableMode) \
144 FUNC(kLastMode)
145
146TEST(DisplayListSkConversions, ToSkBlendMode){
147#define CHECK_TO_SKENUM(V) ASSERT_EQ(ToSk(DlBlendMode::V), SkBlendMode::V);
149#undef CHECK_TO_SKENUM
150}
151
152TEST(DisplayListSkConversions, BlendColorFilterModifiesTransparency) {
153 auto test_mode_color = [](DlBlendMode mode, DlColor color) {
154 std::stringstream desc_str;
155 desc_str << "blend[" << static_cast<int>(mode) << ", " << color.argb()
156 << "]";
157 std::string desc = desc_str.str();
159 auto srgb = SkColorSpace::MakeSRGB();
160 if (filter.modifies_transparent_black()) {
161 auto dl_filter = DlBlendColorFilter::Make(color, mode);
162 auto sk_filter = ToSk(filter);
163 ASSERT_NE(dl_filter, nullptr) << desc;
164 ASSERT_NE(sk_filter, nullptr) << desc;
165 ASSERT_TRUE(sk_filter->filterColor4f(SkColors::kTransparent, srgb.get(),
166 srgb.get()) !=
168 << desc;
169 } else {
170 auto dl_filter = DlBlendColorFilter::Make(color, mode);
171 auto sk_filter = ToSk(filter);
172 EXPECT_EQ(dl_filter == nullptr, sk_filter == nullptr) << desc;
173 ASSERT_TRUE(sk_filter == nullptr ||
174 sk_filter->filterColor4f(SkColors::kTransparent, srgb.get(),
175 srgb.get()) ==
177 << desc;
178 }
179 };
180
181 auto test_mode = [&test_mode_color](DlBlendMode mode) {
182 test_mode_color(mode, DlColor::kTransparent());
183 test_mode_color(mode, DlColor::kWhite());
184 test_mode_color(mode, DlColor::kWhite().modulateOpacity(0.5));
185 test_mode_color(mode, DlColor::kBlack());
186 test_mode_color(mode, DlColor::kBlack().modulateOpacity(0.5));
187 };
188
189#define TEST_MODE(V) test_mode(DlBlendMode::V);
191#undef TEST_MODE
192}
193
194#undef FOR_EACH_BLEND_MODE_ENUM
195
196TEST(DisplayListSkConversions, ConvertWithZeroAndNegativeVerticesAndIndices) {
197 std::shared_ptr<const DlVertices> vertices1 = DlVertices::Make(
198 DlVertexMode::kTriangles, 0, nullptr, nullptr, nullptr, 0, nullptr);
199 EXPECT_NE(vertices1, nullptr);
200 EXPECT_NE(ToSk(vertices1), nullptr);
201
202 std::shared_ptr<const DlVertices> vertices2 = DlVertices::Make(
203 DlVertexMode::kTriangles, -1, nullptr, nullptr, nullptr, -1, nullptr);
204 EXPECT_NE(vertices2, nullptr);
205 EXPECT_NE(ToSk(vertices2), nullptr);
206}
207
208TEST(DisplayListVertices, ConvertWithZeroAndNegativeVerticesAndIndices) {
211 EXPECT_TRUE(builder1.is_valid());
212 std::shared_ptr<DlVertices> vertices1 = builder1.build();
213 EXPECT_NE(vertices1, nullptr);
214 EXPECT_NE(ToSk(vertices1), nullptr);
215
218 EXPECT_TRUE(builder2.is_valid());
219 std::shared_ptr<DlVertices> vertices2 = builder2.build();
220 EXPECT_NE(vertices2, nullptr);
221 EXPECT_NE(ToSk(vertices2), nullptr);
222}
223
224TEST(DisplayListColorSource, ConvertRuntimeEffect) {
227 SkString("vec4 main(vec2 p) { return vec4(0); }"))
228 .effect);
231 SkString("vec4 main(vec2 p) { return vec4(1); }"))
232 .effect);
233 std::shared_ptr<DlRuntimeEffectColorSource> source1 =
235 kTestRuntimeEffect1, {}, std::make_shared<std::vector<uint8_t>>());
236 std::shared_ptr<DlRuntimeEffectColorSource> source2 =
238 kTestRuntimeEffect2, {}, std::make_shared<std::vector<uint8_t>>());
239 std::shared_ptr<DlRuntimeEffectColorSource> source3 =
241 nullptr, {}, std::make_shared<std::vector<uint8_t>>());
242
243 ASSERT_NE(ToSk(source1), nullptr);
244 ASSERT_NE(ToSk(source2), nullptr);
245 ASSERT_EQ(ToSk(source3), nullptr);
246}
247
248TEST(DisplayListColorSource, ConvertRuntimeEffectWithNullSampler) {
251 SkString("vec4 main(vec2 p) { return vec4(0); }"))
252 .effect);
253 std::shared_ptr<DlRuntimeEffectColorSource> source1 =
255 kTestRuntimeEffect1, {nullptr},
256 std::make_shared<std::vector<uint8_t>>());
257
258 ASSERT_EQ(ToSk(source1), nullptr);
259}
260
261TEST(DisplayListSkConversions, MatrixColorFilterModifiesTransparency) {
262 auto test_matrix = [](int element, SkScalar value) {
263 // clang-format off
264 float matrix[] = {
265 1, 0, 0, 0, 0,
266 0, 1, 0, 0, 0,
267 0, 0, 1, 0, 0,
268 0, 0, 0, 1, 0,
269 };
270 // clang-format on
271 std::string desc =
272 "matrix[" + std::to_string(element) + "] = " + std::to_string(value);
273 matrix[element] = value;
275 auto dl_filter = DlMatrixColorFilter::Make(matrix);
276 auto sk_filter = ToSk(filter);
277 auto srgb = SkColorSpace::MakeSRGB();
278 EXPECT_EQ(dl_filter == nullptr, sk_filter == nullptr);
279 EXPECT_EQ(filter.modifies_transparent_black(),
280 sk_filter && sk_filter->filterColor4f(SkColors::kTransparent,
281 srgb.get(), srgb.get()) !=
283 };
284
285 // Tests identity (matrix[0] already == 1 in an identity filter)
286 test_matrix(0, 1);
287 // test_matrix(19, 1);
288 for (int i = 0; i < 20; i++) {
289 test_matrix(i, -0.25);
290 test_matrix(i, 0);
291 test_matrix(i, 0.25);
292 test_matrix(i, 1);
293 test_matrix(i, 1.25);
297 }
298}
299
300TEST(DisplayListSkConversions, ToSkDitheringEnabledForGradients) {
301 // Test that when using the utility method "ToSk", the resulting SkPaint
302 // has "isDither" set to true, if the paint is a gradient, because it's
303 // a supported feature in the Impeller backend.
304
305 DlPaint dl_paint;
306
307 // Set the paint to be a gradient.
309 SkPoint::Make(100, 100), 0,
310 0, 0, DlTileMode::kClamp));
311
312 {
313 SkPaint sk_paint = ToSk(dl_paint);
314 EXPECT_TRUE(sk_paint.isDither());
315 }
316
317 {
318 SkPaint sk_paint = ToStrokedSk(dl_paint);
319 EXPECT_TRUE(sk_paint.isDither());
320 }
321
322 {
323 SkPaint sk_paint = ToNonShaderSk(dl_paint);
324 EXPECT_FALSE(sk_paint.isDither());
325 }
326}
327
328} // namespace testing
329} // namespace flutter
static void test_matrix(skiatest::Reporter *reporter)
@ kOuter_SkBlurStyle
nothing inside, fuzzy outside
Definition: SkBlurTypes.h:14
@ kSolid_SkBlurStyle
solid inside, fuzzy outside
Definition: SkBlurTypes.h:13
@ kInner_SkBlurStyle
fuzzy inside, nothing outside
Definition: SkBlurTypes.h:15
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition: SkBlurTypes.h:12
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
#define SK_ScalarNaN
Definition: SkScalar.h:28
#define SK_ScalarInfinity
Definition: SkScalar.h:26
static sk_sp< SkColorSpace > MakeSRGB()
static SkMatrix RotateDeg(SkScalar deg)
Definition: SkMatrix.h:104
bool isDither() const
Definition: SkPaint.h:175
static Result MakeForShader(SkString sksl, const Options &)
static std::shared_ptr< DlColorFilter > Make(DlColor color, DlBlendMode mode)
bool modifies_transparent_black() const override
static std::shared_ptr< DlRuntimeEffectColorSource > MakeRuntimeEffect(sk_sp< DlRuntimeEffect > runtime_effect, std::vector< std::shared_ptr< DlColorSource > > samplers, std::shared_ptr< std::vector< uint8_t > > uniform_data)
static std::shared_ptr< DlLinearGradientColorSource > MakeLinear(const SkPoint start_point, const SkPoint end_point, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const SkMatrix *matrix=nullptr)
static std::shared_ptr< DlColorFilter > Make(const float matrix[20])
bool modifies_transparent_black() const override
DlPaint & setColorSource(std::shared_ptr< const DlColorSource > source)
Definition: dl_paint.h:131
static sk_sp< DlRuntimeEffect > MakeSkia(const sk_sp< SkRuntimeEffect > &runtime_effect)
A utility class to build up a |DlVertices| object one set of data at a time.
Definition: dl_vertices.h:75
static constexpr Flags kNone
Definition: dl_vertices.h:96
std::shared_ptr< DlVertices > build()
Finalizes and the constructed DlVertices object.
Definition: dl_vertices.cc:279
bool is_valid()
Returns true iff the underlying object was successfully allocated.
Definition: dl_vertices.h:115
static std::shared_ptr< DlVertices > Make(DlVertexMode mode, int vertex_count, const SkPoint vertices[], const SkPoint texture_coordinates[], const DlColor colors[], int index_count=0, const uint16_t indices[]=nullptr)
Constructs a DlVector with compact inline storage for all of its required and optional lists of data.
Definition: dl_vertices.cc:39
DlColor color
#define CHECK_TO_SKENUM(V)
#define FOR_EACH_BLEND_MODE_ENUM(FUNC)
#define TEST_MODE(V)
float SkScalar
Definition: extension.cpp:12
uint8_t value
constexpr SkColor4f kTransparent
Definition: SkColor.h:434
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
static const sk_sp< DlRuntimeEffect > kTestRuntimeEffect1
static const sk_sp< DlRuntimeEffect > kTestRuntimeEffect2
TEST(DisplayListComplexity, EmptyDisplayList)
SkPaint ToSk(const DlPaint &paint)
@ kMiter
extends to miter limit
@ kBevel
connects outside edges
@ kRound
adds circle
@ kButt
no stroke extension
@ kSquare
adds square
SkPaint ToStrokedSk(const DlPaint &paint)
@ kTriangles
The vertices are taken 3 at a time to form a triangle.
SkPaint ToNonShaderSk(const DlPaint &paint)
@ kStrokeAndFill
both strokes and fills shapes
@ kStroke
strokes boundary of shapes
@ kFill
fills interior of shapes
@ kNormal
fuzzy inside and outside
@ kOuter
nothing inside, fuzzy outside
@ kInner
fuzzy inside, nothing outside
@ kSolid
solid inside, fuzzy outside
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
SkSamplingOptions(SkFilterMode::kLinear))
flutter::DlColor DlColor
static SkString to_string(int n)
Definition: nanobench.cpp:119
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
static constexpr DlColor kWhite()
Definition: dl_color.h:23
static constexpr DlColor kBlue()
Definition: dl_color.h:26
static constexpr DlColor kBlack()
Definition: dl_color.h:22
static constexpr DlColor kTransparent()
Definition: dl_color.h:21
static constexpr DlColor kRed()
Definition: dl_color.h:24
static constexpr DlColor kGreen()
Definition: dl_color.h:25
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678