5#include "flutter/flow/layers/clip_rrect_layer.h"
7#include "flutter/flow/layers/layer_tree.h"
8#include "flutter/flow/layers/opacity_layer.h"
9#include "flutter/flow/layers/platform_view_layer.h"
10#include "flutter/flow/testing/layer_test.h"
11#include "flutter/flow/testing/mock_embedder.h"
12#include "flutter/flow/testing/mock_layer.h"
13#include "flutter/fml/macros.h"
28 EXPECT_DEATH_IF_SUPPORTED(
30 "clip_behavior != Clip::kNone");
35 auto layer = std::make_shared<ClipRRectLayer>(layer_rrect,
Clip::kHardEdge);
37 layer->Preroll(preroll_context());
40 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(),
kGiantRect);
41 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
44 EXPECT_EQ(layer->child_paint_bounds(),
kEmptyRect);
45 EXPECT_FALSE(layer->needs_painting(paint_context()));
47 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
48 "needs_painting\\(context\\)");
54 auto layer = std::make_shared<ClipRRectLayer>(layer_rrect,
Clip::kHardEdge);
56 EXPECT_EQ(layer->child_paint_bounds(),
kEmptyRect);
57 EXPECT_FALSE(layer->needs_painting(paint_context()));
59 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
60 "needs_painting\\(context\\)");
71 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
72 auto layer = std::make_shared<ClipRRectLayer>(layer_rrect,
Clip::kHardEdge);
73 layer->Add(mock_layer);
76 preroll_context()->state_stack.set_preroll_delegate(distant_bounds,
78 layer->Preroll(preroll_context());
81 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(), distant_bounds);
82 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
84 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
85 EXPECT_EQ(layer->paint_bounds(), child_bounds);
86 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
87 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
88 EXPECT_TRUE(layer->needs_painting(paint_context()));
89 EXPECT_EQ(mock_layer->parent_cull_rect(),
kEmptyRect);
90 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
91 EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));
93 auto mutator = paint_context().state_stack.save();
94 mutator.clipRect(distant_bounds,
false);
95 EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
96 EXPECT_FALSE(layer->needs_painting(paint_context()));
97 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
98 "needs_painting\\(context\\)");
105 const SkRect device_cull_bounds = initial_matrix.
mapRect(local_cull_bounds);
111 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
112 auto layer = std::make_shared<ClipRRectLayer>(clip_rrect,
Clip::kHardEdge);
113 layer->Add(mock_layer);
115 SkRect clip_cull_rect = clip_bounds;
116 ASSERT_TRUE(clip_cull_rect.
intersect(local_cull_bounds));
117 SkRect clip_layer_bounds = child_bounds;
118 ASSERT_TRUE(clip_layer_bounds.
intersect(clip_bounds));
121 preroll_context()->state_stack.set_preroll_delegate(device_cull_bounds,
123 paint_context().canvas->ClipRect(device_cull_bounds);
124 paint_context().canvas->Transform(initial_matrix);
126 layer->Preroll(preroll_context());
128 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(),
130 EXPECT_EQ(preroll_context()->state_stack.local_cull_rect(),
132 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
134 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
135 EXPECT_EQ(layer->paint_bounds(), clip_layer_bounds);
136 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
137 EXPECT_EQ(mock_layer->parent_cull_rect(), clip_cull_rect);
138 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
139 EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(clip_rrect)}));
141 EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
142 ASSERT_FALSE(layer->needs_painting(paint_context()));
155 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
156 auto layer = std::make_shared<ClipRRectLayer>(layer_rrect,
Clip::kHardEdge);
157 layer->Add(mock_layer);
159 preroll_context()->state_stack.set_preroll_delegate(initial_matrix);
160 layer->Preroll(preroll_context());
163 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(),
kGiantRect);
164 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
166 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
167 EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
168 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
169 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
170 EXPECT_TRUE(layer->needs_painting(paint_context()));
171 EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
172 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
173 EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));
175 layer->Paint(display_list_paint_context());
176 DisplayListBuilder expected_builder;
178 expected_builder.Save();
180 expected_builder.ClipRRect(layer_rrect);
182 expected_builder.DrawPath(child_path, child_paint);
185 expected_builder.Restore();
193 const SkRect device_cull_bounds = initial_matrix.
mapRect(local_cull_bounds);
200 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
201 auto layer = std::make_shared<ClipRRectLayer>(clip_rrect,
Clip::kHardEdge);
202 layer->Add(mock_layer);
204 SkRect clip_cull_rect = clip_bounds;
205 ASSERT_TRUE(clip_cull_rect.
intersect(local_cull_bounds));
206 SkRect clip_layer_bounds = child_bounds;
207 ASSERT_TRUE(clip_layer_bounds.
intersect(clip_bounds));
209 preroll_context()->state_stack.set_preroll_delegate(device_cull_bounds,
212 layer->Preroll(preroll_context());
214 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(),
216 EXPECT_EQ(preroll_context()->state_stack.local_cull_rect(),
218 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
220 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
221 EXPECT_EQ(layer->paint_bounds(), clip_layer_bounds);
222 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
223 EXPECT_EQ(mock_layer->parent_cull_rect(), clip_cull_rect);
224 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
225 EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(clip_rrect)}));
227 layer->Paint(display_list_paint_context());
228 DisplayListBuilder expected_builder;
230 expected_builder.Save();
232 expected_builder.ClipRRect(clip_rrect);
234 expected_builder.DrawPath(child_path, child_paint);
237 expected_builder.Restore();
244 const std::shared_ptr<Layer>& child,
248 auto layer = std::make_shared<ClipRRectLayer>(layer_rrect, clip_behavior);
249 if (child !=
nullptr) {
253 layer->Preroll(context);
266 std::shared_ptr<MockLayer> nochild;
267 auto reader = std::make_shared<MockLayer>(
path,
paint);
268 reader->set_fake_reads_surface(
true);
269 auto nonreader = std::make_shared<MockLayer>(
path,
paint);
274 EXPECT_FALSE(
ReadbackResult(context, save_layer, nochild,
false));
284 EXPECT_FALSE(
ReadbackResult(context, save_layer, nonreader,
false));
307 auto clip_rrect_layer =
309 clip_rrect_layer->Add(mock1);
312 PrerollContext* context = preroll_context();
313 clip_rrect_layer->Preroll(context);
314 EXPECT_EQ(context->renderable_state_flags,
319 clip_rrect_layer->Add(mock2);
323 clip_rrect_layer->Preroll(context);
324 EXPECT_EQ(context->renderable_state_flags,
329 clip_rrect_layer->Add(mock3);
333 clip_rrect_layer->Preroll(context);
334 EXPECT_EQ(context->renderable_state_flags, 0);
338 auto clip_rrect_savelayer = std::make_shared<ClipRRectLayer>(
340 clip_rrect_savelayer->Add(mock1);
341 clip_rrect_savelayer->Add(mock2);
344 clip_rrect_savelayer->Preroll(context);
348 clip_rrect_savelayer->Add(mock3);
349 clip_rrect_savelayer->Preroll(context);
359 auto clip_rrect_bad_child =
361 clip_rrect_bad_child->Add(mock1);
362 clip_rrect_bad_child->Add(mock2);
365 clip_rrect_bad_child->Preroll(context);
366 EXPECT_EQ(context->renderable_state_flags,
369 clip_rrect_bad_child->Add(mock4);
373 clip_rrect_bad_child->Preroll(context);
374 EXPECT_EQ(context->renderable_state_flags, 0);
379 auto clip_rrect_savelayer_bad_child = std::make_shared<ClipRRectLayer>(
381 clip_rrect_savelayer_bad_child->Add(mock1);
382 clip_rrect_savelayer_bad_child->Add(mock2);
385 clip_rrect_savelayer_bad_child->Preroll(context);
389 clip_rrect_savelayer_bad_child->Add(mock4);
390 clip_rrect_savelayer_bad_child->Preroll(context);
402 auto clip_rect_layer =
404 clip_rect_layer->Add(mock1);
405 clip_rect_layer->Add(mock2);
409 PrerollContext* context = preroll_context();
410 clip_rect_layer->Preroll(context);
411 EXPECT_EQ(context->renderable_state_flags,
414 int opacity_alpha = 0x7F;
416 auto opacity_layer = std::make_shared<OpacityLayer>(opacity_alpha,
offset);
417 opacity_layer->Add(clip_rect_layer);
418 opacity_layer->Preroll(context);
419 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
421 DisplayListBuilder expected_builder;
423 expected_builder.Save();
427 expected_builder.Save();
430 expected_builder.DrawPath(
path1,
DlPaint().setAlpha(opacity_alpha));
433 expected_builder.DrawPath(
path2,
DlPaint().setAlpha(opacity_alpha));
435 expected_builder.Restore();
438 expected_builder.Restore();
441 opacity_layer->Paint(display_list_paint_context());
454 auto clip_rrect_layer = std::make_shared<ClipRRectLayer>(
456 clip_rrect_layer->Add(mock1);
457 clip_rrect_layer->Add(mock2);
461 PrerollContext* context = preroll_context();
462 clip_rrect_layer->Preroll(context);
465 int opacity_alpha = 0x7F;
467 auto opacity_layer = std::make_shared<OpacityLayer>(opacity_alpha,
offset);
468 opacity_layer->Add(clip_rrect_layer);
469 opacity_layer->Preroll(context);
470 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
472 DisplayListBuilder expected_builder;
474 expected_builder.Save();
478 expected_builder.Save();
480 expected_builder.SaveLayer(&children_bounds,
481 &
DlPaint().setAlpha(opacity_alpha));
488 expected_builder.Restore();
491 expected_builder.Restore();
494 opacity_layer->Paint(display_list_paint_context());
504 auto layer = std::make_shared<ClipRRectLayer>(clip_rrect,
509 SkMatrix cache_ctm = initial_transform;
510 DisplayListBuilder cache_canvas;
511 cache_canvas.Transform(cache_ctm);
513 use_mock_raster_cache();
514 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
516 const auto* clip_cache_item = layer->raster_cache_item();
518 layer->Preroll(preroll_context());
521 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
524 layer->Preroll(preroll_context());
526 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
529 layer->Preroll(preroll_context());
531 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)1);
532 EXPECT_EQ(clip_cache_item->cache_state(),
533 RasterCacheItem::CacheState::kCurrent);
535 cache_canvas, &
paint));
544 auto layer = std::make_shared<ClipRRectLayer>(clip_rrect,
Clip::kAntiAlias);
548 SkMatrix cache_ctm = initial_transform;
552 use_mock_raster_cache();
553 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
555 const auto* clip_cache_item = layer->raster_cache_item();
557 layer->Preroll(preroll_context());
560 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
563 layer->Preroll(preroll_context());
565 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
568 layer->Preroll(preroll_context());
570 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (
size_t)0);
577 const int64_t view_id = 42;
579 std::make_shared<PlatformViewLayer>(view_offset, view_size, view_id);
585 auto embedder = MockViewEmbedder();
587 embedder.AddCanvas(&fake_overlay_builder);
588 preroll_context()->view_embedder = &embedder;
589 paint_context().view_embedder = &embedder;
591 clip->Preroll(preroll_context());
592 EXPECT_EQ(embedder.prerolled_views(), std::vector<int64_t>({view_id}));
594 clip->Paint(paint_context());
595 EXPECT_EQ(embedder.painted_views(), std::vector<int64_t>({view_id}));
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
void setMatrix(const SkM44 &matrix)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
const SkRect & getBounds() const
SkPath & addOval(const SkRect &oval, SkPathDirection dir=SkPathDirection::kCW)
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
static SkRRect MakeRect(const SkRect &r)
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
static SkRRect MakeEmpty()
static constexpr int kCallerCanApplyOpacity
static void TryToRasterCache(const std::vector< RasterCacheItem * > &raster_cached_entries, const PaintContext *paint_context, bool ignore_raster_cache=false)
static constexpr int kSaveLayerRenderFlags
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)
TEST_F(DisplayListTest, Defaults)
LayerTestBase<::testing::Test > LayerTest
bool DisplayListsEQ_Verbose(const DisplayList *a, const DisplayList *b)
static constexpr SkRect kEmptyRect
static bool ReadbackResult(PrerollContext *context, Clip clip_behavior, const std::shared_ptr< Layer > &child, bool before)
LayerTest ClipRRectLayerTest
@ kAntiAliasWithSaveLayer
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
static constexpr SkRect kGiantRect
static constexpr SkPoint Make(float x, float y)
bool intersect(const SkRect &r)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
SkRect makeInset(float dx, float dy) const
void join(const SkRect &r)
static constexpr SkRect MakeWH(float w, float h)
static constexpr SkSize Make(SkScalar w, SkScalar h)
static constexpr DlColor kYellow()
bool surface_needs_readback
#define EXPECT_TRUE(handle)