Flutter Engine
 
Loading...
Searching...
No Matches
dl_sk_conversions_unittests.cc File Reference
#include "flutter/display_list/dl_blend_mode.h"
#include "flutter/display_list/dl_paint.h"
#include "flutter/display_list/dl_sampling_options.h"
#include "flutter/display_list/dl_tile_mode.h"
#include "flutter/display_list/dl_vertices.h"
#include "flutter/display_list/effects/dl_color_filters.h"
#include "flutter/display_list/effects/dl_color_sources.h"
#include "flutter/display_list/effects/dl_image_filters.h"
#include "flutter/display_list/effects/dl_runtime_effect_skia.h"
#include "flutter/display_list/skia/dl_sk_conversions.h"
#include "flutter/third_party/skia/include/core/SkColorSpace.h"
#include "flutter/third_party/skia/include/core/SkSamplingOptions.h"
#include "flutter/third_party/skia/include/core/SkTileMode.h"
#include "flutter/third_party/skia/include/effects/SkRuntimeEffect.h"
#include "gtest/gtest.h"

Go to the source code of this file.

Namespaces

namespace  flutter
 
namespace  flutter::testing
 

Macros

#define FOR_EACH_BLEND_MODE_ENUM(FUNC)
 
#define CHECK_TO_SKENUM(V)   ASSERT_EQ(ToSk(DlBlendMode::V), SkBlendMode::V);
 
#define TEST_MODE(V)   test_mode(DlBlendMode::V);
 

Functions

 flutter::testing::TEST (DisplayListImageFilter, LocalImageSkiaNull)
 
 flutter::testing::TEST (DisplayListSkConversions, OpOrderPreMethodsVsMatrixMultiply)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkColor)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkTileMode)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkBlurStyle)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkDrawStyle)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkStrokeCap)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkStrokeJoin)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkVertexMode)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkFilterMode)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkSrcRectConstraint)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkSamplingOptions)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkBlendMode)
 
 flutter::testing::TEST (DisplayListSkConversions, BlendColorFilterModifiesTransparency)
 
 flutter::testing::TEST (DisplayListSkConversions, ConvertWithZeroAndNegativeVerticesAndIndices)
 
 flutter::testing::TEST (DisplayListVertices, ConvertWithZeroAndNegativeVerticesAndIndices)
 
 flutter::testing::TEST (DisplayListColorSource, ConvertRuntimeEffect)
 
 flutter::testing::TEST (DisplayListColorSource, ConvertRuntimeEffectWithNullSampler)
 
 flutter::testing::TEST (DisplayListSkConversions, MatrixColorFilterModifiesTransparency)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkDitheringEnabledForGradients)
 
 flutter::testing::TEST (DisplayListSkConversions, ToSkRSTransform)
 

Macro Definition Documentation

◆ CHECK_TO_SKENUM

#define CHECK_TO_SKENUM (   V)    ASSERT_EQ(ToSk(DlBlendMode::V), SkBlendMode::V);

◆ FOR_EACH_BLEND_MODE_ENUM

#define FOR_EACH_BLEND_MODE_ENUM (   FUNC)

Definition at line 185 of file dl_sk_conversions_unittests.cc.

217 {
218#define CHECK_TO_SKENUM(V) ASSERT_EQ(ToSk(DlBlendMode::V), SkBlendMode::V);
220#undef CHECK_TO_SKENUM
221}
222
223TEST(DisplayListSkConversions, BlendColorFilterModifiesTransparency) {
224 auto test_mode_color = [](DlBlendMode mode, DlColor color) {
225 std::stringstream desc_str;
226 desc_str << "blend[" << static_cast<int>(mode) << ", " << color.argb()
227 << "]";
228 std::string desc = desc_str.str();
229 DlBlendColorFilter filter(color, mode);
230 auto srgb = SkColorSpace::MakeSRGB();
231 if (filter.modifies_transparent_black()) {
232 auto dl_filter = DlColorFilter::MakeBlend(color, mode);
233 auto sk_filter = ToSk(filter);
234 ASSERT_NE(dl_filter, nullptr) << desc;
235 ASSERT_NE(sk_filter, nullptr) << desc;
236 ASSERT_TRUE(sk_filter->filterColor4f(SkColors::kTransparent, srgb.get(),
237 srgb.get()) !=
238 SkColors::kTransparent)
239 << desc;
240 } else {
241 auto dl_filter = DlColorFilter::MakeBlend(color, mode);
242 auto sk_filter = ToSk(filter);
243 EXPECT_EQ(dl_filter == nullptr, sk_filter == nullptr) << desc;
244 ASSERT_TRUE(sk_filter == nullptr ||
245 sk_filter->filterColor4f(SkColors::kTransparent, srgb.get(),
246 srgb.get()) ==
247 SkColors::kTransparent)
248 << desc;
249 }
250 };
251
252 auto test_mode = [&test_mode_color](DlBlendMode mode) {
253 test_mode_color(mode, DlColor::kTransparent());
254 test_mode_color(mode, DlColor::kWhite());
255 test_mode_color(mode, DlColor::kWhite().modulateOpacity(0.5));
256 test_mode_color(mode, DlColor::kBlack());
257 test_mode_color(mode, DlColor::kBlack().modulateOpacity(0.5));
258 };
259
260#define TEST_MODE(V) test_mode(DlBlendMode::V);
262#undef TEST_MODE
263}
264
265#undef FOR_EACH_BLEND_MODE_ENUM
266
267TEST(DisplayListSkConversions, ConvertWithZeroAndNegativeVerticesAndIndices) {
268 std::shared_ptr<DlVertices> vertices1 = DlVertices::Make(
269 DlVertexMode::kTriangles, 0, nullptr, nullptr, nullptr, 0, nullptr);
270 EXPECT_NE(vertices1, nullptr);
271 EXPECT_EQ(ToSk(vertices1), nullptr);
272
273 std::shared_ptr<DlVertices> vertices2 = DlVertices::Make(
274 DlVertexMode::kTriangles, -1, nullptr, nullptr, nullptr, -1, nullptr);
275 EXPECT_NE(vertices2, nullptr);
276 EXPECT_EQ(ToSk(vertices2), nullptr);
277}
278
279TEST(DisplayListVertices, ConvertWithZeroAndNegativeVerticesAndIndices) {
280 DlVertices::Builder builder1(DlVertexMode::kTriangles, 0,
281 DlVertices::Builder::kNone, 0);
282 EXPECT_TRUE(builder1.is_valid());
283 std::shared_ptr<DlVertices> vertices1 = builder1.build();
284 EXPECT_NE(vertices1, nullptr);
285 EXPECT_EQ(ToSk(vertices1), nullptr);
286
287 DlVertices::Builder builder2(DlVertexMode::kTriangles, -1,
288 DlVertices::Builder::kNone, -1);
289 EXPECT_TRUE(builder2.is_valid());
290 std::shared_ptr<DlVertices> vertices2 = builder2.build();
291 EXPECT_NE(vertices2, nullptr);
292 EXPECT_EQ(ToSk(vertices2), nullptr);
293}
294
295TEST(DisplayListColorSource, ConvertRuntimeEffect) {
296 const sk_sp<DlRuntimeEffect> kTestRuntimeEffect1 = DlRuntimeEffectSkia::Make(
297 SkRuntimeEffect::MakeForShader(
298 SkString("vec4 main(vec2 p) { return vec4(0); }"))
299 .effect);
300 const sk_sp<DlRuntimeEffect> kTestRuntimeEffect2 = DlRuntimeEffectSkia::Make(
301 SkRuntimeEffect::MakeForShader(
302 SkString("vec4 main(vec2 p) { return vec4(1); }"))
303 .effect);
304 std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeRuntimeEffect(
305 kTestRuntimeEffect1, {}, std::make_shared<std::vector<uint8_t>>());
306 std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRuntimeEffect(
307 kTestRuntimeEffect2, {}, std::make_shared<std::vector<uint8_t>>());
308 std::shared_ptr<DlColorSource> source3 = DlColorSource::MakeRuntimeEffect(
309 nullptr, {}, std::make_shared<std::vector<uint8_t>>());
310
311 ASSERT_NE(ToSk(source1), nullptr);
312 ASSERT_NE(ToSk(source2), nullptr);
313 ASSERT_EQ(ToSk(source3), nullptr);
314}
315
316TEST(DisplayListColorSource, ConvertRuntimeEffectWithNullSampler) {
317 const sk_sp<DlRuntimeEffect> kTestRuntimeEffect1 = DlRuntimeEffectSkia::Make(
318 SkRuntimeEffect::MakeForShader(
319 SkString("vec4 main(vec2 p) { return vec4(0); }"))
320 .effect);
321 std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeRuntimeEffect(
322 kTestRuntimeEffect1, {nullptr}, std::make_shared<std::vector<uint8_t>>());
323
324 ASSERT_EQ(ToSk(source1), nullptr);
325}
326
327TEST(DisplayListSkConversions, MatrixColorFilterModifiesTransparency) {
328 auto test_matrix = [](int element, SkScalar value) {
329 // clang-format off
330 float matrix[] = {
331 1, 0, 0, 0, 0,
332 0, 1, 0, 0, 0,
333 0, 0, 1, 0, 0,
334 0, 0, 0, 1, 0,
335 };
336 // clang-format on
337 std::string desc =
338 "matrix[" + std::to_string(element) + "] = " + std::to_string(value);
339 matrix[element] = value;
340 DlMatrixColorFilter filter(matrix);
341 auto dl_filter = DlColorFilter::MakeMatrix(matrix);
342 auto sk_filter = ToSk(filter);
343 auto srgb = SkColorSpace::MakeSRGB();
344 EXPECT_EQ(dl_filter == nullptr, sk_filter == nullptr);
345 EXPECT_EQ(filter.modifies_transparent_black(),
346 sk_filter && sk_filter->filterColor4f(SkColors::kTransparent,
347 srgb.get(), srgb.get()) !=
348 SkColors::kTransparent);
349 };
350
351 // Tests identity (matrix[0] already == 1 in an identity filter)
352 test_matrix(0, 1);
353 // test_matrix(19, 1);
354 for (int i = 0; i < 20; i++) {
355 test_matrix(i, -0.25);
356 test_matrix(i, 0);
357 test_matrix(i, 0.25);
358 test_matrix(i, 1);
359 test_matrix(i, 1.25);
360 test_matrix(i, SK_ScalarNaN);
361 test_matrix(i, SK_ScalarInfinity);
362 test_matrix(i, -SK_ScalarInfinity);
363 }
364}
365
366TEST(DisplayListSkConversions, ToSkDitheringEnabledForGradients) {
367 // Test that when using the utility method "ToSk", the resulting SkPaint
368 // has "isDither" set to true, if the paint is a gradient, because it's
369 // a supported feature in the Impeller backend.
370
371 DlPaint dl_paint;
372
373 // Set the paint to be a gradient.
374 dl_paint.setColorSource(DlColorSource::MakeLinear(
375 DlPoint(0, 0), DlPoint(100, 100), 0,
376 std::array<DlColor, 1>{DlColor(0)}.data(), 0, DlTileMode::kClamp));
377
378 {
379 SkPaint sk_paint = ToSk(dl_paint);
380 EXPECT_TRUE(sk_paint.isDither());
381 }
382
383 {
384 SkPaint sk_paint = ToStrokedSk(dl_paint);
385 EXPECT_TRUE(sk_paint.isDither());
386 }
387
388 {
389 SkPaint sk_paint = ToNonShaderSk(dl_paint);
390 EXPECT_FALSE(sk_paint.isDither());
391 }
392}
393
394TEST(DisplayListSkConversions, ToSkRSTransform) {
395 constexpr size_t kTransformCount = 4;
396 DlRSTransform transforms[kTransformCount] = {
397 DlRSTransform::Make({0.0f, 0.0f}, 1.0f, DlDegrees(0)),
398 DlRSTransform::Make({12.25f, 14.75f}, 10.0f, DlDegrees(30)),
399 DlRSTransform::Make({-10.4f, 8.25f}, 11.0f, DlDegrees(400)),
400 DlRSTransform::Make({1.0f, 3.0f}, 0.5f, DlDegrees(45)),
401 };
402 SkRSXform expected_transforms[kTransformCount] = {
403 SkRSXform::MakeFromRadians(1.0f, SkDegreesToRadians(0), //
404 0.0f, 0.0f, 0.0f, 0.0f),
405 SkRSXform::MakeFromRadians(10.0f, SkDegreesToRadians(30), //
406 12.25f, 14.75f, 0.0f, 0.0f),
407 SkRSXform::MakeFromRadians(11.0f, SkDegreesToRadians(400), //
408 -10.4f, 8.25f, 0.0f, 0.0f),
409 SkRSXform::MakeFromRadians(0.5f, SkDegreesToRadians(45), //
410 1.0f, 3.0f, 0.0f, 0.0f),
411 };
412 auto sk_transforms = ToSk(transforms);
413 for (size_t i = 0; i < kTransformCount; i++) {
414 // Comparing dl values to transformed copy values
415 // should match exactly because arrays were simply aliased
416 EXPECT_EQ(sk_transforms[i].fSCos, transforms[i].scaled_cos) << i;
417 EXPECT_EQ(sk_transforms[i].fSSin, transforms[i].scaled_sin) << i;
418 EXPECT_EQ(sk_transforms[i].fTx, transforms[i].translate_x) << i;
419 EXPECT_EQ(sk_transforms[i].fTy, transforms[i].translate_y) << i;
420
421 // Comparing dl values to computed Skia values
422 // should match closely, but not exactly due to differences in trig
423 EXPECT_FLOAT_EQ(sk_transforms[i].fSCos, expected_transforms[i].fSCos) << i;
424 EXPECT_FLOAT_EQ(sk_transforms[i].fSSin, expected_transforms[i].fSSin) << i;
425 EXPECT_EQ(sk_transforms[i].fTx, expected_transforms[i].fTx) << i;
426 EXPECT_EQ(sk_transforms[i].fTy, expected_transforms[i].fTy) << i;
427
428 // Comparing the results of transforming a sprite with Skia vs Impeller
429 SkPoint sk_quad[4];
430 expected_transforms[i].toQuad(20, 30, sk_quad);
431 DlQuad dl_quad;
432 transforms[i].GetQuad(20, 30, dl_quad);
433 // Skia order is UL,UR,LR,LL, Impeller order is UL,UR,LL,LR
434 EXPECT_FLOAT_EQ(sk_quad[0].fX, dl_quad[0].x) << i;
435 EXPECT_FLOAT_EQ(sk_quad[0].fY, dl_quad[0].y) << i;
436 EXPECT_FLOAT_EQ(sk_quad[1].fX, dl_quad[1].x) << i;
437 EXPECT_FLOAT_EQ(sk_quad[1].fY, dl_quad[1].y) << i;
438 EXPECT_FLOAT_EQ(sk_quad[2].fX, dl_quad[3].x) << i;
439 EXPECT_FLOAT_EQ(sk_quad[2].fY, dl_quad[3].y) << i;
440 EXPECT_FLOAT_EQ(sk_quad[3].fX, dl_quad[2].x) << i;
441 EXPECT_FLOAT_EQ(sk_quad[3].fY, dl_quad[2].y) << i;
442 }
443}
444
445} // namespace testing
446} // namespace flutter
TEST(AsciiTableTest, Simple)
DlPaint & setColorSource(std::nullptr_t source)
Definition dl_paint.h:131
int32_t value
int32_t x
#define CHECK_TO_SKENUM(V)
#define FOR_EACH_BLEND_MODE_ENUM(FUNC)
#define TEST_MODE(V)
double y
SkPaint ToSk(const DlPaint &paint)
impeller::RSTransform DlRSTransform
impeller::Degrees DlDegrees
SkPaint ToStrokedSk(const DlPaint &paint)
SkPaint ToNonShaderSk(const DlPaint &paint)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all 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
impeller::BlendMode DlBlendMode
impeller::Quad DlQuad
impeller::Point DlPoint
flutter::DlColor DlColor
flutter::DlPaint DlPaint

◆ TEST_MODE

#define TEST_MODE (   V)    test_mode(DlBlendMode::V);