Remove "keyboard" from keyboard strings.
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blobf4e2edbca9176190558aa7034a81d64308dc6ec1
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.
5 #include "cc/trees/occlusion_tracker.h"
7 #include "cc/animation/layer_animation_controller.h"
8 #include "cc/base/math_util.h"
9 #include "cc/layers/layer.h"
10 #include "cc/layers/layer_impl.h"
11 #include "cc/output/copy_output_request.h"
12 #include "cc/output/copy_output_result.h"
13 #include "cc/output/filter_operation.h"
14 #include "cc/output/filter_operations.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_impl_proxy.h"
17 #include "cc/test/fake_layer_tree_host.h"
18 #include "cc/test/fake_layer_tree_host_impl.h"
19 #include "cc/test/geometry_test_utils.h"
20 #include "cc/test/test_occlusion_tracker.h"
21 #include "cc/trees/layer_tree_host_common.h"
22 #include "cc/trees/single_thread_proxy.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/gfx/transform.h"
27 namespace cc {
28 namespace {
30 class TestContentLayer : public Layer {
31 public:
32 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
33 SetIsDrawable(true);
36 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
37 if (override_opaque_contents_rect_)
38 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
39 return Layer::VisibleContentOpaqueRegion();
41 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
42 override_opaque_contents_rect_ = true;
43 opaque_contents_rect_ = opaque_contents_rect;
46 private:
47 virtual ~TestContentLayer() {}
49 bool override_opaque_contents_rect_;
50 gfx::Rect opaque_contents_rect_;
53 class TestContentLayerImpl : public LayerImpl {
54 public:
55 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
56 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
57 SetDrawsContent(true);
60 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
61 if (override_opaque_contents_rect_)
62 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
63 return LayerImpl::VisibleContentOpaqueRegion();
65 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
66 override_opaque_contents_rect_ = true;
67 opaque_contents_rect_ = opaque_contents_rect;
70 private:
71 bool override_opaque_contents_rect_;
72 gfx::Rect opaque_contents_rect_;
75 template <typename LayerType>
76 class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> {
77 public:
78 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect)
79 : TestOcclusionTracker<LayerType>(viewport_rect) {}
81 bool OccludedLayer(const LayerType* layer,
82 const gfx::Rect& content_rect) const {
83 DCHECK(layer->visible_content_rect().Contains(content_rect));
84 return this->Occluded(
85 layer->render_target(), content_rect, layer->draw_transform());
88 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
89 // layer. Simple wrapper around UnoccludedContentRect.
90 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
91 const gfx::Rect& content_rect) const {
92 DCHECK(layer->visible_content_rect().Contains(content_rect));
93 return this->UnoccludedContentRect(
94 layer->render_target(), content_rect, layer->draw_transform());
98 struct OcclusionTrackerTestMainThreadTypes {
99 typedef Layer LayerType;
100 typedef FakeLayerTreeHost HostType;
101 typedef RenderSurface RenderSurfaceType;
102 typedef TestContentLayer ContentLayerType;
103 typedef scoped_refptr<Layer> LayerPtrType;
104 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
105 typedef LayerIterator<Layer> TestLayerIterator;
106 typedef OcclusionTracker<Layer> OcclusionTrackerType;
108 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
109 static ContentLayerPtrType CreateContentLayer(HostType* host) {
110 return make_scoped_refptr(new ContentLayerType());
113 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
114 LayerPtrType ref(*layer);
115 *layer = NULL;
116 return ref;
119 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
120 LayerPtrType ref(*layer);
121 *layer = NULL;
122 return ref;
125 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
128 struct OcclusionTrackerTestImplThreadTypes {
129 typedef LayerImpl LayerType;
130 typedef LayerTreeImpl HostType;
131 typedef RenderSurfaceImpl RenderSurfaceType;
132 typedef TestContentLayerImpl ContentLayerType;
133 typedef scoped_ptr<LayerImpl> LayerPtrType;
134 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
135 typedef LayerIterator<LayerImpl> TestLayerIterator;
136 typedef OcclusionTracker<LayerImpl> OcclusionTrackerType;
138 static LayerPtrType CreateLayer(HostType* host) {
139 return LayerImpl::Create(host, next_layer_impl_id++);
141 static ContentLayerPtrType CreateContentLayer(HostType* host) {
142 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
144 static int next_layer_impl_id;
146 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
147 return layer->Pass();
150 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
151 return layer->PassAs<LayerType>();
154 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
157 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
159 template <typename Types> class OcclusionTrackerTest : public testing::Test {
160 protected:
161 explicit OcclusionTrackerTest(bool opaque_layers)
162 : opaque_layers_(opaque_layers), host_(FakeLayerTreeHost::Create()) {}
164 virtual void RunMyTest() = 0;
166 virtual void TearDown() {
167 Types::DestroyLayer(&root_);
168 render_surface_layer_list_.reset();
169 render_surface_layer_list_impl_.clear();
170 replica_layers_.clear();
171 mask_layers_.clear();
174 typename Types::HostType* GetHost();
176 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
177 const gfx::PointF& position,
178 const gfx::Size& bounds) {
179 typename Types::ContentLayerPtrType layer(
180 Types::CreateContentLayer(GetHost()));
181 typename Types::ContentLayerType* layer_ptr = layer.get();
182 SetProperties(layer_ptr, transform, position, bounds);
184 DCHECK(!root_.get());
185 root_ = Types::PassLayerPtr(&layer);
187 SetRootLayerOnMainThread(layer_ptr);
189 return layer_ptr;
192 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
193 const gfx::Transform& transform,
194 const gfx::PointF& position,
195 const gfx::Size& bounds) {
196 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
197 typename Types::LayerType* layer_ptr = layer.get();
198 SetProperties(layer_ptr, transform, position, bounds);
199 parent->AddChild(Types::PassLayerPtr(&layer));
200 return layer_ptr;
203 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
204 const gfx::Transform& transform,
205 const gfx::PointF& position,
206 const gfx::Size& bounds) {
207 typename Types::LayerType* layer =
208 CreateLayer(parent, transform, position, bounds);
209 layer->SetForceRenderSurface(true);
210 return layer;
213 typename Types::ContentLayerType* CreateDrawingLayer(
214 typename Types::LayerType* parent,
215 const gfx::Transform& transform,
216 const gfx::PointF& position,
217 const gfx::Size& bounds,
218 bool opaque) {
219 typename Types::ContentLayerPtrType layer(
220 Types::CreateContentLayer(GetHost()));
221 typename Types::ContentLayerType* layer_ptr = layer.get();
222 SetProperties(layer_ptr, transform, position, bounds);
224 if (opaque_layers_) {
225 layer_ptr->SetContentsOpaque(opaque);
226 } else {
227 layer_ptr->SetContentsOpaque(false);
228 if (opaque)
229 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
230 else
231 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
234 parent->AddChild(Types::PassLayerPtr(&layer));
235 return layer_ptr;
238 typename Types::LayerType* CreateReplicaLayer(
239 typename Types::LayerType* owning_layer,
240 const gfx::Transform& transform,
241 const gfx::PointF& position,
242 const gfx::Size& bounds) {
243 typename Types::ContentLayerPtrType layer(
244 Types::CreateContentLayer(GetHost()));
245 typename Types::ContentLayerType* layer_ptr = layer.get();
246 SetProperties(layer_ptr, transform, position, bounds);
247 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
248 return layer_ptr;
251 typename Types::LayerType* CreateMaskLayer(
252 typename Types::LayerType* owning_layer,
253 const gfx::Size& bounds) {
254 typename Types::ContentLayerPtrType layer(
255 Types::CreateContentLayer(GetHost()));
256 typename Types::ContentLayerType* layer_ptr = layer.get();
257 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
258 SetMask(owning_layer, Types::PassLayerPtr(&layer));
259 return layer_ptr;
262 typename Types::ContentLayerType* CreateDrawingSurface(
263 typename Types::LayerType* parent,
264 const gfx::Transform& transform,
265 const gfx::PointF& position,
266 const gfx::Size& bounds,
267 bool opaque) {
268 typename Types::ContentLayerType* layer =
269 CreateDrawingLayer(parent, transform, position, bounds, opaque);
270 layer->SetForceRenderSurface(true);
271 return layer;
275 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
277 void AddCopyRequest(Layer* layer) {
278 layer->RequestCopyOfOutput(
279 CopyOutputRequest::CreateBitmapRequest(base::Bind(
280 &OcclusionTrackerTest<Types>::CopyOutputCallback,
281 base::Unretained(this))));
284 void AddCopyRequest(LayerImpl* layer) {
285 ScopedPtrVector<CopyOutputRequest> requests;
286 requests.push_back(
287 CopyOutputRequest::CreateBitmapRequest(base::Bind(
288 &OcclusionTrackerTest<Types>::CopyOutputCallback,
289 base::Unretained(this))));
290 layer->PassCopyRequests(&requests);
293 void CalcDrawEtc(TestContentLayerImpl* root) {
294 DCHECK(root == root_.get());
295 DCHECK(!root->render_surface());
297 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
298 root, root->bounds(), &render_surface_layer_list_impl_);
299 inputs.can_adjust_raster_scales = true;
300 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
302 layer_iterator_ = layer_iterator_begin_ =
303 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
306 void CalcDrawEtc(TestContentLayer* root) {
307 DCHECK(root == root_.get());
308 DCHECK(!root->render_surface());
310 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
311 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
312 root, root->bounds(), render_surface_layer_list_.get());
313 inputs.can_adjust_raster_scales = true;
314 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
316 layer_iterator_ = layer_iterator_begin_ =
317 Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
320 void SetDrawsContent(LayerImpl* layer_impl, bool draws_content) {
321 layer_impl->SetDrawsContent(draws_content);
324 void SetDrawsContent(Layer* layer, bool draws_content) {
325 layer->SetIsDrawable(draws_content);
328 void EnterLayer(typename Types::LayerType* layer,
329 typename Types::OcclusionTrackerType* occlusion) {
330 ASSERT_EQ(layer, *layer_iterator_);
331 ASSERT_TRUE(layer_iterator_.represents_itself());
332 occlusion->EnterLayer(layer_iterator_);
335 void LeaveLayer(typename Types::LayerType* layer,
336 typename Types::OcclusionTrackerType* occlusion) {
337 ASSERT_EQ(layer, *layer_iterator_);
338 ASSERT_TRUE(layer_iterator_.represents_itself());
339 occlusion->LeaveLayer(layer_iterator_);
340 ++layer_iterator_;
343 void VisitLayer(typename Types::LayerType* layer,
344 typename Types::OcclusionTrackerType* occlusion) {
345 EnterLayer(layer, occlusion);
346 LeaveLayer(layer, occlusion);
349 void EnterContributingSurface(
350 typename Types::LayerType* layer,
351 typename Types::OcclusionTrackerType* occlusion) {
352 ASSERT_EQ(layer, *layer_iterator_);
353 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
354 occlusion->EnterLayer(layer_iterator_);
355 occlusion->LeaveLayer(layer_iterator_);
356 ++layer_iterator_;
357 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
358 occlusion->EnterLayer(layer_iterator_);
361 void LeaveContributingSurface(
362 typename Types::LayerType* layer,
363 typename Types::OcclusionTrackerType* occlusion) {
364 ASSERT_EQ(layer, *layer_iterator_);
365 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
366 occlusion->LeaveLayer(layer_iterator_);
367 ++layer_iterator_;
370 void VisitContributingSurface(
371 typename Types::LayerType* layer,
372 typename Types::OcclusionTrackerType* occlusion) {
373 EnterContributingSurface(layer, occlusion);
374 LeaveContributingSurface(layer, occlusion);
377 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
379 const gfx::Transform identity_matrix;
381 private:
382 void SetRootLayerOnMainThread(Layer* root) {
383 host_->SetRootLayer(scoped_refptr<Layer>(root));
386 void SetRootLayerOnMainThread(LayerImpl* root) {}
388 void SetBaseProperties(typename Types::LayerType* layer,
389 const gfx::Transform& transform,
390 const gfx::PointF& position,
391 const gfx::Size& bounds) {
392 layer->SetTransform(transform);
393 layer->SetAnchorPoint(gfx::PointF());
394 layer->SetPosition(position);
395 layer->SetBounds(bounds);
398 void SetProperties(Layer* layer,
399 const gfx::Transform& transform,
400 const gfx::PointF& position,
401 const gfx::Size& bounds) {
402 SetBaseProperties(layer, transform, position, bounds);
405 void SetProperties(LayerImpl* layer,
406 const gfx::Transform& transform,
407 const gfx::PointF& position,
408 const gfx::Size& bounds) {
409 SetBaseProperties(layer, transform, position, bounds);
411 layer->SetContentBounds(layer->bounds());
414 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
415 owning_layer->SetReplicaLayer(layer.get());
416 replica_layers_.push_back(layer);
419 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
420 owning_layer->SetReplicaLayer(layer.Pass());
423 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
424 owning_layer->SetMaskLayer(layer.get());
425 mask_layers_.push_back(layer);
428 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
429 owning_layer->SetMaskLayer(layer.Pass());
432 bool opaque_layers_;
433 scoped_ptr<FakeLayerTreeHost> host_;
434 // These hold ownership of the layers for the duration of the test.
435 typename Types::LayerPtrType root_;
436 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
437 LayerImplList render_surface_layer_list_impl_;
438 typename Types::TestLayerIterator layer_iterator_begin_;
439 typename Types::TestLayerIterator layer_iterator_;
440 typename Types::LayerType* last_layer_visited_;
441 LayerList replica_layers_;
442 LayerList mask_layers_;
445 template <>
446 FakeLayerTreeHost*
447 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
448 return host_.get();
451 template <>
452 LayerTreeImpl*
453 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
454 return host_->host_impl()->active_tree();
457 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
458 class ClassName##MainThreadOpaqueLayers \
459 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
460 public: /* NOLINT(whitespace/indent) */ \
461 ClassName##MainThreadOpaqueLayers() \
462 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
463 }; \
464 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
465 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
466 class ClassName##MainThreadOpaquePaints \
467 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
468 public: /* NOLINT(whitespace/indent) */ \
469 ClassName##MainThreadOpaquePaints() \
470 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
471 }; \
472 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
474 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
475 class ClassName##ImplThreadOpaqueLayers \
476 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
477 public: /* NOLINT(whitespace/indent) */ \
478 ClassName##ImplThreadOpaqueLayers() \
479 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
480 }; \
481 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
482 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
483 class ClassName##ImplThreadOpaquePaints \
484 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
485 public: /* NOLINT(whitespace/indent) */ \
486 ClassName##ImplThreadOpaquePaints() \
487 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
488 }; \
489 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
491 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
492 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
493 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
494 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
495 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
497 #define MAIN_THREAD_TEST(ClassName) \
498 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
500 #define IMPL_THREAD_TEST(ClassName) \
501 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
503 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
504 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
505 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
507 template <class Types>
508 class OcclusionTrackerTestIdentityTransforms
509 : public OcclusionTrackerTest<Types> {
510 protected:
511 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
512 : OcclusionTrackerTest<Types>(opaque_layers) {}
514 void RunMyTest() {
515 typename Types::ContentLayerType* root = this->CreateRoot(
516 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
517 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
518 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
519 typename Types::ContentLayerType* layer =
520 this->CreateDrawingLayer(parent,
521 this->identity_matrix,
522 gfx::PointF(30.f, 30.f),
523 gfx::Size(500, 500),
524 true);
525 parent->SetMasksToBounds(true);
526 this->CalcDrawEtc(root);
528 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
529 gfx::Rect(0, 0, 1000, 1000));
531 this->VisitLayer(layer, &occlusion);
532 this->EnterLayer(parent, &occlusion);
534 EXPECT_EQ(gfx::Rect().ToString(),
535 occlusion.occlusion_from_outside_target().ToString());
536 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
537 occlusion.occlusion_from_inside_target().ToString());
539 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
540 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
541 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
542 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
543 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
545 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
546 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
547 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
548 occlusion.UnoccludedLayerContentRect(
549 parent, gfx::Rect(29, 30, 70, 70)));
550 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
551 occlusion.UnoccludedLayerContentRect(
552 parent, gfx::Rect(29, 29, 70, 70)));
553 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
554 occlusion.UnoccludedLayerContentRect(
555 parent, gfx::Rect(30, 29, 70, 70)));
556 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
557 occlusion.UnoccludedLayerContentRect(
558 parent, gfx::Rect(31, 29, 69, 70)));
559 EXPECT_RECT_EQ(gfx::Rect(),
560 occlusion.UnoccludedLayerContentRect(
561 parent, gfx::Rect(31, 30, 69, 70)));
562 EXPECT_RECT_EQ(gfx::Rect(),
563 occlusion.UnoccludedLayerContentRect(
564 parent, gfx::Rect(31, 31, 69, 69)));
565 EXPECT_RECT_EQ(gfx::Rect(),
566 occlusion.UnoccludedLayerContentRect(
567 parent, gfx::Rect(30, 31, 70, 69)));
568 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
569 occlusion.UnoccludedLayerContentRect(
570 parent, gfx::Rect(29, 31, 70, 69)));
574 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
576 template <class Types>
577 class OcclusionTrackerTestQuadsMismatchLayer
578 : public OcclusionTrackerTest<Types> {
579 protected:
580 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
581 : OcclusionTrackerTest<Types>(opaque_layers) {}
582 void RunMyTest() {
583 gfx::Transform layer_transform;
584 layer_transform.Translate(10.0, 10.0);
586 typename Types::ContentLayerType* parent = this->CreateRoot(
587 this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
588 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
589 parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
590 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
591 layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
592 this->CalcDrawEtc(parent);
594 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
595 gfx::Rect(0, 0, 1000, 1000));
597 this->VisitLayer(layer2, &occlusion);
598 this->EnterLayer(layer1, &occlusion);
600 EXPECT_EQ(gfx::Rect().ToString(),
601 occlusion.occlusion_from_outside_target().ToString());
602 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
603 occlusion.occlusion_from_inside_target().ToString());
605 // This checks cases where the quads don't match their "containing"
606 // layers, e.g. in terms of transforms or clip rect. This is typical for
607 // DelegatedRendererLayer.
609 gfx::Transform quad_transform;
610 quad_transform.Translate(30.0, 30.0);
612 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent,
613 gfx::Rect(0, 0, 10, 10),
614 quad_transform).IsEmpty());
615 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
616 occlusion.UnoccludedContentRect(
617 parent, gfx::Rect(40, 40, 10, 10), quad_transform));
618 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
619 occlusion.UnoccludedContentRect(
620 parent, gfx::Rect(35, 30, 10, 10), quad_transform));
624 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
626 template <class Types>
627 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
628 protected:
629 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
630 : OcclusionTrackerTest<Types>(opaque_layers) {}
631 void RunMyTest() {
632 gfx::Transform layer_transform;
633 layer_transform.Translate(250.0, 250.0);
634 layer_transform.Rotate(90.0);
635 layer_transform.Translate(-250.0, -250.0);
637 typename Types::ContentLayerType* root = this->CreateRoot(
638 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
639 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
640 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
641 typename Types::ContentLayerType* layer =
642 this->CreateDrawingLayer(parent,
643 layer_transform,
644 gfx::PointF(30.f, 30.f),
645 gfx::Size(500, 500),
646 true);
647 parent->SetMasksToBounds(true);
648 this->CalcDrawEtc(root);
650 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
651 gfx::Rect(0, 0, 1000, 1000));
653 this->VisitLayer(layer, &occlusion);
654 this->EnterLayer(parent, &occlusion);
656 EXPECT_EQ(gfx::Rect().ToString(),
657 occlusion.occlusion_from_outside_target().ToString());
658 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
659 occlusion.occlusion_from_inside_target().ToString());
661 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
662 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
663 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
664 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
665 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
667 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
668 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
669 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
670 occlusion.UnoccludedLayerContentRect(
671 parent, gfx::Rect(29, 30, 69, 70)));
672 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
673 occlusion.UnoccludedLayerContentRect(
674 parent, gfx::Rect(29, 29, 70, 70)));
675 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
676 occlusion.UnoccludedLayerContentRect(
677 parent, gfx::Rect(30, 29, 70, 70)));
678 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
679 occlusion.UnoccludedLayerContentRect(
680 parent, gfx::Rect(31, 29, 69, 70)));
681 EXPECT_RECT_EQ(gfx::Rect(),
682 occlusion.UnoccludedLayerContentRect(
683 parent, gfx::Rect(31, 30, 69, 70)));
684 EXPECT_RECT_EQ(gfx::Rect(),
685 occlusion.UnoccludedLayerContentRect(
686 parent, gfx::Rect(31, 31, 69, 69)));
687 EXPECT_RECT_EQ(gfx::Rect(),
688 occlusion.UnoccludedLayerContentRect(
689 parent, gfx::Rect(30, 31, 70, 69)));
690 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
691 occlusion.UnoccludedLayerContentRect(
692 parent, gfx::Rect(29, 31, 70, 69)));
696 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
698 template <class Types>
699 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
700 protected:
701 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
702 : OcclusionTrackerTest<Types>(opaque_layers) {}
703 void RunMyTest() {
704 gfx::Transform layer_transform;
705 layer_transform.Translate(20.0, 20.0);
707 typename Types::ContentLayerType* root = this->CreateRoot(
708 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
709 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
710 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
711 typename Types::ContentLayerType* layer =
712 this->CreateDrawingLayer(parent,
713 layer_transform,
714 gfx::PointF(30.f, 30.f),
715 gfx::Size(500, 500),
716 true);
717 parent->SetMasksToBounds(true);
718 this->CalcDrawEtc(root);
720 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
721 gfx::Rect(0, 0, 1000, 1000));
723 this->VisitLayer(layer, &occlusion);
724 this->EnterLayer(parent, &occlusion);
726 EXPECT_EQ(gfx::Rect().ToString(),
727 occlusion.occlusion_from_outside_target().ToString());
728 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
729 occlusion.occlusion_from_inside_target().ToString());
731 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
732 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
733 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
734 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 49, 50)));
735 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 49)));
737 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
738 parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
739 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
740 occlusion.UnoccludedLayerContentRect(
741 parent, gfx::Rect(49, 50, 50, 50)));
742 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
743 occlusion.UnoccludedLayerContentRect(
744 parent, gfx::Rect(49, 49, 50, 50)));
745 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
746 occlusion.UnoccludedLayerContentRect(
747 parent, gfx::Rect(50, 49, 50, 50)));
748 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
749 occlusion.UnoccludedLayerContentRect(
750 parent, gfx::Rect(51, 49, 49, 50)));
751 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
752 parent, gfx::Rect(51, 50, 49, 50)).IsEmpty());
753 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
754 parent, gfx::Rect(51, 51, 49, 49)).IsEmpty());
755 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
756 parent, gfx::Rect(50, 51, 50, 49)).IsEmpty());
757 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
758 occlusion.UnoccludedLayerContentRect(
759 parent, gfx::Rect(49, 51, 50, 49)));
763 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
765 template <class Types>
766 class OcclusionTrackerTestChildInRotatedChild
767 : public OcclusionTrackerTest<Types> {
768 protected:
769 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
770 : OcclusionTrackerTest<Types>(opaque_layers) {}
771 void RunMyTest() {
772 gfx::Transform child_transform;
773 child_transform.Translate(250.0, 250.0);
774 child_transform.Rotate(90.0);
775 child_transform.Translate(-250.0, -250.0);
777 typename Types::ContentLayerType* parent = this->CreateRoot(
778 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
779 parent->SetMasksToBounds(true);
780 typename Types::LayerType* child = this->CreateSurface(
781 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
782 child->SetMasksToBounds(true);
783 typename Types::ContentLayerType* layer =
784 this->CreateDrawingLayer(child,
785 this->identity_matrix,
786 gfx::PointF(10.f, 10.f),
787 gfx::Size(500, 500),
788 true);
789 this->CalcDrawEtc(parent);
791 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
792 gfx::Rect(0, 0, 1000, 1000));
794 this->VisitLayer(layer, &occlusion);
795 this->EnterContributingSurface(child, &occlusion);
797 EXPECT_EQ(gfx::Rect().ToString(),
798 occlusion.occlusion_from_outside_target().ToString());
799 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
800 occlusion.occlusion_from_inside_target().ToString());
802 this->LeaveContributingSurface(child, &occlusion);
803 this->EnterLayer(parent, &occlusion);
805 EXPECT_EQ(gfx::Rect().ToString(),
806 occlusion.occlusion_from_outside_target().ToString());
807 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
808 occlusion.occlusion_from_inside_target().ToString());
810 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
811 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
812 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
813 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 69, 60)));
814 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 59)));
816 /* Justification for the above occlusion from |layer|:
818 +---------------------+
820 | 30 | rotate(90)
821 | 30 + ---------------------------------+
822 100 | | 10 | | ==>
823 | |10+---------------------------------+
824 | | | | | |
825 | | | | | |
826 | | | | | |
827 +----|--|-------------+ | |
828 | | | |
829 | | | |
830 | | | |500
831 | | | |
832 | | | |
833 | | | |
834 | | | |
835 +--|-------------------------------+ |
837 +---------------------------------+
840 +---------------------+
841 | |30 Visible region of |layer|: /////
843 | +---------------------------------+
844 100| | |10 |
845 | +---------------------------------+ |
846 | | |///////////////| 420 | |
847 | | |///////////////|60 | |
848 | | |///////////////| | |
849 +--|--|---------------+ | |
850 20|10| 70 | |
851 | | | |
852 | | | |
853 | | | |
854 | | | |
855 | | | |
856 | | |10|
857 | +------------------------------|--+
858 | 490 |
859 +---------------------------------+
866 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
868 template <class Types>
869 class OcclusionTrackerTestScaledRenderSurface
870 : public OcclusionTrackerTest<Types> {
871 protected:
872 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
873 : OcclusionTrackerTest<Types>(opaque_layers) {}
875 void RunMyTest() {
876 typename Types::ContentLayerType* parent = this->CreateRoot(
877 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
879 gfx::Transform layer1_matrix;
880 layer1_matrix.Scale(2.0, 2.0);
881 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
882 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
883 layer1->SetForceRenderSurface(true);
885 gfx::Transform layer2_matrix;
886 layer2_matrix.Translate(25.0, 25.0);
887 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
888 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
889 typename Types::ContentLayerType* occluder =
890 this->CreateDrawingLayer(parent,
891 this->identity_matrix,
892 gfx::PointF(100.f, 100.f),
893 gfx::Size(500, 500),
894 true);
895 this->CalcDrawEtc(parent);
897 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
898 gfx::Rect(0, 0, 1000, 1000));
900 this->VisitLayer(occluder, &occlusion);
901 this->EnterLayer(layer2, &occlusion);
903 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
904 occlusion.occlusion_from_outside_target().ToString());
905 EXPECT_EQ(gfx::Rect().ToString(),
906 occlusion.occlusion_from_inside_target().ToString());
908 EXPECT_RECT_EQ(
909 gfx::Rect(0, 0, 25, 25),
910 occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
911 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
912 occlusion.UnoccludedLayerContentRect(
913 layer2, gfx::Rect(10, 25, 25, 25)));
914 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
915 occlusion.UnoccludedLayerContentRect(
916 layer2, gfx::Rect(25, 10, 25, 25)));
917 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
918 layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
922 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
924 template <class Types>
925 class OcclusionTrackerTestVisitTargetTwoTimes
926 : public OcclusionTrackerTest<Types> {
927 protected:
928 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
929 : OcclusionTrackerTest<Types>(opaque_layers) {}
930 void RunMyTest() {
931 gfx::Transform child_transform;
932 child_transform.Translate(250.0, 250.0);
933 child_transform.Rotate(90.0);
934 child_transform.Translate(-250.0, -250.0);
936 typename Types::ContentLayerType* root = this->CreateRoot(
937 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
938 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
939 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
940 parent->SetMasksToBounds(true);
941 typename Types::LayerType* child = this->CreateSurface(
942 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
943 child->SetMasksToBounds(true);
944 typename Types::ContentLayerType* layer =
945 this->CreateDrawingLayer(child,
946 this->identity_matrix,
947 gfx::PointF(10.f, 10.f),
948 gfx::Size(500, 500),
949 true);
950 // |child2| makes |parent|'s surface get considered by OcclusionTracker
951 // first, instead of |child|'s. This exercises different code in
952 // LeaveToRenderTarget, as the target surface has already been seen.
953 typename Types::ContentLayerType* child2 =
954 this->CreateDrawingLayer(parent,
955 this->identity_matrix,
956 gfx::PointF(30.f, 30.f),
957 gfx::Size(60, 20),
958 true);
959 this->CalcDrawEtc(root);
961 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
962 gfx::Rect(0, 0, 1000, 1000));
964 this->VisitLayer(child2, &occlusion);
966 EXPECT_EQ(gfx::Rect().ToString(),
967 occlusion.occlusion_from_outside_target().ToString());
968 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
969 occlusion.occlusion_from_inside_target().ToString());
971 this->VisitLayer(layer, &occlusion);
973 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
974 occlusion.occlusion_from_outside_target().ToString());
975 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
976 occlusion.occlusion_from_inside_target().ToString());
978 this->EnterContributingSurface(child, &occlusion);
980 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
981 occlusion.occlusion_from_outside_target().ToString());
982 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
983 occlusion.occlusion_from_inside_target().ToString());
985 // Occlusion in |child2| should get merged with the |child| surface we are
986 // leaving now.
987 this->LeaveContributingSurface(child, &occlusion);
988 this->EnterLayer(parent, &occlusion);
990 EXPECT_EQ(gfx::Rect().ToString(),
991 occlusion.occlusion_from_outside_target().ToString());
992 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
993 .ToString(),
994 occlusion.occlusion_from_inside_target().ToString());
996 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
997 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
998 occlusion.UnoccludedLayerContentRect(
999 parent, gfx::Rect(30, 30, 70, 70)));
1001 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
1002 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
1003 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
1004 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
1005 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
1007 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1008 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1009 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1011 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1012 parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1013 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1014 occlusion.UnoccludedLayerContentRect(
1015 parent, gfx::Rect(29, 30, 60, 10)));
1016 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1017 occlusion.UnoccludedLayerContentRect(
1018 parent, gfx::Rect(30, 29, 60, 10)));
1019 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1020 occlusion.UnoccludedLayerContentRect(
1021 parent, gfx::Rect(31, 30, 60, 10)));
1022 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1023 parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1025 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1026 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1027 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1028 occlusion.UnoccludedLayerContentRect(
1029 parent, gfx::Rect(29, 40, 70, 60)));
1030 // This rect is mostly occluded by |child2|.
1031 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1032 occlusion.UnoccludedLayerContentRect(
1033 parent, gfx::Rect(30, 39, 70, 60)));
1034 // This rect extends past top/right ends of |child2|.
1035 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1036 occlusion.UnoccludedLayerContentRect(
1037 parent, gfx::Rect(30, 29, 70, 70)));
1038 // This rect extends past left/right ends of |child2|.
1039 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1040 occlusion.UnoccludedLayerContentRect(
1041 parent, gfx::Rect(20, 39, 80, 60)));
1042 EXPECT_RECT_EQ(gfx::Rect(),
1043 occlusion.UnoccludedLayerContentRect(
1044 parent, gfx::Rect(31, 40, 69, 60)));
1045 EXPECT_RECT_EQ(gfx::Rect(),
1046 occlusion.UnoccludedLayerContentRect(
1047 parent, gfx::Rect(30, 41, 70, 59)));
1049 /* Justification for the above occlusion from |layer|:
1051 +---------------------+
1053 | 30 | rotate(90)
1054 | 30 + ------------+--------------------+
1055 100 | | 10 | | | ==>
1056 | |10+----------|----------------------+
1057 | + ------------+ | | |
1058 | | | | | |
1059 | | | | | |
1060 +----|--|-------------+ | |
1061 | | | |
1062 | | | |
1063 | | | |500
1064 | | | |
1065 | | | |
1066 | | | |
1067 | | | |
1068 +--|-------------------------------+ |
1070 +---------------------------------+
1074 +---------------------+
1075 | |30 Visible region of |layer|: /////
1076 | 30 60 | |child2|: \\\\\
1077 | 30 +------------+--------------------+
1078 | |\\\\\\\\\\\\| |10 |
1079 | +--|\\\\\\\\\\\\|-----------------+ |
1080 | | +------------+//| 420 | |
1081 | | |///////////////|60 | |
1082 | | |///////////////| | |
1083 +--|--|---------------+ | |
1084 20|10| 70 | |
1085 | | | |
1086 | | | |
1087 | | | |
1088 | | | |
1089 | | | |
1090 | | |10|
1091 | +------------------------------|--+
1092 | 490 |
1093 +---------------------------------+
1099 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
1101 template <class Types>
1102 class OcclusionTrackerTestSurfaceRotatedOffAxis
1103 : public OcclusionTrackerTest<Types> {
1104 protected:
1105 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
1106 : OcclusionTrackerTest<Types>(opaque_layers) {}
1107 void RunMyTest() {
1108 gfx::Transform child_transform;
1109 child_transform.Translate(250.0, 250.0);
1110 child_transform.Rotate(95.0);
1111 child_transform.Translate(-250.0, -250.0);
1113 gfx::Transform layer_transform;
1114 layer_transform.Translate(10.0, 10.0);
1116 typename Types::ContentLayerType* root = this->CreateRoot(
1117 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1118 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1119 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1120 typename Types::LayerType* child = this->CreateLayer(
1121 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1122 child->SetMasksToBounds(true);
1123 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1124 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
1125 this->CalcDrawEtc(root);
1127 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1128 gfx::Rect(0, 0, 1000, 1000));
1130 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect(
1131 layer_transform, layer->visible_content_rect());
1133 this->VisitLayer(layer, &occlusion);
1134 this->EnterContributingSurface(child, &occlusion);
1136 EXPECT_EQ(gfx::Rect().ToString(),
1137 occlusion.occlusion_from_outside_target().ToString());
1138 EXPECT_EQ(clipped_layer_in_child.ToString(),
1139 occlusion.occlusion_from_inside_target().ToString());
1141 this->LeaveContributingSurface(child, &occlusion);
1142 this->EnterLayer(parent, &occlusion);
1144 EXPECT_EQ(gfx::Rect().ToString(),
1145 occlusion.occlusion_from_outside_target().ToString());
1146 EXPECT_EQ(gfx::Rect().ToString(),
1147 occlusion.occlusion_from_inside_target().ToString());
1149 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
1150 EXPECT_RECT_EQ(
1151 gfx::Rect(75, 55, 1, 1),
1152 occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
1156 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
1158 template <class Types>
1159 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1160 : public OcclusionTrackerTest<Types> {
1161 protected:
1162 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
1163 : OcclusionTrackerTest<Types>(opaque_layers) {}
1164 void RunMyTest() {
1165 gfx::Transform child_transform;
1166 child_transform.Translate(250.0, 250.0);
1167 child_transform.Rotate(90.0);
1168 child_transform.Translate(-250.0, -250.0);
1170 typename Types::ContentLayerType* root = this->CreateRoot(
1171 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1172 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1173 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1174 parent->SetMasksToBounds(true);
1175 typename Types::ContentLayerType* child =
1176 this->CreateDrawingSurface(parent,
1177 child_transform,
1178 gfx::PointF(30.f, 30.f),
1179 gfx::Size(500, 500),
1180 false);
1181 child->SetMasksToBounds(true);
1182 typename Types::ContentLayerType* layer1 =
1183 this->CreateDrawingLayer(child,
1184 this->identity_matrix,
1185 gfx::PointF(10.f, 10.f),
1186 gfx::Size(500, 500),
1187 true);
1188 typename Types::ContentLayerType* layer2 =
1189 this->CreateDrawingLayer(child,
1190 this->identity_matrix,
1191 gfx::PointF(10.f, 450.f),
1192 gfx::Size(500, 60),
1193 true);
1194 this->CalcDrawEtc(root);
1196 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1197 gfx::Rect(0, 0, 1000, 1000));
1199 this->VisitLayer(layer2, &occlusion);
1200 this->VisitLayer(layer1, &occlusion);
1201 this->VisitLayer(child, &occlusion);
1202 this->EnterContributingSurface(child, &occlusion);
1204 EXPECT_EQ(gfx::Rect().ToString(),
1205 occlusion.occlusion_from_outside_target().ToString());
1206 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1207 occlusion.occlusion_from_inside_target().ToString());
1209 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
1210 EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
1211 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 59, 70)));
1212 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 69)));
1214 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1215 child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1216 EXPECT_RECT_EQ(
1217 gfx::Rect(9, 430, 1, 70),
1218 occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
1219 EXPECT_RECT_EQ(gfx::Rect(),
1220 occlusion.UnoccludedLayerContentRect(
1221 child, gfx::Rect(11, 430, 59, 70)));
1222 EXPECT_RECT_EQ(gfx::Rect(),
1223 occlusion.UnoccludedLayerContentRect(
1224 child, gfx::Rect(10, 431, 60, 69)));
1226 this->LeaveContributingSurface(child, &occlusion);
1227 this->EnterLayer(parent, &occlusion);
1229 EXPECT_EQ(gfx::Rect().ToString(),
1230 occlusion.occlusion_from_outside_target().ToString());
1231 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1232 occlusion.occlusion_from_inside_target().ToString());
1234 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1235 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1236 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1238 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1239 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1240 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1241 occlusion.UnoccludedLayerContentRect(
1242 parent, gfx::Rect(29, 40, 70, 60)));
1243 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1244 occlusion.UnoccludedLayerContentRect(
1245 parent, gfx::Rect(30, 39, 70, 60)));
1246 EXPECT_RECT_EQ(gfx::Rect(),
1247 occlusion.UnoccludedLayerContentRect(
1248 parent, gfx::Rect(31, 40, 69, 60)));
1249 EXPECT_RECT_EQ(gfx::Rect(),
1250 occlusion.UnoccludedLayerContentRect(
1251 parent, gfx::Rect(30, 41, 70, 59)));
1253 /* Justification for the above occlusion from |layer1| and |layer2|:
1255 +---------------------+
1256 | |30 Visible region of |layer1|: /////
1257 | | Visible region of |layer2|: \\\\\
1258 | +---------------------------------+
1259 | | |10 |
1260 | +---------------+-----------------+ |
1261 | | |\\\\\\\\\\\\|//| 420 | |
1262 | | |\\\\\\\\\\\\|//|60 | |
1263 | | |\\\\\\\\\\\\|//| | |
1264 +--|--|------------|--+ | |
1265 20|10| 70 | | |
1266 | | | | |
1267 | | | | |
1268 | | | | |
1269 | | | | |
1270 | | | | |
1271 | | | |10|
1272 | +------------|-----------------|--+
1273 | | 490 |
1274 +---------------+-----------------+
1275 60 440
1280 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1282 template <class Types>
1283 class OcclusionTrackerTestOverlappingSurfaceSiblings
1284 : public OcclusionTrackerTest<Types> {
1285 protected:
1286 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
1287 : OcclusionTrackerTest<Types>(opaque_layers) {}
1288 void RunMyTest() {
1289 gfx::Transform child_transform;
1290 child_transform.Translate(250.0, 250.0);
1291 child_transform.Rotate(90.0);
1292 child_transform.Translate(-250.0, -250.0);
1294 typename Types::ContentLayerType* parent = this->CreateRoot(
1295 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1296 parent->SetMasksToBounds(true);
1297 typename Types::LayerType* child1 = this->CreateSurface(
1298 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
1299 typename Types::LayerType* child2 = this->CreateSurface(
1300 parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
1301 typename Types::ContentLayerType* layer1 =
1302 this->CreateDrawingLayer(child1,
1303 this->identity_matrix,
1304 gfx::PointF(-10.f, -10.f),
1305 gfx::Size(510, 510),
1306 true);
1307 typename Types::ContentLayerType* layer2 =
1308 this->CreateDrawingLayer(child2,
1309 this->identity_matrix,
1310 gfx::PointF(-10.f, -10.f),
1311 gfx::Size(510, 510),
1312 true);
1313 this->CalcDrawEtc(parent);
1315 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1316 gfx::Rect(0, 0, 1000, 1000));
1318 this->VisitLayer(layer2, &occlusion);
1319 this->EnterContributingSurface(child2, &occlusion);
1321 EXPECT_EQ(gfx::Rect().ToString(),
1322 occlusion.occlusion_from_outside_target().ToString());
1323 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1324 occlusion.occlusion_from_inside_target().ToString());
1326 // There is nothing above child2's surface in the z-order.
1327 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1328 occlusion.UnoccludedContributingSurfaceContentRect(
1329 child2, false, gfx::Rect(-10, 420, 70, 80)));
1331 this->LeaveContributingSurface(child2, &occlusion);
1332 this->VisitLayer(layer1, &occlusion);
1333 this->EnterContributingSurface(child1, &occlusion);
1335 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1336 occlusion.occlusion_from_outside_target().ToString());
1337 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1338 occlusion.occlusion_from_inside_target().ToString());
1340 // child2's contents will occlude child1 below it.
1341 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1342 occlusion.UnoccludedContributingSurfaceContentRect(
1343 child1, false, gfx::Rect(-10, 430, 80, 70)));
1345 this->LeaveContributingSurface(child1, &occlusion);
1346 this->EnterLayer(parent, &occlusion);
1348 EXPECT_EQ(gfx::Rect().ToString(),
1349 occlusion.occlusion_from_outside_target().ToString());
1350 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1351 .ToString(),
1352 occlusion.occlusion_from_inside_target().ToString());
1354 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1356 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1357 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1358 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1360 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1361 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1362 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1364 /* Justification for the above occlusion:
1366 +---------------------+
1367 | 20 | layer1
1368 | 30+ ---------------------------------+
1369 100 | 30| | layer2 |
1370 |20+----------------------------------+ |
1371 | | | | | |
1372 | | | | | |
1373 | | | | | |
1374 +--|-|----------------+ | |
1375 | | | | 510
1376 | | | |
1377 | | | |
1378 | | | |
1379 | | | |
1380 | | | |
1381 | | | |
1382 | +--------------------------------|-+
1384 +----------------------------------+
1390 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1392 template <class Types>
1393 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1394 : public OcclusionTrackerTest<Types> {
1395 protected:
1396 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1397 bool opaque_layers)
1398 : OcclusionTrackerTest<Types>(opaque_layers) {}
1399 void RunMyTest() {
1400 gfx::Transform child1_transform;
1401 child1_transform.Translate(250.0, 250.0);
1402 child1_transform.Rotate(-90.0);
1403 child1_transform.Translate(-250.0, -250.0);
1405 gfx::Transform child2_transform;
1406 child2_transform.Translate(250.0, 250.0);
1407 child2_transform.Rotate(90.0);
1408 child2_transform.Translate(-250.0, -250.0);
1410 typename Types::ContentLayerType* parent = this->CreateRoot(
1411 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1412 parent->SetMasksToBounds(true);
1413 typename Types::LayerType* child1 = this->CreateSurface(
1414 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1415 typename Types::LayerType* child2 =
1416 this->CreateDrawingSurface(parent,
1417 child2_transform,
1418 gfx::PointF(20.f, 40.f),
1419 gfx::Size(10, 10),
1420 false);
1421 typename Types::ContentLayerType* layer1 =
1422 this->CreateDrawingLayer(child1,
1423 this->identity_matrix,
1424 gfx::PointF(-10.f, -20.f),
1425 gfx::Size(510, 510),
1426 true);
1427 typename Types::ContentLayerType* layer2 =
1428 this->CreateDrawingLayer(child2,
1429 this->identity_matrix,
1430 gfx::PointF(-10.f, -10.f),
1431 gfx::Size(510, 510),
1432 true);
1433 this->CalcDrawEtc(parent);
1435 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1436 gfx::Rect(0, 0, 1000, 1000));
1438 this->VisitLayer(layer2, &occlusion);
1439 this->EnterLayer(child2, &occlusion);
1441 EXPECT_EQ(gfx::Rect().ToString(),
1442 occlusion.occlusion_from_outside_target().ToString());
1443 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1444 occlusion.occlusion_from_inside_target().ToString());
1446 this->LeaveLayer(child2, &occlusion);
1447 this->EnterContributingSurface(child2, &occlusion);
1449 // There is nothing above child2's surface in the z-order.
1450 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1451 occlusion.UnoccludedContributingSurfaceContentRect(
1452 child2, false, gfx::Rect(-10, 420, 70, 80)));
1454 this->LeaveContributingSurface(child2, &occlusion);
1455 this->VisitLayer(layer1, &occlusion);
1456 this->EnterContributingSurface(child1, &occlusion);
1458 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1459 occlusion.occlusion_from_outside_target().ToString());
1460 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1461 occlusion.occlusion_from_inside_target().ToString());
1463 // child2's contents will occlude child1 below it.
1464 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1465 occlusion.UnoccludedContributingSurfaceContentRect(
1466 child1, false, gfx::Rect(420, -20, 80, 90)));
1467 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1468 occlusion.UnoccludedContributingSurfaceContentRect(
1469 child1, false, gfx::Rect(420, -10, 80, 90)));
1470 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1471 occlusion.UnoccludedContributingSurfaceContentRect(
1472 child1, false, gfx::Rect(420, -20, 70, 90)));
1474 this->LeaveContributingSurface(child1, &occlusion);
1475 this->EnterLayer(parent, &occlusion);
1477 EXPECT_EQ(gfx::Rect().ToString(),
1478 occlusion.occlusion_from_outside_target().ToString());
1479 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1480 occlusion.occlusion_from_inside_target().ToString());
1482 /* Justification for the above occlusion:
1484 +---------------------+
1485 |20 | layer1
1486 10+----------------------------------+
1487 100 || 30 | layer2 |
1488 |20+----------------------------------+
1489 || | | | |
1490 || | | | |
1491 || | | | |
1492 +|-|------------------+ | |
1493 | | | | 510
1494 | | 510 | |
1495 | | | |
1496 | | | |
1497 | | | |
1498 | | | |
1499 | | 520 | |
1500 +----------------------------------+ |
1502 +----------------------------------+
1508 ALL_OCCLUSIONTRACKER_TEST(
1509 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1511 template <class Types>
1512 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1513 protected:
1514 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1515 : OcclusionTrackerTest<Types>(opaque_layers) {}
1516 void RunMyTest() {
1517 gfx::Transform layer_transform;
1518 layer_transform.Translate(250.0, 250.0);
1519 layer_transform.Rotate(90.0);
1520 layer_transform.Translate(-250.0, -250.0);
1522 typename Types::ContentLayerType* parent = this->CreateRoot(
1523 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1524 parent->SetMasksToBounds(true);
1525 typename Types::ContentLayerType* blur_layer =
1526 this->CreateDrawingLayer(parent,
1527 layer_transform,
1528 gfx::PointF(30.f, 30.f),
1529 gfx::Size(500, 500),
1530 true);
1531 typename Types::ContentLayerType* opaque_layer =
1532 this->CreateDrawingLayer(parent,
1533 layer_transform,
1534 gfx::PointF(30.f, 30.f),
1535 gfx::Size(500, 500),
1536 true);
1537 typename Types::ContentLayerType* opacity_layer =
1538 this->CreateDrawingLayer(parent,
1539 layer_transform,
1540 gfx::PointF(30.f, 30.f),
1541 gfx::Size(500, 500),
1542 true);
1544 FilterOperations filters;
1545 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1546 blur_layer->SetFilters(filters);
1548 filters.Clear();
1549 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1550 opaque_layer->SetFilters(filters);
1552 filters.Clear();
1553 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1554 opacity_layer->SetFilters(filters);
1556 this->CalcDrawEtc(parent);
1558 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1559 gfx::Rect(0, 0, 1000, 1000));
1561 // Opacity layer won't contribute to occlusion.
1562 this->VisitLayer(opacity_layer, &occlusion);
1563 this->EnterContributingSurface(opacity_layer, &occlusion);
1565 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1566 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1568 // And has nothing to contribute to its parent surface.
1569 this->LeaveContributingSurface(opacity_layer, &occlusion);
1570 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1571 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1573 // Opaque layer will contribute to occlusion.
1574 this->VisitLayer(opaque_layer, &occlusion);
1575 this->EnterContributingSurface(opaque_layer, &occlusion);
1577 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1578 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1579 occlusion.occlusion_from_inside_target().ToString());
1581 // And it gets translated to the parent surface.
1582 this->LeaveContributingSurface(opaque_layer, &occlusion);
1583 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1584 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1585 occlusion.occlusion_from_inside_target().ToString());
1587 // The blur layer needs to throw away any occlusion from outside its
1588 // subtree.
1589 this->EnterLayer(blur_layer, &occlusion);
1590 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1591 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1593 // And it won't contribute to occlusion.
1594 this->LeaveLayer(blur_layer, &occlusion);
1595 this->EnterContributingSurface(blur_layer, &occlusion);
1596 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1597 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1599 // But the opaque layer's occlusion is preserved on the parent.
1600 this->LeaveContributingSurface(blur_layer, &occlusion);
1601 this->EnterLayer(parent, &occlusion);
1602 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1603 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1604 occlusion.occlusion_from_inside_target().ToString());
1608 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1610 template <class Types>
1611 class OcclusionTrackerTestReplicaDoesOcclude
1612 : public OcclusionTrackerTest<Types> {
1613 protected:
1614 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1615 : OcclusionTrackerTest<Types>(opaque_layers) {}
1616 void RunMyTest() {
1617 typename Types::ContentLayerType* parent = this->CreateRoot(
1618 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1619 typename Types::LayerType* surface =
1620 this->CreateDrawingSurface(parent,
1621 this->identity_matrix,
1622 gfx::PointF(0.f, 100.f),
1623 gfx::Size(50, 50),
1624 true);
1625 this->CreateReplicaLayer(
1626 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1627 this->CalcDrawEtc(parent);
1629 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1630 gfx::Rect(0, 0, 1000, 1000));
1632 this->VisitLayer(surface, &occlusion);
1634 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1635 occlusion.occlusion_from_inside_target().ToString());
1637 this->VisitContributingSurface(surface, &occlusion);
1638 this->EnterLayer(parent, &occlusion);
1640 // The surface and replica should both be occluding the parent.
1641 EXPECT_EQ(
1642 UnionRegions(gfx::Rect(0, 100, 50, 50),
1643 gfx::Rect(50, 150, 50, 50)).ToString(),
1644 occlusion.occlusion_from_inside_target().ToString());
1648 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1650 template <class Types>
1651 class OcclusionTrackerTestReplicaWithClipping
1652 : public OcclusionTrackerTest<Types> {
1653 protected:
1654 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1655 : OcclusionTrackerTest<Types>(opaque_layers) {}
1656 void RunMyTest() {
1657 typename Types::ContentLayerType* parent = this->CreateRoot(
1658 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1659 parent->SetMasksToBounds(true);
1660 typename Types::LayerType* surface =
1661 this->CreateDrawingSurface(parent,
1662 this->identity_matrix,
1663 gfx::PointF(0.f, 100.f),
1664 gfx::Size(50, 50),
1665 true);
1666 this->CreateReplicaLayer(
1667 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1668 this->CalcDrawEtc(parent);
1670 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1671 gfx::Rect(0, 0, 1000, 1000));
1673 this->VisitLayer(surface, &occlusion);
1675 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1676 occlusion.occlusion_from_inside_target().ToString());
1678 this->VisitContributingSurface(surface, &occlusion);
1679 this->EnterLayer(parent, &occlusion);
1681 // The surface and replica should both be occluding the parent.
1682 EXPECT_EQ(
1683 UnionRegions(gfx::Rect(0, 100, 50, 50),
1684 gfx::Rect(50, 150, 50, 20)).ToString(),
1685 occlusion.occlusion_from_inside_target().ToString());
1689 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1691 template <class Types>
1692 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1693 protected:
1694 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1695 : OcclusionTrackerTest<Types>(opaque_layers) {}
1696 void RunMyTest() {
1697 typename Types::ContentLayerType* parent = this->CreateRoot(
1698 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1699 typename Types::LayerType* surface =
1700 this->CreateDrawingSurface(parent,
1701 this->identity_matrix,
1702 gfx::PointF(0.f, 100.f),
1703 gfx::Size(50, 50),
1704 true);
1705 typename Types::LayerType* replica = this->CreateReplicaLayer(
1706 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1707 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1708 this->CalcDrawEtc(parent);
1710 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1711 gfx::Rect(0, 0, 1000, 1000));
1713 this->VisitLayer(surface, &occlusion);
1715 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1716 occlusion.occlusion_from_inside_target().ToString());
1718 this->VisitContributingSurface(surface, &occlusion);
1719 this->EnterLayer(parent, &occlusion);
1721 // The replica should not be occluding the parent, since it has a mask
1722 // applied to it.
1723 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1724 occlusion.occlusion_from_inside_target().ToString());
1728 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1730 template <class Types>
1731 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1732 : public OcclusionTrackerTest<Types> {
1733 protected:
1734 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1735 : OcclusionTrackerTest<Types>(opaque_layers) {}
1736 void RunMyTest() {
1737 typename Types::ContentLayerType* parent = this->CreateRoot(
1738 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1739 typename Types::ContentLayerType* layer =
1740 this->CreateDrawingSurface(parent,
1741 this->identity_matrix,
1742 gfx::PointF(),
1743 gfx::Size(200, 200),
1744 false);
1745 this->CalcDrawEtc(parent);
1747 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1748 gfx::Rect(0, 0, 1000, 1000));
1749 this->EnterLayer(layer, &occlusion);
1751 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1752 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1753 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1754 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1756 this->LeaveLayer(layer, &occlusion);
1757 this->VisitContributingSurface(layer, &occlusion);
1758 this->EnterLayer(parent, &occlusion);
1760 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1764 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1766 template <class Types>
1767 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1768 : public OcclusionTrackerTest<Types> {
1769 protected:
1770 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1771 : OcclusionTrackerTest<Types>(opaque_layers) {}
1772 void RunMyTest() {
1773 typename Types::ContentLayerType* parent = this->CreateRoot(
1774 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1775 typename Types::ContentLayerType* layer =
1776 this->CreateDrawingLayer(parent,
1777 this->identity_matrix,
1778 gfx::PointF(100.f, 100.f),
1779 gfx::Size(200, 200),
1780 false);
1781 this->CalcDrawEtc(parent);
1783 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1784 gfx::Rect(0, 0, 1000, 1000));
1785 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1787 this->ResetLayerIterator();
1788 this->VisitLayer(layer, &occlusion);
1789 this->EnterLayer(parent, &occlusion);
1791 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1792 occlusion.occlusion_from_inside_target().ToString());
1794 EXPECT_FALSE(
1795 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1796 EXPECT_TRUE(
1797 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1798 EXPECT_FALSE(
1799 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1802 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1803 gfx::Rect(0, 0, 1000, 1000));
1804 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1806 this->ResetLayerIterator();
1807 this->VisitLayer(layer, &occlusion);
1808 this->EnterLayer(parent, &occlusion);
1810 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1811 occlusion.occlusion_from_inside_target().ToString());
1813 EXPECT_FALSE(
1814 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1815 EXPECT_FALSE(
1816 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1817 EXPECT_TRUE(
1818 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1821 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1822 gfx::Rect(0, 0, 1000, 1000));
1823 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1825 this->ResetLayerIterator();
1826 this->VisitLayer(layer, &occlusion);
1827 this->EnterLayer(parent, &occlusion);
1829 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1830 occlusion.occlusion_from_inside_target().ToString());
1832 EXPECT_FALSE(
1833 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1834 EXPECT_FALSE(
1835 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1836 EXPECT_FALSE(
1837 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1842 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1844 template <class Types>
1845 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
1846 protected:
1847 explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
1848 : OcclusionTrackerTest<Types>(opaque_layers) {}
1849 void RunMyTest() {
1850 gfx::Transform transform;
1851 transform.RotateAboutYAxis(30.0);
1853 typename Types::ContentLayerType* parent = this->CreateRoot(
1854 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1855 typename Types::LayerType* container = this->CreateLayer(
1856 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1857 typename Types::ContentLayerType* layer =
1858 this->CreateDrawingLayer(container,
1859 transform,
1860 gfx::PointF(100.f, 100.f),
1861 gfx::Size(200, 200),
1862 true);
1863 this->CalcDrawEtc(parent);
1865 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1866 gfx::Rect(0, 0, 1000, 1000));
1867 this->EnterLayer(layer, &occlusion);
1869 // The layer is rotated in 3d but without preserving 3d, so it only gets
1870 // resized.
1871 EXPECT_RECT_EQ(
1872 gfx::Rect(0, 0, 200, 200),
1873 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1877 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
1879 template <class Types>
1880 class OcclusionTrackerTestUnsorted3dLayers
1881 : public OcclusionTrackerTest<Types> {
1882 protected:
1883 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
1884 : OcclusionTrackerTest<Types>(opaque_layers) {}
1885 void RunMyTest() {
1886 // Currently, The main thread layer iterator does not iterate over 3d items
1887 // in sorted order, because layer sorting is not performed on the main
1888 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1889 // layer occludes other layers that have not yet been iterated over. For
1890 // now, the expected behavior is that a 3d layer simply does not add any
1891 // occlusion to the occlusion tracker.
1893 gfx::Transform translation_to_front;
1894 translation_to_front.Translate3d(0.0, 0.0, -10.0);
1895 gfx::Transform translation_to_back;
1896 translation_to_front.Translate3d(0.0, 0.0, -100.0);
1898 typename Types::ContentLayerType* parent = this->CreateRoot(
1899 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1900 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
1901 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
1902 typename Types::ContentLayerType* child2 =
1903 this->CreateDrawingLayer(parent,
1904 translation_to_front,
1905 gfx::PointF(50.f, 50.f),
1906 gfx::Size(100, 100),
1907 true);
1908 parent->SetShouldFlattenTransform(false);
1909 parent->SetIs3dSorted(true);
1910 child1->SetIs3dSorted(true);
1911 child2->SetIs3dSorted(true);
1913 this->CalcDrawEtc(parent);
1915 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1916 gfx::Rect(0, 0, 1000, 1000));
1917 this->VisitLayer(child2, &occlusion);
1918 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1919 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1921 this->VisitLayer(child1, &occlusion);
1922 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1923 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1927 // This test will have different layer ordering on the impl thread; the test
1928 // will only work on the main thread.
1929 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1931 template <class Types>
1932 class OcclusionTrackerTestPerspectiveTransform
1933 : public OcclusionTrackerTest<Types> {
1934 protected:
1935 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
1936 : OcclusionTrackerTest<Types>(opaque_layers) {}
1937 void RunMyTest() {
1938 gfx::Transform transform;
1939 transform.Translate(150.0, 150.0);
1940 transform.ApplyPerspectiveDepth(400.0);
1941 transform.RotateAboutXAxis(-30.0);
1942 transform.Translate(-150.0, -150.0);
1944 typename Types::ContentLayerType* parent = this->CreateRoot(
1945 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1946 typename Types::LayerType* container = this->CreateLayer(
1947 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1948 typename Types::ContentLayerType* layer =
1949 this->CreateDrawingLayer(container,
1950 transform,
1951 gfx::PointF(100.f, 100.f),
1952 gfx::Size(200, 200),
1953 true);
1954 container->SetShouldFlattenTransform(false);
1955 container->SetIs3dSorted(true);
1956 layer->SetIs3dSorted(true);
1957 layer->SetShouldFlattenTransform(false);
1959 this->CalcDrawEtc(parent);
1961 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1962 gfx::Rect(0, 0, 1000, 1000));
1963 this->EnterLayer(layer, &occlusion);
1965 EXPECT_RECT_EQ(
1966 gfx::Rect(0, 0, 200, 200),
1967 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1971 // This test requires accumulating occlusion of 3d layers, which are skipped by
1972 // the occlusion tracker on the main thread. So this test should run on the impl
1973 // thread.
1974 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
1975 template <class Types>
1976 class OcclusionTrackerTestPerspectiveTransformBehindCamera
1977 : public OcclusionTrackerTest<Types> {
1978 protected:
1979 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
1980 bool opaque_layers)
1981 : OcclusionTrackerTest<Types>(opaque_layers) {}
1982 void RunMyTest() {
1983 // This test is based on the platform/chromium/compositing/3d-corners.html
1984 // layout test.
1985 gfx::Transform transform;
1986 transform.Translate(250.0, 50.0);
1987 transform.ApplyPerspectiveDepth(10.0);
1988 transform.Translate(-250.0, -50.0);
1989 transform.Translate(250.0, 50.0);
1990 transform.RotateAboutXAxis(-167.0);
1991 transform.Translate(-250.0, -50.0);
1993 typename Types::ContentLayerType* parent = this->CreateRoot(
1994 this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
1995 typename Types::LayerType* container = this->CreateLayer(
1996 parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
1997 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1998 container, transform, gfx::PointF(), gfx::Size(500, 500), true);
1999 container->SetShouldFlattenTransform(false);
2000 container->SetIs3dSorted(true);
2001 layer->SetShouldFlattenTransform(false);
2002 layer->SetIs3dSorted(true);
2003 this->CalcDrawEtc(parent);
2005 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2006 gfx::Rect(0, 0, 1000, 1000));
2007 this->EnterLayer(layer, &occlusion);
2009 // The bottom 11 pixel rows of this layer remain visible inside the
2010 // container, after translation to the target surface. When translated back,
2011 // this will include many more pixels but must include at least the bottom
2012 // 11 rows.
2013 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2014 layer, gfx::Rect(0, 26, 500, 474)).
2015 Contains(gfx::Rect(0, 489, 500, 11)));
2019 // This test requires accumulating occlusion of 3d layers, which are skipped by
2020 // the occlusion tracker on the main thread. So this test should run on the impl
2021 // thread.
2022 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2024 template <class Types>
2025 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2026 : public OcclusionTrackerTest<Types> {
2027 protected:
2028 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2029 bool opaque_layers)
2030 : OcclusionTrackerTest<Types>(opaque_layers) {}
2031 void RunMyTest() {
2032 gfx::Transform transform;
2033 transform.Translate(50.0, 50.0);
2034 transform.ApplyPerspectiveDepth(100.0);
2035 transform.Translate3d(0.0, 0.0, 110.0);
2036 transform.Translate(-50.0, -50.0);
2038 typename Types::ContentLayerType* parent = this->CreateRoot(
2039 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2040 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2041 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2042 parent->SetShouldFlattenTransform(false);
2043 parent->SetIs3dSorted(true);
2044 layer->SetShouldFlattenTransform(false);
2045 layer->SetIs3dSorted(true);
2046 this->CalcDrawEtc(parent);
2048 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2049 gfx::Rect(0, 0, 1000, 1000));
2051 // The |layer| is entirely behind the camera and should not occlude.
2052 this->VisitLayer(layer, &occlusion);
2053 this->EnterLayer(parent, &occlusion);
2054 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2055 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2059 // This test requires accumulating occlusion of 3d layers, which are skipped by
2060 // the occlusion tracker on the main thread. So this test should run on the impl
2061 // thread.
2062 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2064 template <class Types>
2065 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2066 : public OcclusionTrackerTest<Types> {
2067 protected:
2068 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2069 bool opaque_layers)
2070 : OcclusionTrackerTest<Types>(opaque_layers) {}
2071 void RunMyTest() {
2072 gfx::Transform transform;
2073 transform.Translate(50.0, 50.0);
2074 transform.ApplyPerspectiveDepth(100.0);
2075 transform.Translate3d(0.0, 0.0, 99.0);
2076 transform.Translate(-50.0, -50.0);
2078 typename Types::ContentLayerType* parent = this->CreateRoot(
2079 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2080 parent->SetMasksToBounds(true);
2081 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2082 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2083 parent->SetShouldFlattenTransform(false);
2084 parent->SetIs3dSorted(true);
2085 layer->SetShouldFlattenTransform(false);
2086 layer->SetIs3dSorted(true);
2087 this->CalcDrawEtc(parent);
2089 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2090 gfx::Rect(0, 0, 1000, 1000));
2092 // This is very close to the camera, so pixels in its visible_content_rect()
2093 // will actually go outside of the layer's clip rect. Ensure that those
2094 // pixels don't occlude things outside the clip rect.
2095 this->VisitLayer(layer, &occlusion);
2096 this->EnterLayer(parent, &occlusion);
2097 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2098 occlusion.occlusion_from_inside_target().ToString());
2099 EXPECT_EQ(gfx::Rect().ToString(),
2100 occlusion.occlusion_from_outside_target().ToString());
2104 // This test requires accumulating occlusion of 3d layers, which are skipped by
2105 // the occlusion tracker on the main thread. So this test should run on the impl
2106 // thread.
2107 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2109 template <class Types>
2110 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2111 : public OcclusionTrackerTest<Types> {
2112 protected:
2113 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
2114 : OcclusionTrackerTest<Types>(opaque_layers) {}
2115 void RunMyTest() {
2116 // parent
2117 // +--layer
2118 // +--surface
2119 // | +--surface_child
2120 // | +--surface_child2
2121 // +--parent2
2122 // +--topmost
2124 typename Types::ContentLayerType* parent = this->CreateRoot(
2125 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2126 typename Types::ContentLayerType* layer =
2127 this->CreateDrawingLayer(parent,
2128 this->identity_matrix,
2129 gfx::PointF(),
2130 gfx::Size(300, 300),
2131 true);
2132 typename Types::ContentLayerType* surface =
2133 this->CreateDrawingSurface(parent,
2134 this->identity_matrix,
2135 gfx::PointF(),
2136 gfx::Size(300, 300),
2137 true);
2138 typename Types::ContentLayerType* surface_child =
2139 this->CreateDrawingLayer(surface,
2140 this->identity_matrix,
2141 gfx::PointF(),
2142 gfx::Size(200, 300),
2143 true);
2144 typename Types::ContentLayerType* surface_child2 =
2145 this->CreateDrawingLayer(surface,
2146 this->identity_matrix,
2147 gfx::PointF(),
2148 gfx::Size(100, 300),
2149 true);
2150 typename Types::ContentLayerType* parent2 =
2151 this->CreateDrawingLayer(parent,
2152 this->identity_matrix,
2153 gfx::PointF(),
2154 gfx::Size(300, 300),
2155 false);
2156 typename Types::ContentLayerType* topmost =
2157 this->CreateDrawingLayer(parent,
2158 this->identity_matrix,
2159 gfx::PointF(250.f, 0.f),
2160 gfx::Size(50, 300),
2161 true);
2163 AddOpacityTransitionToController(
2164 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2165 AddOpacityTransitionToController(
2166 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2167 this->CalcDrawEtc(parent);
2169 EXPECT_TRUE(layer->draw_opacity_is_animating());
2170 EXPECT_FALSE(surface->draw_opacity_is_animating());
2171 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2173 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2174 gfx::Rect(0, 0, 1000, 1000));
2176 this->VisitLayer(topmost, &occlusion);
2177 this->EnterLayer(parent2, &occlusion);
2178 // This occlusion will affect all surfaces.
2179 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2180 occlusion.occlusion_from_inside_target().ToString());
2181 EXPECT_EQ(gfx::Rect().ToString(),
2182 occlusion.occlusion_from_outside_target().ToString());
2183 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2184 occlusion.UnoccludedLayerContentRect(
2185 parent2, gfx::Rect(0, 0, 300, 300)).ToString());
2186 this->LeaveLayer(parent2, &occlusion);
2188 this->VisitLayer(surface_child2, &occlusion);
2189 this->EnterLayer(surface_child, &occlusion);
2190 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2191 occlusion.occlusion_from_inside_target().ToString());
2192 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2193 occlusion.occlusion_from_outside_target().ToString());
2194 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2195 occlusion.UnoccludedLayerContentRect(
2196 surface_child, gfx::Rect(0, 0, 200, 300)));
2197 this->LeaveLayer(surface_child, &occlusion);
2198 this->EnterLayer(surface, &occlusion);
2199 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2200 occlusion.occlusion_from_inside_target().ToString());
2201 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2202 occlusion.occlusion_from_outside_target().ToString());
2203 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2204 occlusion.UnoccludedLayerContentRect(
2205 surface, gfx::Rect(0, 0, 300, 300)));
2206 this->LeaveLayer(surface, &occlusion);
2208 this->EnterContributingSurface(surface, &occlusion);
2209 // Occlusion within the surface is lost when leaving the animating surface.
2210 EXPECT_EQ(gfx::Rect().ToString(),
2211 occlusion.occlusion_from_inside_target().ToString());
2212 EXPECT_EQ(gfx::Rect().ToString(),
2213 occlusion.occlusion_from_outside_target().ToString());
2214 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2215 occlusion.UnoccludedContributingSurfaceContentRect(
2216 surface, false, gfx::Rect(0, 0, 300, 300)));
2217 this->LeaveContributingSurface(surface, &occlusion);
2219 // Occlusion from outside the animating surface still exists.
2220 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2221 occlusion.occlusion_from_inside_target().ToString());
2222 EXPECT_EQ(gfx::Rect().ToString(),
2223 occlusion.occlusion_from_outside_target().ToString());
2225 this->VisitLayer(layer, &occlusion);
2226 this->EnterLayer(parent, &occlusion);
2228 // Occlusion is not added for the animating |layer|.
2229 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2230 occlusion.UnoccludedLayerContentRect(
2231 parent, gfx::Rect(0, 0, 300, 300)));
2235 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2237 template <class Types>
2238 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2239 : public OcclusionTrackerTest<Types> {
2240 protected:
2241 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
2242 : OcclusionTrackerTest<Types>(opaque_layers) {}
2243 void RunMyTest() {
2244 typename Types::ContentLayerType* parent = this->CreateRoot(
2245 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2246 typename Types::ContentLayerType* layer =
2247 this->CreateDrawingLayer(parent,
2248 this->identity_matrix,
2249 gfx::PointF(),
2250 gfx::Size(300, 300),
2251 true);
2252 typename Types::ContentLayerType* surface =
2253 this->CreateDrawingSurface(parent,
2254 this->identity_matrix,
2255 gfx::PointF(),
2256 gfx::Size(300, 300),
2257 true);
2258 typename Types::ContentLayerType* surface_child =
2259 this->CreateDrawingLayer(surface,
2260 this->identity_matrix,
2261 gfx::PointF(),
2262 gfx::Size(200, 300),
2263 true);
2264 typename Types::ContentLayerType* surface_child2 =
2265 this->CreateDrawingLayer(surface,
2266 this->identity_matrix,
2267 gfx::PointF(),
2268 gfx::Size(100, 300),
2269 true);
2270 typename Types::ContentLayerType* parent2 =
2271 this->CreateDrawingLayer(parent,
2272 this->identity_matrix,
2273 gfx::PointF(),
2274 gfx::Size(300, 300),
2275 false);
2276 typename Types::ContentLayerType* topmost =
2277 this->CreateDrawingLayer(parent,
2278 this->identity_matrix,
2279 gfx::PointF(250.f, 0.f),
2280 gfx::Size(50, 300),
2281 true);
2283 AddOpacityTransitionToController(
2284 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2285 AddOpacityTransitionToController(
2286 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2287 this->CalcDrawEtc(parent);
2289 EXPECT_TRUE(layer->draw_opacity_is_animating());
2290 EXPECT_FALSE(surface->draw_opacity_is_animating());
2291 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2293 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2294 gfx::Rect(0, 0, 1000, 1000));
2296 this->VisitLayer(topmost, &occlusion);
2297 this->EnterLayer(parent2, &occlusion);
2298 // This occlusion will affect all surfaces.
2299 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2300 occlusion.occlusion_from_inside_target().ToString());
2301 EXPECT_EQ(gfx::Rect().ToString(),
2302 occlusion.occlusion_from_outside_target().ToString());
2303 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2304 occlusion.UnoccludedLayerContentRect(
2305 parent, gfx::Rect(0, 0, 300, 300)));
2306 this->LeaveLayer(parent2, &occlusion);
2308 this->VisitLayer(surface_child2, &occlusion);
2309 this->EnterLayer(surface_child, &occlusion);
2310 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2311 occlusion.occlusion_from_inside_target().ToString());
2312 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2313 occlusion.occlusion_from_outside_target().ToString());
2314 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2315 occlusion.UnoccludedLayerContentRect(
2316 surface_child, gfx::Rect(0, 0, 200, 300)));
2317 this->LeaveLayer(surface_child, &occlusion);
2318 this->EnterLayer(surface, &occlusion);
2319 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2320 occlusion.occlusion_from_inside_target().ToString());
2321 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2322 occlusion.occlusion_from_outside_target().ToString());
2323 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2324 occlusion.UnoccludedLayerContentRect(
2325 surface, gfx::Rect(0, 0, 300, 300)));
2326 this->LeaveLayer(surface, &occlusion);
2328 this->EnterContributingSurface(surface, &occlusion);
2329 // Occlusion within the surface is lost when leaving the animating surface.
2330 EXPECT_EQ(gfx::Rect().ToString(),
2331 occlusion.occlusion_from_inside_target().ToString());
2332 EXPECT_EQ(gfx::Rect().ToString(),
2333 occlusion.occlusion_from_outside_target().ToString());
2334 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2335 occlusion.UnoccludedContributingSurfaceContentRect(
2336 surface, false, gfx::Rect(0, 0, 300, 300)));
2337 this->LeaveContributingSurface(surface, &occlusion);
2339 // Occlusion from outside the animating surface still exists.
2340 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2341 occlusion.occlusion_from_inside_target().ToString());
2342 EXPECT_EQ(gfx::Rect().ToString(),
2343 occlusion.occlusion_from_outside_target().ToString());
2345 this->VisitLayer(layer, &occlusion);
2346 this->EnterLayer(parent, &occlusion);
2348 // Occlusion is not added for the animating |layer|.
2349 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2350 occlusion.UnoccludedLayerContentRect(
2351 parent, gfx::Rect(0, 0, 300, 300)));
2355 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2357 template <class Types>
2358 class OcclusionTrackerTestAnimationTranslateOnMainThread
2359 : public OcclusionTrackerTest<Types> {
2360 protected:
2361 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2362 bool opaque_layers)
2363 : OcclusionTrackerTest<Types>(opaque_layers) {}
2364 void RunMyTest() {
2365 typename Types::ContentLayerType* parent = this->CreateRoot(
2366 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2367 typename Types::ContentLayerType* layer =
2368 this->CreateDrawingLayer(parent,
2369 this->identity_matrix,
2370 gfx::PointF(),
2371 gfx::Size(300, 300),
2372 true);
2373 typename Types::ContentLayerType* surface =
2374 this->CreateDrawingSurface(parent,
2375 this->identity_matrix,
2376 gfx::PointF(),
2377 gfx::Size(300, 300),
2378 true);
2379 typename Types::ContentLayerType* surface_child =
2380 this->CreateDrawingLayer(surface,
2381 this->identity_matrix,
2382 gfx::PointF(),
2383 gfx::Size(200, 300),
2384 true);
2385 typename Types::ContentLayerType* surface_child2 =
2386 this->CreateDrawingLayer(surface,
2387 this->identity_matrix,
2388 gfx::PointF(),
2389 gfx::Size(100, 300),
2390 true);
2391 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
2392 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
2394 AddAnimatedTransformToController(
2395 layer->layer_animation_controller(), 10.0, 30, 0);
2396 AddAnimatedTransformToController(
2397 surface->layer_animation_controller(), 10.0, 30, 0);
2398 AddAnimatedTransformToController(
2399 surface_child->layer_animation_controller(), 10.0, 30, 0);
2400 this->CalcDrawEtc(parent);
2402 EXPECT_TRUE(layer->draw_transform_is_animating());
2403 EXPECT_TRUE(layer->screen_space_transform_is_animating());
2404 EXPECT_TRUE(
2405 surface->render_surface()->target_surface_transforms_are_animating());
2406 EXPECT_TRUE(
2407 surface->render_surface()->screen_space_transforms_are_animating());
2408 // The surface owning layer doesn't animate against its own surface.
2409 EXPECT_FALSE(surface->draw_transform_is_animating());
2410 EXPECT_TRUE(surface->screen_space_transform_is_animating());
2411 EXPECT_TRUE(surface_child->draw_transform_is_animating());
2412 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
2414 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2415 gfx::Rect(0, 0, 1000, 1000));
2417 this->VisitLayer(surface2, &occlusion);
2418 this->EnterContributingSurface(surface2, &occlusion);
2420 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2421 occlusion.occlusion_from_inside_target().ToString());
2423 this->LeaveContributingSurface(surface2, &occlusion);
2424 this->EnterLayer(surface_child2, &occlusion);
2425 // surface_child2 is moving in screen space but not relative to its target,
2426 // so occlusion should happen in its target space only. It also means that
2427 // things occluding from outside the target (e.g. surface2) cannot occlude
2428 // this layer.
2429 EXPECT_EQ(gfx::Rect().ToString(),
2430 occlusion.occlusion_from_outside_target().ToString());
2431 EXPECT_EQ(gfx::Rect().ToString(),
2432 occlusion.occlusion_from_inside_target().ToString());
2434 this->LeaveLayer(surface_child2, &occlusion);
2435 this->EnterLayer(surface_child, &occlusion);
2436 // surface_child2 added to the occlusion since it is not moving relative
2437 // to its target.
2438 EXPECT_EQ(gfx::Rect().ToString(),
2439 occlusion.occlusion_from_outside_target().ToString());
2440 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2441 occlusion.occlusion_from_inside_target().ToString());
2443 this->LeaveLayer(surface_child, &occlusion);
2444 // surface_child is moving relative to its target, so it does not add
2445 // occlusion.
2446 EXPECT_EQ(gfx::Rect().ToString(),
2447 occlusion.occlusion_from_outside_target().ToString());
2448 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2449 occlusion.occlusion_from_inside_target().ToString());
2451 this->EnterLayer(surface, &occlusion);
2452 EXPECT_EQ(gfx::Rect().ToString(),
2453 occlusion.occlusion_from_outside_target().ToString());
2454 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2455 occlusion.occlusion_from_inside_target().ToString());
2457 this->LeaveLayer(surface, &occlusion);
2458 // The surface's owning layer is moving in screen space but not relative to
2459 // its target, so it adds to the occlusion.
2460 EXPECT_EQ(gfx::Rect().ToString(),
2461 occlusion.occlusion_from_outside_target().ToString());
2462 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2463 occlusion.occlusion_from_inside_target().ToString());
2465 this->EnterContributingSurface(surface, &occlusion);
2466 this->LeaveContributingSurface(surface, &occlusion);
2467 // The |surface| is moving in the screen and in its target, so all occlusion
2468 // within the surface is lost when leaving it. Only the |surface2| occlusion
2469 // is left.
2470 EXPECT_EQ(gfx::Rect().ToString(),
2471 occlusion.occlusion_from_outside_target().ToString());
2472 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2473 occlusion.occlusion_from_inside_target().ToString());
2475 this->VisitLayer(layer, &occlusion);
2476 // The |layer| is animating in the screen and in its target, so no occlusion
2477 // is added.
2478 EXPECT_EQ(gfx::Rect().ToString(),
2479 occlusion.occlusion_from_outside_target().ToString());
2480 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2481 occlusion.occlusion_from_inside_target().ToString());
2485 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
2487 template <class Types>
2488 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2489 : public OcclusionTrackerTest<Types> {
2490 protected:
2491 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2492 bool opaque_layers)
2493 : OcclusionTrackerTest<Types>(opaque_layers) {}
2494 void RunMyTest() {
2495 gfx::Transform surface_transform;
2496 surface_transform.Translate(300.0, 300.0);
2497 surface_transform.Scale(2.0, 2.0);
2498 surface_transform.Translate(-150.0, -150.0);
2500 typename Types::ContentLayerType* parent = this->CreateRoot(
2501 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2502 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
2503 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
2504 typename Types::ContentLayerType* surface2 =
2505 this->CreateDrawingSurface(parent,
2506 this->identity_matrix,
2507 gfx::PointF(50.f, 50.f),
2508 gfx::Size(300, 300),
2509 false);
2510 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2511 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2512 this->CalcDrawEtc(parent);
2514 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2515 gfx::Rect(0, 0, 1000, 1000));
2517 this->VisitLayer(surface2, &occlusion);
2518 this->VisitContributingSurface(surface2, &occlusion);
2520 EXPECT_EQ(gfx::Rect().ToString(),
2521 occlusion.occlusion_from_outside_target().ToString());
2522 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2523 occlusion.occlusion_from_inside_target().ToString());
2525 // Clear any stored occlusion.
2526 occlusion.set_occlusion_from_outside_target(Region());
2527 occlusion.set_occlusion_from_inside_target(Region());
2529 this->VisitLayer(surface, &occlusion);
2530 this->VisitContributingSurface(surface, &occlusion);
2532 EXPECT_EQ(gfx::Rect().ToString(),
2533 occlusion.occlusion_from_outside_target().ToString());
2534 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2535 occlusion.occlusion_from_inside_target().ToString());
2539 MAIN_AND_IMPL_THREAD_TEST(
2540 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2542 template <class Types>
2543 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2544 : public OcclusionTrackerTest<Types> {
2545 protected:
2546 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2547 bool opaque_layers)
2548 : OcclusionTrackerTest<Types>(opaque_layers) {}
2549 void RunMyTest() {
2550 typename Types::ContentLayerType* parent = this->CreateRoot(
2551 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2552 parent->SetMasksToBounds(true);
2553 typename Types::ContentLayerType* surface =
2554 this->CreateDrawingSurface(parent,
2555 this->identity_matrix,
2556 gfx::PointF(),
2557 gfx::Size(500, 300),
2558 false);
2559 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2560 this->CalcDrawEtc(parent);
2562 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2563 gfx::Rect(0, 0, 1000, 1000));
2565 this->VisitLayer(surface, &occlusion);
2566 this->VisitContributingSurface(surface, &occlusion);
2568 EXPECT_EQ(gfx::Rect().ToString(),
2569 occlusion.occlusion_from_outside_target().ToString());
2570 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2571 occlusion.occlusion_from_inside_target().ToString());
2575 MAIN_AND_IMPL_THREAD_TEST(
2576 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2578 template <class Types>
2579 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
2580 protected:
2581 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
2582 : OcclusionTrackerTest<Types>(opaque_layers) {}
2583 void RunMyTest() {
2584 typename Types::ContentLayerType* parent = this->CreateRoot(
2585 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2586 typename Types::LayerType* surface =
2587 this->CreateDrawingSurface(parent,
2588 this->identity_matrix,
2589 gfx::PointF(),
2590 gfx::Size(100, 100),
2591 true);
2592 this->CreateReplicaLayer(surface,
2593 this->identity_matrix,
2594 gfx::PointF(0.f, 100.f),
2595 gfx::Size(100, 100));
2596 typename Types::LayerType* topmost =
2597 this->CreateDrawingLayer(parent,
2598 this->identity_matrix,
2599 gfx::PointF(0.f, 100.f),
2600 gfx::Size(100, 100),
2601 true);
2602 this->CalcDrawEtc(parent);
2604 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2605 gfx::Rect(0, 0, 1000, 1000));
2607 // |topmost| occludes the replica, but not the surface itself.
2608 this->VisitLayer(topmost, &occlusion);
2610 EXPECT_EQ(gfx::Rect().ToString(),
2611 occlusion.occlusion_from_outside_target().ToString());
2612 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2613 occlusion.occlusion_from_inside_target().ToString());
2615 this->VisitLayer(surface, &occlusion);
2617 // Render target with replica ignores occlusion from outside.
2618 EXPECT_EQ(gfx::Rect().ToString(),
2619 occlusion.occlusion_from_outside_target().ToString());
2620 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2621 occlusion.occlusion_from_inside_target().ToString());
2623 this->EnterContributingSurface(surface, &occlusion);
2625 // Surface is not occluded so it shouldn't think it is.
2626 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2627 occlusion.UnoccludedContributingSurfaceContentRect(
2628 surface, false, gfx::Rect(0, 0, 100, 100)));
2632 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
2634 template <class Types>
2635 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2636 : public OcclusionTrackerTest<Types> {
2637 protected:
2638 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
2639 : OcclusionTrackerTest<Types>(opaque_layers) {}
2640 void RunMyTest() {
2641 typename Types::ContentLayerType* parent = this->CreateRoot(
2642 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2643 typename Types::LayerType* surface =
2644 this->CreateDrawingSurface(parent,
2645 this->identity_matrix,
2646 gfx::PointF(),
2647 gfx::Size(100, 100),
2648 true);
2649 this->CreateReplicaLayer(surface,
2650 this->identity_matrix,
2651 gfx::PointF(0.f, 100.f),
2652 gfx::Size(100, 100));
2653 typename Types::LayerType* topmost =
2654 this->CreateDrawingLayer(parent,
2655 this->identity_matrix,
2656 gfx::PointF(),
2657 gfx::Size(100, 110),
2658 true);
2659 this->CalcDrawEtc(parent);
2661 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2662 gfx::Rect(0, 0, 1000, 1000));
2664 // |topmost| occludes the surface, but not the entire surface's replica.
2665 this->VisitLayer(topmost, &occlusion);
2667 EXPECT_EQ(gfx::Rect().ToString(),
2668 occlusion.occlusion_from_outside_target().ToString());
2669 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2670 occlusion.occlusion_from_inside_target().ToString());
2672 this->VisitLayer(surface, &occlusion);
2674 // Render target with replica ignores occlusion from outside.
2675 EXPECT_EQ(gfx::Rect().ToString(),
2676 occlusion.occlusion_from_outside_target().ToString());
2677 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2678 occlusion.occlusion_from_inside_target().ToString());
2680 this->EnterContributingSurface(surface, &occlusion);
2682 // Surface is occluded, but only the top 10px of the replica.
2683 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2684 occlusion.UnoccludedContributingSurfaceContentRect(
2685 surface, false, gfx::Rect(0, 0, 100, 100)));
2686 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2687 occlusion.UnoccludedContributingSurfaceContentRect(
2688 surface, true, gfx::Rect(0, 0, 100, 100)));
2692 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2694 template <class Types>
2695 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
2696 : public OcclusionTrackerTest<Types> {
2697 protected:
2698 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
2699 bool opaque_layers)
2700 : OcclusionTrackerTest<Types>(opaque_layers) {}
2701 void RunMyTest() {
2702 typename Types::ContentLayerType* parent = this->CreateRoot(
2703 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2704 typename Types::LayerType* surface =
2705 this->CreateDrawingSurface(parent,
2706 this->identity_matrix,
2707 gfx::PointF(),
2708 gfx::Size(100, 100),
2709 true);
2710 this->CreateReplicaLayer(surface,
2711 this->identity_matrix,
2712 gfx::PointF(0.f, 100.f),
2713 gfx::Size(100, 100));
2714 typename Types::LayerType* over_surface = this->CreateDrawingLayer(
2715 parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
2716 typename Types::LayerType* over_replica =
2717 this->CreateDrawingLayer(parent,
2718 this->identity_matrix,
2719 gfx::PointF(0.f, 100.f),
2720 gfx::Size(50, 100),
2721 true);
2722 this->CalcDrawEtc(parent);
2724 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2725 gfx::Rect(0, 0, 1000, 1000));
2727 // These occlude the surface and replica differently, so we can test each
2728 // one.
2729 this->VisitLayer(over_replica, &occlusion);
2730 this->VisitLayer(over_surface, &occlusion);
2732 EXPECT_EQ(gfx::Rect().ToString(),
2733 occlusion.occlusion_from_outside_target().ToString());
2734 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2735 .ToString(),
2736 occlusion.occlusion_from_inside_target().ToString());
2738 this->VisitLayer(surface, &occlusion);
2740 // Render target with replica ignores occlusion from outside.
2741 EXPECT_EQ(gfx::Rect().ToString(),
2742 occlusion.occlusion_from_outside_target().ToString());
2743 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2744 occlusion.occlusion_from_inside_target().ToString());
2746 this->EnterContributingSurface(surface, &occlusion);
2748 // Surface and replica are occluded different amounts.
2749 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
2750 occlusion.UnoccludedContributingSurfaceContentRect(
2751 surface, false, gfx::Rect(0, 0, 100, 100)));
2752 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2753 occlusion.UnoccludedContributingSurfaceContentRect(
2754 surface, true, gfx::Rect(0, 0, 100, 100)));
2758 ALL_OCCLUSIONTRACKER_TEST(
2759 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2761 template <class Types>
2762 class OcclusionTrackerTestSurfaceChildOfSurface
2763 : public OcclusionTrackerTest<Types> {
2764 protected:
2765 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
2766 : OcclusionTrackerTest<Types>(opaque_layers) {}
2767 void RunMyTest() {
2768 // This test verifies that the surface cliprect does not end up empty and
2769 // clip away the entire unoccluded rect.
2771 typename Types::ContentLayerType* parent = this->CreateRoot(
2772 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2773 typename Types::LayerType* surface =
2774 this->CreateDrawingSurface(parent,
2775 this->identity_matrix,
2776 gfx::PointF(),
2777 gfx::Size(100, 100),
2778 true);
2779 typename Types::LayerType* surface_child =
2780 this->CreateDrawingSurface(surface,
2781 this->identity_matrix,
2782 gfx::PointF(0.f, 10.f),
2783 gfx::Size(100, 50),
2784 true);
2785 typename Types::LayerType* topmost = this->CreateDrawingLayer(
2786 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2787 this->CalcDrawEtc(parent);
2789 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2790 gfx::Rect(-100, -100, 1000, 1000));
2792 // |topmost| occludes everything partially so we know occlusion is happening
2793 // at all.
2794 this->VisitLayer(topmost, &occlusion);
2796 EXPECT_EQ(gfx::Rect().ToString(),
2797 occlusion.occlusion_from_outside_target().ToString());
2798 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2799 occlusion.occlusion_from_inside_target().ToString());
2801 this->VisitLayer(surface_child, &occlusion);
2803 // surface_child increases the occlusion in the screen by a narrow sliver.
2804 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2805 occlusion.occlusion_from_outside_target().ToString());
2806 // In its own surface, surface_child is at 0,0 as is its occlusion.
2807 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2808 occlusion.occlusion_from_inside_target().ToString());
2810 // The root layer always has a clip rect. So the parent of |surface| has a
2811 // clip rect. However, the owning layer for |surface| does not mask to
2812 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2813 // |surface_child| exercises different code paths as its parent does not
2814 // have a clip rect.
2816 this->EnterContributingSurface(surface_child, &occlusion);
2817 // The surface_child's parent does not have a clip rect as it owns a render
2818 // surface. Make sure the unoccluded rect does not get clipped away
2819 // inappropriately.
2820 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
2821 occlusion.UnoccludedContributingSurfaceContentRect(
2822 surface_child, false, gfx::Rect(0, 0, 100, 50)));
2823 this->LeaveContributingSurface(surface_child, &occlusion);
2825 // When the surface_child's occlusion is transformed up to its parent, make
2826 // sure it is not clipped away inappropriately also.
2827 this->EnterLayer(surface, &occlusion);
2828 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2829 occlusion.occlusion_from_outside_target().ToString());
2830 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2831 occlusion.occlusion_from_inside_target().ToString());
2832 this->LeaveLayer(surface, &occlusion);
2834 this->EnterContributingSurface(surface, &occlusion);
2835 // The surface's parent does have a clip rect as it is the root layer.
2836 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
2837 occlusion.UnoccludedContributingSurfaceContentRect(
2838 surface, false, gfx::Rect(0, 0, 100, 100)));
2842 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2844 template <class Types>
2845 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
2846 : public OcclusionTrackerTest<Types> {
2847 protected:
2848 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
2849 bool opaque_layers)
2850 : OcclusionTrackerTest<Types>(opaque_layers) {}
2851 void RunMyTest() {
2852 // This test verifies that the top-most surface is considered occluded
2853 // outside of its target's clip rect and outside the viewport rect.
2855 typename Types::ContentLayerType* parent = this->CreateRoot(
2856 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2857 typename Types::LayerType* surface =
2858 this->CreateDrawingSurface(parent,
2859 this->identity_matrix,
2860 gfx::PointF(),
2861 gfx::Size(100, 300),
2862 true);
2863 this->CalcDrawEtc(parent);
2865 // Make a viewport rect that is larger than the root layer.
2866 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2867 gfx::Rect(0, 0, 1000, 1000));
2869 this->VisitLayer(surface, &occlusion);
2871 // The root layer always has a clip rect. So the parent of |surface| has a
2872 // clip rect giving the surface itself a clip rect.
2873 this->EnterContributingSurface(surface, &occlusion);
2874 // Make sure the parent's clip rect clips the unoccluded region of the
2875 // child surface.
2876 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
2877 occlusion.UnoccludedContributingSurfaceContentRect(
2878 surface, false, gfx::Rect(0, 0, 100, 300)));
2880 this->ResetLayerIterator();
2882 // Make a viewport rect that is smaller than the root layer.
2883 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2884 gfx::Rect(0, 0, 100, 100));
2886 this->VisitLayer(surface, &occlusion);
2888 // The root layer always has a clip rect. So the parent of |surface| has a
2889 // clip rect giving the surface itself a clip rect.
2890 this->EnterContributingSurface(surface, &occlusion);
2891 // Make sure the viewport rect clips the unoccluded region of the child
2892 // surface.
2893 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2894 occlusion.UnoccludedContributingSurfaceContentRect(
2895 surface, false, gfx::Rect(0, 0, 100, 300)));
2900 ALL_OCCLUSIONTRACKER_TEST(
2901 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
2903 template <class Types>
2904 class OcclusionTrackerTestSurfaceChildOfClippingSurface
2905 : public OcclusionTrackerTest<Types> {
2906 protected:
2907 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers)
2908 : OcclusionTrackerTest<Types>(opaque_layers) {}
2909 void RunMyTest() {
2910 // This test verifies that the surface cliprect does not end up empty and
2911 // clip away the entire unoccluded rect.
2913 typename Types::ContentLayerType* parent = this->CreateRoot(
2914 this->identity_matrix, gfx::PointF(), gfx::Size(80, 200));
2915 parent->SetMasksToBounds(true);
2916 typename Types::LayerType* surface =
2917 this->CreateDrawingSurface(parent,
2918 this->identity_matrix,
2919 gfx::PointF(),
2920 gfx::Size(100, 100),
2921 true);
2922 typename Types::LayerType* surface_child =
2923 this->CreateDrawingSurface(surface,
2924 this->identity_matrix,
2925 gfx::PointF(),
2926 gfx::Size(100, 100),
2927 false);
2928 typename Types::LayerType* topmost = this->CreateDrawingLayer(
2929 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2930 this->CalcDrawEtc(parent);
2932 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2933 gfx::Rect(0, 0, 1000, 1000));
2935 // |topmost| occludes everything partially so we know occlusion is happening
2936 // at all.
2937 this->VisitLayer(topmost, &occlusion);
2939 EXPECT_EQ(gfx::Rect().ToString(),
2940 occlusion.occlusion_from_outside_target().ToString());
2941 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
2942 occlusion.occlusion_from_inside_target().ToString());
2944 // surface_child is not opaque and does not occlude, so we have a non-empty
2945 // unoccluded area on surface.
2946 this->VisitLayer(surface_child, &occlusion);
2948 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
2949 occlusion.occlusion_from_outside_target().ToString());
2950 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
2951 occlusion.occlusion_from_inside_target().ToString());
2953 // The root layer always has a clip rect. So the parent of |surface| has a
2954 // clip rect. However, the owning layer for |surface| does not mask to
2955 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2956 // |surface_child| exercises different code paths as its parent does not
2957 // have a clip rect.
2959 this->EnterContributingSurface(surface_child, &occlusion);
2960 // The surface_child's parent does not have a clip rect as it owns a render
2961 // surface.
2962 EXPECT_EQ(
2963 gfx::Rect(0, 50, 80, 50).ToString(),
2964 occlusion.UnoccludedContributingSurfaceContentRect(
2965 surface_child, false, gfx::Rect(0, 0, 100, 100)).ToString());
2966 this->LeaveContributingSurface(surface_child, &occlusion);
2968 this->VisitLayer(surface, &occlusion);
2969 this->EnterContributingSurface(surface, &occlusion);
2970 // The surface's parent does have a clip rect as it is the root layer.
2971 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
2972 occlusion.UnoccludedContributingSurfaceContentRect(
2973 surface, false, gfx::Rect(0, 0, 100, 100)).ToString());
2977 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
2979 template <class Types>
2980 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2981 : public OcclusionTrackerTest<Types> {
2982 protected:
2983 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2984 bool opaque_layers)
2985 : OcclusionTrackerTest<Types>(opaque_layers) {}
2986 void RunMyTest() {
2987 gfx::Transform scale_by_half;
2988 scale_by_half.Scale(0.5, 0.5);
2990 // Make a 50x50 filtered surface that is completely surrounded by opaque
2991 // layers which are above it in the z-order. The surface is scaled to test
2992 // that the pixel moving is done in the target space, where the background
2993 // filter is applied.
2994 typename Types::ContentLayerType* parent = this->CreateRoot(
2995 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
2996 typename Types::LayerType* filtered_surface =
2997 this->CreateDrawingLayer(parent,
2998 scale_by_half,
2999 gfx::PointF(50.f, 50.f),
3000 gfx::Size(100, 100),
3001 false);
3002 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3003 parent, this->identity_matrix, gfx::PointF(), gfx::Size(200, 50), true);
3004 typename Types::LayerType* occluding_layer2 =
3005 this->CreateDrawingLayer(parent,
3006 this->identity_matrix,
3007 gfx::PointF(0.f, 100.f),
3008 gfx::Size(200, 50),
3009 true);
3010 typename Types::LayerType* occluding_layer3 =
3011 this->CreateDrawingLayer(parent,
3012 this->identity_matrix,
3013 gfx::PointF(0.f, 50.f),
3014 gfx::Size(50, 50),
3015 true);
3016 typename Types::LayerType* occluding_layer4 =
3017 this->CreateDrawingLayer(parent,
3018 this->identity_matrix,
3019 gfx::PointF(100.f, 50.f),
3020 gfx::Size(100, 50),
3021 true);
3023 // Filters make the layer own a surface.
3024 FilterOperations filters;
3025 filters.Append(FilterOperation::CreateBlurFilter(10.f));
3026 filtered_surface->SetBackgroundFilters(filters);
3028 // Save the distance of influence for the blur effect.
3029 int outset_top, outset_right, outset_bottom, outset_left;
3030 filters.GetOutsets(
3031 &outset_top, &outset_right, &outset_bottom, &outset_left);
3033 this->CalcDrawEtc(parent);
3035 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3036 gfx::Rect(0, 0, 1000, 1000));
3038 // These layers occlude pixels directly beside the filtered_surface. Because
3039 // filtered surface blends pixels in a radius, it will need to see some of
3040 // the pixels (up to radius far) underneath the occluding layers.
3041 this->VisitLayer(occluding_layer4, &occlusion);
3042 this->VisitLayer(occluding_layer3, &occlusion);
3043 this->VisitLayer(occluding_layer2, &occlusion);
3044 this->VisitLayer(occluding_layer1, &occlusion);
3046 Region expected_occlusion;
3047 expected_occlusion.Union(gfx::Rect(0, 0, 200, 50));
3048 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3049 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3050 expected_occlusion.Union(gfx::Rect(0, 100, 200, 50));
3052 EXPECT_EQ(expected_occlusion.ToString(),
3053 occlusion.occlusion_from_inside_target().ToString());
3054 EXPECT_EQ(gfx::Rect().ToString(),
3055 occlusion.occlusion_from_outside_target().ToString());
3057 this->VisitLayer(filtered_surface, &occlusion);
3059 // The filtered layer does not occlude.
3060 Region expected_occlusion_outside_surface;
3061 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 200, 50));
3062 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3063 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3064 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 200, 50));
3066 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3067 occlusion.occlusion_from_outside_target().ToString());
3068 EXPECT_EQ(gfx::Rect().ToString(),
3069 occlusion.occlusion_from_inside_target().ToString());
3071 // The surface has a background blur, so it needs pixels that are currently
3072 // considered occluded in order to be drawn. So the pixels it needs should
3073 // be removed some the occluded area so that when we get to the parent they
3074 // are drawn.
3075 this->VisitContributingSurface(filtered_surface, &occlusion);
3077 this->EnterLayer(parent, &occlusion);
3079 Region expected_blurred_occlusion;
3080 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 200, 50 - outset_top));
3081 expected_blurred_occlusion.Union(gfx::Rect(
3082 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
3083 expected_blurred_occlusion.Union(
3084 gfx::Rect(100 + outset_right,
3085 50 - outset_top,
3086 100 - outset_right,
3087 50 + outset_top + outset_bottom));
3088 expected_blurred_occlusion.Union(
3089 gfx::Rect(0, 100 + outset_bottom, 200, 50 - outset_bottom));
3091 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3092 occlusion.occlusion_from_inside_target().ToString());
3093 EXPECT_EQ(gfx::Rect().ToString(),
3094 occlusion.occlusion_from_outside_target().ToString());
3096 gfx::Rect outset_rect;
3097 gfx::Rect test_rect;
3099 // Nothing in the blur outsets for the filtered_surface is occluded.
3100 outset_rect = gfx::Rect(50 - outset_left,
3101 50 - outset_top,
3102 50 + outset_left + outset_right,
3103 50 + outset_top + outset_bottom);
3104 test_rect = outset_rect;
3105 EXPECT_EQ(
3106 outset_rect.ToString(),
3107 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3109 // Stuff outside the blur outsets is still occluded though.
3110 test_rect = outset_rect;
3111 test_rect.Inset(0, 0, -1, 0);
3112 EXPECT_EQ(
3113 outset_rect.ToString(),
3114 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3115 test_rect = outset_rect;
3116 test_rect.Inset(0, 0, 0, -1);
3117 EXPECT_EQ(
3118 outset_rect.ToString(),
3119 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3120 test_rect = outset_rect;
3121 test_rect.Inset(-1, 0, 0, 0);
3122 EXPECT_EQ(
3123 outset_rect.ToString(),
3124 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3125 test_rect = outset_rect;
3126 test_rect.Inset(0, -1, 0, 0);
3127 EXPECT_EQ(
3128 outset_rect.ToString(),
3129 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3133 ALL_OCCLUSIONTRACKER_TEST(
3134 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
3136 template <class Types>
3137 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3138 : public OcclusionTrackerTest<Types> {
3139 protected:
3140 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3141 bool opaque_layers)
3142 : OcclusionTrackerTest<Types>(opaque_layers) {}
3143 void RunMyTest() {
3144 gfx::Transform scale_by_half;
3145 scale_by_half.Scale(0.5, 0.5);
3147 // Makes two surfaces that completely cover |parent|. The occlusion both
3148 // above and below the filters will be reduced by each of them.
3149 typename Types::ContentLayerType* root = this->CreateRoot(
3150 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
3151 typename Types::LayerType* parent = this->CreateSurface(
3152 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
3153 parent->SetMasksToBounds(true);
3154 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
3155 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3156 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
3157 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3158 typename Types::LayerType* occluding_layer_above =
3159 this->CreateDrawingLayer(parent,
3160 this->identity_matrix,
3161 gfx::PointF(100.f, 100.f),
3162 gfx::Size(50, 50),
3163 true);
3165 // Filters make the layers own surfaces.
3166 FilterOperations filters;
3167 filters.Append(FilterOperation::CreateBlurFilter(1.f));
3168 filtered_surface1->SetBackgroundFilters(filters);
3169 filtered_surface2->SetBackgroundFilters(filters);
3171 // Save the distance of influence for the blur effect.
3172 int outset_top, outset_right, outset_bottom, outset_left;
3173 filters.GetOutsets(
3174 &outset_top, &outset_right, &outset_bottom, &outset_left);
3176 this->CalcDrawEtc(root);
3178 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3179 gfx::Rect(0, 0, 1000, 1000));
3181 this->VisitLayer(occluding_layer_above, &occlusion);
3182 EXPECT_EQ(gfx::Rect().ToString(),
3183 occlusion.occlusion_from_outside_target().ToString());
3184 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3185 occlusion.occlusion_from_inside_target().ToString());
3187 this->VisitLayer(filtered_surface2, &occlusion);
3188 this->VisitContributingSurface(filtered_surface2, &occlusion);
3189 this->VisitLayer(filtered_surface1, &occlusion);
3190 this->VisitContributingSurface(filtered_surface1, &occlusion);
3192 // Test expectations in the target.
3193 gfx::Rect expected_occlusion =
3194 gfx::Rect(100 / 2 + outset_right * 2,
3195 100 / 2 + outset_bottom * 2,
3196 50 / 2 - (outset_left + outset_right) * 2,
3197 50 / 2 - (outset_top + outset_bottom) * 2);
3198 EXPECT_EQ(expected_occlusion.ToString(),
3199 occlusion.occlusion_from_inside_target().ToString());
3201 // Test expectations in the screen are the same as in the target, as the
3202 // render surface is 1:1 with the screen.
3203 EXPECT_EQ(expected_occlusion.ToString(),
3204 occlusion.occlusion_from_outside_target().ToString());
3208 ALL_OCCLUSIONTRACKER_TEST(
3209 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
3211 template <class Types>
3212 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3213 : public OcclusionTrackerTest<Types> {
3214 protected:
3215 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3216 bool opaque_layers)
3217 : OcclusionTrackerTest<Types>(opaque_layers) {}
3218 void RunMyTest() {
3219 gfx::Transform scale_by_half;
3220 scale_by_half.Scale(0.5, 0.5);
3222 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3223 // centered below each. The surface is scaled to test that the pixel moving
3224 // is done in the target space, where the background filter is applied, but
3225 // the surface appears at 50, 50 and the replica at 200, 50.
3226 typename Types::ContentLayerType* parent = this->CreateRoot(
3227 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3228 typename Types::LayerType* behind_surface_layer =
3229 this->CreateDrawingLayer(parent,
3230 this->identity_matrix,
3231 gfx::PointF(60.f, 60.f),
3232 gfx::Size(30, 30),
3233 true);
3234 typename Types::LayerType* behind_replica_layer =
3235 this->CreateDrawingLayer(parent,
3236 this->identity_matrix,
3237 gfx::PointF(210.f, 60.f),
3238 gfx::Size(30, 30),
3239 true);
3240 typename Types::LayerType* filtered_surface =
3241 this->CreateDrawingLayer(parent,
3242 scale_by_half,
3243 gfx::PointF(50.f, 50.f),
3244 gfx::Size(100, 100),
3245 false);
3246 this->CreateReplicaLayer(filtered_surface,
3247 this->identity_matrix,
3248 gfx::PointF(300.f, 0.f),
3249 gfx::Size());
3251 // Filters make the layer own a surface.
3252 FilterOperations filters;
3253 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3254 filtered_surface->SetBackgroundFilters(filters);
3256 this->CalcDrawEtc(parent);
3258 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3259 gfx::Rect(0, 0, 1000, 1000));
3261 // The surface has a background blur, so it blurs non-opaque pixels below
3262 // it.
3263 this->VisitLayer(filtered_surface, &occlusion);
3264 this->VisitContributingSurface(filtered_surface, &occlusion);
3266 this->VisitLayer(behind_replica_layer, &occlusion);
3267 this->VisitLayer(behind_surface_layer, &occlusion);
3269 // The layers behind the surface are not blurred, and their occlusion does
3270 // not change, until we leave the surface. So it should not be modified by
3271 // the filter here.
3272 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
3273 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
3275 Region expected_opaque_bounds =
3276 UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
3277 EXPECT_EQ(expected_opaque_bounds.ToString(),
3278 occlusion.occlusion_from_inside_target().ToString());
3280 EXPECT_EQ(gfx::Rect().ToString(),
3281 occlusion.occlusion_from_outside_target().ToString());
3285 ALL_OCCLUSIONTRACKER_TEST(
3286 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
3288 template <class Types>
3289 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3290 : public OcclusionTrackerTest<Types> {
3291 protected:
3292 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3293 bool opaque_layers)
3294 : OcclusionTrackerTest<Types>(opaque_layers) {}
3295 void RunMyTest() {
3296 gfx::Transform scale_by_half;
3297 scale_by_half.Scale(0.5, 0.5);
3299 // Make a 50x50 filtered surface that is completely occluded by an opaque
3300 // layer which is above it in the z-order. The surface is
3301 // scaled to test that the pixel moving is done in the target space, where
3302 // the background filter is applied, but the surface appears at 50, 50.
3303 typename Types::ContentLayerType* parent = this->CreateRoot(
3304 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
3305 typename Types::LayerType* filtered_surface =
3306 this->CreateDrawingLayer(parent,
3307 scale_by_half,
3308 gfx::PointF(50.f, 50.f),
3309 gfx::Size(100, 100),
3310 false);
3311 typename Types::LayerType* occluding_layer =
3312 this->CreateDrawingLayer(parent,
3313 this->identity_matrix,
3314 gfx::PointF(50.f, 50.f),
3315 gfx::Size(50, 50),
3316 true);
3318 // Filters make the layer own a surface.
3319 FilterOperations filters;
3320 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3321 filtered_surface->SetBackgroundFilters(filters);
3323 this->CalcDrawEtc(parent);
3325 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3326 gfx::Rect(0, 0, 1000, 1000));
3328 this->VisitLayer(occluding_layer, &occlusion);
3330 this->VisitLayer(filtered_surface, &occlusion);
3332 // The layers above the filtered surface occlude from outside.
3333 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
3335 EXPECT_EQ(gfx::Rect().ToString(),
3336 occlusion.occlusion_from_inside_target().ToString());
3337 EXPECT_EQ(occlusion_above_surface.ToString(),
3338 occlusion.occlusion_from_outside_target().ToString());
3341 // The surface has a background blur, so it blurs non-opaque pixels below
3342 // it.
3343 this->VisitContributingSurface(filtered_surface, &occlusion);
3345 // The filter is completely occluded, so it should not blur anything and
3346 // reduce any occlusion.
3347 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
3349 EXPECT_EQ(occlusion_above_surface.ToString(),
3350 occlusion.occlusion_from_inside_target().ToString());
3351 EXPECT_EQ(gfx::Rect().ToString(),
3352 occlusion.occlusion_from_outside_target().ToString());
3357 ALL_OCCLUSIONTRACKER_TEST(
3358 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
3360 template <class Types>
3361 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3362 : public OcclusionTrackerTest<Types> {
3363 protected:
3364 explicit
3365 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3366 bool opaque_layers)
3367 : OcclusionTrackerTest<Types>(opaque_layers) {}
3368 void RunMyTest() {
3369 gfx::Transform scale_by_half;
3370 scale_by_half.Scale(0.5, 0.5);
3372 // Make a surface and its replica, each 50x50, that are partially occluded
3373 // by opaque layers which are above them in the z-order. The surface is
3374 // scaled to test that the pixel moving is done in the target space, where
3375 // the background filter is applied, but the surface appears at 50, 50 and
3376 // the replica at 200, 50.
3377 typename Types::ContentLayerType* parent = this->CreateRoot(
3378 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3379 typename Types::LayerType* filtered_surface =
3380 this->CreateDrawingLayer(parent,
3381 scale_by_half,
3382 gfx::PointF(50.f, 50.f),
3383 gfx::Size(100, 100),
3384 false);
3385 this->CreateReplicaLayer(filtered_surface,
3386 this->identity_matrix,
3387 gfx::PointF(300.f, 0.f),
3388 gfx::Size());
3389 typename Types::LayerType* above_surface_layer =
3390 this->CreateDrawingLayer(parent,
3391 this->identity_matrix,
3392 gfx::PointF(70.f, 50.f),
3393 gfx::Size(30, 50),
3394 true);
3395 typename Types::LayerType* above_replica_layer =
3396 this->CreateDrawingLayer(parent,
3397 this->identity_matrix,
3398 gfx::PointF(200.f, 50.f),
3399 gfx::Size(30, 50),
3400 true);
3401 typename Types::LayerType* beside_surface_layer =
3402 this->CreateDrawingLayer(parent,
3403 this->identity_matrix,
3404 gfx::PointF(90.f, 40.f),
3405 gfx::Size(10, 10),
3406 true);
3407 typename Types::LayerType* beside_replica_layer =
3408 this->CreateDrawingLayer(parent,
3409 this->identity_matrix,
3410 gfx::PointF(200.f, 40.f),
3411 gfx::Size(10, 10),
3412 true);
3414 // Filters make the layer own a surface.
3415 FilterOperations filters;
3416 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3417 filtered_surface->SetBackgroundFilters(filters);
3419 // Save the distance of influence for the blur effect.
3420 int outset_top, outset_right, outset_bottom, outset_left;
3421 filters.GetOutsets(
3422 &outset_top, &outset_right, &outset_bottom, &outset_left);
3424 this->CalcDrawEtc(parent);
3426 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3427 gfx::Rect(0, 0, 1000, 1000));
3429 this->VisitLayer(beside_replica_layer, &occlusion);
3430 this->VisitLayer(beside_surface_layer, &occlusion);
3431 this->VisitLayer(above_replica_layer, &occlusion);
3432 this->VisitLayer(above_surface_layer, &occlusion);
3434 // The surface has a background blur, so it blurs non-opaque pixels below
3435 // it.
3436 this->VisitLayer(filtered_surface, &occlusion);
3437 this->VisitContributingSurface(filtered_surface, &occlusion);
3439 // The filter in the surface and replica are partially unoccluded. Only the
3440 // unoccluded parts should reduce occlusion. This means it will push back
3441 // the occlusion that touches the unoccluded part (occlusion_above___), but
3442 // it will not touch occlusion_beside____ since that is not beside the
3443 // unoccluded part of the surface, even though it is beside the occluded
3444 // part of the surface.
3445 gfx::Rect occlusion_above_surface =
3446 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
3447 gfx::Rect occlusion_above_replica =
3448 gfx::Rect(200, 50, 30 - outset_left, 50);
3449 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
3450 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
3452 Region expected_occlusion;
3453 expected_occlusion.Union(occlusion_above_surface);
3454 expected_occlusion.Union(occlusion_above_replica);
3455 expected_occlusion.Union(occlusion_beside_surface);
3456 expected_occlusion.Union(occlusion_beside_replica);
3458 ASSERT_EQ(expected_occlusion.ToString(),
3459 occlusion.occlusion_from_inside_target().ToString());
3460 EXPECT_EQ(gfx::Rect().ToString(),
3461 occlusion.occlusion_from_outside_target().ToString());
3463 Region::Iterator expected_rects(expected_occlusion);
3464 Region::Iterator target_surface_rects(
3465 occlusion.occlusion_from_inside_target());
3466 for (; expected_rects.has_rect();
3467 expected_rects.next(), target_surface_rects.next()) {
3468 ASSERT_TRUE(target_surface_rects.has_rect());
3469 EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
3474 ALL_OCCLUSIONTRACKER_TEST(
3475 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
3477 template <class Types>
3478 class OcclusionTrackerTestMinimumTrackingSize
3479 : public OcclusionTrackerTest<Types> {
3480 protected:
3481 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
3482 : OcclusionTrackerTest<Types>(opaque_layers) {}
3483 void RunMyTest() {
3484 gfx::Size tracking_size(100, 100);
3485 gfx::Size below_tracking_size(99, 99);
3487 typename Types::ContentLayerType* parent = this->CreateRoot(
3488 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3489 typename Types::LayerType* large = this->CreateDrawingLayer(
3490 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
3491 typename Types::LayerType* small =
3492 this->CreateDrawingLayer(parent,
3493 this->identity_matrix,
3494 gfx::PointF(),
3495 below_tracking_size,
3496 true);
3497 this->CalcDrawEtc(parent);
3499 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3500 gfx::Rect(0, 0, 1000, 1000));
3501 occlusion.set_minimum_tracking_size(tracking_size);
3503 // The small layer is not tracked because it is too small.
3504 this->VisitLayer(small, &occlusion);
3506 EXPECT_EQ(gfx::Rect().ToString(),
3507 occlusion.occlusion_from_outside_target().ToString());
3508 EXPECT_EQ(gfx::Rect().ToString(),
3509 occlusion.occlusion_from_inside_target().ToString());
3511 // The large layer is tracked as it is large enough.
3512 this->VisitLayer(large, &occlusion);
3514 EXPECT_EQ(gfx::Rect().ToString(),
3515 occlusion.occlusion_from_outside_target().ToString());
3516 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
3517 occlusion.occlusion_from_inside_target().ToString());
3521 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
3523 template <class Types>
3524 class OcclusionTrackerTestScaledLayerIsClipped
3525 : public OcclusionTrackerTest<Types> {
3526 protected:
3527 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
3528 : OcclusionTrackerTest<Types>(opaque_layers) {}
3529 void RunMyTest() {
3530 gfx::Transform scale_transform;
3531 scale_transform.Scale(512.0, 512.0);
3533 typename Types::ContentLayerType* parent = this->CreateRoot(
3534 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3535 typename Types::LayerType* clip = this->CreateLayer(parent,
3536 this->identity_matrix,
3537 gfx::PointF(10.f, 10.f),
3538 gfx::Size(50, 50));
3539 clip->SetMasksToBounds(true);
3540 typename Types::LayerType* scale = this->CreateLayer(
3541 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3542 typename Types::LayerType* scaled = this->CreateDrawingLayer(
3543 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3544 this->CalcDrawEtc(parent);
3546 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3547 gfx::Rect(0, 0, 1000, 1000));
3549 this->VisitLayer(scaled, &occlusion);
3551 EXPECT_EQ(gfx::Rect().ToString(),
3552 occlusion.occlusion_from_outside_target().ToString());
3553 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3554 occlusion.occlusion_from_inside_target().ToString());
3558 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
3560 template <class Types>
3561 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3562 : public OcclusionTrackerTest<Types> {
3563 protected:
3564 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
3565 : OcclusionTrackerTest<Types>(opaque_layers) {}
3566 void RunMyTest() {
3567 gfx::Transform scale_transform;
3568 scale_transform.Scale(512.0, 512.0);
3570 typename Types::ContentLayerType* parent = this->CreateRoot(
3571 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3572 typename Types::LayerType* clip = this->CreateLayer(parent,
3573 this->identity_matrix,
3574 gfx::PointF(10.f, 10.f),
3575 gfx::Size(50, 50));
3576 clip->SetMasksToBounds(true);
3577 typename Types::LayerType* surface = this->CreateDrawingSurface(
3578 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
3579 typename Types::LayerType* scale = this->CreateLayer(
3580 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3581 typename Types::LayerType* scaled = this->CreateDrawingLayer(
3582 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3583 this->CalcDrawEtc(parent);
3585 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3586 gfx::Rect(0, 0, 1000, 1000));
3588 this->VisitLayer(scaled, &occlusion);
3589 this->VisitLayer(surface, &occlusion);
3590 this->VisitContributingSurface(surface, &occlusion);
3592 EXPECT_EQ(gfx::Rect().ToString(),
3593 occlusion.occlusion_from_outside_target().ToString());
3594 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3595 occlusion.occlusion_from_inside_target().ToString());
3599 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
3601 template <class Types>
3602 class OcclusionTrackerTestCopyRequestDoesOcclude
3603 : public OcclusionTrackerTest<Types> {
3604 protected:
3605 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
3606 : OcclusionTrackerTest<Types>(opaque_layers) {}
3607 void RunMyTest() {
3608 typename Types::ContentLayerType* root = this->CreateRoot(
3609 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3610 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3611 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3612 typename Types::LayerType* copy = this->CreateLayer(parent,
3613 this->identity_matrix,
3614 gfx::Point(100, 0),
3615 gfx::Size(200, 400));
3616 this->AddCopyRequest(copy);
3617 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3618 copy,
3619 this->identity_matrix,
3620 gfx::PointF(),
3621 gfx::Size(200, 400),
3622 true);
3623 this->CalcDrawEtc(root);
3625 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3626 gfx::Rect(0, 0, 1000, 1000));
3628 this->VisitLayer(copy_child, &occlusion);
3629 EXPECT_EQ(gfx::Rect().ToString(),
3630 occlusion.occlusion_from_outside_target().ToString());
3631 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3632 occlusion.occlusion_from_inside_target().ToString());
3634 // CopyRequests cause the layer to own a surface.
3635 this->VisitContributingSurface(copy, &occlusion);
3637 // The occlusion from the copy should be kept.
3638 EXPECT_EQ(gfx::Rect().ToString(),
3639 occlusion.occlusion_from_outside_target().ToString());
3640 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3641 occlusion.occlusion_from_inside_target().ToString());
3645 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
3647 template <class Types>
3648 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3649 : public OcclusionTrackerTest<Types> {
3650 protected:
3651 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3652 bool opaque_layers)
3653 : OcclusionTrackerTest<Types>(opaque_layers) {}
3654 void RunMyTest() {
3655 typename Types::ContentLayerType* root = this->CreateRoot(
3656 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3657 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3658 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3659 typename Types::LayerType* hide = this->CreateLayer(
3660 parent, this->identity_matrix, gfx::Point(), gfx::Size());
3661 typename Types::LayerType* copy = this->CreateLayer(
3662 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
3663 this->AddCopyRequest(copy);
3664 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3665 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
3667 // The |copy| layer is hidden but since it is being copied, it will be
3668 // drawn.
3669 hide->SetHideLayerAndSubtree(true);
3671 this->CalcDrawEtc(root);
3673 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3674 gfx::Rect(0, 0, 1000, 1000));
3676 this->VisitLayer(copy_child, &occlusion);
3677 EXPECT_EQ(gfx::Rect().ToString(),
3678 occlusion.occlusion_from_outside_target().ToString());
3679 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3680 occlusion.occlusion_from_inside_target().ToString());
3682 // CopyRequests cause the layer to own a surface.
3683 this->VisitContributingSurface(copy, &occlusion);
3685 // The occlusion from the copy should be dropped since it is hidden.
3686 EXPECT_EQ(gfx::Rect().ToString(),
3687 occlusion.occlusion_from_outside_target().ToString());
3688 EXPECT_EQ(gfx::Rect().ToString(),
3689 occlusion.occlusion_from_inside_target().ToString());
3693 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
3695 template <class Types>
3696 class OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
3697 : public OcclusionTrackerTest<Types> {
3698 protected:
3699 explicit OcclusionTrackerTestEmptyEventLayerDoesNotOcclude(
3700 bool opaque_layers)
3701 : OcclusionTrackerTest<Types>(opaque_layers) {}
3702 void RunMyTest() {
3703 typename Types::ContentLayerType* root = this->CreateRoot(
3704 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3705 typename Types::ContentLayerType* empty_layer = this->CreateDrawingLayer(
3706 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), true);
3707 this->SetDrawsContent(empty_layer, false);
3708 empty_layer->SetTouchEventHandlerRegion(gfx::Rect(10, 10, 10, 10));
3710 this->CalcDrawEtc(root);
3712 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3713 gfx::Rect(0, 0, 1000, 1000));
3715 this->VisitLayer(empty_layer, &occlusion);
3717 EXPECT_EQ(gfx::Rect().ToString(),
3718 occlusion.occlusion_from_outside_target().ToString());
3719 EXPECT_EQ(gfx::Rect().ToString(),
3720 occlusion.occlusion_from_inside_target().ToString());
3724 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude)
3726 } // namespace
3727 } // namespace cc