Flutter Impeller
entity_pass_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 <memory>
6 
7 #include "flutter/testing/testing.h"
8 #include "gtest/gtest.h"
10 #include "impeller/entity/entity.h"
12 
13 namespace impeller {
14 namespace testing {
15 
16 TEST(EntityPassClipStackTest, CanPushAndPopEntities) {
17  EntityPassClipStack recorder =
18  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
19 
20  EXPECT_TRUE(recorder.GetReplayEntities().empty());
21 
22  Entity entity;
24  Rect::MakeLTRB(0, 0, 100, 100));
25  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
26 
28  Rect::MakeLTRB(0, 0, 50, 50));
29  EXPECT_EQ(recorder.GetReplayEntities().size(), 2u);
30  ASSERT_TRUE(recorder.GetReplayEntities()[0].clip_coverage.has_value());
31  ASSERT_TRUE(recorder.GetReplayEntities()[1].clip_coverage.has_value());
32  // NOLINTBEGIN(bugprone-unchecked-optional-access)
33  EXPECT_EQ(recorder.GetReplayEntities()[0].clip_coverage.value(),
34  Rect::MakeLTRB(0, 0, 100, 100));
35  EXPECT_EQ(recorder.GetReplayEntities()[1].clip_coverage.value(),
36  Rect::MakeLTRB(0, 0, 50, 50));
37  // NOLINTEND(bugprone-unchecked-optional-access)
38 
40  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
41 
43  EXPECT_TRUE(recorder.GetReplayEntities().empty());
44 }
45 
46 TEST(EntityPassClipStackTest, CanPopEntitiesSafely) {
47  EntityPassClipStack recorder =
48  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
49 
50  EXPECT_TRUE(recorder.GetReplayEntities().empty());
51 
52  Entity entity;
54  EXPECT_TRUE(recorder.GetReplayEntities().empty());
55 }
56 
57 TEST(EntityPassClipStackTest, CanAppendNoChange) {
58  EntityPassClipStack recorder =
59  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
60 
61  EXPECT_TRUE(recorder.GetReplayEntities().empty());
62 
63  Entity entity;
65  Rect());
66  EXPECT_TRUE(recorder.GetReplayEntities().empty());
67 }
68 
69 TEST(EntityPassClipStackTest, AppendCoverageNoChange) {
70  EntityPassClipStack recorder =
71  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
72 
73  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
74  Rect::MakeSize(Size::MakeWH(100, 100)));
75  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
76 
77  Entity entity;
81  .coverage = std::nullopt,
82  },
83  entity, 0, Point(0, 0));
84  EXPECT_TRUE(result.should_render);
85  EXPECT_FALSE(result.clip_did_change);
86 
87  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
88  Rect::MakeSize(Size::MakeWH(100, 100)));
89  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
90 }
91 
92 TEST(EntityPassClipStackTest, AppendAndRestoreClipCoverage) {
93  EntityPassClipStack recorder =
94  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
95 
96  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
97 
98  // Push a clip.
99  Entity entity;
103  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
104  },
105  entity, 0, Point(0, 0));
106  EXPECT_TRUE(result.should_render);
107  EXPECT_TRUE(result.clip_did_change);
108 
109  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
110  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
111  Rect::MakeLTRB(50, 50, 55, 55));
112  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
113  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
114 
115  // Restore the clip.
116  auto restore_clip = std::make_shared<ClipRestoreContents>();
117  restore_clip->SetRestoreHeight(0);
118  entity.SetContents(std::move(restore_clip));
119  recorder.ApplyClipState(
122  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
123  },
124  entity, 0, Point(0, 0));
125 
126  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
127  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
128  Rect::MakeSize(Size::MakeWH(100, 100)));
129  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
130  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
131 }
132 
133 TEST(EntityPassClipStackTest, UnbalancedRestore) {
134  EntityPassClipStack recorder =
135  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
136 
137  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
138 
139  // Restore the clip.
140  Entity entity;
141  auto restore_clip = std::make_shared<ClipRestoreContents>();
142  restore_clip->SetRestoreHeight(0);
143  entity.SetContents(std::move(restore_clip));
147  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
148  },
149  entity, 0, Point(0, 0));
150  EXPECT_FALSE(result.should_render);
151  EXPECT_FALSE(result.clip_did_change);
152 
153  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
154  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
155  Rect::MakeSize(Size::MakeWH(100, 100)));
156  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
157  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
158 }
159 
160 TEST(EntityPassClipStackTest, ClipAndRestoreWithSubpasses) {
161  EntityPassClipStack recorder =
162  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
163 
164  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
165 
166  // Push a clip.
167  Entity entity;
168  {
172  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
173  },
174  entity, 0, Point(0, 0));
175  EXPECT_TRUE(result.should_render);
176  EXPECT_TRUE(result.clip_did_change);
177  }
178 
179  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
180  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
181  Rect::MakeLTRB(50, 50, 55, 55));
182  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
183  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
184 
185  // Begin a subpass.
186  recorder.PushSubpass(Rect::MakeLTRB(50, 50, 55, 55), 1);
187  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
188  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
189  Rect::MakeLTRB(50, 50, 55, 55));
190 
191  {
195  .coverage = Rect::MakeLTRB(54, 54, 55, 55),
196  },
197  entity, 0, Point(0, 0));
198  EXPECT_TRUE(result.should_render);
199  EXPECT_TRUE(result.clip_did_change);
200  }
201 
202  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
203  Rect::MakeLTRB(54, 54, 55, 55));
204 
205  // End subpass.
206  recorder.PopSubpass();
207 
208  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
209  Rect::MakeLTRB(50, 50, 55, 55));
210 }
211 
212 } // namespace testing
213 } // namespace impeller
impeller::EntityPassClipStack::ClipStateResult::should_render
bool should_render
Definition: entity_pass_clip_stack.h:34
impeller::EntityPassClipStack::PushSubpass
void PushSubpass(std::optional< Rect > subpass_coverage, size_t clip_height)
Definition: entity_pass_clip_stack.cc:31
entity.h
impeller::EntityPassClipStack::GetClipCoverageLayers
const std::vector< ClipCoverageLayer > GetClipCoverageLayers() const
Definition: entity_pass_clip_stack.cc:47
impeller::testing::TEST
TEST(AiksCanvasTest, EmptyCullRect)
Definition: canvas_unittests.cc:18
impeller::Contents::ClipCoverage::Type::kRestore
@ kRestore
impeller::Entity::SetContents
void SetContents(std::shared_ptr< Contents > contents)
Definition: entity.cc:90
impeller::Entity
Definition: entity.h:20
impeller::EntityPassClipStack::ApplyClipState
ClipStateResult ApplyClipState(Contents::ClipCoverage global_clip_coverage, Entity &entity, size_t clip_height_floor, Point global_pass_position)
Applies the current clip state to an Entity. If the given Entity is a clip operation,...
Definition: entity_pass_clip_stack.cc:51
impeller::EntityPassClipStack::GetReplayEntities
const std::vector< ReplayResult > & GetReplayEntities() const
Definition: entity_pass_clip_stack.cc:158
impeller::Point
TPoint< Scalar > Point
Definition: point.h:322
impeller::Contents::ClipCoverage::type
Type type
Definition: contents.h:40
clip_contents.h
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:769
impeller::EntityPassClipStack::PopSubpass
void PopSubpass()
Definition: entity_pass_clip_stack.cc:42
entity_pass_clip_stack.h
impeller::EntityPassClipStack::RecordEntity
void RecordEntity(const Entity &entity, Contents::ClipCoverage::Type type, std::optional< Rect > clip_coverage)
Definition: entity_pass_clip_stack.cc:133
impeller::EntityPassClipStack::ClipStateResult::clip_did_change
bool clip_did_change
Definition: entity_pass_clip_stack.h:37
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:146
impeller::Contents::ClipCoverage
Definition: contents.h:37
impeller::Contents::ClipCoverage::Type::kAppend
@ kAppend
impeller::EntityPassClipStack
A class that tracks all clips that have been recorded in the current entity pass stencil.
Definition: entity_pass_clip_stack.h:24
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::TSize< Scalar >::MakeWH
static constexpr TSize MakeWH(Type width, Type height)
Definition: size.h:34
impeller::EntityPassClipStack::ClipStateResult
Definition: entity_pass_clip_stack.h:31
impeller
Definition: aiks_blend_unittests.cc:18
impeller::Contents::ClipCoverage::Type::kNoChange
@ kNoChange