Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
canvas_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 <unordered_map>
10#include "gtest/gtest.h"
22#include "third_party/abseil-cpp/absl/status/status_matchers.h"
23
24namespace impeller {
25namespace testing {
26
27std::unique_ptr<Canvas> CreateTestCanvas(
28 ContentContext& context,
29 std::optional<Rect> cull_rect = std::nullopt,
30 bool requires_readback = false) {
31 TextureDescriptor onscreen_desc;
32 onscreen_desc.size = {100, 100};
33 onscreen_desc.format =
35 onscreen_desc.usage = TextureUsage::kRenderTarget;
37 onscreen_desc.sample_count = SampleCount::kCount1;
38 std::shared_ptr<Texture> onscreen =
39 context.GetContext()->GetResourceAllocator()->CreateTexture(
40 onscreen_desc);
41
42 ColorAttachment color0;
44 if (context.GetContext()->GetCapabilities()->SupportsOffscreenMSAA()) {
45 TextureDescriptor onscreen_msaa_desc = onscreen_desc;
46 onscreen_msaa_desc.sample_count = SampleCount::kCount4;
48 onscreen_msaa_desc.type = TextureType::kTexture2DMultisample;
49
50 std::shared_ptr<Texture> onscreen_msaa =
51 context.GetContext()->GetResourceAllocator()->CreateTexture(
52 onscreen_msaa_desc);
53 color0.resolve_texture = onscreen;
54 color0.texture = onscreen_msaa;
56 } else {
57 color0.texture = onscreen;
58 }
59
60 RenderTarget render_target;
61 render_target.SetColorAttachment(color0, 0);
62
63 if (cull_rect.has_value()) {
64 return std::make_unique<Canvas>(
65 context, render_target, /*is_onscreen=*/false,
66 /*requires_readback=*/requires_readback, cull_rect.value());
67 }
68 return std::make_unique<Canvas>(context, render_target, /*is_onscreen=*/false,
69 /*requires_readback=*/requires_readback);
70}
71
72TEST_P(AiksTest, TransformMultipliesCorrectly) {
73 ContentContext context(GetContext(), nullptr);
74 auto canvas = CreateTestCanvas(context);
75
76 ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), Matrix());
77
78 // clang-format off
79 canvas->Translate(Vector3(100, 200));
81 canvas->GetCurrentTransform(),
82 Matrix( 1, 0, 0, 0,
83 0, 1, 0, 0,
84 0, 0, 1, 0,
85 100, 200, 0, 1));
86
87 canvas->Rotate(Radians(kPiOver2));
89 canvas->GetCurrentTransform(),
90 Matrix( 0, 1, 0, 0,
91 -1, 0, 0, 0,
92 0, 0, 1, 0,
93 100, 200, 0, 1));
94
95 canvas->Scale(Vector3(2, 3));
97 canvas->GetCurrentTransform(),
98 Matrix( 0, 2, 0, 0,
99 -3, 0, 0, 0,
100 0, 0, 0, 0,
101 100, 200, 0, 1));
102
103 canvas->Translate(Vector3(100, 200));
105 canvas->GetCurrentTransform(),
106 Matrix( 0, 2, 0, 0,
107 -3, 0, 0, 0,
108 0, 0, 0, 0,
109 -500, 400, 0, 1));
110 // clang-format on
111}
112
113TEST_P(AiksTest, CanvasCanPushPopCTM) {
114 ContentContext context(GetContext(), nullptr);
115 auto canvas = CreateTestCanvas(context);
116
117 ASSERT_EQ(canvas->GetSaveCount(), 1u);
118 ASSERT_EQ(canvas->Restore(), false);
119
120 canvas->Translate(Size{100, 100});
121 canvas->Save(10);
122 ASSERT_EQ(canvas->GetSaveCount(), 2u);
123 ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
124 Matrix::MakeTranslation({100.0, 100.0, 0.0}));
125 ASSERT_TRUE(canvas->Restore());
126 ASSERT_EQ(canvas->GetSaveCount(), 1u);
127 ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
128 Matrix::MakeTranslation({100.0, 100.0, 0.0}));
129}
130
131TEST_P(AiksTest, CanvasCTMCanBeUpdated) {
132 ContentContext context(GetContext(), nullptr);
133 auto canvas = CreateTestCanvas(context);
134
135 Matrix identity;
136 ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), identity);
137 canvas->Translate(Size{100, 100});
138 ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
139 Matrix::MakeTranslation({100.0, 100.0, 0.0}));
140}
141
142TEST_P(AiksTest, BackdropCountDownNormal) {
143 ContentContext context(GetContext(), nullptr);
145 GTEST_SKIP() << "Test requires device with framebuffer fetch";
146 }
147 auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
148 /*requires_readback=*/true);
149 // 3 backdrop filters
150 canvas->SetBackdropData({}, 3);
151
152 auto blur =
154 flutter::DlRect rect = flutter::DlRect::MakeLTRB(0, 0, 50, 50);
155
156 EXPECT_TRUE(canvas->RequiresReadback());
157 canvas->DrawRect(rect, {.color = Color::Azure()});
158 canvas->SaveLayer({}, rect, blur.get(),
160 /*total_content_depth=*/1);
161 canvas->Restore();
162 EXPECT_TRUE(canvas->RequiresReadback());
163
164 canvas->SaveLayer({}, rect, blur.get(),
166 /*total_content_depth=*/1);
167 canvas->Restore();
168 EXPECT_TRUE(canvas->RequiresReadback());
169
170 canvas->SaveLayer({}, rect, blur.get(),
172 /*total_content_depth=*/1);
173 canvas->Restore();
174 EXPECT_FALSE(canvas->RequiresReadback());
175}
176
177TEST_P(AiksTest, BackdropCountDownBackdropId) {
178 ContentContext context(GetContext(), nullptr);
180 GTEST_SKIP() << "Test requires device with framebuffer fetch";
181 }
182 auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
183 /*requires_readback=*/true);
184 // 3 backdrop filters all with same id.
185 std::unordered_map<int64_t, BackdropData> data;
187 canvas->SetBackdropData(data, 3);
188
189 auto blur =
191
192 EXPECT_TRUE(canvas->RequiresReadback());
193 canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
194 {.color = Color::Azure()});
195 canvas->SaveLayer({}, std::nullopt, blur.get(),
197 /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
198 /*backdrop_id=*/1);
199 canvas->Restore();
200 EXPECT_FALSE(canvas->RequiresReadback());
201
202 canvas->SaveLayer({}, std::nullopt, blur.get(),
204 /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
205 /*backdrop_id=*/1);
206 canvas->Restore();
207 EXPECT_FALSE(canvas->RequiresReadback());
208
209 canvas->SaveLayer({}, std::nullopt, blur.get(),
211 /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
212 /*backdrop_id=*/1);
213 canvas->Restore();
214 EXPECT_FALSE(canvas->RequiresReadback());
215}
216
217TEST_P(AiksTest, BackdropCountDownBackdropIdMixed) {
218 ContentContext context(GetContext(), nullptr);
220 GTEST_SKIP() << "Test requires device with framebuffer fetch";
221 }
222 auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
223 /*requires_readback=*/true);
224 // 3 backdrop filters, 2 with same id.
225 std::unordered_map<int64_t, BackdropData> data;
227 canvas->SetBackdropData(data, 3);
228
229 auto blur =
231
232 EXPECT_TRUE(canvas->RequiresReadback());
233 canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
234 {.color = Color::Azure()});
235 canvas->SaveLayer({}, std::nullopt, blur.get(),
237 canvas->Restore();
238 EXPECT_TRUE(canvas->RequiresReadback());
239
240 canvas->SaveLayer({}, std::nullopt, blur.get(),
242 canvas->Restore();
243 EXPECT_FALSE(canvas->RequiresReadback());
244
245 canvas->SaveLayer({}, std::nullopt, blur.get(),
247 canvas->Restore();
248 EXPECT_FALSE(canvas->RequiresReadback());
249}
250
251// We only know the total number of backdrop filters, not the number of backdrop
252// filters in the root pass. If we reach a count of 0 while in a nested
253// saveLayer, we should not restore to the onscreen.
254TEST_P(AiksTest, BackdropCountDownWithNestedSaveLayers) {
255 ContentContext context(GetContext(), nullptr);
257 GTEST_SKIP() << "Test requires device with framebuffer fetch";
258 }
259 auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
260 /*requires_readback=*/true);
261
262 canvas->SetBackdropData({}, 2);
263
264 auto blur =
266
267 EXPECT_TRUE(canvas->RequiresReadback());
268 canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
269 {.color = Color::Azure()});
270 canvas->SaveLayer({}, std::nullopt, blur.get(),
272 /*total_content_depth=*/3);
273
274 // This filter is nested in the first saveLayer. We cannot restore to onscreen
275 // here.
276 canvas->SaveLayer({}, std::nullopt, blur.get(),
278 /*total_content_depth=*/1);
279 canvas->Restore();
280 EXPECT_TRUE(canvas->RequiresReadback());
281
282 canvas->Restore();
283 EXPECT_TRUE(canvas->RequiresReadback());
284}
285
286TEST_P(AiksTest, DrawVerticesLinearGradientWithEmptySize) {
287 RenderCallback callback = [&](RenderTarget& render_target) {
288 ContentContext context(GetContext(), nullptr);
289 Canvas canvas(context, render_target, true, false);
290
291 std::vector<flutter::DlPoint> vertex_coordinates = {
292 flutter::DlPoint(0, 0),
293 flutter::DlPoint(600, 0),
294 flutter::DlPoint(0, 600),
295 };
296 std::vector<flutter::DlPoint> texture_coordinates = {
297 flutter::DlPoint(0, 0),
298 flutter::DlPoint(500, 0),
299 flutter::DlPoint(0, 500),
300 };
301 std::vector<uint16_t> indices = {0, 1, 2};
302 flutter::DlVertices::Builder vertices_builder(
303 flutter::DlVertexMode::kTriangleStrip, vertex_coordinates.size(),
305 vertices_builder.store_vertices(vertex_coordinates.data());
306 vertices_builder.store_indices(indices.data());
307 vertices_builder.store_texture_coordinates(texture_coordinates.data());
308 auto vertices = vertices_builder.build();
309
310 // The start and end points of the gradient form an empty rectangle.
311 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
313 std::vector<Scalar> stops = {0.0, 1.0};
315 {0, 0}, {0, 600}, 2, colors.data(), stops.data(),
317
318 Paint paint;
319 paint.color_source = gradient.get();
320 canvas.DrawVertices(std::make_shared<DlVerticesGeometry>(vertices, context),
321 BlendMode::kSrcOver, paint);
322
323 canvas.EndReplay();
324 return true;
325 };
326
328}
329
330TEST_P(AiksTest, DrawVerticesWithEmptyTextureCoordinates) {
331 auto runtime_stages_result =
332 OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
333 ABSL_ASSERT_OK(runtime_stages_result);
334 std::shared_ptr<RuntimeStage> runtime_stage =
335 runtime_stages_result.value()[GetRuntimeStageBackend()];
336 ASSERT_TRUE(runtime_stage);
337
338 auto runtime_effect = flutter::DlRuntimeEffectImpeller::Make(runtime_stage);
339 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
341 runtime_effect, {}, uniform_data);
342
343 RenderCallback callback = [&](RenderTarget& render_target) {
344 ContentContext context(GetContext(), nullptr);
345 Canvas canvas(context, render_target, true, false);
346
347 std::vector<flutter::DlPoint> vertex_coordinates = {
348 flutter::DlPoint(100, 100),
349 flutter::DlPoint(300, 100),
350 flutter::DlPoint(100, 300),
351 };
352 // The bounding box of the texture coordinates is empty.
353 std::vector<flutter::DlPoint> texture_coordinates = {
354 flutter::DlPoint(0, 0),
355 flutter::DlPoint(0, 100),
356 flutter::DlPoint(0, 0),
357 };
358 std::vector<uint16_t> indices = {0, 1, 2};
359 flutter::DlVertices::Builder vertices_builder(
360 flutter::DlVertexMode::kTriangleStrip, vertex_coordinates.size(),
362 vertices_builder.store_vertices(vertex_coordinates.data());
363 vertices_builder.store_indices(indices.data());
364 vertices_builder.store_texture_coordinates(texture_coordinates.data());
365 auto vertices = vertices_builder.build();
366
367 Paint paint;
368 paint.color_source = color_source.get();
369 canvas.DrawVertices(std::make_shared<DlVerticesGeometry>(vertices, context),
370 BlendMode::kSrcOver, paint);
371
372 canvas.EndReplay();
373 return true;
374 };
375
377}
378
379TEST_P(AiksTest, SupportsBlitToOnscreen) {
380 ContentContext context(GetContext(), nullptr);
381 auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
382 /*requires_readback=*/true);
383
384 if (GetBackend() != PlaygroundBackend::kMetal &&
385 GetBackend() != PlaygroundBackend::kMetalSDF) {
386 EXPECT_FALSE(canvas->SupportsBlitToOnscreen());
387 } else {
388 EXPECT_TRUE(canvas->SupportsBlitToOnscreen());
389 }
390}
391
392TEST_P(AiksTest, RoundSuperellipseShadowComparison) {
393 // Config
394 Size default_size(600, 400);
395 Point left_center(400, 700);
396 Point right_center(1300, 700);
397 Color color = Color::Red();
398
399 // Convert `color` to a `color_source`. This forces
400 // `canvas.DrawRoundSuperellipse` to use the regular shadow algorithm
401 // (blurring) instead of the fast shadow algorithm.
402 std::shared_ptr<flutter::DlColorSource> color_source;
403 {
404 flutter::DlColor dl_color = flutter::DlColor(color.ToARGB());
405 std::vector<flutter::DlColor> colors = {dl_color, dl_color};
406 std::vector<Scalar> stops = {0.0, 1.0};
408 {0, 0}, {1000, 1000}, 2, colors.data(), stops.data(),
410 }
411
412 RenderCallback callback = [&](RenderTarget& render_target) {
413 ContentContext context(GetContext(), nullptr);
414 Canvas canvas(context, render_target, true, false);
415 // Somehow there's a scaling factor between PlaygroundPoint and Canvas.
416 Matrix ctm = Matrix::MakeScale(Vector2(1, 1) * 0.5);
417 Matrix i_ctm = ctm.Invert();
418
419 static Scalar sigma = 0.05;
420 static Scalar radius = 200;
421
422 // Define the ImGui
423 ImGui::Begin("Shadow", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
424 {
425 ImGui::SliderFloat("Sigma", &sigma, 0, 100);
426 ImGui::SliderFloat("Radius", &radius, 0, 1000);
427 }
428 ImGui::End();
429
430 static PlaygroundPoint right_reference_var(
431 ctm * (right_center + default_size / 2), 30, Color::White());
432 Point right_reference = i_ctm * DrawPlaygroundPoint(right_reference_var);
433 Point half_size = (right_reference - right_center).Abs();
434 Rect left_bounds = Rect::MakeEllipseBounds(left_center, half_size);
435 Rect right_bounds = Rect::MakeEllipseBounds(right_center, half_size);
436
437 Paint paint{
438 .color = color,
439 .mask_blur_descriptor =
441 .sigma = Sigma(sigma),
442 },
443 };
444
445 // Left: Draw with canvas
447 RoundSuperellipse::MakeRectRadius(left_bounds, radius), paint);
448
449 // Right: Direct draw
450 paint.color_source = color_source.get();
452 RoundSuperellipse::MakeRectRadius(right_bounds, radius), paint);
453
454 canvas.EndReplay();
455 return true;
456 };
457
459}
460
461TEST_P(AiksTest, ImageTextureCacheBehavesCorrectly) {
462 ContentContext context(GetContext(), nullptr);
463
465 desc.size = {100, 100};
467 auto texture =
468 context.GetContext()->GetResourceAllocator()->CreateTexture(desc);
469
471
472 context.SetTextureCachingEnabled(true);
473 auto cached_tex1 = dl_image->GetCachedTexture(context);
474 ASSERT_EQ(cached_tex1, texture);
475
476 auto cached_tex2 = context.GetCachedTexture(dl_image.get());
477 ASSERT_EQ(cached_tex2, texture);
478
479 context.RemoveCachedTexture(dl_image.get());
480 auto cached_tex3 = context.GetCachedTexture(dl_image.get());
481 ASSERT_EQ(cached_tex3, nullptr);
482
483 auto cached_tex4 = dl_image->GetCachedTexture(context);
484 ASSERT_EQ(cached_tex4, texture);
485
486 context.ClearCachedTextures();
487 auto cached_tex5 = context.GetCachedTexture(dl_image.get());
488 ASSERT_EQ(cached_tex5, nullptr);
489
490 context.SetTextureCachingEnabled(false);
491}
492
493/// Verifies blend mode compatibility with SDF rendering.
494///
495/// The compatibility condition is:
496/// `mix(blend(src, dst), dst, 1 - sdf_alpha) == blend(src * sdf_alpha, dst)`
497TEST_P(AiksTest, BlendModeCompatibilityWithSDFRendering) {
498 std::vector<Color> colors = {
500 Color::Black(),
501 Color::White(),
506 };
507
508 for (int i = 0; i <= static_cast<int>(BlendMode::kLastMode); i++) {
509 BlendMode blend_mode = static_cast<BlendMode>(i);
510 bool blend_mode_is_compatible = true;
511
512 for (const auto& src : colors) {
513 for (const auto& dst : colors) {
514 for (Scalar sdf_alpha = 0.0; sdf_alpha < 1.01; sdf_alpha += 0.2) {
515 // `mix(blend(src, dst), dst, 1 - sdf_alpha)`:
516 // 1. Blend src onto dst.
517 Color blended = dst.Blend(src, blend_mode);
518 // 2. Mix with dst using sdf_alpha. Mix by lerping using
519 // pre-multiplied colors.
520 Color blended_then_sdf_alpha_applied =
521 Color::Lerp(blended.Premultiply(), dst.Premultiply(),
522 1.0 - sdf_alpha)
523 .Unpremultiply();
524
525 // `blend(src * sdf_alpha, dst)`:
526 // 1. Apply sdf_alpha to src's alpha.
527 Color sdf_alpha_applied = src.WithAlpha(src.alpha * sdf_alpha);
528 // 2. Blend onto dst.
529 Color sdf_alpha_applied_then_blended =
530 dst.Blend(sdf_alpha_applied, blend_mode);
531
532 // Compare results.
533 if (blended_then_sdf_alpha_applied !=
534 sdf_alpha_applied_then_blended) {
535 blend_mode_is_compatible = false;
536 }
537 }
538 }
539 }
540
541 Paint paint = {.blend_mode = blend_mode};
542 EXPECT_EQ(blend_mode_is_compatible,
544 << "Failure for BlendMode: " << BlendModeToString(blend_mode);
545 }
546}
547
548TEST(CanvasTest, NonAntialiasedPaintIncompatibleWithSDFRendering) {
549 Paint paint;
550 paint.anti_alias = false;
551 EXPECT_FALSE(Canvas::IsCompatibleWithSDFRendering(paint));
552}
553
554TEST(CanvasTest, AntialiasedPaintCompatibleWithSDFRendering) {
555 Paint paint;
556 EXPECT_TRUE(Canvas::IsCompatibleWithSDFRendering(paint));
557}
558
559} // namespace testing
560} // namespace impeller
static std::shared_ptr< DlColorSource > MakeLinear(const DlPoint start_point, const DlPoint end_point, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const DlMatrix *matrix=nullptr)
static std::shared_ptr< DlColorSource > 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< DlImageFilter > MakeBlur(DlScalar sigma_x, DlScalar sigma_y, DlTileMode tile_mode)
static sk_sp< DlRuntimeEffect > Make(std::shared_ptr< impeller::RuntimeStage > runtime_stage)
A utility class to build up a |DlVertices| object one set of data at a time.
Definition dl_vertices.h:73
void store_vertices(const DlPoint vertices[])
Copies the indicated list of points as vertices.
void store_indices(const uint16_t indices[])
Copies the indicated list of 16-bit indices as vertex indices.
void store_texture_coordinates(const DlPoint points[])
Copies the indicated list of points as texture coordinates.
std::shared_ptr< DlVertices > build()
Finalizes and the constructed DlVertices object.
static constexpr Flags kHasTextureCoordinates
Definition dl_vertices.h:95
void DrawRoundSuperellipse(const RoundSuperellipse &rse, const Paint &paint)
Definition canvas.cc:1026
void DrawVertices(const std::shared_ptr< VerticesGeometry > &vertices, BlendMode blend_mode, const Paint &paint)
Definition canvas.cc:1301
static bool IsCompatibleWithSDFRendering(const Paint &paint)
Definition canvas.cc:2456
virtual bool SupportsFramebufferFetch() const =0
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
virtual PixelFormat GetDefaultColorFormat() const =0
Returns a supported PixelFormat for textures that store 4-channel colors (red/green/blue/alpha).
std::shared_ptr< Texture > GetCachedTexture(const flutter::DlImage *image) const
Get a cached texture for the given image.
const Capabilities & GetDeviceCapabilities() const
void SetTextureCachingEnabled(bool enabled)
Enable or disable texture caching.
void RemoveCachedTexture(const flutter::DlImage *image) const
Remove a cached texture for the given image.
std::shared_ptr< Context > GetContext() const
void ClearCachedTextures() const
Clear all cached textures.
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
bool OpenPlaygroundHere(const RenderCallback &render_callback)
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
FlutterDesktopBinaryReply callback
#define ASSERT_MATRIX_NEAR(a, b)
FlTexture * texture
TEST(FrameTimingsRecorderTest, RecordVsync)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switch_defs.h:36
impeller::Point DlPoint
std::unique_ptr< Canvas > CreateTestCanvas(ContentContext &context, std::optional< Rect > cull_rect=std::nullopt, bool requires_readback=false)
TEST_P(AiksTest, DrawAtlasNoColor)
Point Vector2
Definition point.h:430
float Scalar
Definition scalar.h:19
Point DrawPlaygroundPoint(PlaygroundPoint &point)
Definition widgets.cc:11
const char * BlendModeToString(BlendMode blend_mode)
Definition color.cc:45
constexpr float kPiOver2
Definition constants.h:32
BlendMode
Definition color.h:58
@ kContainsContents
The caller claims the bounds are a reasonably tight estimate of the coverage of the contents and shou...
static constexpr DlColor kBlue()
Definition dl_color.h:73
static constexpr DlColor kRed()
Definition dl_color.h:71
std::shared_ptr< Texture > resolve_texture
Definition formats.h:662
LoadAction load_action
Definition formats.h:663
std::shared_ptr< Texture > texture
Definition formats.h:661
StoreAction store_action
Definition formats.h:664
uint32_t ToARGB() const
Convert to ARGB 32 bit color.
Definition color.h:259
static constexpr Color LimeGreen()
Definition color.h:607
static constexpr Color Azure()
Definition color.h:303
static constexpr Color BlackTransparent()
Definition color.h:275
static constexpr Color Black()
Definition color.h:271
static constexpr Color CornflowerBlue()
Definition color.h:347
static constexpr Color White()
Definition color.h:269
constexpr Color WithAlpha(Scalar new_alpha) const
Definition color.h:283
static constexpr Color Red()
Definition color.h:277
constexpr Color Unpremultiply() const
Definition color.h:216
constexpr Color Premultiply() const
Definition color.h:212
static constexpr Color Lerp(Color a, Color b, Scalar t)
Return a color that is linearly interpolated between colors a and b, according to the value of t.
Definition color.h:232
Color Blend(Color source, BlendMode blend_mode) const
Blends an unpremultiplied destination color into a given unpremultiplied source color to form a new u...
Definition color.cc:155
A 4x4 matrix using column-major storage.
Definition matrix.h:37
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
Matrix Invert() const
Definition matrix.cc:99
static constexpr Matrix MakeScale(const Vector3 &s)
Definition matrix.h:104
const flutter::DlColorSource * color_source
Definition paint.h:80
bool anti_alias
Definition paint.h:88
Color color
Definition paint.h:79
BlendMode blend_mode
Definition paint.h:86
static RoundSuperellipse MakeRectRadius(const Rect &rect, Scalar radius)
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition sigma.h:32
static constexpr TRect MakeEllipseBounds(const TPoint< Type > &center, const TSize< Type > &radii)
Definition rect.h:164
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...