Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(514)

Side by Side Diff: cc/trees/layer_tree_host_unittest_occlusion.cc

Issue 935333002: Update from https://crrev.com/316786 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/trees/layer_tree_host_unittest.cc ('k') | cc/trees/layer_tree_host_unittest_picture.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/trees/layer_tree_host.h" 5 #include "cc/trees/layer_tree_host.h"
6 6
7 #include "cc/layers/layer.h" 7 #include "cc/layers/layer.h"
8 #include "cc/output/copy_output_request.h" 8 #include "cc/layers/picture_layer.h"
9 #include "cc/output/copy_output_result.h" 9 #include "cc/test/fake_content_layer_client.h"
10 #include "cc/test/layer_tree_test.h" 10 #include "cc/test/layer_tree_test.h"
11 #include "cc/test/test_occlusion_tracker.h" 11 #include "cc/trees/layer_tree_impl.h"
12 12
13 namespace cc { 13 namespace cc {
14 namespace { 14 namespace {
15 15
16 class TestLayer : public Layer { 16 #define EXPECT_OCCLUSION_EQ(expected, actual) \
17 public: 17 EXPECT_TRUE(expected.IsEqual(actual)) \
18 static scoped_refptr<TestLayer> Create() { 18 << " Expected: " << expected.ToString() << std::endl \
19 return make_scoped_refptr(new TestLayer()); 19 << " Actual: " << actual.ToString();
20 }
21
22 bool Update(ResourceUpdateQueue* update_queue,
23 const OcclusionTracker<Layer>* occlusion) override {
24 if (!occlusion)
25 return false;
26
27 const TestOcclusionTracker<Layer>* test_occlusion =
28 static_cast<const TestOcclusionTracker<Layer>*>(occlusion);
29 occlusion_ = UnionSimpleEnclosedRegions(
30 test_occlusion->occlusion_from_inside_target(),
31 test_occlusion->occlusion_from_outside_target());
32 return false;
33 }
34
35 const SimpleEnclosedRegion& occlusion() const { return occlusion_; }
36 const SimpleEnclosedRegion& expected_occlusion() const {
37 return expected_occlusion_;
38 }
39 void set_expected_occlusion(const gfx::Rect& occlusion) {
40 expected_occlusion_ = SimpleEnclosedRegion(occlusion);
41 }
42
43 private:
44 TestLayer() : Layer() {
45 SetIsDrawable(true);
46 }
47 ~TestLayer() override {}
48
49 SimpleEnclosedRegion occlusion_;
50 SimpleEnclosedRegion expected_occlusion_;
51 };
52 20
53 class LayerTreeHostOcclusionTest : public LayerTreeTest { 21 class LayerTreeHostOcclusionTest : public LayerTreeTest {
54 public:
55 LayerTreeHostOcclusionTest()
56 : root_(TestLayer::Create()),
57 child_(TestLayer::Create()),
58 child2_(TestLayer::Create()),
59 grand_child_(TestLayer::Create()),
60 mask_(TestLayer::Create()) {
61 }
62
63 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
64
65 void DidCommit() override {
66 TestLayer* root = static_cast<TestLayer*>(layer_tree_host()->root_layer());
67 VerifyOcclusion(root);
68
69 EndTest();
70 }
71
72 void AfterTest() override {}
73
74 void VerifyOcclusion(TestLayer* layer) const {
75 EXPECT_EQ(layer->expected_occlusion().ToString(),
76 layer->occlusion().ToString());
77
78 for (size_t i = 0; i < layer->children().size(); ++i) {
79 TestLayer* child = static_cast<TestLayer*>(layer->children()[i].get());
80 VerifyOcclusion(child);
81 }
82 }
83
84 void SetLayerPropertiesForTesting(TestLayer* layer,
85 TestLayer* parent,
86 const gfx::Transform& transform,
87 const gfx::PointF& position,
88 const gfx::Size& bounds,
89 bool opaque) const {
90 layer->RemoveAllChildren();
91 if (parent)
92 parent->AddChild(layer);
93 layer->SetTransform(transform);
94 layer->SetPosition(position);
95 layer->SetBounds(bounds);
96 layer->SetContentsOpaque(opaque);
97 }
98
99 protected: 22 protected:
100 void InitializeSettings(LayerTreeSettings* settings) override { 23 void InitializeSettings(LayerTreeSettings* settings) override {
101 settings->minimum_occlusion_tracking_size = gfx::Size(); 24 settings->minimum_occlusion_tracking_size = gfx::Size();
102 } 25 }
103 26 };
104 scoped_refptr<TestLayer> root_; 27
105 scoped_refptr<TestLayer> child_; 28 // Verify occlusion is set on the layer draw properties.
106 scoped_refptr<TestLayer> child2_; 29 class LayerTreeHostOcclusionTestDrawPropertiesOnLayer
107 scoped_refptr<TestLayer> grand_child_; 30 : public LayerTreeHostOcclusionTest {
108 scoped_refptr<TestLayer> mask_; 31 public:
109 32 void SetupTree() override {
110 gfx::Transform identity_matrix_; 33 scoped_refptr<Layer> root = Layer::Create();
111 }; 34 root->SetBounds(gfx::Size(100, 100));
112 35 root->SetIsDrawable(true);
113 36
114 class LayerTreeHostOcclusionTestOcclusionSurfaceClipping 37 scoped_refptr<Layer> child = Layer::Create();
115 : public LayerTreeHostOcclusionTest { 38 child->SetBounds(gfx::Size(50, 60));
116 public: 39 child->SetPosition(gfx::PointF(10.f, 5.5f));
117 void SetupTree() override { 40 child->SetContentsOpaque(true);
118 // The child layer is a surface and the grand_child is opaque, but clipped 41 child->SetIsDrawable(true);
119 // to the child and root 42 root->AddChild(child);
120 SetLayerPropertiesForTesting( 43
121 root_.get(), NULL, identity_matrix_, 44 layer_tree_host()->SetRootLayer(root);
122 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 45 LayerTreeTest::SetupTree();
123 SetLayerPropertiesForTesting( 46 }
124 child_.get(), root_.get(), identity_matrix_, 47
125 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false); 48 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
126 SetLayerPropertiesForTesting( 49
127 grand_child_.get(), child_.get(), identity_matrix_, 50 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
128 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 51 LayerImpl* root = impl->active_tree()->root_layer();
129 52 LayerImpl* child = root->children()[0];
130 child_->SetMasksToBounds(true); 53
131 child_->SetForceRenderSurface(true); 54 // Verify the draw properties are valid.
132 55 EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember());
133 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190)); 56 EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember());
134 root_->set_expected_occlusion(gfx::Rect(10, 10, 10, 190)); 57
135 58 EXPECT_OCCLUSION_EQ(
136 layer_tree_host()->SetRootLayer(root_); 59 Occlusion(child->draw_transform(), SimpleEnclosedRegion(),
137 LayerTreeTest::SetupTree(); 60 SimpleEnclosedRegion()),
138 } 61 child->draw_properties().occlusion_in_content_space);
62 EXPECT_OCCLUSION_EQ(
63 Occlusion(root->draw_transform(), SimpleEnclosedRegion(),
64 SimpleEnclosedRegion(gfx::Rect(10, 6, 50, 59))),
65 root->draw_properties().occlusion_in_content_space);
66 EndTest();
67 }
68
69 void AfterTest() override {}
70 };
71
72 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnLayer);
73
74 // Verify occlusion is set on the render surfaces.
75 class LayerTreeHostOcclusionTestDrawPropertiesOnSurface
76 : public LayerTreeHostOcclusionTest {
77 public:
78 void SetupTree() override {
79 scoped_refptr<Layer> root = Layer::Create();
80 root->SetBounds(gfx::Size(100, 100));
81 root->SetIsDrawable(true);
82
83 scoped_refptr<Layer> child = Layer::Create();
84 child->SetBounds(gfx::Size(1, 1));
85 child->SetPosition(gfx::PointF(10.f, 5.5f));
86 child->SetIsDrawable(true);
87 child->SetForceRenderSurface(true);
88 root->AddChild(child);
89
90 scoped_refptr<Layer> child2 = Layer::Create();
91 child2->SetBounds(gfx::Size(10, 12));
92 child2->SetPosition(gfx::PointF(13.f, 8.5f));
93 child2->SetContentsOpaque(true);
94 child2->SetIsDrawable(true);
95 root->AddChild(child2);
96
97 layer_tree_host()->SetRootLayer(root);
98 LayerTreeTest::SetupTree();
99 }
100
101 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
102
103 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
104 LayerImpl* root = impl->active_tree()->root_layer();
105 LayerImpl* child = root->children()[0];
106 RenderSurfaceImpl* surface = child->render_surface();
107
108 // Verify the draw properties are valid.
109 EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember());
110 EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember());
111 EXPECT_EQ(child, child->render_target());
112
113 EXPECT_OCCLUSION_EQ(
114 Occlusion(surface->draw_transform(), SimpleEnclosedRegion(),
115 SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
116 surface->occlusion_in_content_space());
117 EndTest();
118 }
119
120 void AfterTest() override {}
139 }; 121 };
140 122
141 SINGLE_AND_MULTI_THREAD_TEST_F( 123 SINGLE_AND_MULTI_THREAD_TEST_F(
142 LayerTreeHostOcclusionTestOcclusionSurfaceClipping); 124 LayerTreeHostOcclusionTestDrawPropertiesOnSurface);
143 125
144 class LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque 126 // Verify occlusion is set on mask layers.
145 : public LayerTreeHostOcclusionTest { 127 class LayerTreeHostOcclusionTestDrawPropertiesOnMask
146 public: 128 : public LayerTreeHostOcclusionTest {
147 void SetupTree() override { 129 public:
148 // If the child layer is opaque, then it adds to the occlusion seen by the 130 void SetupTree() override {
149 // root_. 131 scoped_refptr<Layer> root = Layer::Create();
150 SetLayerPropertiesForTesting( 132 root->SetBounds(gfx::Size(100, 100));
151 root_.get(), NULL, identity_matrix_, 133 root->SetIsDrawable(true);
152 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); 134
153 SetLayerPropertiesForTesting( 135 scoped_refptr<Layer> child = Layer::Create();
154 child_.get(), root_.get(), identity_matrix_, 136 child->SetBounds(gfx::Size(30, 40));
155 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); 137 child->SetPosition(gfx::PointF(10.f, 5.5f));
156 SetLayerPropertiesForTesting( 138 child->SetIsDrawable(true);
157 grand_child_.get(), child_.get(), identity_matrix_, 139 root->AddChild(child);
158 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true); 140
159 141 scoped_refptr<Layer> make_surface_bigger = Layer::Create();
160 child_->SetMasksToBounds(true); 142 make_surface_bigger->SetBounds(gfx::Size(100, 100));
161 child_->SetForceRenderSurface(true); 143 make_surface_bigger->SetPosition(gfx::PointF(-10.f, -15.f));
162 144 make_surface_bigger->SetIsDrawable(true);
163 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190)); 145 child->AddChild(make_surface_bigger);
164 root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190)); 146
165 147 scoped_refptr<Layer> mask = PictureLayer::Create(&client_);
166 layer_tree_host()->SetRootLayer(root_); 148 mask->SetBounds(gfx::Size(30, 40));
167 LayerTreeTest::SetupTree(); 149 mask->SetIsDrawable(true);
168 } 150 child->SetMaskLayer(mask.get());
151
152 scoped_refptr<Layer> child2 = Layer::Create();
153 child2->SetBounds(gfx::Size(10, 12));
154 child2->SetPosition(gfx::PointF(13.f, 8.5f));
155 child2->SetContentsOpaque(true);
156 child2->SetIsDrawable(true);
157 root->AddChild(child2);
158
159 layer_tree_host()->SetRootLayer(root);
160 LayerTreeTest::SetupTree();
161 }
162
163 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
164
165 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
166 LayerImpl* root = impl->active_tree()->root_layer();
167 LayerImpl* child = root->children()[0];
168 RenderSurfaceImpl* surface = child->render_surface();
169 LayerImpl* mask = child->mask_layer();
170
171 // Verify the draw properties are valid.
172 EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember());
173 EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember());
174 EXPECT_EQ(child, child->render_target());
175
176 gfx::Transform transform = surface->draw_transform();
177 transform.PreconcatTransform(child->draw_transform());
178
179 EXPECT_OCCLUSION_EQ(
180 Occlusion(transform, SimpleEnclosedRegion(),
181 SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
182 mask->draw_properties().occlusion_in_content_space);
183 EndTest();
184 }
185
186 void AfterTest() override {}
187
188 FakeContentLayerClient client_;
189 };
190
191 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnMask);
192
193 // Verify occlusion is set to empty inside the subtree of a replica. This is
194 // done because the tile system does not know about replicas, and so would not
195 // know that something is unoccluded on the replica even though it's occluded on
196 // the original.
197 class LayerTreeHostOcclusionTestDrawPropertiesInsideReplica
198 : public LayerTreeHostOcclusionTest {
199 public:
200 void SetupTree() override {
201 scoped_refptr<Layer> root = Layer::Create();
202 root->SetBounds(gfx::Size(100, 100));
203 root->SetIsDrawable(true);
204
205 scoped_refptr<Layer> child = Layer::Create();
206 child->SetBounds(gfx::Size(1, 1));
207 child->SetPosition(gfx::PointF(10.f, 5.5f));
208 child->SetIsDrawable(true);
209 child->SetForceRenderSurface(true);
210 root->AddChild(child);
211
212 scoped_refptr<Layer> replica = Layer::Create();
213 gfx::Transform translate;
214 translate.Translate(20.f, 4.f);
215 replica->SetTransform(translate);
216 child->SetReplicaLayer(replica.get());
217
218 scoped_refptr<Layer> mask = PictureLayer::Create(&client_);
219 mask->SetBounds(gfx::Size(30, 40));
220 mask->SetIsDrawable(true);
221 child->SetMaskLayer(mask.get());
222
223 scoped_refptr<Layer> child2 = Layer::Create();
224 child2->SetBounds(gfx::Size(10, 12));
225 child2->SetPosition(gfx::PointF(13.f, 8.5f));
226 child2->SetContentsOpaque(true);
227 child2->SetIsDrawable(true);
228 root->AddChild(child2);
229
230 layer_tree_host()->SetRootLayer(root);
231 LayerTreeTest::SetupTree();
232 }
233
234 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
235
236 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
237 LayerImpl* root = impl->active_tree()->root_layer();
238 LayerImpl* child = root->children()[0];
239 RenderSurfaceImpl* surface = child->render_surface();
240 LayerImpl* mask = child->mask_layer();
241
242 // Verify the draw properties are valid.
243 EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember());
244 EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember());
245 EXPECT_EQ(child, child->render_target());
246
247 // No occlusion from on child, which is part of the replica.
248 EXPECT_OCCLUSION_EQ(Occlusion(),
249 child->draw_properties().occlusion_in_content_space);
250 // Occlusion on the surface is okay.
251 EXPECT_OCCLUSION_EQ(
252 Occlusion(surface->draw_transform(), SimpleEnclosedRegion(),
253 SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
254 surface->occlusion_in_content_space());
255 // No occlusion on the replica'd mask.
256 EXPECT_OCCLUSION_EQ(Occlusion(),
257 mask->draw_properties().occlusion_in_content_space);
258 EndTest();
259 }
260
261 void AfterTest() override {}
262
263 FakeContentLayerClient client_;
169 }; 264 };
170 265
171 SINGLE_AND_MULTI_THREAD_TEST_F( 266 SINGLE_AND_MULTI_THREAD_TEST_F(
172 LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque); 267 LayerTreeHostOcclusionTestDrawPropertiesInsideReplica);
173
174 class LayerTreeHostOcclusionTestOcclusionTwoChildren
175 : public LayerTreeHostOcclusionTest {
176 public:
177 void SetupTree() override {
178 // Add a second child to the root layer and the regions should merge
179 SetLayerPropertiesForTesting(
180 root_.get(), NULL, identity_matrix_,
181 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
182 SetLayerPropertiesForTesting(
183 child_.get(), root_.get(), identity_matrix_,
184 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false);
185 SetLayerPropertiesForTesting(
186 grand_child_.get(), child_.get(), identity_matrix_,
187 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
188 SetLayerPropertiesForTesting(
189 child2_.get(), root_.get(), identity_matrix_,
190 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
191
192 child_->SetMasksToBounds(true);
193 child_->SetForceRenderSurface(true);
194
195 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
196 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
197 root_->set_expected_occlusion(gfx::Rect(10, 10, 20, 190));
198
199 layer_tree_host()->SetRootLayer(root_);
200 LayerTreeTest::SetupTree();
201 }
202 };
203
204 SINGLE_AND_MULTI_THREAD_TEST_F(
205 LayerTreeHostOcclusionTestOcclusionTwoChildren);
206
207 class LayerTreeHostOcclusionTestOcclusionMask
208 : public LayerTreeHostOcclusionTest {
209 public:
210 void SetupTree() override {
211 // If the child layer has a mask on it, then it shouldn't contribute to
212 // occlusion on stuff below it.
213 SetLayerPropertiesForTesting(
214 root_.get(), NULL, identity_matrix_,
215 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
216 SetLayerPropertiesForTesting(
217 child2_.get(), root_.get(), identity_matrix_,
218 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
219 SetLayerPropertiesForTesting(
220 child_.get(), root_.get(), identity_matrix_,
221 gfx::PointF(20.f, 20.f), gfx::Size(500, 500), true);
222 SetLayerPropertiesForTesting(
223 grand_child_.get(), child_.get(), identity_matrix_,
224 gfx::PointF(-10.f, -10.f), gfx::Size(500, 500), true);
225
226 child_->SetMasksToBounds(true);
227 child_->SetForceRenderSurface(true);
228 child_->SetMaskLayer(mask_.get());
229
230 child_->set_expected_occlusion(gfx::Rect(0, 0, 180, 180));
231 root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190));
232
233 layer_tree_host()->SetRootLayer(root_);
234 LayerTreeTest::SetupTree();
235 }
236 };
237
238 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionMask);
239
240 class LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion
241 : public LayerTreeHostOcclusionTest {
242 public:
243 void SetupTree() override {
244 // If the child layer with a mask is below child2, then child2 should
245 // contribute to occlusion on everything, and child shouldn't contribute
246 // to the root_.
247 SetLayerPropertiesForTesting(
248 root_.get(), NULL, identity_matrix_,
249 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
250 SetLayerPropertiesForTesting(
251 child_.get(), root_.get(), identity_matrix_,
252 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
253 SetLayerPropertiesForTesting(
254 grand_child_.get(), child_.get(), identity_matrix_,
255 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
256 SetLayerPropertiesForTesting(
257 child2_.get(), root_.get(), identity_matrix_,
258 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
259
260 child_->SetMasksToBounds(true);
261 child_->SetForceRenderSurface(true);
262 child_->SetMaskLayer(mask_.get());
263
264 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
265 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
266 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
267
268 layer_tree_host()->SetRootLayer(root_);
269 LayerTreeTest::SetupTree();
270 }
271 };
272
273 SINGLE_AND_MULTI_THREAD_TEST_F(
274 LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion);
275
276 class LayerTreeHostOcclusionTestOcclusionOpacity
277 : public LayerTreeHostOcclusionTest {
278 public:
279 void SetupTree() override {
280 // If the child layer has a non-opaque opacity, then it shouldn't
281 // contribute to occlusion on stuff below it
282 SetLayerPropertiesForTesting(
283 root_.get(), NULL, identity_matrix_,
284 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
285 SetLayerPropertiesForTesting(
286 child2_.get(), root_.get(), identity_matrix_,
287 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
288 SetLayerPropertiesForTesting(
289 child_.get(), root_.get(), identity_matrix_,
290 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
291 SetLayerPropertiesForTesting(
292 grand_child_.get(), child_.get(), identity_matrix_,
293 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
294
295 child_->SetMasksToBounds(true);
296 child_->SetForceRenderSurface(true);
297 child_->SetOpacity(0.5f);
298
299 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
300 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
301
302 layer_tree_host()->SetRootLayer(root_);
303 LayerTreeTest::SetupTree();
304 }
305 };
306
307 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionOpacity);
308
309 class LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion
310 : public LayerTreeHostOcclusionTest {
311 public:
312 void SetupTree() override {
313 // If the child layer with non-opaque opacity is below child2, then
314 // child2 should contribute to occlusion on everything, and child shouldn't
315 // contribute to the root_.
316 SetLayerPropertiesForTesting(
317 root_.get(), NULL, identity_matrix_,
318 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
319 SetLayerPropertiesForTesting(
320 child_.get(), root_.get(), identity_matrix_,
321 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
322 SetLayerPropertiesForTesting(
323 grand_child_.get(), child_.get(), identity_matrix_,
324 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
325 SetLayerPropertiesForTesting(
326 child2_.get(), root_.get(), identity_matrix_,
327 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
328
329 child_->SetMasksToBounds(true);
330 child_->SetForceRenderSurface(true);
331 child_->SetOpacity(0.5f);
332
333 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
334 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
335 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
336
337 layer_tree_host()->SetRootLayer(root_);
338 LayerTreeTest::SetupTree();
339 }
340 };
341
342 SINGLE_AND_MULTI_THREAD_TEST_F(
343 LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion);
344
345 class LayerTreeHostOcclusionTestOcclusionBlending
346 : public LayerTreeHostOcclusionTest {
347 public:
348 void SetupTree() override {
349 // If the child layer has a blend mode, then it shouldn't
350 // contribute to occlusion on stuff below it
351 SetLayerPropertiesForTesting(
352 root_.get(), NULL, identity_matrix_,
353 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
354 SetLayerPropertiesForTesting(
355 child2_.get(), root_.get(), identity_matrix_,
356 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
357 SetLayerPropertiesForTesting(
358 child_.get(), root_.get(), identity_matrix_,
359 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
360 SetLayerPropertiesForTesting(
361 grand_child_.get(), child_.get(), identity_matrix_,
362 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
363
364 child_->SetMasksToBounds(true);
365 child_->SetBlendMode(SkXfermode::kMultiply_Mode);
366 child_->SetForceRenderSurface(true);
367
368 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
369 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
370
371 layer_tree_host()->SetRootLayer(root_);
372 LayerTreeTest::SetupTree();
373 }
374 };
375
376 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionBlending);
377
378 class LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion
379 : public LayerTreeHostOcclusionTest {
380 public:
381 void SetupTree() override {
382 // If the child layer with a blend mode is below child2, then
383 // child2 should contribute to occlusion on everything, and child shouldn't
384 // contribute to the root_.
385 SetLayerPropertiesForTesting(
386 root_.get(), NULL, identity_matrix_,
387 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
388 SetLayerPropertiesForTesting(
389 child_.get(), root_.get(), identity_matrix_,
390 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
391 SetLayerPropertiesForTesting(
392 grand_child_.get(), child_.get(), identity_matrix_,
393 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
394 SetLayerPropertiesForTesting(
395 child2_.get(), root_.get(), identity_matrix_,
396 gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
397
398 child_->SetMasksToBounds(true);
399 child_->SetBlendMode(SkXfermode::kMultiply_Mode);
400
401 grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
402 child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
403 root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
404
405 layer_tree_host()->SetRootLayer(root_);
406 LayerTreeTest::SetupTree();
407 }
408 };
409
410 SINGLE_AND_MULTI_THREAD_TEST_F(
411 LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion);
412
413 class LayerTreeHostOcclusionTestOcclusionOpacityFilter
414 : public LayerTreeHostOcclusionTest {
415 public:
416 void SetupTree() override {
417 FilterOperations filters;
418 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
419
420 // If the child layer has a filter that changes alpha values, and is below
421 // child2, then child2 should contribute to occlusion on everything,
422 // and child shouldn't contribute to the root
423 SetLayerPropertiesForTesting(
424 root_.get(), NULL, identity_matrix_,
425 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
426 SetLayerPropertiesForTesting(child_.get(),
427 root_.get(),
428 identity_matrix_,
429 gfx::PointF(0.f, 0.f),
430 gfx::Size(500, 500),
431 true);
432 SetLayerPropertiesForTesting(grand_child_.get(),
433 child_.get(),
434 identity_matrix_,
435 gfx::PointF(0.f, 0.f),
436 gfx::Size(500, 500),
437 true);
438 SetLayerPropertiesForTesting(child2_.get(),
439 root_.get(),
440 identity_matrix_,
441 gfx::PointF(10.f, 10.f),
442 gfx::Size(30, 30),
443 true);
444
445 child_->SetMasksToBounds(true);
446 child_->SetFilters(filters);
447
448 // child2_ occludes grand_child_, showing it does occlude inside child_'s
449 // subtree.
450 grand_child_->set_expected_occlusion(gfx::Rect(10, 10, 30, 30));
451 // grand_child_ occludes child_, showing there is more occlusion in
452 // child_'s subtree.
453 child_->set_expected_occlusion(gfx::Rect(0, 0, 200, 200));
454 // child2_'s occlusion reaches the root, but child_'s subtree does not.
455 root_->set_expected_occlusion(gfx::Rect(10, 10, 30, 30));
456
457 layer_tree_host()->SetRootLayer(root_);
458 LayerTreeTest::SetupTree();
459 }
460 };
461
462 SINGLE_AND_MULTI_THREAD_TEST_F(
463 LayerTreeHostOcclusionTestOcclusionOpacityFilter);
464
465 class LayerTreeHostOcclusionTestOcclusionBlurFilter
466 : public LayerTreeHostOcclusionTest {
467 public:
468 void SetupTree() override {
469 gfx::Transform child_transform;
470 child_transform.Translate(250.0, 250.0);
471 child_transform.Rotate(90.0);
472 child_transform.Translate(-250.0, -250.0);
473
474 FilterOperations filters;
475 filters.Append(FilterOperation::CreateBlurFilter(10.f));
476
477 // If the child layer has a filter that moves pixels/changes alpha, and is
478 // below child2, then child should not inherit occlusion from outside its
479 // subtree, and should not contribute to the root
480 SetLayerPropertiesForTesting(
481 root_.get(), NULL, identity_matrix_,
482 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
483 SetLayerPropertiesForTesting(
484 child_.get(), root_.get(), child_transform,
485 gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true);
486 SetLayerPropertiesForTesting(
487 grand_child_.get(), child_.get(), identity_matrix_,
488 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
489 SetLayerPropertiesForTesting(
490 child2_.get(), root_.get(), identity_matrix_,
491 gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true);
492
493 child_->SetMasksToBounds(true);
494 child_->SetFilters(filters);
495
496 child_->set_expected_occlusion(gfx::Rect(10, 330, 160, 170));
497 root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130));
498
499 layer_tree_host()->SetRootLayer(root_);
500 LayerTreeTest::SetupTree();
501 }
502 };
503
504 SINGLE_AND_MULTI_THREAD_TEST_F(
505 LayerTreeHostOcclusionTestOcclusionBlurFilter);
506
507 class LayerTreeHostOcclusionTestOcclusionCopyRequest
508 : public LayerTreeHostOcclusionTest {
509 public:
510 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
511
512 void SetupTree() override {
513 // If the child layer has copy request, and is below child2,
514 // then child should not inherit occlusion from outside its subtree.
515 // The child layer will still receive occlusion from inside, and
516 // the root layer will recive occlusion from child.
517 SetLayerPropertiesForTesting(
518 root_.get(), NULL, identity_matrix_,
519 gfx::PointF(), gfx::Size(100, 100), true);
520 SetLayerPropertiesForTesting(
521 child_.get(), root_.get(), identity_matrix_,
522 gfx::PointF(), gfx::Size(75, 75), true);
523 SetLayerPropertiesForTesting(
524 grand_child_.get(), child_.get(), identity_matrix_,
525 gfx::PointF(), gfx::Size(75, 50), true);
526 SetLayerPropertiesForTesting(
527 child2_.get(), root_.get(), identity_matrix_,
528 gfx::PointF(0.f, 25.f), gfx::Size(75, 75), true);
529
530 child_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
531 base::Bind(&CopyOutputCallback)));
532 EXPECT_TRUE(child_->HasCopyRequest());
533
534 child_->set_expected_occlusion(gfx::Rect(0, 0, 75, 50));
535 root_->set_expected_occlusion(gfx::Rect(0, 0, 75, 100));
536
537 layer_tree_host()->SetRootLayer(root_);
538 LayerTreeTest::SetupTree();
539 }
540 };
541
542 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionCopyRequest);
543
544 class LayerTreeHostOcclusionTestOcclusionReplica
545 : public LayerTreeHostOcclusionTest {
546 public:
547 void SetupTree() override {
548 // If the child layer has copy request, and is below child2,
549 // then child should not inherit occlusion from outside its subtree.
550 // The child layer will still receive occlusion from inside, and
551 // the root layer will recive occlusion from child.
552 SetLayerPropertiesForTesting(
553 root_.get(), NULL, identity_matrix_,
554 gfx::PointF(), gfx::Size(100, 100), true);
555 SetLayerPropertiesForTesting(
556 child_.get(), root_.get(), identity_matrix_,
557 gfx::PointF(), gfx::Size(75, 75), true);
558 SetLayerPropertiesForTesting(
559 grand_child_.get(), child_.get(), identity_matrix_,
560 gfx::PointF(), gfx::Size(75, 50), true);
561 SetLayerPropertiesForTesting(
562 child2_.get(), root_.get(), identity_matrix_,
563 gfx::PointF(0.f, 25.f), gfx::Size(75, 75), true);
564
565 scoped_refptr<Layer> replica_layer(Layer::Create());
566 child_->SetReplicaLayer(replica_layer.get());
567 EXPECT_TRUE(child_->has_replica());
568
569 child_->set_expected_occlusion(gfx::Rect(0, 0, 75, 50));
570 root_->set_expected_occlusion(gfx::Rect(0, 0, 75, 100));
571
572 layer_tree_host()->SetRootLayer(root_);
573 LayerTreeTest::SetupTree();
574 }
575 };
576
577 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionReplica);
578
579 class LayerTreeHostOcclusionTestManySurfaces
580 : public LayerTreeHostOcclusionTest {
581 public:
582 void SetupTree() override {
583 // We create enough RenderSurfaces that it will trigger Vector reallocation
584 // while computing occlusion.
585 std::vector<scoped_refptr<TestLayer>> layers;
586 int num_surfaces = 200;
587 int root_width = 400;
588 int root_height = 400;
589
590 for (int i = 0; i < num_surfaces; ++i) {
591 layers.push_back(TestLayer::Create());
592 if (i == 0) {
593 SetLayerPropertiesForTesting(
594 layers.back().get(), NULL, identity_matrix_,
595 gfx::PointF(0.f, 0.f),
596 gfx::Size(root_width, root_height), true);
597 } else {
598 SetLayerPropertiesForTesting(
599 layers.back().get(), layers[layers.size() - 2].get(),
600 identity_matrix_,
601 gfx::PointF(1.f, 1.f),
602 gfx::Size(root_width-i, root_height-i), true);
603 layers.back()->SetForceRenderSurface(true);
604 }
605 }
606
607 for (int i = 1; i < num_surfaces; ++i) {
608 scoped_refptr<TestLayer> child = TestLayer::Create();
609 SetLayerPropertiesForTesting(
610 child.get(), layers[i].get(), identity_matrix_,
611 gfx::PointF(0.f, 0.f), gfx::Size(root_width, root_height), false);
612 }
613
614 for (int i = 0; i < num_surfaces-1; ++i) {
615 gfx::Rect expected_occlusion(1, 1, root_width-i-1, root_height-i-1);
616 layers[i]->set_expected_occlusion(expected_occlusion);
617 }
618
619 layer_tree_host()->SetRootLayer(layers[0]);
620 LayerTreeTest::SetupTree();
621 }
622 };
623
624 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestManySurfaces);
625 268
626 } // namespace 269 } // namespace
627 } // namespace cc 270 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/layer_tree_host_unittest.cc ('k') | cc/trees/layer_tree_host_unittest_picture.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698