5#include "flutter/flow/layers/opacity_layer.h"
7#include "flutter/flow/layers/clip_rect_layer.h"
8#include "flutter/flow/layers/image_filter_layer.h"
9#include "flutter/flow/layers/layer_tree.h"
10#include "flutter/flow/layers/platform_view_layer.h"
11#include "flutter/flow/layers/transform_layer.h"
12#include "flutter/flow/raster_cache_util.h"
13#include "flutter/flow/testing/diff_context_test.h"
14#include "flutter/flow/testing/layer_test.h"
15#include "flutter/flow/testing/mock_embedder.h"
16#include "flutter/flow/testing/mock_layer.h"
17#include "flutter/fml/macros.h"
18#include "flutter/testing/display_list_testing.h"
19#include "gtest/gtest.h"
31 auto mock_layer = std::make_shared<MockLayer>(
SkPath());
34 layer->Add(mock_layer);
36 layer->Preroll(preroll_context());
37 EXPECT_EQ(mock_layer->paint_bounds(),
SkPath().getBounds());
38 EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
39 EXPECT_EQ(layer->child_paint_bounds(), mock_layer->paint_bounds());
40 EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
41 EXPECT_FALSE(layer->needs_painting(paint_context()));
43 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
44 "needs_painting\\(context\\)");
49 child_path.
addRect(5.0f, 6.0f, 20.5f, 21.5f);
50 auto mock_layer = std::make_shared<MockLayer>(child_path);
53 layer->Add(mock_layer);
55 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
56 "needs_painting\\(context\\)");
62 child_path1.
addRect(10.0f, 10.0f, 20.0f, 20.f);
64 auto layer = std::make_shared<OpacityLayer>(0.5,
SkPoint::Make(10, 10));
65 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
66 layer->Add(mock_layer1);
69 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
70 layer->Preroll(preroll_context());
72 SkRect layer_bounds = mock_layer1->paint_bounds();
73 mock_layer1->parent_matrix().mapRect(&layer_bounds);
79 const SkAlpha alpha_half = 255 / 2;
83 auto mock_layer = std::make_shared<MockLayer>(child_path);
85 std::make_shared<OpacityLayer>(alpha_half,
SkPoint::Make(0.0f, 0.0f));
86 layer->Add(mock_layer);
89 SkMatrix cache_ctm = initial_transform;
95 use_mock_raster_cache();
97 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
99 const auto* cacheable_opacity_item = layer->raster_cache_item();
101 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
102 EXPECT_EQ(cacheable_opacity_item->cache_state(),
104 EXPECT_FALSE(cacheable_opacity_item->GetId().has_value());
106 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
107 layer->Preroll(preroll_context());
110 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)1);
112 EXPECT_EQ(cacheable_opacity_item->cache_state(),
113 RasterCacheItem::CacheState::kChildren);
115 cacheable_opacity_item->GetId().value(),
118 EXPECT_FALSE(raster_cache()->
Draw(cacheable_opacity_item->GetId().value(),
119 other_canvas, &
paint));
120 EXPECT_TRUE(raster_cache()->
Draw(cacheable_opacity_item->GetId().value(),
121 cache_canvas, &
paint));
125 const SkAlpha alpha_half = 255 / 2;
131 auto mock_layer1 = std::make_shared<MockLayer>(child_path1);
132 auto mock_layer2 = std::make_shared<MockLayer>(child_path2);
134 std::make_shared<OpacityLayer>(alpha_half,
SkPoint::Make(0.0f, 0.0f));
135 layer->Add(mock_layer1);
136 layer->Add(mock_layer2);
138 SkMatrix cache_ctm = initial_transform;
139 DisplayListBuilder cache_canvas;
141 DisplayListBuilder other_canvas;
144 use_mock_raster_cache();
146 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
148 const auto* cacheable_opacity_item = layer->raster_cache_item();
150 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
151 EXPECT_EQ(cacheable_opacity_item->cache_state(),
153 EXPECT_FALSE(cacheable_opacity_item->GetId().has_value());
155 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
156 layer->Preroll(preroll_context());
159 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)1);
161 EXPECT_EQ(cacheable_opacity_item->cache_state(),
162 RasterCacheItem::CacheState::kChildren);
164 cacheable_opacity_item->GetId().value(),
167 EXPECT_FALSE(raster_cache()->
Draw(cacheable_opacity_item->GetId().value(),
168 other_canvas, &
paint));
169 EXPECT_TRUE(raster_cache()->
Draw(cacheable_opacity_item->GetId().value(),
170 cache_canvas, &
paint));
178 opacity_layer->Add(mock_layer);
182 use_mock_raster_cache();
184 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
186 const auto* cacheable_opacity_item = opacity_layer->raster_cache_item();
188 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
189 EXPECT_EQ(cacheable_opacity_item->cache_state(),
191 EXPECT_FALSE(cacheable_opacity_item->GetId().has_value());
193 opacity_layer->Preroll(preroll_context());
197 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
199 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
200 EXPECT_EQ(cacheable_opacity_item->cache_state(),
202 EXPECT_FALSE(cacheable_opacity_item->Draw(paint_context(), &
paint));
212 const SkRect expected_layer_bounds =
214 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
215 auto layer = std::make_shared<OpacityLayer>(
SK_AlphaOPAQUE, layer_offset);
216 layer->Add(mock_layer);
218 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
219 layer->Preroll(preroll_context());
220 EXPECT_EQ(mock_layer->paint_bounds(), child_path.
getBounds());
221 EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds);
222 EXPECT_EQ(layer->child_paint_bounds(), child_path.
getBounds());
223 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
224 EXPECT_TRUE(layer->needs_painting(paint_context()));
225 EXPECT_EQ(mock_layer->parent_matrix(),
227 EXPECT_EQ(mock_layer->parent_mutators(),
228 std::vector({Mutator(layer_transform)}));
232 expected_builder.
Save();
234 expected_builder.
Translate(layer_offset.
fX, layer_offset.
fY);
237 expected_builder.
DrawPath(child_path, child_paint);
242 layer->Paint(display_list_paint_context());
254 const SkRect expected_layer_bounds =
256 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
259 layer->Add(mock_layer);
261 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
262 layer->Preroll(preroll_context());
263 EXPECT_EQ(mock_layer->paint_bounds(), child_path.
getBounds());
264 EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds);
265 EXPECT_EQ(layer->child_paint_bounds(), child_path.
getBounds());
266 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
267 EXPECT_TRUE(layer->needs_painting(paint_context()));
268 EXPECT_EQ(mock_layer->parent_matrix(),
271 mock_layer->parent_mutators(),
272 std::vector({Mutator(layer_transform), Mutator(SK_AlphaTRANSPARENT)}));
276 expected_builder.
Save();
278 expected_builder.
Translate(layer_offset.
fX, layer_offset.
fY);
281 expected_builder.
SaveLayer(&child_bounds, &save_paint);
283 expected_builder.
DrawPath(child_path, child_paint);
290 layer->Paint(display_list_paint_context());
301 const SkRect expected_layer_bounds =
303 const SkAlpha alpha_half = 255 / 2;
304 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
305 auto layer = std::make_shared<OpacityLayer>(alpha_half, layer_offset);
306 layer->Add(mock_layer);
308 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
309 layer->Preroll(preroll_context());
310 EXPECT_EQ(mock_layer->paint_bounds(), child_path.
getBounds());
311 EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds);
312 EXPECT_EQ(layer->child_paint_bounds(), child_path.
getBounds());
313 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
314 EXPECT_TRUE(layer->needs_painting(paint_context()));
315 EXPECT_EQ(mock_layer->parent_matrix(),
317 EXPECT_EQ(mock_layer->parent_mutators(),
318 std::vector({Mutator(layer_transform), Mutator(alpha_half)}));
321 expected_layer_bounds.
makeOffset(-layer_offset.
fX, -layer_offset.
fY)
328 expected_builder.Save();
329 expected_builder.Translate(layer_offset.
fX, layer_offset.
fY);
331 expected_builder.SaveLayer(&opacity_bounds, &save_paint);
333 expected_builder.DrawPath(child_path, child_dl_paint);
335 expected_builder.Restore();
337 expected_builder.Restore();
341 layer->Paint(display_list_paint_context());
361 auto mock_layer1 = std::make_shared<MockLayer>(child1_path, child1_paint);
362 auto mock_layer2 = std::make_shared<MockLayer>(child2_path, child2_paint);
363 auto mock_layer3 = std::make_shared<MockLayer>(child3_path, child3_paint);
364 auto layer1 = std::make_shared<OpacityLayer>(alpha1, layer1_offset);
365 auto layer2 = std::make_shared<OpacityLayer>(alpha2, layer2_offset);
366 layer2->Add(mock_layer2);
367 layer1->Add(mock_layer1);
369 layer1->Add(mock_layer3);
371 const SkRect expected_layer2_bounds =
373 SkRect layer1_child_bounds = expected_layer2_bounds;
376 SkRect expected_layer1_bounds = layer1_transform.
mapRect(layer1_child_bounds);
377 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
378 layer1->Preroll(preroll_context());
379 EXPECT_EQ(mock_layer1->paint_bounds(), child1_path.
getBounds());
380 EXPECT_EQ(mock_layer2->paint_bounds(), child2_path.
getBounds());
381 EXPECT_EQ(mock_layer3->paint_bounds(), child3_path.
getBounds());
382 EXPECT_EQ(layer1->paint_bounds(), expected_layer1_bounds);
383 EXPECT_EQ(layer1->child_paint_bounds(), layer1_child_bounds);
384 EXPECT_EQ(layer2->paint_bounds(), expected_layer2_bounds);
385 EXPECT_EQ(layer2->child_paint_bounds(), child2_path.
getBounds());
386 EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
387 EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
388 EXPECT_TRUE(mock_layer3->needs_painting(paint_context()));
389 EXPECT_TRUE(layer1->needs_painting(paint_context()));
390 EXPECT_TRUE(layer2->needs_painting(paint_context()));
391 EXPECT_EQ(mock_layer1->parent_matrix(),
393 EXPECT_EQ(mock_layer1->parent_mutators(),
394 std::vector({Mutator(layer1_transform), Mutator(alpha1)}));
396 mock_layer2->parent_matrix(),
399 EXPECT_EQ(mock_layer2->parent_mutators(),
400 std::vector({Mutator(layer1_transform), Mutator(alpha1),
401 Mutator(layer2_transform), Mutator(alpha2)}));
402 EXPECT_EQ(mock_layer3->parent_matrix(),
404 EXPECT_EQ(mock_layer3->parent_mutators(),
405 std::vector({Mutator(layer1_transform), Mutator(alpha1)}));
408 expected_layer1_bounds.
makeOffset(-layer1_offset.
fX, -layer1_offset.
fY);
410 expected_layer2_bounds.
makeOffset(-layer2_offset.
fX, -layer2_offset.
fY);
418 expected_builder.
Save();
420 expected_builder.
Translate(layer1_offset.
fX, layer1_offset.
fY);
422 expected_builder.
SaveLayer(&opacity1_bounds, &opacity1_paint);
424 expected_builder.
DrawPath(child1_path, child1_paint);
427 expected_builder.
Save();
429 expected_builder.
Translate(layer2_offset.
fX, layer2_offset.
fY);
431 expected_builder.
SaveLayer(&opacity2_bounds, &opacity2_paint);
434 expected_builder.
DrawPath(child2_path, child2_paint);
443 expected_builder.
DrawPath(child3_path, child3_paint);
450 layer1->Paint(display_list_paint_context());
456 layer->Add(std::make_shared<MockLayer>(
SkPath()));
459 preroll_context()->surface_needs_readback =
false;
460 layer->Preroll(preroll_context());
461 EXPECT_FALSE(preroll_context()->surface_needs_readback);
464 auto mock_layer = std::make_shared<MockLayer>(
SkPath(),
DlPaint());
465 mock_layer->set_fake_reads_surface(
true);
466 layer->Add(mock_layer);
467 preroll_context()->surface_needs_readback =
false;
468 layer->Preroll(preroll_context());
469 EXPECT_FALSE(preroll_context()->surface_needs_readback);
473 auto clip_rect_layer = std::make_shared<ClipRectLayer>(
477 auto mock_layer = std::make_shared<MockLayer>(
SkPath());
478 clip_rect_layer->Add(opacity_layer);
479 opacity_layer->Add(mock_layer);
480 clip_rect_layer->Preroll(preroll_context());
481 EXPECT_EQ(mock_layer->parent_cull_rect().fLeft, -20);
482 EXPECT_EQ(mock_layer->parent_cull_rect().fTop, -20);
489 opacity_layer->Add(mock_layer);
492 opacity_layer->Preroll(context);
495 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
502 opacity_layer->Add(mock_layer);
505 opacity_layer->Preroll(context);
508 EXPECT_FALSE(opacity_layer->children_can_accept_opacity());
514 auto container_layer = std::make_shared<ContainerLayer>();
516 container_layer->Add(mock_layer);
517 opacity_layer->Add(container_layer);
520 opacity_layer->Preroll(context);
523 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
529 auto transformLayer = std::make_shared<TransformLayer>(
SkMatrix::Scale(2, 2));
531 transformLayer->Add(mock_layer);
532 opacity_layer->Add(transformLayer);
535 opacity_layer->Preroll(context);
538 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
544 auto filter_layer = std::make_shared<ImageFilterLayer>(
547 filter_layer->Add(mock_layer);
548 opacity_layer->Add(filter_layer);
551 opacity_layer->Preroll(context);
554 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
561 auto opacity_layer_1 = std::make_shared<OpacityLayer>(128, offset1);
562 auto opacity_layer_2 = std::make_shared<OpacityLayer>(64, offset2);
564 opacity_layer_2->Add(mock_layer);
565 opacity_layer_1->Add(opacity_layer_2);
568 opacity_layer_1->Preroll(context);
571 EXPECT_TRUE(opacity_layer_1->children_can_accept_opacity());
572 EXPECT_TRUE(opacity_layer_2->children_can_accept_opacity());
577 savelayer_paint.
setOpacity(inherited_opacity);
581 expected_builder.
Save();
585 expected_builder.
Save();
589 expected_builder.
DrawPath(mock_path,
590 DlPaint().setOpacity(inherited_opacity));
599 opacity_layer_1->Paint(display_list_paint_context());
607 auto opacity_layer_1 = std::make_shared<OpacityLayer>(128, offset1);
608 auto opacity_layer_2 = std::make_shared<OpacityLayer>(64, offset2);
610 opacity_layer_2->Add(mock_layer);
611 opacity_layer_1->Add(opacity_layer_2);
614 opacity_layer_1->Preroll(context);
617 EXPECT_TRUE(opacity_layer_1->children_can_accept_opacity());
618 EXPECT_FALSE(opacity_layer_2->children_can_accept_opacity());
623 savelayer_paint.
setOpacity(inherited_opacity);
627 expected_builder.
Save();
631 expected_builder.
Save();
634 expected_builder.
SaveLayer(&mock_layer->paint_bounds(),
646 opacity_layer_1->Paint(display_list_paint_context());
653 auto picture = CreateDisplayListLayer(
666 auto picture = CreateDisplayListLayer(
671 tree1.root()->Add(layer);
679 use_mock_raster_cache();
685 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
686 auto layer = std::make_shared<OpacityLayer>(
SK_AlphaOPAQUE, layer_offset);
687 layer->Add(mock_layer);
689 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
690 layer->Preroll(preroll_context());
694 expected_builder.
Save();
695 expected_builder.
Translate(layer_offset.
fX, layer_offset.
fY);
703 expected_builder.
DrawPath(child_path, child_paint);
709 layer->Paint(display_list_paint_context());
717 const int64_t view_id = 42;
719 std::make_shared<PlatformViewLayer>(view_offset, view_size, view_id);
727 embedder.AddCanvas(&fake_overlay_builder);
728 preroll_context()->view_embedder = &embedder;
729 paint_context().view_embedder = &embedder;
731 opacity->Preroll(preroll_context());
732 EXPECT_EQ(embedder.prerolled_views(), std::vector<int64_t>({view_id}));
734 opacity->Paint(paint_context());
735 EXPECT_EQ(embedder.painted_views(), std::vector<int64_t>({view_id}));
@ kOpaque_SkAlphaType
pixel is opaque
constexpr SkAlpha SK_AlphaOPAQUE
constexpr SkAlpha SK_AlphaTRANSPARENT
#define SkScalarRoundToScalar(x)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
const SkRect & getBounds() const
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
virtual void Add(std::shared_ptr< Layer > layer)
void Transform(const SkMatrix *matrix) override
void TransformReset() override
void Translate(SkScalar tx, SkScalar ty) override
void DrawPath(const SkPath &path, const DlPaint &paint) override
void Transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
void SaveLayer(const SkRect *bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr) override
sk_sp< DisplayList > Build()
DlPaint & setAlpha(uint8_t alpha)
DlPaint & setOpacity(SkScalar opacity)
static constexpr int kCallerCanApplyOpacity
static void TryToRasterCache(const std::vector< RasterCacheItem * > &raster_cached_entries, const PaintContext *paint_context, bool ignore_raster_cache=false)
static std::optional< std::vector< RasterCacheKeyID > > LayerChildrenIds(const Layer *layer)
static std::shared_ptr< MockLayer > MakeOpacityCompatible(const SkPath &path)
static std::shared_ptr< MockLayer > Make(const SkPath &path, DlPaint paint=DlPaint())
static void Draw(SkCanvas *canvas, const SkRect &rect)
sk_sp< const SkPicture > picture
TEST_F(DisplayListTest, Defaults)
LayerTestBase<::testing::Test > LayerTest
DiffContextTest OpacityLayerDiffTest
bool DisplayListsEQ_Verbose(const DisplayList *a, const DisplayList *b)
LayerTest OpacityLayerTest
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
static constexpr SkIRect MakeEmpty()
static constexpr SkPoint Make(float x, float y)
constexpr SkRect makeOffset(float dx, float dy) const
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
void roundOut(SkIRect *dst) const
void join(const SkRect &r)
static constexpr SkRect MakeWH(float w, float h)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
static constexpr SkSize Make(SkScalar w, SkScalar h)
static constexpr DlColor kBlue()
static constexpr DlColor kMidGrey()
static constexpr DlColor kRed()
static constexpr DlColor kGreen()
int renderable_state_flags
#define EXPECT_TRUE(handle)