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

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

Issue 915083004: cc: Make occlusion a draw property. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: occlusiondrawproperty: notvirtual 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
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 class LayerTreeHostOcclusionTest : public LayerTreeTest {
22 protected:
23 void InitializeSettings(LayerTreeSettings* settings) override {
24 settings->minimum_occlusion_tracking_size = gfx::Size();
20 } 25 }
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 }; 26 };
52 27
53 class LayerTreeHostOcclusionTest : public LayerTreeTest { 28 // Verify occlusion is set on the layer draw properties.
29 class LayerTreeHostOcclusionTestDrawPropertiesOnLayer
30 : public LayerTreeHostOcclusionTest {
54 public: 31 public:
55 LayerTreeHostOcclusionTest() 32 void SetupTree() override {
56 : root_(TestLayer::Create()), 33 scoped_refptr<Layer> root = Layer::Create();
57 child_(TestLayer::Create()), 34 root->SetBounds(gfx::Size(100, 100));
58 child2_(TestLayer::Create()), 35 root->SetIsDrawable(true);
59 grand_child_(TestLayer::Create()), 36
60 mask_(TestLayer::Create()) { 37 scoped_refptr<Layer> child = Layer::Create();
38 child->SetBounds(gfx::Size(50, 60));
39 child->SetPosition(gfx::PointF(10.f, 5.5f));
40 child->SetContentsOpaque(true);
41 child->SetIsDrawable(true);
42 root->AddChild(child);
43
44 layer_tree_host()->SetRootLayer(root);
45 LayerTreeTest::SetupTree();
61 } 46 }
62 47
63 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 48 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
64 49
65 void DidCommit() override { 50 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
66 TestLayer* root = static_cast<TestLayer*>(layer_tree_host()->root_layer()); 51 LayerImpl* root = impl->active_tree()->root_layer();
67 VerifyOcclusion(root); 52 LayerImpl* child = root->children()[0];
68 53
54 // Verify the draw properties are valid.
55 EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember());
56 EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember());
57
58 EXPECT_OCCLUSION_EQ(
59 Occlusion(child->draw_transform(), SimpleEnclosedRegion(),
60 SimpleEnclosedRegion()),
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 root->AddChild(child);
88
89 scoped_refptr<Layer> replica = Layer::Create();
90 gfx::Transform translate;
91 translate.Translate(20.f, 4.f);
92 replica->SetTransform(translate);
93 child->SetReplicaLayer(replica.get());
94
95 scoped_refptr<Layer> child2 = Layer::Create();
96 child2->SetBounds(gfx::Size(10, 12));
97 child2->SetPosition(gfx::PointF(13.f, 8.5f));
98 child2->SetContentsOpaque(true);
99 child2->SetIsDrawable(true);
100 root->AddChild(child2);
101
102 layer_tree_host()->SetRootLayer(root);
103 LayerTreeTest::SetupTree();
104 }
105
106 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
107
108 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
109 LayerImpl* root = impl->active_tree()->root_layer();
110 LayerImpl* child = root->children()[0];
111 RenderSurfaceImpl* surface = child->render_surface();
112
113 // Verify the draw properties are valid.
114 EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember());
115 EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember());
116 EXPECT_EQ(child, child->render_target());
117
118 EXPECT_OCCLUSION_EQ(
119 Occlusion(surface->draw_transform(), SimpleEnclosedRegion(),
120 SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
121 surface->occlusion_in_content_space());
122 EXPECT_OCCLUSION_EQ(
123 Occlusion(surface->replica_draw_transform(), SimpleEnclosedRegion(),
124 SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
125 surface->replica_occlusion_in_content_space());
126 EndTest();
127 }
128
129 void AfterTest() override {}
130 };
131
132 SINGLE_AND_MULTI_THREAD_TEST_F(
133 LayerTreeHostOcclusionTestDrawPropertiesOnSurface);
134
135 // Verify occlusion is set on mask layers.
136 class LayerTreeHostOcclusionTestDrawPropertiesOnMask
137 : public LayerTreeHostOcclusionTest {
138 public:
139 void SetupTree() override {
140 scoped_refptr<Layer> root = Layer::Create();
141 root->SetBounds(gfx::Size(100, 100));
142 root->SetIsDrawable(true);
143
144 scoped_refptr<Layer> child = Layer::Create();
145 child->SetBounds(gfx::Size(30, 40));
146 child->SetPosition(gfx::PointF(10.f, 5.5f));
147 child->SetIsDrawable(true);
148 root->AddChild(child);
149
150 scoped_refptr<Layer> make_surface_bigger = Layer::Create();
151 make_surface_bigger->SetBounds(gfx::Size(100, 100));
152 make_surface_bigger->SetPosition(gfx::PointF(-10.f, -15.f));
153 make_surface_bigger->SetIsDrawable(true);
154 child->AddChild(make_surface_bigger);
155
156 scoped_refptr<Layer> mask = PictureLayer::Create(&client_);
157 mask->SetBounds(gfx::Size(30, 40));
158 mask->SetIsDrawable(true);
159 child->SetMaskLayer(mask.get());
160
161 scoped_refptr<Layer> child2 = Layer::Create();
162 child2->SetBounds(gfx::Size(10, 12));
163 child2->SetPosition(gfx::PointF(13.f, 8.5f));
164 child2->SetContentsOpaque(true);
165 child2->SetIsDrawable(true);
166 root->AddChild(child2);
167
168 layer_tree_host()->SetRootLayer(root);
169 LayerTreeTest::SetupTree();
170 }
171
172 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
173
174 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
175 LayerImpl* root = impl->active_tree()->root_layer();
176 LayerImpl* child = root->children()[0];
177 RenderSurfaceImpl* surface = child->render_surface();
178 LayerImpl* mask = child->mask_layer();
179
180 // Verify the draw properties are valid.
181 EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember());
182 EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember());
183 EXPECT_EQ(child, child->render_target());
184
185 gfx::Transform transform = surface->draw_transform();
186 transform.PreconcatTransform(child->draw_transform());
187
188 EXPECT_OCCLUSION_EQ(
189 Occlusion(transform, SimpleEnclosedRegion(),
190 SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
191 mask->draw_properties().occlusion_in_content_space);
69 EndTest(); 192 EndTest();
70 } 193 }
71 194
72 void AfterTest() override {} 195 void AfterTest() override {}
73 196
74 void VerifyOcclusion(TestLayer* layer) const { 197 FakeContentLayerClient client_;
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:
100 void InitializeSettings(LayerTreeSettings* settings) override {
101 settings->minimum_occlusion_tracking_size = gfx::Size();
102 }
103
104 scoped_refptr<TestLayer> root_;
105 scoped_refptr<TestLayer> child_;
106 scoped_refptr<TestLayer> child2_;
107 scoped_refptr<TestLayer> grand_child_;
108 scoped_refptr<TestLayer> mask_;
109
110 gfx::Transform identity_matrix_;
111 }; 198 };
112 199
113 200 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnMask);
114 class LayerTreeHostOcclusionTestOcclusionSurfaceClipping
115 : public LayerTreeHostOcclusionTest {
116 public:
117 void SetupTree() override {
118 // The child layer is a surface and the grand_child is opaque, but clipped
119 // to the child and root
120 SetLayerPropertiesForTesting(
121 root_.get(), NULL, identity_matrix_,
122 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
123 SetLayerPropertiesForTesting(
124 child_.get(), root_.get(), identity_matrix_,
125 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false);
126 SetLayerPropertiesForTesting(
127 grand_child_.get(), child_.get(), identity_matrix_,
128 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
129
130 child_->SetMasksToBounds(true);
131 child_->SetForceRenderSurface(true);
132
133 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
134 root_->set_expected_occlusion(gfx::Rect(10, 10, 10, 190));
135
136 layer_tree_host()->SetRootLayer(root_);
137 LayerTreeTest::SetupTree();
138 }
139 };
140
141 SINGLE_AND_MULTI_THREAD_TEST_F(
142 LayerTreeHostOcclusionTestOcclusionSurfaceClipping);
143
144 class LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque
145 : public LayerTreeHostOcclusionTest {
146 public:
147 void SetupTree() override {
148 // If the child layer is opaque, then it adds to the occlusion seen by the
149 // root_.
150 SetLayerPropertiesForTesting(
151 root_.get(), NULL, identity_matrix_,
152 gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
153 SetLayerPropertiesForTesting(
154 child_.get(), root_.get(), identity_matrix_,
155 gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
156 SetLayerPropertiesForTesting(
157 grand_child_.get(), child_.get(), identity_matrix_,
158 gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
159
160 child_->SetMasksToBounds(true);
161 child_->SetForceRenderSurface(true);
162
163 child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
164 root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190));
165
166 layer_tree_host()->SetRootLayer(root_);
167 LayerTreeTest::SetupTree();
168 }
169 };
170
171 SINGLE_AND_MULTI_THREAD_TEST_F(
172 LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque);
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 201
626 } // namespace 202 } // namespace
627 } // namespace cc 203 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698