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 "flutter/testing/testing.h"
6 #include "gtest/gtest.h"
9 
10 namespace impeller {
11 namespace testing {
12 
13 TEST(EntityPassClipStackTest, CanPushAndPopEntities) {
14  EntityPassClipStack recorder =
15  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
16 
17  EXPECT_TRUE(recorder.GetReplayEntities().empty());
18 
19  Entity entity;
21  Rect::MakeLTRB(0, 0, 100, 100));
22  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
23 
25  Rect::MakeLTRB(0, 0, 50, 50));
26  EXPECT_EQ(recorder.GetReplayEntities().size(), 2u);
27  ASSERT_TRUE(recorder.GetReplayEntities()[0].clip_coverage.has_value());
28  ASSERT_TRUE(recorder.GetReplayEntities()[1].clip_coverage.has_value());
29  // NOLINTBEGIN(bugprone-unchecked-optional-access)
30  EXPECT_EQ(recorder.GetReplayEntities()[0].clip_coverage.value(),
31  Rect::MakeLTRB(0, 0, 100, 100));
32  EXPECT_EQ(recorder.GetReplayEntities()[1].clip_coverage.value(),
33  Rect::MakeLTRB(0, 0, 50, 50));
34  // NOLINTEND(bugprone-unchecked-optional-access)
35 
37  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
38 
40  EXPECT_TRUE(recorder.GetReplayEntities().empty());
41 }
42 
43 TEST(EntityPassClipStackTest, CanPopEntitiesSafely) {
44  EntityPassClipStack recorder =
45  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
46 
47  EXPECT_TRUE(recorder.GetReplayEntities().empty());
48 
49  Entity entity;
51  EXPECT_TRUE(recorder.GetReplayEntities().empty());
52 }
53 
54 TEST(EntityPassClipStackTest, CanAppendNoChange) {
55  EntityPassClipStack recorder =
56  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
57 
58  EXPECT_TRUE(recorder.GetReplayEntities().empty());
59 
60  Entity entity;
62  Rect());
63  EXPECT_TRUE(recorder.GetReplayEntities().empty());
64 }
65 
66 TEST(EntityPassClipStackTest, AppendCoverageNoChange) {
67  EntityPassClipStack recorder =
68  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
69 
70  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
71  Rect::MakeSize(Size::MakeWH(100, 100)));
72  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u);
73 
74  Entity entity;
78  .coverage = std::nullopt,
79  },
80  entity, 0, Point(0, 0));
81  EXPECT_TRUE(result.should_render);
82  EXPECT_FALSE(result.clip_did_change);
83 
84  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
85  Rect::MakeSize(Size::MakeWH(100, 100)));
86  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u);
87 }
88 
89 TEST(EntityPassClipStackTest, AppendAndRestoreClipCoverage) {
90  EntityPassClipStack recorder =
91  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
92 
93  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
94 
95  // Push a clip.
96  Entity entity;
97  entity.SetClipDepth(0);
101  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
102  },
103  entity, 0, Point(0, 0));
104  EXPECT_TRUE(result.should_render);
105  EXPECT_TRUE(result.clip_did_change);
106 
107  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
108  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
109  Rect::MakeLTRB(50, 50, 55, 55));
110  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_depth, 1u);
111  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
112 
113  // Restore the clip.
114  entity.SetClipDepth(0);
115  recorder.ApplyClipState(
118  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
119  },
120  entity, 0, Point(0, 0));
121 
122  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
123  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
124  Rect::MakeSize(Size::MakeWH(100, 100)));
125  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u);
126  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
127 }
128 
129 TEST(EntityPassClipStackTest, UnbalancedRestore) {
130  EntityPassClipStack recorder =
131  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
132 
133  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
134 
135  // Restore the clip.
136  Entity entity;
137  entity.SetClipDepth(0);
141  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
142  },
143  entity, 0, Point(0, 0));
144  EXPECT_FALSE(result.should_render);
145  EXPECT_FALSE(result.clip_did_change);
146 
147  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
148  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
149  Rect::MakeSize(Size::MakeWH(100, 100)));
150  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u);
151  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
152 }
153 
154 TEST(EntityPassClipStackTest, ClipAndRestoreWithSubpasses) {
155  EntityPassClipStack recorder =
156  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
157 
158  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
159 
160  // Push a clip.
161  Entity entity;
162  entity.SetClipDepth(0u);
163  {
167  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
168  },
169  entity, 0, Point(0, 0));
170  EXPECT_TRUE(result.should_render);
171  EXPECT_TRUE(result.clip_did_change);
172  }
173 
174  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
175  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
176  Rect::MakeLTRB(50, 50, 55, 55));
177  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_depth, 1u);
178  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
179 
180  // Begin a subpass.
181  recorder.PushSubpass(Rect::MakeLTRB(50, 50, 55, 55), 1);
182  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
183  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
184  Rect::MakeLTRB(50, 50, 55, 55));
185 
186  entity.SetClipDepth(1);
187  {
191  .coverage = Rect::MakeLTRB(54, 54, 55, 55),
192  },
193  entity, 0, Point(0, 0));
194  EXPECT_TRUE(result.should_render);
195  EXPECT_TRUE(result.clip_did_change);
196  }
197 
198  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
199  Rect::MakeLTRB(54, 54, 55, 55));
200 
201  // End subpass.
202  recorder.PopSubpass();
203 
204  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
205  Rect::MakeLTRB(50, 50, 55, 55));
206 }
207 
208 } // namespace testing
209 } // namespace impeller
impeller::Entity::SetClipDepth
void SetClipDepth(uint32_t clip_depth)
Definition: entity.cc:101
impeller::EntityPassClipStack::ClipStateResult::should_render
bool should_render
Definition: entity_pass_clip_stack.h:34
entity.h
impeller::EntityPassClipStack::GetClipCoverageLayers
const std::vector< ClipCoverageLayer > GetClipCoverageLayers() const
Definition: entity_pass_clip_stack.cc:48
impeller::Contents::ClipCoverage::Type::kRestore
@ kRestore
impeller::Entity
Definition: entity.h:21
impeller::EntityPassClipStack::GetReplayEntities
const std::vector< ReplayResult > & GetReplayEntities() const
Definition: entity_pass_clip_stack.cc:169
impeller::Point
TPoint< Scalar > Point
Definition: point.h:316
impeller::EntityPassClipStack::ApplyClipState
ClipStateResult ApplyClipState(Contents::ClipCoverage global_clip_coverage, Entity &entity, size_t clip_depth_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:52
impeller::Contents::ClipCoverage::type
Type type
Definition: contents.h:43
impeller::testing::TEST
TEST(CanvasRecorder, Save)
Definition: canvas_recorder_unittests.cc:65
impeller::EntityPassClipStack::PushSubpass
void PushSubpass(std::optional< Rect > subpass_coverage, size_t clip_depth)
Definition: entity_pass_clip_stack.cc:32
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:661
impeller::EntityPassClipStack::PopSubpass
void PopSubpass()
Definition: entity_pass_clip_stack.cc:43
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:144
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:40
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_blur_unittests.cc:20
impeller::Contents::ClipCoverage::Type::kNoChange
@ kNoChange