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