| 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"
9 #include "impeller/entity/contents/clip_contents.h"
10 #include "impeller/entity/entity.h"
11 #include "impeller/entity/entity_pass_clip_stack.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;
23 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kAppend,
24 Rect::MakeLTRB(0, 0, 100, 100));
25 EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
26
27 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kAppend,
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
39 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
40 EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
41
42 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
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;
53 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
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;
64 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kNoChange,
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;
78 EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
79 Contents::ClipCoverage{
80 .type = Contents::ClipCoverage::Type::kNoChange,
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;
100 EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
101 Contents::ClipCoverage{
102 .type = Contents::ClipCoverage::Type::kAppend,
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(
120 Contents::ClipCoverage{
121 .type = Contents::ClipCoverage::Type::kRestore,
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));
144 EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
145 Contents::ClipCoverage{
146 .type = Contents::ClipCoverage::Type::kRestore,
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 {
169 EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
170 Contents::ClipCoverage{
171 .type = Contents::ClipCoverage::Type::kAppend,
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 {
192 EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
193 Contents::ClipCoverage{
194 .type = Contents::ClipCoverage::Type::kAppend,
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