IndexedDB: fsync after transactions.
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob6b66c28b70a4ed62a38a95864cfaad51df9aa1f6
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/debug/overdraw_metrics.h"
10 #include "cc/layers/layer.h"
11 #include "cc/layers/layer_impl.h"
12 #include "cc/output/copy_output_request.h"
13 #include "cc/output/copy_output_result.h"
14 #include "cc/output/filter_operation.h"
15 #include "cc/output/filter_operations.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_impl_proxy.h"
18 #include "cc/test/fake_layer_tree_host.h"
19 #include "cc/test/fake_layer_tree_host_impl.h"
20 #include "cc/test/geometry_test_utils.h"
21 #include "cc/test/occlusion_tracker_test_common.h"
22 #include "cc/trees/layer_tree_host_common.h"
23 #include "cc/trees/single_thread_proxy.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/transform.h"
28 namespace cc {
29 namespace {
31 class TestContentLayer : public Layer {
32 public:
33 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
34 SetIsDrawable(true);
37 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
38 if (override_opaque_contents_rect_)
39 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
40 return Layer::VisibleContentOpaqueRegion();
42 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
43 override_opaque_contents_rect_ = true;
44 opaque_contents_rect_ = opaque_contents_rect;
47 private:
48 virtual ~TestContentLayer() {}
50 bool override_opaque_contents_rect_;
51 gfx::Rect opaque_contents_rect_;
54 class TestContentLayerImpl : public LayerImpl {
55 public:
56 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
57 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
58 SetDrawsContent(true);
61 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
62 if (override_opaque_contents_rect_)
63 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
64 return LayerImpl::VisibleContentOpaqueRegion();
66 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
67 override_opaque_contents_rect_ = true;
68 opaque_contents_rect_ = opaque_contents_rect;
71 private:
72 bool override_opaque_contents_rect_;
73 gfx::Rect opaque_contents_rect_;
76 static inline bool LayerImplDrawTransformIsUnknown(const Layer* layer) {
77 return layer->draw_transform_is_animating();
79 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl* layer) {
80 return false;
83 template <typename LayerType, typename RenderSurfaceType>
84 class TestOcclusionTrackerWithClip
85 : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> {
86 public:
87 TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect,
88 bool record_metrics_for_frame)
89 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(
90 viewport_rect,
91 record_metrics_for_frame) {}
92 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect)
93 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewport_rect,
94 false) {}
96 bool OccludedLayer(const LayerType* layer,
97 const gfx::Rect& content_rect) const {
98 DCHECK(layer->visible_content_rect().Contains(content_rect));
99 return this->Occluded(layer->render_target(),
100 content_rect,
101 layer->draw_transform(),
102 LayerImplDrawTransformIsUnknown(layer));
105 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
106 // layer. Simple wrapper around UnoccludedContentRect.
107 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
108 const gfx::Rect& content_rect) const {
109 DCHECK(layer->visible_content_rect().Contains(content_rect));
110 return this->UnoccludedContentRect(
111 layer->render_target(),
112 content_rect,
113 layer->draw_transform(),
114 LayerImplDrawTransformIsUnknown(layer));
118 struct OcclusionTrackerTestMainThreadTypes {
119 typedef Layer LayerType;
120 typedef FakeLayerTreeHost HostType;
121 typedef RenderSurface RenderSurfaceType;
122 typedef TestContentLayer ContentLayerType;
123 typedef scoped_refptr<Layer> LayerPtrType;
124 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
125 typedef LayerIterator<Layer,
126 RenderSurfaceLayerList,
127 RenderSurface,
128 LayerIteratorActions::FrontToBack> TestLayerIterator;
129 typedef OcclusionTracker OcclusionTrackerType;
131 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
132 static ContentLayerPtrType CreateContentLayer(HostType* host) {
133 return make_scoped_refptr(new ContentLayerType());
136 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
137 LayerPtrType ref(*layer);
138 *layer = NULL;
139 return ref;
142 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
143 LayerPtrType ref(*layer);
144 *layer = NULL;
145 return ref;
148 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
151 struct OcclusionTrackerTestImplThreadTypes {
152 typedef LayerImpl LayerType;
153 typedef LayerTreeImpl HostType;
154 typedef RenderSurfaceImpl RenderSurfaceType;
155 typedef TestContentLayerImpl ContentLayerType;
156 typedef scoped_ptr<LayerImpl> LayerPtrType;
157 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
158 typedef LayerIterator<LayerImpl,
159 LayerImplList,
160 RenderSurfaceImpl,
161 LayerIteratorActions::FrontToBack> TestLayerIterator;
162 typedef OcclusionTrackerImpl OcclusionTrackerType;
164 static LayerPtrType CreateLayer(HostType* host) {
165 return LayerImpl::Create(host, next_layer_impl_id++);
167 static ContentLayerPtrType CreateContentLayer(HostType* host) {
168 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
170 static int next_layer_impl_id;
172 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
173 return layer->Pass();
176 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
177 return layer->PassAs<LayerType>();
180 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
183 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
185 template <typename Types> class OcclusionTrackerTest : public testing::Test {
186 protected:
187 explicit OcclusionTrackerTest(bool opaque_layers)
188 : opaque_layers_(opaque_layers), host_(FakeLayerTreeHost::Create()) {}
190 virtual void RunMyTest() = 0;
192 virtual void TearDown() {
193 Types::DestroyLayer(&root_);
194 render_surface_layer_list_.reset();
195 render_surface_layer_list_impl_.clear();
196 replica_layers_.clear();
197 mask_layers_.clear();
200 typename Types::HostType* GetHost();
202 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
203 const gfx::PointF& position,
204 gfx::Size bounds) {
205 typename Types::ContentLayerPtrType layer(
206 Types::CreateContentLayer(GetHost()));
207 typename Types::ContentLayerType* layer_ptr = layer.get();
208 SetProperties(layer_ptr, transform, position, bounds);
210 DCHECK(!root_.get());
211 root_ = Types::PassLayerPtr(&layer);
213 SetRootLayerOnMainThread(layer_ptr);
215 return layer_ptr;
218 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
219 const gfx::Transform& transform,
220 const gfx::PointF& position,
221 gfx::Size bounds) {
222 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
223 typename Types::LayerType* layer_ptr = layer.get();
224 SetProperties(layer_ptr, transform, position, bounds);
225 parent->AddChild(Types::PassLayerPtr(&layer));
226 return layer_ptr;
229 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
230 const gfx::Transform& transform,
231 const gfx::PointF& position,
232 gfx::Size bounds) {
233 typename Types::LayerType* layer =
234 CreateLayer(parent, transform, position, bounds);
235 layer->SetForceRenderSurface(true);
236 return layer;
239 typename Types::ContentLayerType* CreateDrawingLayer(
240 typename Types::LayerType* parent,
241 const gfx::Transform& transform,
242 const gfx::PointF& position,
243 gfx::Size bounds,
244 bool opaque) {
245 typename Types::ContentLayerPtrType layer(
246 Types::CreateContentLayer(GetHost()));
247 typename Types::ContentLayerType* layer_ptr = layer.get();
248 SetProperties(layer_ptr, transform, position, bounds);
250 if (opaque_layers_) {
251 layer_ptr->SetContentsOpaque(opaque);
252 } else {
253 layer_ptr->SetContentsOpaque(false);
254 if (opaque)
255 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
256 else
257 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
260 parent->AddChild(Types::PassLayerPtr(&layer));
261 return layer_ptr;
264 typename Types::LayerType* CreateReplicaLayer(
265 typename Types::LayerType* owning_layer,
266 const gfx::Transform& transform,
267 const gfx::PointF& position,
268 gfx::Size bounds) {
269 typename Types::ContentLayerPtrType layer(
270 Types::CreateContentLayer(GetHost()));
271 typename Types::ContentLayerType* layer_ptr = layer.get();
272 SetProperties(layer_ptr, transform, position, bounds);
273 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
274 return layer_ptr;
277 typename Types::LayerType* CreateMaskLayer(
278 typename Types::LayerType* owning_layer,
279 gfx::Size bounds) {
280 typename Types::ContentLayerPtrType layer(
281 Types::CreateContentLayer(GetHost()));
282 typename Types::ContentLayerType* layer_ptr = layer.get();
283 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
284 SetMask(owning_layer, Types::PassLayerPtr(&layer));
285 return layer_ptr;
288 typename Types::ContentLayerType* CreateDrawingSurface(
289 typename Types::LayerType* parent,
290 const gfx::Transform& transform,
291 const gfx::PointF& position,
292 gfx::Size bounds,
293 bool opaque) {
294 typename Types::ContentLayerType* layer =
295 CreateDrawingLayer(parent, transform, position, bounds, opaque);
296 layer->SetForceRenderSurface(true);
297 return layer;
301 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
303 void AddCopyRequest(Layer* layer) {
304 layer->RequestCopyOfOutput(
305 CopyOutputRequest::CreateBitmapRequest(base::Bind(
306 &OcclusionTrackerTest<Types>::CopyOutputCallback,
307 base::Unretained(this))));
310 void AddCopyRequest(LayerImpl* layer) {
311 ScopedPtrVector<CopyOutputRequest> requests;
312 requests.push_back(
313 CopyOutputRequest::CreateBitmapRequest(base::Bind(
314 &OcclusionTrackerTest<Types>::CopyOutputCallback,
315 base::Unretained(this))));
316 layer->PassCopyRequests(&requests);
319 void CalcDrawEtc(TestContentLayerImpl* root) {
320 DCHECK(root == root_.get());
321 DCHECK(!root->render_surface());
323 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
324 root, root->bounds(), &render_surface_layer_list_impl_);
325 inputs.can_adjust_raster_scales = true;
326 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
328 layer_iterator_ = layer_iterator_begin_ =
329 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
332 void CalcDrawEtc(TestContentLayer* root) {
333 DCHECK(root == root_.get());
334 DCHECK(!root->render_surface());
336 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
337 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
338 root, root->bounds(), render_surface_layer_list_.get());
339 inputs.can_adjust_raster_scales = true;
340 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
342 layer_iterator_ = layer_iterator_begin_ =
343 Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
346 void SetDrawsContent(LayerImpl* layer_impl, bool draws_content) {
347 layer_impl->SetDrawsContent(draws_content);
350 void SetDrawsContent(Layer* layer, bool draws_content) {
351 layer->SetIsDrawable(draws_content);
354 void EnterLayer(typename Types::LayerType* layer,
355 typename Types::OcclusionTrackerType* occlusion) {
356 ASSERT_EQ(layer, *layer_iterator_);
357 ASSERT_TRUE(layer_iterator_.represents_itself());
358 occlusion->EnterLayer(layer_iterator_);
361 void LeaveLayer(typename Types::LayerType* layer,
362 typename Types::OcclusionTrackerType* occlusion) {
363 ASSERT_EQ(layer, *layer_iterator_);
364 ASSERT_TRUE(layer_iterator_.represents_itself());
365 occlusion->LeaveLayer(layer_iterator_);
366 ++layer_iterator_;
369 void VisitLayer(typename Types::LayerType* layer,
370 typename Types::OcclusionTrackerType* occlusion) {
371 EnterLayer(layer, occlusion);
372 LeaveLayer(layer, occlusion);
375 void EnterContributingSurface(
376 typename Types::LayerType* layer,
377 typename Types::OcclusionTrackerType* occlusion) {
378 ASSERT_EQ(layer, *layer_iterator_);
379 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
380 occlusion->EnterLayer(layer_iterator_);
381 occlusion->LeaveLayer(layer_iterator_);
382 ++layer_iterator_;
383 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
384 occlusion->EnterLayer(layer_iterator_);
387 void LeaveContributingSurface(
388 typename Types::LayerType* layer,
389 typename Types::OcclusionTrackerType* occlusion) {
390 ASSERT_EQ(layer, *layer_iterator_);
391 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
392 occlusion->LeaveLayer(layer_iterator_);
393 ++layer_iterator_;
396 void VisitContributingSurface(
397 typename Types::LayerType* layer,
398 typename Types::OcclusionTrackerType* occlusion) {
399 EnterContributingSurface(layer, occlusion);
400 LeaveContributingSurface(layer, occlusion);
403 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
405 const gfx::Transform identity_matrix;
407 private:
408 void SetRootLayerOnMainThread(Layer* root) {
409 host_->SetRootLayer(scoped_refptr<Layer>(root));
412 void SetRootLayerOnMainThread(LayerImpl* root) {}
414 void SetBaseProperties(typename Types::LayerType* layer,
415 const gfx::Transform& transform,
416 const gfx::PointF& position,
417 gfx::Size bounds) {
418 layer->SetTransform(transform);
419 layer->SetSublayerTransform(gfx::Transform());
420 layer->SetAnchorPoint(gfx::PointF());
421 layer->SetPosition(position);
422 layer->SetBounds(bounds);
425 void SetProperties(Layer* layer,
426 const gfx::Transform& transform,
427 const gfx::PointF& position,
428 gfx::Size bounds) {
429 SetBaseProperties(layer, transform, position, bounds);
432 void SetProperties(LayerImpl* layer,
433 const gfx::Transform& transform,
434 const gfx::PointF& position,
435 gfx::Size bounds) {
436 SetBaseProperties(layer, transform, position, bounds);
438 layer->SetContentBounds(layer->bounds());
441 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
442 owning_layer->SetReplicaLayer(layer.get());
443 replica_layers_.push_back(layer);
446 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
447 owning_layer->SetReplicaLayer(layer.Pass());
450 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
451 owning_layer->SetMaskLayer(layer.get());
452 mask_layers_.push_back(layer);
455 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
456 owning_layer->SetMaskLayer(layer.Pass());
459 bool opaque_layers_;
460 scoped_ptr<FakeLayerTreeHost> host_;
461 // These hold ownership of the layers for the duration of the test.
462 typename Types::LayerPtrType root_;
463 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
464 LayerImplList render_surface_layer_list_impl_;
465 typename Types::TestLayerIterator layer_iterator_begin_;
466 typename Types::TestLayerIterator layer_iterator_;
467 typename Types::LayerType* last_layer_visited_;
468 LayerList replica_layers_;
469 LayerList mask_layers_;
472 template <>
473 FakeLayerTreeHost*
474 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
475 return host_.get();
478 template <>
479 LayerTreeImpl*
480 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
481 return host_->host_impl()->active_tree();
484 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
485 class ClassName##MainThreadOpaqueLayers \
486 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
487 public: /* NOLINT(whitespace/indent) */ \
488 ClassName##MainThreadOpaqueLayers() \
489 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
490 }; \
491 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
492 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
493 class ClassName##MainThreadOpaquePaints \
494 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
495 public: /* NOLINT(whitespace/indent) */ \
496 ClassName##MainThreadOpaquePaints() \
497 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
498 }; \
499 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
501 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
502 class ClassName##ImplThreadOpaqueLayers \
503 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
504 public: /* NOLINT(whitespace/indent) */ \
505 ClassName##ImplThreadOpaqueLayers() \
506 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
507 }; \
508 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
509 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
510 class ClassName##ImplThreadOpaquePaints \
511 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
512 public: /* NOLINT(whitespace/indent) */ \
513 ClassName##ImplThreadOpaquePaints() \
514 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
515 }; \
516 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
518 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
519 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
520 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
521 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
522 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
524 #define MAIN_THREAD_TEST(ClassName) \
525 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
527 #define IMPL_THREAD_TEST(ClassName) \
528 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
530 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
531 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
532 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
534 template <class Types>
535 class OcclusionTrackerTestIdentityTransforms
536 : public OcclusionTrackerTest<Types> {
537 protected:
538 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
539 : OcclusionTrackerTest<Types>(opaque_layers) {}
541 void RunMyTest() {
542 typename Types::ContentLayerType* root = this->CreateRoot(
543 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
544 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
545 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
546 typename Types::ContentLayerType* layer =
547 this->CreateDrawingLayer(parent,
548 this->identity_matrix,
549 gfx::PointF(30.f, 30.f),
550 gfx::Size(500, 500),
551 true);
552 parent->SetMasksToBounds(true);
553 this->CalcDrawEtc(root);
555 TestOcclusionTrackerWithClip<typename Types::LayerType,
556 typename Types::RenderSurfaceType> occlusion(
557 gfx::Rect(0, 0, 1000, 1000), false);
559 this->VisitLayer(layer, &occlusion);
560 this->EnterLayer(parent, &occlusion);
562 EXPECT_EQ(gfx::Rect().ToString(),
563 occlusion.occlusion_from_outside_target().ToString());
564 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
565 occlusion.occlusion_from_inside_target().ToString());
567 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
568 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
569 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
570 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
571 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
573 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
574 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
575 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
576 occlusion.UnoccludedLayerContentRect(
577 parent, gfx::Rect(29, 30, 70, 70)));
578 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
579 occlusion.UnoccludedLayerContentRect(
580 parent, gfx::Rect(29, 29, 70, 70)));
581 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
582 occlusion.UnoccludedLayerContentRect(
583 parent, gfx::Rect(30, 29, 70, 70)));
584 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
585 occlusion.UnoccludedLayerContentRect(
586 parent, gfx::Rect(31, 29, 69, 70)));
587 EXPECT_RECT_EQ(gfx::Rect(),
588 occlusion.UnoccludedLayerContentRect(
589 parent, gfx::Rect(31, 30, 69, 70)));
590 EXPECT_RECT_EQ(gfx::Rect(),
591 occlusion.UnoccludedLayerContentRect(
592 parent, gfx::Rect(31, 31, 69, 69)));
593 EXPECT_RECT_EQ(gfx::Rect(),
594 occlusion.UnoccludedLayerContentRect(
595 parent, gfx::Rect(30, 31, 70, 69)));
596 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
597 occlusion.UnoccludedLayerContentRect(
598 parent, gfx::Rect(29, 31, 70, 69)));
602 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
604 template <class Types>
605 class OcclusionTrackerTestQuadsMismatchLayer
606 : public OcclusionTrackerTest<Types> {
607 protected:
608 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
609 : OcclusionTrackerTest<Types>(opaque_layers) {}
610 void RunMyTest() {
611 gfx::Transform layer_transform;
612 layer_transform.Translate(10.0, 10.0);
614 typename Types::ContentLayerType* parent = this->CreateRoot(
615 this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
616 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
617 parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
618 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
619 layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
620 this->CalcDrawEtc(parent);
622 TestOcclusionTrackerWithClip<typename Types::LayerType,
623 typename Types::RenderSurfaceType> occlusion(
624 gfx::Rect(0, 0, 1000, 1000));
626 this->VisitLayer(layer2, &occlusion);
627 this->EnterLayer(layer1, &occlusion);
629 EXPECT_EQ(gfx::Rect().ToString(),
630 occlusion.occlusion_from_outside_target().ToString());
631 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
632 occlusion.occlusion_from_inside_target().ToString());
634 // This checks cases where the quads don't match their "containing"
635 // layers, e.g. in terms of transforms or clip rect. This is typical for
636 // DelegatedRendererLayer.
638 gfx::Transform quad_transform;
639 quad_transform.Translate(30.0, 30.0);
641 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent,
642 gfx::Rect(0, 0, 10, 10),
643 quad_transform,
644 false).IsEmpty());
645 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
646 occlusion.UnoccludedContentRect(parent,
647 gfx::Rect(0, 0, 10, 10),
648 quad_transform,
649 true));
650 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
651 occlusion.UnoccludedContentRect(parent,
652 gfx::Rect(40, 40, 10, 10),
653 quad_transform,
654 false));
655 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
656 occlusion.UnoccludedContentRect(parent,
657 gfx::Rect(35, 30, 10, 10),
658 quad_transform,
659 false));
663 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
665 template <class Types>
666 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
667 protected:
668 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
669 : OcclusionTrackerTest<Types>(opaque_layers) {}
670 void RunMyTest() {
671 gfx::Transform layer_transform;
672 layer_transform.Translate(250.0, 250.0);
673 layer_transform.Rotate(90.0);
674 layer_transform.Translate(-250.0, -250.0);
676 typename Types::ContentLayerType* root = this->CreateRoot(
677 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
678 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
679 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
680 typename Types::ContentLayerType* layer =
681 this->CreateDrawingLayer(parent,
682 layer_transform,
683 gfx::PointF(30.f, 30.f),
684 gfx::Size(500, 500),
685 true);
686 parent->SetMasksToBounds(true);
687 this->CalcDrawEtc(root);
689 TestOcclusionTrackerWithClip<typename Types::LayerType,
690 typename Types::RenderSurfaceType> occlusion(
691 gfx::Rect(0, 0, 1000, 1000));
693 this->VisitLayer(layer, &occlusion);
694 this->EnterLayer(parent, &occlusion);
696 EXPECT_EQ(gfx::Rect().ToString(),
697 occlusion.occlusion_from_outside_target().ToString());
698 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
699 occlusion.occlusion_from_inside_target().ToString());
701 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
702 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
703 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
704 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
705 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
707 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
708 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
709 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
710 occlusion.UnoccludedLayerContentRect(
711 parent, gfx::Rect(29, 30, 69, 70)));
712 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
713 occlusion.UnoccludedLayerContentRect(
714 parent, gfx::Rect(29, 29, 70, 70)));
715 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
716 occlusion.UnoccludedLayerContentRect(
717 parent, gfx::Rect(30, 29, 70, 70)));
718 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
719 occlusion.UnoccludedLayerContentRect(
720 parent, gfx::Rect(31, 29, 69, 70)));
721 EXPECT_RECT_EQ(gfx::Rect(),
722 occlusion.UnoccludedLayerContentRect(
723 parent, gfx::Rect(31, 30, 69, 70)));
724 EXPECT_RECT_EQ(gfx::Rect(),
725 occlusion.UnoccludedLayerContentRect(
726 parent, gfx::Rect(31, 31, 69, 69)));
727 EXPECT_RECT_EQ(gfx::Rect(),
728 occlusion.UnoccludedLayerContentRect(
729 parent, gfx::Rect(30, 31, 70, 69)));
730 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
731 occlusion.UnoccludedLayerContentRect(
732 parent, gfx::Rect(29, 31, 70, 69)));
736 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
738 template <class Types>
739 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
740 protected:
741 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
742 : OcclusionTrackerTest<Types>(opaque_layers) {}
743 void RunMyTest() {
744 gfx::Transform layer_transform;
745 layer_transform.Translate(20.0, 20.0);
747 typename Types::ContentLayerType* root = this->CreateRoot(
748 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
749 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
750 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
751 typename Types::ContentLayerType* layer =
752 this->CreateDrawingLayer(parent,
753 layer_transform,
754 gfx::PointF(30.f, 30.f),
755 gfx::Size(500, 500),
756 true);
757 parent->SetMasksToBounds(true);
758 this->CalcDrawEtc(root);
760 TestOcclusionTrackerWithClip<typename Types::LayerType,
761 typename Types::RenderSurfaceType> occlusion(
762 gfx::Rect(0, 0, 1000, 1000));
764 this->VisitLayer(layer, &occlusion);
765 this->EnterLayer(parent, &occlusion);
767 EXPECT_EQ(gfx::Rect().ToString(),
768 occlusion.occlusion_from_outside_target().ToString());
769 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
770 occlusion.occlusion_from_inside_target().ToString());
772 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
773 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
774 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
775 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 49, 50)));
776 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 49)));
778 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
779 parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
780 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
781 occlusion.UnoccludedLayerContentRect(
782 parent, gfx::Rect(49, 50, 50, 50)));
783 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
784 occlusion.UnoccludedLayerContentRect(
785 parent, gfx::Rect(49, 49, 50, 50)));
786 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
787 occlusion.UnoccludedLayerContentRect(
788 parent, gfx::Rect(50, 49, 50, 50)));
789 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
790 occlusion.UnoccludedLayerContentRect(
791 parent, gfx::Rect(51, 49, 49, 50)));
792 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
793 parent, gfx::Rect(51, 50, 49, 50)).IsEmpty());
794 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
795 parent, gfx::Rect(51, 51, 49, 49)).IsEmpty());
796 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
797 parent, gfx::Rect(50, 51, 50, 49)).IsEmpty());
798 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
799 occlusion.UnoccludedLayerContentRect(
800 parent, gfx::Rect(49, 51, 50, 49)));
804 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
806 template <class Types>
807 class OcclusionTrackerTestChildInRotatedChild
808 : public OcclusionTrackerTest<Types> {
809 protected:
810 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
811 : OcclusionTrackerTest<Types>(opaque_layers) {}
812 void RunMyTest() {
813 gfx::Transform child_transform;
814 child_transform.Translate(250.0, 250.0);
815 child_transform.Rotate(90.0);
816 child_transform.Translate(-250.0, -250.0);
818 typename Types::ContentLayerType* parent = this->CreateRoot(
819 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
820 parent->SetMasksToBounds(true);
821 typename Types::LayerType* child = this->CreateSurface(
822 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
823 child->SetMasksToBounds(true);
824 typename Types::ContentLayerType* layer =
825 this->CreateDrawingLayer(child,
826 this->identity_matrix,
827 gfx::PointF(10.f, 10.f),
828 gfx::Size(500, 500),
829 true);
830 this->CalcDrawEtc(parent);
832 TestOcclusionTrackerWithClip<typename Types::LayerType,
833 typename Types::RenderSurfaceType> occlusion(
834 gfx::Rect(0, 0, 1000, 1000));
836 this->VisitLayer(layer, &occlusion);
837 this->EnterContributingSurface(child, &occlusion);
839 EXPECT_EQ(gfx::Rect().ToString(),
840 occlusion.occlusion_from_outside_target().ToString());
841 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
842 occlusion.occlusion_from_inside_target().ToString());
844 this->LeaveContributingSurface(child, &occlusion);
845 this->EnterLayer(parent, &occlusion);
847 EXPECT_EQ(gfx::Rect().ToString(),
848 occlusion.occlusion_from_outside_target().ToString());
849 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
850 occlusion.occlusion_from_inside_target().ToString());
852 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
853 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
854 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
855 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 69, 60)));
856 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 59)));
858 /* Justification for the above occlusion from |layer|:
860 +---------------------+
862 | 30 | rotate(90)
863 | 30 + ---------------------------------+
864 100 | | 10 | | ==>
865 | |10+---------------------------------+
866 | | | | | |
867 | | | | | |
868 | | | | | |
869 +----|--|-------------+ | |
870 | | | |
871 | | | |
872 | | | |500
873 | | | |
874 | | | |
875 | | | |
876 | | | |
877 +--|-------------------------------+ |
879 +---------------------------------+
882 +---------------------+
883 | |30 Visible region of |layer|: /////
885 | +---------------------------------+
886 100| | |10 |
887 | +---------------------------------+ |
888 | | |///////////////| 420 | |
889 | | |///////////////|60 | |
890 | | |///////////////| | |
891 +--|--|---------------+ | |
892 20|10| 70 | |
893 | | | |
894 | | | |
895 | | | |
896 | | | |
897 | | | |
898 | | |10|
899 | +------------------------------|--+
900 | 490 |
901 +---------------------------------+
908 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
910 template <class Types>
911 class OcclusionTrackerTestScaledRenderSurface
912 : public OcclusionTrackerTest<Types> {
913 protected:
914 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
915 : OcclusionTrackerTest<Types>(opaque_layers) {}
917 void RunMyTest() {
918 typename Types::ContentLayerType* parent = this->CreateRoot(
919 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
921 gfx::Transform layer1_matrix;
922 layer1_matrix.Scale(2.0, 2.0);
923 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
924 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
925 layer1->SetForceRenderSurface(true);
927 gfx::Transform layer2_matrix;
928 layer2_matrix.Translate(25.0, 25.0);
929 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
930 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
931 typename Types::ContentLayerType* occluder =
932 this->CreateDrawingLayer(parent,
933 this->identity_matrix,
934 gfx::PointF(100.f, 100.f),
935 gfx::Size(500, 500),
936 true);
937 this->CalcDrawEtc(parent);
939 TestOcclusionTrackerWithClip<typename Types::LayerType,
940 typename Types::RenderSurfaceType> occlusion(
941 gfx::Rect(0, 0, 1000, 1000));
943 this->VisitLayer(occluder, &occlusion);
944 this->EnterLayer(layer2, &occlusion);
946 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
947 occlusion.occlusion_from_outside_target().ToString());
948 EXPECT_EQ(gfx::Rect().ToString(),
949 occlusion.occlusion_from_inside_target().ToString());
951 EXPECT_RECT_EQ(
952 gfx::Rect(0, 0, 25, 25),
953 occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
954 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
955 occlusion.UnoccludedLayerContentRect(
956 layer2, gfx::Rect(10, 25, 25, 25)));
957 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
958 occlusion.UnoccludedLayerContentRect(
959 layer2, gfx::Rect(25, 10, 25, 25)));
960 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
961 layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
965 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
967 template <class Types>
968 class OcclusionTrackerTestVisitTargetTwoTimes
969 : public OcclusionTrackerTest<Types> {
970 protected:
971 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
972 : OcclusionTrackerTest<Types>(opaque_layers) {}
973 void RunMyTest() {
974 gfx::Transform child_transform;
975 child_transform.Translate(250.0, 250.0);
976 child_transform.Rotate(90.0);
977 child_transform.Translate(-250.0, -250.0);
979 typename Types::ContentLayerType* root = this->CreateRoot(
980 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
981 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
982 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
983 parent->SetMasksToBounds(true);
984 typename Types::LayerType* child = this->CreateSurface(
985 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
986 child->SetMasksToBounds(true);
987 typename Types::ContentLayerType* layer =
988 this->CreateDrawingLayer(child,
989 this->identity_matrix,
990 gfx::PointF(10.f, 10.f),
991 gfx::Size(500, 500),
992 true);
993 // |child2| makes |parent|'s surface get considered by OcclusionTracker
994 // first, instead of |child|'s. This exercises different code in
995 // LeaveToRenderTarget, as the target surface has already been seen.
996 typename Types::ContentLayerType* child2 =
997 this->CreateDrawingLayer(parent,
998 this->identity_matrix,
999 gfx::PointF(30.f, 30.f),
1000 gfx::Size(60, 20),
1001 true);
1002 this->CalcDrawEtc(root);
1004 TestOcclusionTrackerWithClip<typename Types::LayerType,
1005 typename Types::RenderSurfaceType> occlusion(
1006 gfx::Rect(0, 0, 1000, 1000));
1008 this->VisitLayer(child2, &occlusion);
1010 EXPECT_EQ(gfx::Rect().ToString(),
1011 occlusion.occlusion_from_outside_target().ToString());
1012 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1013 occlusion.occlusion_from_inside_target().ToString());
1015 this->VisitLayer(layer, &occlusion);
1017 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1018 occlusion.occlusion_from_outside_target().ToString());
1019 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1020 occlusion.occlusion_from_inside_target().ToString());
1022 this->EnterContributingSurface(child, &occlusion);
1024 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1025 occlusion.occlusion_from_outside_target().ToString());
1026 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1027 occlusion.occlusion_from_inside_target().ToString());
1029 // Occlusion in |child2| should get merged with the |child| surface we are
1030 // leaving now.
1031 this->LeaveContributingSurface(child, &occlusion);
1032 this->EnterLayer(parent, &occlusion);
1034 EXPECT_EQ(gfx::Rect().ToString(),
1035 occlusion.occlusion_from_outside_target().ToString());
1036 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1037 .ToString(),
1038 occlusion.occlusion_from_inside_target().ToString());
1040 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
1041 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1042 occlusion.UnoccludedLayerContentRect(
1043 parent, gfx::Rect(30, 30, 70, 70)));
1045 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
1046 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
1047 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
1048 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
1049 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
1051 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1052 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1053 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1055 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1056 parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1057 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1058 occlusion.UnoccludedLayerContentRect(
1059 parent, gfx::Rect(29, 30, 60, 10)));
1060 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1061 occlusion.UnoccludedLayerContentRect(
1062 parent, gfx::Rect(30, 29, 60, 10)));
1063 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1064 occlusion.UnoccludedLayerContentRect(
1065 parent, gfx::Rect(31, 30, 60, 10)));
1066 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1067 parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1069 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1070 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1071 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1072 occlusion.UnoccludedLayerContentRect(
1073 parent, gfx::Rect(29, 40, 70, 60)));
1074 // This rect is mostly occluded by |child2|.
1075 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1076 occlusion.UnoccludedLayerContentRect(
1077 parent, gfx::Rect(30, 39, 70, 60)));
1078 // This rect extends past top/right ends of |child2|.
1079 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1080 occlusion.UnoccludedLayerContentRect(
1081 parent, gfx::Rect(30, 29, 70, 70)));
1082 // This rect extends past left/right ends of |child2|.
1083 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1084 occlusion.UnoccludedLayerContentRect(
1085 parent, gfx::Rect(20, 39, 80, 60)));
1086 EXPECT_RECT_EQ(gfx::Rect(),
1087 occlusion.UnoccludedLayerContentRect(
1088 parent, gfx::Rect(31, 40, 69, 60)));
1089 EXPECT_RECT_EQ(gfx::Rect(),
1090 occlusion.UnoccludedLayerContentRect(
1091 parent, gfx::Rect(30, 41, 70, 59)));
1093 /* Justification for the above occlusion from |layer|:
1095 +---------------------+
1097 | 30 | rotate(90)
1098 | 30 + ------------+--------------------+
1099 100 | | 10 | | | ==>
1100 | |10+----------|----------------------+
1101 | + ------------+ | | |
1102 | | | | | |
1103 | | | | | |
1104 +----|--|-------------+ | |
1105 | | | |
1106 | | | |
1107 | | | |500
1108 | | | |
1109 | | | |
1110 | | | |
1111 | | | |
1112 +--|-------------------------------+ |
1114 +---------------------------------+
1118 +---------------------+
1119 | |30 Visible region of |layer|: /////
1120 | 30 60 | |child2|: \\\\\
1121 | 30 +------------+--------------------+
1122 | |\\\\\\\\\\\\| |10 |
1123 | +--|\\\\\\\\\\\\|-----------------+ |
1124 | | +------------+//| 420 | |
1125 | | |///////////////|60 | |
1126 | | |///////////////| | |
1127 +--|--|---------------+ | |
1128 20|10| 70 | |
1129 | | | |
1130 | | | |
1131 | | | |
1132 | | | |
1133 | | | |
1134 | | |10|
1135 | +------------------------------|--+
1136 | 490 |
1137 +---------------------------------+
1143 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
1145 template <class Types>
1146 class OcclusionTrackerTestSurfaceRotatedOffAxis
1147 : public OcclusionTrackerTest<Types> {
1148 protected:
1149 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
1150 : OcclusionTrackerTest<Types>(opaque_layers) {}
1151 void RunMyTest() {
1152 gfx::Transform child_transform;
1153 child_transform.Translate(250.0, 250.0);
1154 child_transform.Rotate(95.0);
1155 child_transform.Translate(-250.0, -250.0);
1157 gfx::Transform layer_transform;
1158 layer_transform.Translate(10.0, 10.0);
1160 typename Types::ContentLayerType* root = this->CreateRoot(
1161 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1162 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1163 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1164 typename Types::LayerType* child = this->CreateLayer(
1165 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1166 child->SetMasksToBounds(true);
1167 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1168 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
1169 this->CalcDrawEtc(root);
1171 TestOcclusionTrackerWithClip<typename Types::LayerType,
1172 typename Types::RenderSurfaceType> occlusion(
1173 gfx::Rect(0, 0, 1000, 1000));
1175 gfx::Rect clipped_layer_in_child = MathUtil::MapClippedRect(
1176 layer_transform, layer->visible_content_rect());
1178 this->VisitLayer(layer, &occlusion);
1179 this->EnterContributingSurface(child, &occlusion);
1181 EXPECT_EQ(gfx::Rect().ToString(),
1182 occlusion.occlusion_from_outside_target().ToString());
1183 EXPECT_EQ(clipped_layer_in_child.ToString(),
1184 occlusion.occlusion_from_inside_target().ToString());
1186 this->LeaveContributingSurface(child, &occlusion);
1187 this->EnterLayer(parent, &occlusion);
1189 EXPECT_EQ(gfx::Rect().ToString(),
1190 occlusion.occlusion_from_outside_target().ToString());
1191 EXPECT_EQ(gfx::Rect().ToString(),
1192 occlusion.occlusion_from_inside_target().ToString());
1194 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
1195 EXPECT_RECT_EQ(
1196 gfx::Rect(75, 55, 1, 1),
1197 occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
1201 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
1203 template <class Types>
1204 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1205 : public OcclusionTrackerTest<Types> {
1206 protected:
1207 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
1208 : OcclusionTrackerTest<Types>(opaque_layers) {}
1209 void RunMyTest() {
1210 gfx::Transform child_transform;
1211 child_transform.Translate(250.0, 250.0);
1212 child_transform.Rotate(90.0);
1213 child_transform.Translate(-250.0, -250.0);
1215 typename Types::ContentLayerType* root = this->CreateRoot(
1216 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1217 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1218 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1219 parent->SetMasksToBounds(true);
1220 typename Types::ContentLayerType* child =
1221 this->CreateDrawingSurface(parent,
1222 child_transform,
1223 gfx::PointF(30.f, 30.f),
1224 gfx::Size(500, 500),
1225 false);
1226 child->SetMasksToBounds(true);
1227 typename Types::ContentLayerType* layer1 =
1228 this->CreateDrawingLayer(child,
1229 this->identity_matrix,
1230 gfx::PointF(10.f, 10.f),
1231 gfx::Size(500, 500),
1232 true);
1233 typename Types::ContentLayerType* layer2 =
1234 this->CreateDrawingLayer(child,
1235 this->identity_matrix,
1236 gfx::PointF(10.f, 450.f),
1237 gfx::Size(500, 60),
1238 true);
1239 this->CalcDrawEtc(root);
1241 TestOcclusionTrackerWithClip<typename Types::LayerType,
1242 typename Types::RenderSurfaceType> occlusion(
1243 gfx::Rect(0, 0, 1000, 1000));
1245 this->VisitLayer(layer2, &occlusion);
1246 this->VisitLayer(layer1, &occlusion);
1247 this->VisitLayer(child, &occlusion);
1248 this->EnterContributingSurface(child, &occlusion);
1250 EXPECT_EQ(gfx::Rect().ToString(),
1251 occlusion.occlusion_from_outside_target().ToString());
1252 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1253 occlusion.occlusion_from_inside_target().ToString());
1255 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
1256 EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
1257 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 59, 70)));
1258 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 69)));
1260 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1261 child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1262 EXPECT_RECT_EQ(
1263 gfx::Rect(9, 430, 1, 70),
1264 occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
1265 EXPECT_RECT_EQ(gfx::Rect(),
1266 occlusion.UnoccludedLayerContentRect(
1267 child, gfx::Rect(11, 430, 59, 70)));
1268 EXPECT_RECT_EQ(gfx::Rect(),
1269 occlusion.UnoccludedLayerContentRect(
1270 child, gfx::Rect(10, 431, 60, 69)));
1272 this->LeaveContributingSurface(child, &occlusion);
1273 this->EnterLayer(parent, &occlusion);
1275 EXPECT_EQ(gfx::Rect().ToString(),
1276 occlusion.occlusion_from_outside_target().ToString());
1277 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1278 occlusion.occlusion_from_inside_target().ToString());
1280 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1281 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1282 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1284 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1285 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1286 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1287 occlusion.UnoccludedLayerContentRect(
1288 parent, gfx::Rect(29, 40, 70, 60)));
1289 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1290 occlusion.UnoccludedLayerContentRect(
1291 parent, gfx::Rect(30, 39, 70, 60)));
1292 EXPECT_RECT_EQ(gfx::Rect(),
1293 occlusion.UnoccludedLayerContentRect(
1294 parent, gfx::Rect(31, 40, 69, 60)));
1295 EXPECT_RECT_EQ(gfx::Rect(),
1296 occlusion.UnoccludedLayerContentRect(
1297 parent, gfx::Rect(30, 41, 70, 59)));
1299 /* Justification for the above occlusion from |layer1| and |layer2|:
1301 +---------------------+
1302 | |30 Visible region of |layer1|: /////
1303 | | Visible region of |layer2|: \\\\\
1304 | +---------------------------------+
1305 | | |10 |
1306 | +---------------+-----------------+ |
1307 | | |\\\\\\\\\\\\|//| 420 | |
1308 | | |\\\\\\\\\\\\|//|60 | |
1309 | | |\\\\\\\\\\\\|//| | |
1310 +--|--|------------|--+ | |
1311 20|10| 70 | | |
1312 | | | | |
1313 | | | | |
1314 | | | | |
1315 | | | | |
1316 | | | | |
1317 | | | |10|
1318 | +------------|-----------------|--+
1319 | | 490 |
1320 +---------------+-----------------+
1321 60 440
1326 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1328 template <class Types>
1329 class OcclusionTrackerTestOverlappingSurfaceSiblings
1330 : public OcclusionTrackerTest<Types> {
1331 protected:
1332 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
1333 : OcclusionTrackerTest<Types>(opaque_layers) {}
1334 void RunMyTest() {
1335 gfx::Transform child_transform;
1336 child_transform.Translate(250.0, 250.0);
1337 child_transform.Rotate(90.0);
1338 child_transform.Translate(-250.0, -250.0);
1340 typename Types::ContentLayerType* parent = this->CreateRoot(
1341 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1342 parent->SetMasksToBounds(true);
1343 typename Types::LayerType* child1 = this->CreateSurface(
1344 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
1345 typename Types::LayerType* child2 = this->CreateSurface(
1346 parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
1347 typename Types::ContentLayerType* layer1 =
1348 this->CreateDrawingLayer(child1,
1349 this->identity_matrix,
1350 gfx::PointF(-10.f, -10.f),
1351 gfx::Size(510, 510),
1352 true);
1353 typename Types::ContentLayerType* layer2 =
1354 this->CreateDrawingLayer(child2,
1355 this->identity_matrix,
1356 gfx::PointF(-10.f, -10.f),
1357 gfx::Size(510, 510),
1358 true);
1359 this->CalcDrawEtc(parent);
1361 TestOcclusionTrackerWithClip<typename Types::LayerType,
1362 typename Types::RenderSurfaceType> occlusion(
1363 gfx::Rect(0, 0, 1000, 1000));
1365 this->VisitLayer(layer2, &occlusion);
1366 this->EnterContributingSurface(child2, &occlusion);
1368 EXPECT_EQ(gfx::Rect().ToString(),
1369 occlusion.occlusion_from_outside_target().ToString());
1370 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1371 occlusion.occlusion_from_inside_target().ToString());
1373 // There is nothing above child2's surface in the z-order.
1374 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1375 occlusion.UnoccludedContributingSurfaceContentRect(
1376 child2, false, gfx::Rect(-10, 420, 70, 80)));
1378 this->LeaveContributingSurface(child2, &occlusion);
1379 this->VisitLayer(layer1, &occlusion);
1380 this->EnterContributingSurface(child1, &occlusion);
1382 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1383 occlusion.occlusion_from_outside_target().ToString());
1384 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1385 occlusion.occlusion_from_inside_target().ToString());
1387 // child2's contents will occlude child1 below it.
1388 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1389 occlusion.UnoccludedContributingSurfaceContentRect(
1390 child1, false, gfx::Rect(-10, 430, 80, 70)));
1392 this->LeaveContributingSurface(child1, &occlusion);
1393 this->EnterLayer(parent, &occlusion);
1395 EXPECT_EQ(gfx::Rect().ToString(),
1396 occlusion.occlusion_from_outside_target().ToString());
1397 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1398 .ToString(),
1399 occlusion.occlusion_from_inside_target().ToString());
1401 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1403 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1404 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1405 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1407 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1408 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1409 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1411 /* Justification for the above occlusion:
1413 +---------------------+
1414 | 20 | layer1
1415 | 30+ ---------------------------------+
1416 100 | 30| | layer2 |
1417 |20+----------------------------------+ |
1418 | | | | | |
1419 | | | | | |
1420 | | | | | |
1421 +--|-|----------------+ | |
1422 | | | | 510
1423 | | | |
1424 | | | |
1425 | | | |
1426 | | | |
1427 | | | |
1428 | | | |
1429 | +--------------------------------|-+
1431 +----------------------------------+
1437 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1439 template <class Types>
1440 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1441 : public OcclusionTrackerTest<Types> {
1442 protected:
1443 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1444 bool opaque_layers)
1445 : OcclusionTrackerTest<Types>(opaque_layers) {}
1446 void RunMyTest() {
1447 gfx::Transform child1_transform;
1448 child1_transform.Translate(250.0, 250.0);
1449 child1_transform.Rotate(-90.0);
1450 child1_transform.Translate(-250.0, -250.0);
1452 gfx::Transform child2_transform;
1453 child2_transform.Translate(250.0, 250.0);
1454 child2_transform.Rotate(90.0);
1455 child2_transform.Translate(-250.0, -250.0);
1457 typename Types::ContentLayerType* parent = this->CreateRoot(
1458 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1459 parent->SetMasksToBounds(true);
1460 typename Types::LayerType* child1 = this->CreateSurface(
1461 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1462 typename Types::LayerType* child2 =
1463 this->CreateDrawingSurface(parent,
1464 child2_transform,
1465 gfx::PointF(20.f, 40.f),
1466 gfx::Size(10, 10),
1467 false);
1468 typename Types::ContentLayerType* layer1 =
1469 this->CreateDrawingLayer(child1,
1470 this->identity_matrix,
1471 gfx::PointF(-10.f, -20.f),
1472 gfx::Size(510, 510),
1473 true);
1474 typename Types::ContentLayerType* layer2 =
1475 this->CreateDrawingLayer(child2,
1476 this->identity_matrix,
1477 gfx::PointF(-10.f, -10.f),
1478 gfx::Size(510, 510),
1479 true);
1480 this->CalcDrawEtc(parent);
1482 TestOcclusionTrackerWithClip<typename Types::LayerType,
1483 typename Types::RenderSurfaceType> occlusion(
1484 gfx::Rect(0, 0, 1000, 1000));
1486 this->VisitLayer(layer2, &occlusion);
1487 this->EnterLayer(child2, &occlusion);
1489 EXPECT_EQ(gfx::Rect().ToString(),
1490 occlusion.occlusion_from_outside_target().ToString());
1491 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1492 occlusion.occlusion_from_inside_target().ToString());
1494 this->LeaveLayer(child2, &occlusion);
1495 this->EnterContributingSurface(child2, &occlusion);
1497 // There is nothing above child2's surface in the z-order.
1498 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1499 occlusion.UnoccludedContributingSurfaceContentRect(
1500 child2, false, gfx::Rect(-10, 420, 70, 80)));
1502 this->LeaveContributingSurface(child2, &occlusion);
1503 this->VisitLayer(layer1, &occlusion);
1504 this->EnterContributingSurface(child1, &occlusion);
1506 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1507 occlusion.occlusion_from_outside_target().ToString());
1508 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1509 occlusion.occlusion_from_inside_target().ToString());
1511 // child2's contents will occlude child1 below it.
1512 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1513 occlusion.UnoccludedContributingSurfaceContentRect(
1514 child1, false, gfx::Rect(420, -20, 80, 90)));
1515 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1516 occlusion.UnoccludedContributingSurfaceContentRect(
1517 child1, false, gfx::Rect(420, -10, 80, 90)));
1518 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1519 occlusion.UnoccludedContributingSurfaceContentRect(
1520 child1, false, gfx::Rect(420, -20, 70, 90)));
1522 this->LeaveContributingSurface(child1, &occlusion);
1523 this->EnterLayer(parent, &occlusion);
1525 EXPECT_EQ(gfx::Rect().ToString(),
1526 occlusion.occlusion_from_outside_target().ToString());
1527 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1528 occlusion.occlusion_from_inside_target().ToString());
1530 /* Justification for the above occlusion:
1532 +---------------------+
1533 |20 | layer1
1534 10+----------------------------------+
1535 100 || 30 | layer2 |
1536 |20+----------------------------------+
1537 || | | | |
1538 || | | | |
1539 || | | | |
1540 +|-|------------------+ | |
1541 | | | | 510
1542 | | 510 | |
1543 | | | |
1544 | | | |
1545 | | | |
1546 | | | |
1547 | | 520 | |
1548 +----------------------------------+ |
1550 +----------------------------------+
1556 ALL_OCCLUSIONTRACKER_TEST(
1557 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1559 template <class Types>
1560 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1561 protected:
1562 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1563 : OcclusionTrackerTest<Types>(opaque_layers) {}
1564 void RunMyTest() {
1565 gfx::Transform layer_transform;
1566 layer_transform.Translate(250.0, 250.0);
1567 layer_transform.Rotate(90.0);
1568 layer_transform.Translate(-250.0, -250.0);
1570 typename Types::ContentLayerType* parent = this->CreateRoot(
1571 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1572 parent->SetMasksToBounds(true);
1573 typename Types::ContentLayerType* blur_layer =
1574 this->CreateDrawingLayer(parent,
1575 layer_transform,
1576 gfx::PointF(30.f, 30.f),
1577 gfx::Size(500, 500),
1578 true);
1579 typename Types::ContentLayerType* opaque_layer =
1580 this->CreateDrawingLayer(parent,
1581 layer_transform,
1582 gfx::PointF(30.f, 30.f),
1583 gfx::Size(500, 500),
1584 true);
1585 typename Types::ContentLayerType* opacity_layer =
1586 this->CreateDrawingLayer(parent,
1587 layer_transform,
1588 gfx::PointF(30.f, 30.f),
1589 gfx::Size(500, 500),
1590 true);
1592 FilterOperations filters;
1593 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1594 blur_layer->SetFilters(filters);
1596 filters.Clear();
1597 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1598 opaque_layer->SetFilters(filters);
1600 filters.Clear();
1601 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1602 opacity_layer->SetFilters(filters);
1604 this->CalcDrawEtc(parent);
1606 TestOcclusionTrackerWithClip<typename Types::LayerType,
1607 typename Types::RenderSurfaceType> occlusion(
1608 gfx::Rect(0, 0, 1000, 1000));
1610 // Opacity layer won't contribute to occlusion.
1611 this->VisitLayer(opacity_layer, &occlusion);
1612 this->EnterContributingSurface(opacity_layer, &occlusion);
1614 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1615 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1617 // And has nothing to contribute to its parent surface.
1618 this->LeaveContributingSurface(opacity_layer, &occlusion);
1619 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1620 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1622 // Opaque layer will contribute to occlusion.
1623 this->VisitLayer(opaque_layer, &occlusion);
1624 this->EnterContributingSurface(opaque_layer, &occlusion);
1626 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1627 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1628 occlusion.occlusion_from_inside_target().ToString());
1630 // And it gets translated to the parent surface.
1631 this->LeaveContributingSurface(opaque_layer, &occlusion);
1632 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1633 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1634 occlusion.occlusion_from_inside_target().ToString());
1636 // The blur layer needs to throw away any occlusion from outside its
1637 // subtree.
1638 this->EnterLayer(blur_layer, &occlusion);
1639 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1640 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1642 // And it won't contribute to occlusion.
1643 this->LeaveLayer(blur_layer, &occlusion);
1644 this->EnterContributingSurface(blur_layer, &occlusion);
1645 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1646 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1648 // But the opaque layer's occlusion is preserved on the parent.
1649 this->LeaveContributingSurface(blur_layer, &occlusion);
1650 this->EnterLayer(parent, &occlusion);
1651 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1652 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1653 occlusion.occlusion_from_inside_target().ToString());
1657 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1659 template <class Types>
1660 class OcclusionTrackerTestReplicaDoesOcclude
1661 : public OcclusionTrackerTest<Types> {
1662 protected:
1663 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1664 : OcclusionTrackerTest<Types>(opaque_layers) {}
1665 void RunMyTest() {
1666 typename Types::ContentLayerType* parent = this->CreateRoot(
1667 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1668 typename Types::LayerType* surface =
1669 this->CreateDrawingSurface(parent,
1670 this->identity_matrix,
1671 gfx::PointF(0.f, 100.f),
1672 gfx::Size(50, 50),
1673 true);
1674 this->CreateReplicaLayer(
1675 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1676 this->CalcDrawEtc(parent);
1678 TestOcclusionTrackerWithClip<typename Types::LayerType,
1679 typename Types::RenderSurfaceType> occlusion(
1680 gfx::Rect(0, 0, 1000, 1000));
1682 this->VisitLayer(surface, &occlusion);
1684 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1685 occlusion.occlusion_from_inside_target().ToString());
1687 this->VisitContributingSurface(surface, &occlusion);
1688 this->EnterLayer(parent, &occlusion);
1690 // The surface and replica should both be occluding the parent.
1691 EXPECT_EQ(
1692 UnionRegions(gfx::Rect(0, 100, 50, 50),
1693 gfx::Rect(50, 150, 50, 50)).ToString(),
1694 occlusion.occlusion_from_inside_target().ToString());
1698 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1700 template <class Types>
1701 class OcclusionTrackerTestReplicaWithClipping
1702 : public OcclusionTrackerTest<Types> {
1703 protected:
1704 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1705 : OcclusionTrackerTest<Types>(opaque_layers) {}
1706 void RunMyTest() {
1707 typename Types::ContentLayerType* parent = this->CreateRoot(
1708 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1709 parent->SetMasksToBounds(true);
1710 typename Types::LayerType* surface =
1711 this->CreateDrawingSurface(parent,
1712 this->identity_matrix,
1713 gfx::PointF(0.f, 100.f),
1714 gfx::Size(50, 50),
1715 true);
1716 this->CreateReplicaLayer(
1717 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1718 this->CalcDrawEtc(parent);
1720 TestOcclusionTrackerWithClip<typename Types::LayerType,
1721 typename Types::RenderSurfaceType> occlusion(
1722 gfx::Rect(0, 0, 1000, 1000));
1724 this->VisitLayer(surface, &occlusion);
1726 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1727 occlusion.occlusion_from_inside_target().ToString());
1729 this->VisitContributingSurface(surface, &occlusion);
1730 this->EnterLayer(parent, &occlusion);
1732 // The surface and replica should both be occluding the parent.
1733 EXPECT_EQ(
1734 UnionRegions(gfx::Rect(0, 100, 50, 50),
1735 gfx::Rect(50, 150, 50, 20)).ToString(),
1736 occlusion.occlusion_from_inside_target().ToString());
1740 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1742 template <class Types>
1743 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1744 protected:
1745 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1746 : OcclusionTrackerTest<Types>(opaque_layers) {}
1747 void RunMyTest() {
1748 typename Types::ContentLayerType* parent = this->CreateRoot(
1749 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1750 typename Types::LayerType* surface =
1751 this->CreateDrawingSurface(parent,
1752 this->identity_matrix,
1753 gfx::PointF(0.f, 100.f),
1754 gfx::Size(50, 50),
1755 true);
1756 typename Types::LayerType* replica = this->CreateReplicaLayer(
1757 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1758 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1759 this->CalcDrawEtc(parent);
1761 TestOcclusionTrackerWithClip<typename Types::LayerType,
1762 typename Types::RenderSurfaceType> occlusion(
1763 gfx::Rect(0, 0, 1000, 1000));
1765 this->VisitLayer(surface, &occlusion);
1767 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1768 occlusion.occlusion_from_inside_target().ToString());
1770 this->VisitContributingSurface(surface, &occlusion);
1771 this->EnterLayer(parent, &occlusion);
1773 // The replica should not be occluding the parent, since it has a mask
1774 // applied to it.
1775 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1776 occlusion.occlusion_from_inside_target().ToString());
1780 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1782 template <class Types>
1783 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1784 : public OcclusionTrackerTest<Types> {
1785 protected:
1786 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1787 : OcclusionTrackerTest<Types>(opaque_layers) {}
1788 void RunMyTest() {
1789 typename Types::ContentLayerType* parent = this->CreateRoot(
1790 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1791 typename Types::ContentLayerType* layer =
1792 this->CreateDrawingSurface(parent,
1793 this->identity_matrix,
1794 gfx::PointF(),
1795 gfx::Size(200, 200),
1796 false);
1797 this->CalcDrawEtc(parent);
1799 TestOcclusionTrackerWithClip<typename Types::LayerType,
1800 typename Types::RenderSurfaceType> occlusion(
1801 gfx::Rect(0, 0, 1000, 1000));
1802 this->EnterLayer(layer, &occlusion);
1804 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1805 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1806 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1807 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1809 this->LeaveLayer(layer, &occlusion);
1810 this->VisitContributingSurface(layer, &occlusion);
1811 this->EnterLayer(parent, &occlusion);
1813 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1817 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1819 template <class Types>
1820 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1821 : public OcclusionTrackerTest<Types> {
1822 protected:
1823 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1824 : OcclusionTrackerTest<Types>(opaque_layers) {}
1825 void RunMyTest() {
1826 typename Types::ContentLayerType* parent = this->CreateRoot(
1827 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1828 typename Types::ContentLayerType* layer =
1829 this->CreateDrawingLayer(parent,
1830 this->identity_matrix,
1831 gfx::PointF(100.f, 100.f),
1832 gfx::Size(200, 200),
1833 false);
1834 this->CalcDrawEtc(parent);
1836 TestOcclusionTrackerWithClip<typename Types::LayerType,
1837 typename Types::RenderSurfaceType> occlusion(
1838 gfx::Rect(0, 0, 1000, 1000));
1839 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1841 this->ResetLayerIterator();
1842 this->VisitLayer(layer, &occlusion);
1843 this->EnterLayer(parent, &occlusion);
1845 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1846 occlusion.occlusion_from_inside_target().ToString());
1848 EXPECT_FALSE(
1849 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1850 EXPECT_TRUE(
1851 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1852 EXPECT_FALSE(
1853 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1856 TestOcclusionTrackerWithClip<typename Types::LayerType,
1857 typename Types::RenderSurfaceType> occlusion(
1858 gfx::Rect(0, 0, 1000, 1000));
1859 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1861 this->ResetLayerIterator();
1862 this->VisitLayer(layer, &occlusion);
1863 this->EnterLayer(parent, &occlusion);
1865 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1866 occlusion.occlusion_from_inside_target().ToString());
1868 EXPECT_FALSE(
1869 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1870 EXPECT_FALSE(
1871 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1872 EXPECT_TRUE(
1873 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1876 TestOcclusionTrackerWithClip<typename Types::LayerType,
1877 typename Types::RenderSurfaceType> occlusion(
1878 gfx::Rect(0, 0, 1000, 1000));
1879 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1881 this->ResetLayerIterator();
1882 this->VisitLayer(layer, &occlusion);
1883 this->EnterLayer(parent, &occlusion);
1885 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1886 occlusion.occlusion_from_inside_target().ToString());
1888 EXPECT_FALSE(
1889 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1890 EXPECT_FALSE(
1891 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1892 EXPECT_FALSE(
1893 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1898 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1900 template <class Types>
1901 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
1902 protected:
1903 explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
1904 : OcclusionTrackerTest<Types>(opaque_layers) {}
1905 void RunMyTest() {
1906 gfx::Transform transform;
1907 transform.RotateAboutYAxis(30.0);
1909 typename Types::ContentLayerType* parent = this->CreateRoot(
1910 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1911 typename Types::LayerType* container = this->CreateLayer(
1912 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1913 typename Types::ContentLayerType* layer =
1914 this->CreateDrawingLayer(container,
1915 transform,
1916 gfx::PointF(100.f, 100.f),
1917 gfx::Size(200, 200),
1918 true);
1919 this->CalcDrawEtc(parent);
1921 TestOcclusionTrackerWithClip<typename Types::LayerType,
1922 typename Types::RenderSurfaceType> occlusion(
1923 gfx::Rect(0, 0, 1000, 1000));
1924 this->EnterLayer(layer, &occlusion);
1926 // The layer is rotated in 3d but without preserving 3d, so it only gets
1927 // resized.
1928 EXPECT_RECT_EQ(
1929 gfx::Rect(0, 0, 200, 200),
1930 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1934 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
1936 template <class Types>
1937 class OcclusionTrackerTestUnsorted3dLayers
1938 : public OcclusionTrackerTest<Types> {
1939 protected:
1940 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
1941 : OcclusionTrackerTest<Types>(opaque_layers) {}
1942 void RunMyTest() {
1943 // Currently, The main thread layer iterator does not iterate over 3d items
1944 // in sorted order, because layer sorting is not performed on the main
1945 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1946 // layer occludes other layers that have not yet been iterated over. For
1947 // now, the expected behavior is that a 3d layer simply does not add any
1948 // occlusion to the occlusion tracker.
1950 gfx::Transform translation_to_front;
1951 translation_to_front.Translate3d(0.0, 0.0, -10.0);
1952 gfx::Transform translation_to_back;
1953 translation_to_front.Translate3d(0.0, 0.0, -100.0);
1955 typename Types::ContentLayerType* parent = this->CreateRoot(
1956 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1957 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
1958 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
1959 typename Types::ContentLayerType* child2 =
1960 this->CreateDrawingLayer(parent,
1961 translation_to_front,
1962 gfx::PointF(50.f, 50.f),
1963 gfx::Size(100, 100),
1964 true);
1965 parent->SetPreserves3d(true);
1967 this->CalcDrawEtc(parent);
1969 TestOcclusionTrackerWithClip<typename Types::LayerType,
1970 typename Types::RenderSurfaceType> occlusion(
1971 gfx::Rect(0, 0, 1000, 1000));
1972 this->VisitLayer(child2, &occlusion);
1973 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1974 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1976 this->VisitLayer(child1, &occlusion);
1977 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1978 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1982 // This test will have different layer ordering on the impl thread; the test
1983 // will only work on the main thread.
1984 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1986 template <class Types>
1987 class OcclusionTrackerTestPerspectiveTransform
1988 : public OcclusionTrackerTest<Types> {
1989 protected:
1990 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
1991 : OcclusionTrackerTest<Types>(opaque_layers) {}
1992 void RunMyTest() {
1993 gfx::Transform transform;
1994 transform.Translate(150.0, 150.0);
1995 transform.ApplyPerspectiveDepth(400.0);
1996 transform.RotateAboutXAxis(-30.0);
1997 transform.Translate(-150.0, -150.0);
1999 typename Types::ContentLayerType* parent = this->CreateRoot(
2000 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2001 typename Types::LayerType* container = this->CreateLayer(
2002 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2003 typename Types::ContentLayerType* layer =
2004 this->CreateDrawingLayer(container,
2005 transform,
2006 gfx::PointF(100.f, 100.f),
2007 gfx::Size(200, 200),
2008 true);
2009 container->SetPreserves3d(true);
2010 layer->SetPreserves3d(true);
2011 this->CalcDrawEtc(parent);
2013 TestOcclusionTrackerWithClip<typename Types::LayerType,
2014 typename Types::RenderSurfaceType> occlusion(
2015 gfx::Rect(0, 0, 1000, 1000));
2016 this->EnterLayer(layer, &occlusion);
2018 EXPECT_RECT_EQ(
2019 gfx::Rect(0, 0, 200, 200),
2020 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2024 // This test requires accumulating occlusion of 3d layers, which are skipped by
2025 // the occlusion tracker on the main thread. So this test should run on the impl
2026 // thread.
2027 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
2029 template <class Types>
2030 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2031 : public OcclusionTrackerTest<Types> {
2032 protected:
2033 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2034 bool opaque_layers)
2035 : OcclusionTrackerTest<Types>(opaque_layers) {}
2036 void RunMyTest() {
2037 // This test is based on the platform/chromium/compositing/3d-corners.html
2038 // layout test.
2039 gfx::Transform transform;
2040 transform.Translate(250.0, 50.0);
2041 transform.ApplyPerspectiveDepth(10.0);
2042 transform.Translate(-250.0, -50.0);
2043 transform.Translate(250.0, 50.0);
2044 transform.RotateAboutXAxis(-167.0);
2045 transform.Translate(-250.0, -50.0);
2047 typename Types::ContentLayerType* parent = this->CreateRoot(
2048 this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
2049 typename Types::LayerType* container = this->CreateLayer(
2050 parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2051 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2052 container, transform, gfx::PointF(), gfx::Size(500, 500), true);
2053 container->SetPreserves3d(true);
2054 layer->SetPreserves3d(true);
2055 this->CalcDrawEtc(parent);
2057 TestOcclusionTrackerWithClip<typename Types::LayerType,
2058 typename Types::RenderSurfaceType> occlusion(
2059 gfx::Rect(0, 0, 1000, 1000));
2060 this->EnterLayer(layer, &occlusion);
2062 // The bottom 11 pixel rows of this layer remain visible inside the
2063 // container, after translation to the target surface. When translated back,
2064 // this will include many more pixels but must include at least the bottom
2065 // 11 rows.
2066 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2067 layer, gfx::Rect(0, 26, 500, 474)).
2068 Contains(gfx::Rect(0, 489, 500, 11)));
2072 // This test requires accumulating occlusion of 3d layers, which are skipped by
2073 // the occlusion tracker on the main thread. So this test should run on the impl
2074 // thread.
2075 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2077 template <class Types>
2078 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2079 : public OcclusionTrackerTest<Types> {
2080 protected:
2081 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2082 bool opaque_layers)
2083 : OcclusionTrackerTest<Types>(opaque_layers) {}
2084 void RunMyTest() {
2085 gfx::Transform transform;
2086 transform.Translate(50.0, 50.0);
2087 transform.ApplyPerspectiveDepth(100.0);
2088 transform.Translate3d(0.0, 0.0, 110.0);
2089 transform.Translate(-50.0, -50.0);
2091 typename Types::ContentLayerType* parent = this->CreateRoot(
2092 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2093 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2094 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2095 parent->SetPreserves3d(true);
2096 layer->SetPreserves3d(true);
2097 this->CalcDrawEtc(parent);
2099 TestOcclusionTrackerWithClip<typename Types::LayerType,
2100 typename Types::RenderSurfaceType> occlusion(
2101 gfx::Rect(0, 0, 1000, 1000));
2103 // The |layer| is entirely behind the camera and should not occlude.
2104 this->VisitLayer(layer, &occlusion);
2105 this->EnterLayer(parent, &occlusion);
2106 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2107 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2111 // This test requires accumulating occlusion of 3d layers, which are skipped by
2112 // the occlusion tracker on the main thread. So this test should run on the impl
2113 // thread.
2114 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2116 template <class Types>
2117 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2118 : public OcclusionTrackerTest<Types> {
2119 protected:
2120 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2121 bool opaque_layers)
2122 : OcclusionTrackerTest<Types>(opaque_layers) {}
2123 void RunMyTest() {
2124 gfx::Transform transform;
2125 transform.Translate(50.0, 50.0);
2126 transform.ApplyPerspectiveDepth(100.0);
2127 transform.Translate3d(0.0, 0.0, 99.0);
2128 transform.Translate(-50.0, -50.0);
2130 typename Types::ContentLayerType* parent = this->CreateRoot(
2131 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2132 parent->SetMasksToBounds(true);
2133 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2134 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2135 parent->SetPreserves3d(true);
2136 layer->SetPreserves3d(true);
2137 this->CalcDrawEtc(parent);
2139 TestOcclusionTrackerWithClip<typename Types::LayerType,
2140 typename Types::RenderSurfaceType> occlusion(
2141 gfx::Rect(0, 0, 1000, 1000));
2143 // This is very close to the camera, so pixels in its visible_content_rect()
2144 // will actually go outside of the layer's clip rect. Ensure that those
2145 // pixels don't occlude things outside the clip rect.
2146 this->VisitLayer(layer, &occlusion);
2147 this->EnterLayer(parent, &occlusion);
2148 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2149 occlusion.occlusion_from_inside_target().ToString());
2150 EXPECT_EQ(gfx::Rect().ToString(),
2151 occlusion.occlusion_from_outside_target().ToString());
2155 // This test requires accumulating occlusion of 3d layers, which are skipped by
2156 // the occlusion tracker on the main thread. So this test should run on the impl
2157 // thread.
2158 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2160 template <class Types>
2161 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2162 : public OcclusionTrackerTest<Types> {
2163 protected:
2164 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
2165 : OcclusionTrackerTest<Types>(opaque_layers) {}
2166 void RunMyTest() {
2167 // parent
2168 // +--layer
2169 // +--surface
2170 // | +--surface_child
2171 // | +--surface_child2
2172 // +--parent2
2173 // +--topmost
2175 typename Types::ContentLayerType* parent = this->CreateRoot(
2176 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2177 typename Types::ContentLayerType* layer =
2178 this->CreateDrawingLayer(parent,
2179 this->identity_matrix,
2180 gfx::PointF(),
2181 gfx::Size(300, 300),
2182 true);
2183 typename Types::ContentLayerType* surface =
2184 this->CreateDrawingSurface(parent,
2185 this->identity_matrix,
2186 gfx::PointF(),
2187 gfx::Size(300, 300),
2188 true);
2189 typename Types::ContentLayerType* surface_child =
2190 this->CreateDrawingLayer(surface,
2191 this->identity_matrix,
2192 gfx::PointF(),
2193 gfx::Size(200, 300),
2194 true);
2195 typename Types::ContentLayerType* surface_child2 =
2196 this->CreateDrawingLayer(surface,
2197 this->identity_matrix,
2198 gfx::PointF(),
2199 gfx::Size(100, 300),
2200 true);
2201 typename Types::ContentLayerType* parent2 =
2202 this->CreateDrawingLayer(parent,
2203 this->identity_matrix,
2204 gfx::PointF(),
2205 gfx::Size(300, 300),
2206 false);
2207 typename Types::ContentLayerType* topmost =
2208 this->CreateDrawingLayer(parent,
2209 this->identity_matrix,
2210 gfx::PointF(250.f, 0.f),
2211 gfx::Size(50, 300),
2212 true);
2214 AddOpacityTransitionToController(
2215 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2216 AddOpacityTransitionToController(
2217 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2218 this->CalcDrawEtc(parent);
2220 EXPECT_TRUE(layer->draw_opacity_is_animating());
2221 EXPECT_FALSE(surface->draw_opacity_is_animating());
2222 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2224 TestOcclusionTrackerWithClip<typename Types::LayerType,
2225 typename Types::RenderSurfaceType> occlusion(
2226 gfx::Rect(0, 0, 1000, 1000));
2228 this->VisitLayer(topmost, &occlusion);
2229 this->EnterLayer(parent2, &occlusion);
2230 // This occlusion will affect all surfaces.
2231 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2232 occlusion.occlusion_from_inside_target().ToString());
2233 EXPECT_EQ(gfx::Rect().ToString(),
2234 occlusion.occlusion_from_outside_target().ToString());
2235 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2236 occlusion.UnoccludedLayerContentRect(
2237 parent2, gfx::Rect(0, 0, 300, 300)).ToString());
2238 this->LeaveLayer(parent2, &occlusion);
2240 this->VisitLayer(surface_child2, &occlusion);
2241 this->EnterLayer(surface_child, &occlusion);
2242 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2243 occlusion.occlusion_from_inside_target().ToString());
2244 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2245 occlusion.occlusion_from_outside_target().ToString());
2246 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2247 occlusion.UnoccludedLayerContentRect(
2248 surface_child, gfx::Rect(0, 0, 200, 300)));
2249 this->LeaveLayer(surface_child, &occlusion);
2250 this->EnterLayer(surface, &occlusion);
2251 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2252 occlusion.occlusion_from_inside_target().ToString());
2253 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2254 occlusion.occlusion_from_outside_target().ToString());
2255 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2256 occlusion.UnoccludedLayerContentRect(
2257 surface, gfx::Rect(0, 0, 300, 300)));
2258 this->LeaveLayer(surface, &occlusion);
2260 this->EnterContributingSurface(surface, &occlusion);
2261 // Occlusion within the surface is lost when leaving the animating surface.
2262 EXPECT_EQ(gfx::Rect().ToString(),
2263 occlusion.occlusion_from_inside_target().ToString());
2264 EXPECT_EQ(gfx::Rect().ToString(),
2265 occlusion.occlusion_from_outside_target().ToString());
2266 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2267 occlusion.UnoccludedContributingSurfaceContentRect(
2268 surface, false, gfx::Rect(0, 0, 300, 300)));
2269 this->LeaveContributingSurface(surface, &occlusion);
2271 // Occlusion from outside the animating surface still exists.
2272 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2273 occlusion.occlusion_from_inside_target().ToString());
2274 EXPECT_EQ(gfx::Rect().ToString(),
2275 occlusion.occlusion_from_outside_target().ToString());
2277 this->VisitLayer(layer, &occlusion);
2278 this->EnterLayer(parent, &occlusion);
2280 // Occlusion is not added for the animating |layer|.
2281 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2282 occlusion.UnoccludedLayerContentRect(
2283 parent, gfx::Rect(0, 0, 300, 300)));
2287 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2289 template <class Types>
2290 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2291 : public OcclusionTrackerTest<Types> {
2292 protected:
2293 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
2294 : OcclusionTrackerTest<Types>(opaque_layers) {}
2295 void RunMyTest() {
2296 typename Types::ContentLayerType* parent = this->CreateRoot(
2297 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2298 typename Types::ContentLayerType* layer =
2299 this->CreateDrawingLayer(parent,
2300 this->identity_matrix,
2301 gfx::PointF(),
2302 gfx::Size(300, 300),
2303 true);
2304 typename Types::ContentLayerType* surface =
2305 this->CreateDrawingSurface(parent,
2306 this->identity_matrix,
2307 gfx::PointF(),
2308 gfx::Size(300, 300),
2309 true);
2310 typename Types::ContentLayerType* surface_child =
2311 this->CreateDrawingLayer(surface,
2312 this->identity_matrix,
2313 gfx::PointF(),
2314 gfx::Size(200, 300),
2315 true);
2316 typename Types::ContentLayerType* surface_child2 =
2317 this->CreateDrawingLayer(surface,
2318 this->identity_matrix,
2319 gfx::PointF(),
2320 gfx::Size(100, 300),
2321 true);
2322 typename Types::ContentLayerType* parent2 =
2323 this->CreateDrawingLayer(parent,
2324 this->identity_matrix,
2325 gfx::PointF(),
2326 gfx::Size(300, 300),
2327 false);
2328 typename Types::ContentLayerType* topmost =
2329 this->CreateDrawingLayer(parent,
2330 this->identity_matrix,
2331 gfx::PointF(250.f, 0.f),
2332 gfx::Size(50, 300),
2333 true);
2335 AddOpacityTransitionToController(
2336 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2337 AddOpacityTransitionToController(
2338 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2339 this->CalcDrawEtc(parent);
2341 EXPECT_TRUE(layer->draw_opacity_is_animating());
2342 EXPECT_FALSE(surface->draw_opacity_is_animating());
2343 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2345 TestOcclusionTrackerWithClip<typename Types::LayerType,
2346 typename Types::RenderSurfaceType> occlusion(
2347 gfx::Rect(0, 0, 1000, 1000));
2349 this->VisitLayer(topmost, &occlusion);
2350 this->EnterLayer(parent2, &occlusion);
2351 // This occlusion will affect all surfaces.
2352 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2353 occlusion.occlusion_from_inside_target().ToString());
2354 EXPECT_EQ(gfx::Rect().ToString(),
2355 occlusion.occlusion_from_outside_target().ToString());
2356 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2357 occlusion.UnoccludedLayerContentRect(
2358 parent, gfx::Rect(0, 0, 300, 300)));
2359 this->LeaveLayer(parent2, &occlusion);
2361 this->VisitLayer(surface_child2, &occlusion);
2362 this->EnterLayer(surface_child, &occlusion);
2363 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2364 occlusion.occlusion_from_inside_target().ToString());
2365 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2366 occlusion.occlusion_from_outside_target().ToString());
2367 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2368 occlusion.UnoccludedLayerContentRect(
2369 surface_child, gfx::Rect(0, 0, 200, 300)));
2370 this->LeaveLayer(surface_child, &occlusion);
2371 this->EnterLayer(surface, &occlusion);
2372 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2373 occlusion.occlusion_from_inside_target().ToString());
2374 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2375 occlusion.occlusion_from_outside_target().ToString());
2376 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2377 occlusion.UnoccludedLayerContentRect(
2378 surface, gfx::Rect(0, 0, 300, 300)));
2379 this->LeaveLayer(surface, &occlusion);
2381 this->EnterContributingSurface(surface, &occlusion);
2382 // Occlusion within the surface is lost when leaving the animating surface.
2383 EXPECT_EQ(gfx::Rect().ToString(),
2384 occlusion.occlusion_from_inside_target().ToString());
2385 EXPECT_EQ(gfx::Rect().ToString(),
2386 occlusion.occlusion_from_outside_target().ToString());
2387 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2388 occlusion.UnoccludedContributingSurfaceContentRect(
2389 surface, false, gfx::Rect(0, 0, 300, 300)));
2390 this->LeaveContributingSurface(surface, &occlusion);
2392 // Occlusion from outside the animating surface still exists.
2393 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2394 occlusion.occlusion_from_inside_target().ToString());
2395 EXPECT_EQ(gfx::Rect().ToString(),
2396 occlusion.occlusion_from_outside_target().ToString());
2398 this->VisitLayer(layer, &occlusion);
2399 this->EnterLayer(parent, &occlusion);
2401 // Occlusion is not added for the animating |layer|.
2402 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2403 occlusion.UnoccludedLayerContentRect(
2404 parent, gfx::Rect(0, 0, 300, 300)));
2408 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2410 template <class Types>
2411 class OcclusionTrackerTestAnimationTranslateOnMainThread
2412 : public OcclusionTrackerTest<Types> {
2413 protected:
2414 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2415 bool opaque_layers)
2416 : OcclusionTrackerTest<Types>(opaque_layers) {}
2417 void RunMyTest() {
2418 typename Types::ContentLayerType* parent = this->CreateRoot(
2419 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2420 typename Types::ContentLayerType* layer =
2421 this->CreateDrawingLayer(parent,
2422 this->identity_matrix,
2423 gfx::PointF(),
2424 gfx::Size(300, 300),
2425 true);
2426 typename Types::ContentLayerType* surface =
2427 this->CreateDrawingSurface(parent,
2428 this->identity_matrix,
2429 gfx::PointF(),
2430 gfx::Size(300, 300),
2431 true);
2432 typename Types::ContentLayerType* surface_child =
2433 this->CreateDrawingLayer(surface,
2434 this->identity_matrix,
2435 gfx::PointF(),
2436 gfx::Size(200, 300),
2437 true);
2438 typename Types::ContentLayerType* surface_child2 =
2439 this->CreateDrawingLayer(surface,
2440 this->identity_matrix,
2441 gfx::PointF(),
2442 gfx::Size(100, 300),
2443 true);
2444 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
2445 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
2447 AddAnimatedTransformToController(
2448 layer->layer_animation_controller(), 10.0, 30, 0);
2449 AddAnimatedTransformToController(
2450 surface->layer_animation_controller(), 10.0, 30, 0);
2451 AddAnimatedTransformToController(
2452 surface_child->layer_animation_controller(), 10.0, 30, 0);
2453 this->CalcDrawEtc(parent);
2455 EXPECT_TRUE(layer->draw_transform_is_animating());
2456 EXPECT_TRUE(layer->screen_space_transform_is_animating());
2457 EXPECT_TRUE(
2458 surface->render_surface()->target_surface_transforms_are_animating());
2459 EXPECT_TRUE(
2460 surface->render_surface()->screen_space_transforms_are_animating());
2461 // The surface owning layer doesn't animate against its own surface.
2462 EXPECT_FALSE(surface->draw_transform_is_animating());
2463 EXPECT_TRUE(surface->screen_space_transform_is_animating());
2464 EXPECT_TRUE(surface_child->draw_transform_is_animating());
2465 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
2467 TestOcclusionTrackerWithClip<typename Types::LayerType,
2468 typename Types::RenderSurfaceType> occlusion(
2469 gfx::Rect(0, 0, 1000, 1000));
2471 this->VisitLayer(surface2, &occlusion);
2472 this->EnterContributingSurface(surface2, &occlusion);
2474 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2475 occlusion.occlusion_from_inside_target().ToString());
2477 this->LeaveContributingSurface(surface2, &occlusion);
2478 this->EnterLayer(surface_child2, &occlusion);
2480 // surface_child2 is moving in screen space but not relative to its target,
2481 // so occlusion should happen in its target space only. It also means that
2482 // things occluding from outside the target (e.g. surface2) cannot occlude
2483 // this layer.
2484 EXPECT_EQ(gfx::Rect().ToString(),
2485 occlusion.occlusion_from_outside_target().ToString());
2487 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2488 occlusion.UnoccludedLayerContentRect(
2489 surface_child2, gfx::Rect(0, 0, 100, 300)));
2490 EXPECT_FALSE(
2491 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2493 this->LeaveLayer(surface_child2, &occlusion);
2494 this->EnterLayer(surface_child, &occlusion);
2495 EXPECT_FALSE(
2496 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300)));
2497 EXPECT_EQ(gfx::Rect().ToString(),
2498 occlusion.occlusion_from_outside_target().ToString());
2499 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2500 occlusion.occlusion_from_inside_target().ToString());
2501 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2502 occlusion.UnoccludedLayerContentRect(
2503 surface, gfx::Rect(0, 0, 300, 300)));
2505 // The surface_child is occluded by the surface_child2, but is moving
2506 // relative its target, so it can't be occluded.
2507 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2508 occlusion.UnoccludedLayerContentRect(
2509 surface_child, gfx::Rect(0, 0, 200, 300)));
2510 EXPECT_FALSE(
2511 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2513 this->LeaveLayer(surface_child, &occlusion);
2514 this->EnterLayer(surface, &occlusion);
2515 // The surface_child is moving in screen space but not relative to its
2516 // target, so occlusion should happen from within the target only.
2517 EXPECT_EQ(gfx::Rect().ToString(),
2518 occlusion.occlusion_from_outside_target().ToString());
2519 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2520 occlusion.occlusion_from_inside_target().ToString());
2521 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2522 occlusion.UnoccludedLayerContentRect(
2523 surface, gfx::Rect(0, 0, 300, 300)));
2525 this->LeaveLayer(surface, &occlusion);
2526 // The surface's owning layer is moving in screen space but not relative to
2527 // its target, so occlusion should happen within the target only.
2528 EXPECT_EQ(gfx::Rect().ToString(),
2529 occlusion.occlusion_from_outside_target().ToString());
2530 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2531 occlusion.occlusion_from_inside_target().ToString());
2532 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2533 occlusion.UnoccludedLayerContentRect(
2534 surface, gfx::Rect(0, 0, 300, 300)));
2536 this->EnterContributingSurface(surface, &occlusion);
2537 // The contributing |surface| is animating so it can't be occluded.
2538 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2539 occlusion.UnoccludedContributingSurfaceContentRect(
2540 surface, false, gfx::Rect(0, 0, 300, 300)));
2541 this->LeaveContributingSurface(surface, &occlusion);
2543 this->EnterLayer(layer, &occlusion);
2544 // The |surface| is moving in the screen and in its target, so all occlusion
2545 // within the surface is lost when leaving it.
2546 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2547 occlusion.UnoccludedLayerContentRect(
2548 parent, gfx::Rect(0, 0, 300, 300)));
2549 this->LeaveLayer(layer, &occlusion);
2551 this->EnterLayer(parent, &occlusion);
2552 // The |layer| is animating in the screen and in its target, so no occlusion
2553 // is added.
2554 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2555 occlusion.UnoccludedLayerContentRect(
2556 parent, gfx::Rect(0, 0, 300, 300)));
2560 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
2562 template <class Types>
2563 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2564 : public OcclusionTrackerTest<Types> {
2565 protected:
2566 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2567 bool opaque_layers)
2568 : OcclusionTrackerTest<Types>(opaque_layers) {}
2569 void RunMyTest() {
2570 gfx::Transform surface_transform;
2571 surface_transform.Translate(300.0, 300.0);
2572 surface_transform.Scale(2.0, 2.0);
2573 surface_transform.Translate(-150.0, -150.0);
2575 typename Types::ContentLayerType* parent = this->CreateRoot(
2576 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2577 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
2578 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
2579 typename Types::ContentLayerType* surface2 =
2580 this->CreateDrawingSurface(parent,
2581 this->identity_matrix,
2582 gfx::PointF(50.f, 50.f),
2583 gfx::Size(300, 300),
2584 false);
2585 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2586 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2587 this->CalcDrawEtc(parent);
2589 TestOcclusionTrackerWithClip<typename Types::LayerType,
2590 typename Types::RenderSurfaceType> occlusion(
2591 gfx::Rect(0, 0, 1000, 1000));
2593 this->VisitLayer(surface2, &occlusion);
2594 this->VisitContributingSurface(surface2, &occlusion);
2596 EXPECT_EQ(gfx::Rect().ToString(),
2597 occlusion.occlusion_from_outside_target().ToString());
2598 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2599 occlusion.occlusion_from_inside_target().ToString());
2601 // Clear any stored occlusion.
2602 occlusion.set_occlusion_from_outside_target(Region());
2603 occlusion.set_occlusion_from_inside_target(Region());
2605 this->VisitLayer(surface, &occlusion);
2606 this->VisitContributingSurface(surface, &occlusion);
2608 EXPECT_EQ(gfx::Rect().ToString(),
2609 occlusion.occlusion_from_outside_target().ToString());
2610 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2611 occlusion.occlusion_from_inside_target().ToString());
2615 MAIN_AND_IMPL_THREAD_TEST(
2616 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2618 template <class Types>
2619 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2620 : public OcclusionTrackerTest<Types> {
2621 protected:
2622 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2623 bool opaque_layers)
2624 : OcclusionTrackerTest<Types>(opaque_layers) {}
2625 void RunMyTest() {
2626 typename Types::ContentLayerType* parent = this->CreateRoot(
2627 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2628 parent->SetMasksToBounds(true);
2629 typename Types::ContentLayerType* surface =
2630 this->CreateDrawingSurface(parent,
2631 this->identity_matrix,
2632 gfx::PointF(),
2633 gfx::Size(500, 300),
2634 false);
2635 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2636 this->CalcDrawEtc(parent);
2638 TestOcclusionTrackerWithClip<typename Types::LayerType,
2639 typename Types::RenderSurfaceType> occlusion(
2640 gfx::Rect(0, 0, 1000, 1000));
2642 this->VisitLayer(surface, &occlusion);
2643 this->VisitContributingSurface(surface, &occlusion);
2645 EXPECT_EQ(gfx::Rect().ToString(),
2646 occlusion.occlusion_from_outside_target().ToString());
2647 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2648 occlusion.occlusion_from_inside_target().ToString());
2652 MAIN_AND_IMPL_THREAD_TEST(
2653 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2655 template <class Types>
2656 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
2657 protected:
2658 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
2659 : OcclusionTrackerTest<Types>(opaque_layers) {}
2660 void RunMyTest() {
2661 typename Types::ContentLayerType* parent = this->CreateRoot(
2662 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2663 typename Types::LayerType* surface =
2664 this->CreateDrawingSurface(parent,
2665 this->identity_matrix,
2666 gfx::PointF(),
2667 gfx::Size(100, 100),
2668 true);
2669 this->CreateReplicaLayer(surface,
2670 this->identity_matrix,
2671 gfx::PointF(0.f, 100.f),
2672 gfx::Size(100, 100));
2673 typename Types::LayerType* topmost =
2674 this->CreateDrawingLayer(parent,
2675 this->identity_matrix,
2676 gfx::PointF(0.f, 100.f),
2677 gfx::Size(100, 100),
2678 true);
2679 this->CalcDrawEtc(parent);
2681 TestOcclusionTrackerWithClip<typename Types::LayerType,
2682 typename Types::RenderSurfaceType> occlusion(
2683 gfx::Rect(0, 0, 1000, 1000));
2685 // |topmost| occludes the replica, but not the surface itself.
2686 this->VisitLayer(topmost, &occlusion);
2688 EXPECT_EQ(gfx::Rect().ToString(),
2689 occlusion.occlusion_from_outside_target().ToString());
2690 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2691 occlusion.occlusion_from_inside_target().ToString());
2693 this->VisitLayer(surface, &occlusion);
2695 // Render target with replica ignores occlusion from outside.
2696 EXPECT_EQ(gfx::Rect().ToString(),
2697 occlusion.occlusion_from_outside_target().ToString());
2698 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2699 occlusion.occlusion_from_inside_target().ToString());
2701 this->EnterContributingSurface(surface, &occlusion);
2703 // Surface is not occluded so it shouldn't think it is.
2704 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2705 occlusion.UnoccludedContributingSurfaceContentRect(
2706 surface, false, gfx::Rect(0, 0, 100, 100)));
2710 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
2712 template <class Types>
2713 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2714 : public OcclusionTrackerTest<Types> {
2715 protected:
2716 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
2717 : OcclusionTrackerTest<Types>(opaque_layers) {}
2718 void RunMyTest() {
2719 typename Types::ContentLayerType* parent = this->CreateRoot(
2720 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2721 typename Types::LayerType* surface =
2722 this->CreateDrawingSurface(parent,
2723 this->identity_matrix,
2724 gfx::PointF(),
2725 gfx::Size(100, 100),
2726 true);
2727 this->CreateReplicaLayer(surface,
2728 this->identity_matrix,
2729 gfx::PointF(0.f, 100.f),
2730 gfx::Size(100, 100));
2731 typename Types::LayerType* topmost =
2732 this->CreateDrawingLayer(parent,
2733 this->identity_matrix,
2734 gfx::PointF(),
2735 gfx::Size(100, 110),
2736 true);
2737 this->CalcDrawEtc(parent);
2739 TestOcclusionTrackerWithClip<typename Types::LayerType,
2740 typename Types::RenderSurfaceType> occlusion(
2741 gfx::Rect(0, 0, 1000, 1000));
2743 // |topmost| occludes the surface, but not the entire surface's replica.
2744 this->VisitLayer(topmost, &occlusion);
2746 EXPECT_EQ(gfx::Rect().ToString(),
2747 occlusion.occlusion_from_outside_target().ToString());
2748 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2749 occlusion.occlusion_from_inside_target().ToString());
2751 this->VisitLayer(surface, &occlusion);
2753 // Render target with replica ignores occlusion from outside.
2754 EXPECT_EQ(gfx::Rect().ToString(),
2755 occlusion.occlusion_from_outside_target().ToString());
2756 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2757 occlusion.occlusion_from_inside_target().ToString());
2759 this->EnterContributingSurface(surface, &occlusion);
2761 // Surface is occluded, but only the top 10px of the replica.
2762 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2763 occlusion.UnoccludedContributingSurfaceContentRect(
2764 surface, false, gfx::Rect(0, 0, 100, 100)));
2765 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2766 occlusion.UnoccludedContributingSurfaceContentRect(
2767 surface, true, gfx::Rect(0, 0, 100, 100)));
2771 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2773 template <class Types>
2774 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
2775 : public OcclusionTrackerTest<Types> {
2776 protected:
2777 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
2778 bool opaque_layers)
2779 : OcclusionTrackerTest<Types>(opaque_layers) {}
2780 void RunMyTest() {
2781 typename Types::ContentLayerType* parent = this->CreateRoot(
2782 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2783 typename Types::LayerType* surface =
2784 this->CreateDrawingSurface(parent,
2785 this->identity_matrix,
2786 gfx::PointF(),
2787 gfx::Size(100, 100),
2788 true);
2789 this->CreateReplicaLayer(surface,
2790 this->identity_matrix,
2791 gfx::PointF(0.f, 100.f),
2792 gfx::Size(100, 100));
2793 typename Types::LayerType* over_surface = this->CreateDrawingLayer(
2794 parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
2795 typename Types::LayerType* over_replica =
2796 this->CreateDrawingLayer(parent,
2797 this->identity_matrix,
2798 gfx::PointF(0.f, 100.f),
2799 gfx::Size(50, 100),
2800 true);
2801 this->CalcDrawEtc(parent);
2803 TestOcclusionTrackerWithClip<typename Types::LayerType,
2804 typename Types::RenderSurfaceType> occlusion(
2805 gfx::Rect(0, 0, 1000, 1000));
2807 // These occlude the surface and replica differently, so we can test each
2808 // one.
2809 this->VisitLayer(over_replica, &occlusion);
2810 this->VisitLayer(over_surface, &occlusion);
2812 EXPECT_EQ(gfx::Rect().ToString(),
2813 occlusion.occlusion_from_outside_target().ToString());
2814 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2815 .ToString(),
2816 occlusion.occlusion_from_inside_target().ToString());
2818 this->VisitLayer(surface, &occlusion);
2820 // Render target with replica ignores occlusion from outside.
2821 EXPECT_EQ(gfx::Rect().ToString(),
2822 occlusion.occlusion_from_outside_target().ToString());
2823 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2824 occlusion.occlusion_from_inside_target().ToString());
2826 this->EnterContributingSurface(surface, &occlusion);
2828 // Surface and replica are occluded different amounts.
2829 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
2830 occlusion.UnoccludedContributingSurfaceContentRect(
2831 surface, false, gfx::Rect(0, 0, 100, 100)));
2832 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2833 occlusion.UnoccludedContributingSurfaceContentRect(
2834 surface, true, gfx::Rect(0, 0, 100, 100)));
2838 ALL_OCCLUSIONTRACKER_TEST(
2839 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2841 template <class Types>
2842 class OcclusionTrackerTestSurfaceChildOfSurface
2843 : public OcclusionTrackerTest<Types> {
2844 protected:
2845 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
2846 : OcclusionTrackerTest<Types>(opaque_layers) {}
2847 void RunMyTest() {
2848 // This test verifies that the surface cliprect does not end up empty and
2849 // clip away the entire unoccluded rect.
2851 typename Types::ContentLayerType* parent = this->CreateRoot(
2852 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2853 typename Types::LayerType* surface =
2854 this->CreateDrawingSurface(parent,
2855 this->identity_matrix,
2856 gfx::PointF(),
2857 gfx::Size(100, 100),
2858 true);
2859 typename Types::LayerType* surface_child =
2860 this->CreateDrawingSurface(surface,
2861 this->identity_matrix,
2862 gfx::PointF(0.f, 10.f),
2863 gfx::Size(100, 50),
2864 true);
2865 typename Types::LayerType* topmost = this->CreateDrawingLayer(
2866 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2867 this->CalcDrawEtc(parent);
2869 TestOcclusionTrackerWithClip<typename Types::LayerType,
2870 typename Types::RenderSurfaceType> occlusion(
2871 gfx::Rect(-100, -100, 1000, 1000));
2873 // |topmost| occludes everything partially so we know occlusion is happening
2874 // at all.
2875 this->VisitLayer(topmost, &occlusion);
2877 EXPECT_EQ(gfx::Rect().ToString(),
2878 occlusion.occlusion_from_outside_target().ToString());
2879 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2880 occlusion.occlusion_from_inside_target().ToString());
2882 this->VisitLayer(surface_child, &occlusion);
2884 // surface_child increases the occlusion in the screen by a narrow sliver.
2885 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2886 occlusion.occlusion_from_outside_target().ToString());
2887 // In its own surface, surface_child is at 0,0 as is its occlusion.
2888 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2889 occlusion.occlusion_from_inside_target().ToString());
2891 // The root layer always has a clip rect. So the parent of |surface| has a
2892 // clip rect. However, the owning layer for |surface| does not mask to
2893 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2894 // |surface_child| exercises different code paths as its parent does not
2895 // have a clip rect.
2897 this->EnterContributingSurface(surface_child, &occlusion);
2898 // The surface_child's parent does not have a clip rect as it owns a render
2899 // surface. Make sure the unoccluded rect does not get clipped away
2900 // inappropriately.
2901 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
2902 occlusion.UnoccludedContributingSurfaceContentRect(
2903 surface_child, false, gfx::Rect(0, 0, 100, 50)));
2904 this->LeaveContributingSurface(surface_child, &occlusion);
2906 // When the surface_child's occlusion is transformed up to its parent, make
2907 // sure it is not clipped away inappropriately also.
2908 this->EnterLayer(surface, &occlusion);
2909 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2910 occlusion.occlusion_from_outside_target().ToString());
2911 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2912 occlusion.occlusion_from_inside_target().ToString());
2913 this->LeaveLayer(surface, &occlusion);
2915 this->EnterContributingSurface(surface, &occlusion);
2916 // The surface's parent does have a clip rect as it is the root layer.
2917 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
2918 occlusion.UnoccludedContributingSurfaceContentRect(
2919 surface, false, gfx::Rect(0, 0, 100, 100)));
2923 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2925 template <class Types>
2926 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
2927 : public OcclusionTrackerTest<Types> {
2928 protected:
2929 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
2930 bool opaque_layers)
2931 : OcclusionTrackerTest<Types>(opaque_layers) {}
2932 void RunMyTest() {
2933 // This test verifies that the top-most surface is considered occluded
2934 // outside of its target's clip rect and outside the viewport rect.
2936 typename Types::ContentLayerType* parent = this->CreateRoot(
2937 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2938 typename Types::LayerType* surface =
2939 this->CreateDrawingSurface(parent,
2940 this->identity_matrix,
2941 gfx::PointF(),
2942 gfx::Size(100, 300),
2943 true);
2944 this->CalcDrawEtc(parent);
2946 // Make a viewport rect that is larger than the root layer.
2947 TestOcclusionTrackerWithClip<typename Types::LayerType,
2948 typename Types::RenderSurfaceType> occlusion(
2949 gfx::Rect(0, 0, 1000, 1000));
2951 this->VisitLayer(surface, &occlusion);
2953 // The root layer always has a clip rect. So the parent of |surface| has a
2954 // clip rect giving the surface itself a clip rect.
2955 this->EnterContributingSurface(surface, &occlusion);
2956 // Make sure the parent's clip rect clips the unoccluded region of the
2957 // child surface.
2958 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
2959 occlusion.UnoccludedContributingSurfaceContentRect(
2960 surface, false, gfx::Rect(0, 0, 100, 300)));
2962 this->ResetLayerIterator();
2964 // Make a viewport rect that is smaller than the root layer.
2965 TestOcclusionTrackerWithClip<typename Types::LayerType,
2966 typename Types::RenderSurfaceType> occlusion(
2967 gfx::Rect(0, 0, 100, 100));
2969 this->VisitLayer(surface, &occlusion);
2971 // The root layer always has a clip rect. So the parent of |surface| has a
2972 // clip rect giving the surface itself a clip rect.
2973 this->EnterContributingSurface(surface, &occlusion);
2974 // Make sure the viewport rect clips the unoccluded region of the child
2975 // surface.
2976 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2977 occlusion.UnoccludedContributingSurfaceContentRect(
2978 surface, false, gfx::Rect(0, 0, 100, 300)));
2983 ALL_OCCLUSIONTRACKER_TEST(
2984 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
2986 template <class Types>
2987 class OcclusionTrackerTestSurfaceChildOfClippingSurface
2988 : public OcclusionTrackerTest<Types> {
2989 protected:
2990 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers)
2991 : OcclusionTrackerTest<Types>(opaque_layers) {}
2992 void RunMyTest() {
2993 // This test verifies that the surface cliprect does not end up empty and
2994 // clip away the entire unoccluded rect.
2996 typename Types::ContentLayerType* parent = this->CreateRoot(
2997 this->identity_matrix, gfx::PointF(), gfx::Size(80, 200));
2998 parent->SetMasksToBounds(true);
2999 typename Types::LayerType* surface =
3000 this->CreateDrawingSurface(parent,
3001 this->identity_matrix,
3002 gfx::PointF(),
3003 gfx::Size(100, 100),
3004 true);
3005 typename Types::LayerType* surface_child =
3006 this->CreateDrawingSurface(surface,
3007 this->identity_matrix,
3008 gfx::PointF(),
3009 gfx::Size(100, 100),
3010 false);
3011 typename Types::LayerType* topmost = this->CreateDrawingLayer(
3012 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3013 this->CalcDrawEtc(parent);
3015 TestOcclusionTrackerWithClip<typename Types::LayerType,
3016 typename Types::RenderSurfaceType> occlusion(
3017 gfx::Rect(0, 0, 1000, 1000));
3019 // |topmost| occludes everything partially so we know occlusion is happening
3020 // at all.
3021 this->VisitLayer(topmost, &occlusion);
3023 EXPECT_EQ(gfx::Rect().ToString(),
3024 occlusion.occlusion_from_outside_target().ToString());
3025 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3026 occlusion.occlusion_from_inside_target().ToString());
3028 // surface_child is not opaque and does not occlude, so we have a non-empty
3029 // unoccluded area on surface.
3030 this->VisitLayer(surface_child, &occlusion);
3032 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3033 occlusion.occlusion_from_outside_target().ToString());
3034 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3035 occlusion.occlusion_from_inside_target().ToString());
3037 // The root layer always has a clip rect. So the parent of |surface| has a
3038 // clip rect. However, the owning layer for |surface| does not mask to
3039 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3040 // |surface_child| exercises different code paths as its parent does not
3041 // have a clip rect.
3043 this->EnterContributingSurface(surface_child, &occlusion);
3044 // The surface_child's parent does not have a clip rect as it owns a render
3045 // surface.
3046 EXPECT_EQ(
3047 gfx::Rect(0, 50, 80, 50).ToString(),
3048 occlusion.UnoccludedContributingSurfaceContentRect(
3049 surface_child, false, gfx::Rect(0, 0, 100, 100)).ToString());
3050 this->LeaveContributingSurface(surface_child, &occlusion);
3052 this->VisitLayer(surface, &occlusion);
3053 this->EnterContributingSurface(surface, &occlusion);
3054 // The surface's parent does have a clip rect as it is the root layer.
3055 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3056 occlusion.UnoccludedContributingSurfaceContentRect(
3057 surface, false, gfx::Rect(0, 0, 100, 100)).ToString());
3061 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
3063 template <class Types>
3064 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3065 : public OcclusionTrackerTest<Types> {
3066 protected:
3067 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3068 bool opaque_layers)
3069 : OcclusionTrackerTest<Types>(opaque_layers) {}
3070 void RunMyTest() {
3071 gfx::Transform scale_by_half;
3072 scale_by_half.Scale(0.5, 0.5);
3074 // Make a 50x50 filtered surface that is completely surrounded by opaque
3075 // layers which are above it in the z-order. The surface is scaled to test
3076 // that the pixel moving is done in the target space, where the background
3077 // filter is applied.
3078 typename Types::ContentLayerType* parent = this->CreateRoot(
3079 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
3080 typename Types::LayerType* filtered_surface =
3081 this->CreateDrawingLayer(parent,
3082 scale_by_half,
3083 gfx::PointF(50.f, 50.f),
3084 gfx::Size(100, 100),
3085 false);
3086 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3087 parent, this->identity_matrix, gfx::PointF(), gfx::Size(200, 50), true);
3088 typename Types::LayerType* occluding_layer2 =
3089 this->CreateDrawingLayer(parent,
3090 this->identity_matrix,
3091 gfx::PointF(0.f, 100.f),
3092 gfx::Size(200, 50),
3093 true);
3094 typename Types::LayerType* occluding_layer3 =
3095 this->CreateDrawingLayer(parent,
3096 this->identity_matrix,
3097 gfx::PointF(0.f, 50.f),
3098 gfx::Size(50, 50),
3099 true);
3100 typename Types::LayerType* occluding_layer4 =
3101 this->CreateDrawingLayer(parent,
3102 this->identity_matrix,
3103 gfx::PointF(100.f, 50.f),
3104 gfx::Size(100, 50),
3105 true);
3107 // Filters make the layer own a surface.
3108 FilterOperations filters;
3109 filters.Append(FilterOperation::CreateBlurFilter(10.f));
3110 filtered_surface->SetBackgroundFilters(filters);
3112 // Save the distance of influence for the blur effect.
3113 int outset_top, outset_right, outset_bottom, outset_left;
3114 filters.GetOutsets(
3115 &outset_top, &outset_right, &outset_bottom, &outset_left);
3117 this->CalcDrawEtc(parent);
3119 TestOcclusionTrackerWithClip<typename Types::LayerType,
3120 typename Types::RenderSurfaceType> occlusion(
3121 gfx::Rect(0, 0, 1000, 1000));
3123 // These layers occlude pixels directly beside the filtered_surface. Because
3124 // filtered surface blends pixels in a radius, it will need to see some of
3125 // the pixels (up to radius far) underneath the occluding layers.
3126 this->VisitLayer(occluding_layer4, &occlusion);
3127 this->VisitLayer(occluding_layer3, &occlusion);
3128 this->VisitLayer(occluding_layer2, &occlusion);
3129 this->VisitLayer(occluding_layer1, &occlusion);
3131 Region expected_occlusion;
3132 expected_occlusion.Union(gfx::Rect(0, 0, 200, 50));
3133 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3134 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3135 expected_occlusion.Union(gfx::Rect(0, 100, 200, 50));
3137 EXPECT_EQ(expected_occlusion.ToString(),
3138 occlusion.occlusion_from_inside_target().ToString());
3139 EXPECT_EQ(gfx::Rect().ToString(),
3140 occlusion.occlusion_from_outside_target().ToString());
3142 this->VisitLayer(filtered_surface, &occlusion);
3144 // The filtered layer does not occlude.
3145 Region expected_occlusion_outside_surface;
3146 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 200, 50));
3147 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3148 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3149 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 200, 50));
3151 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3152 occlusion.occlusion_from_outside_target().ToString());
3153 EXPECT_EQ(gfx::Rect().ToString(),
3154 occlusion.occlusion_from_inside_target().ToString());
3156 // The surface has a background blur, so it needs pixels that are currently
3157 // considered occluded in order to be drawn. So the pixels it needs should
3158 // be removed some the occluded area so that when we get to the parent they
3159 // are drawn.
3160 this->VisitContributingSurface(filtered_surface, &occlusion);
3162 this->EnterLayer(parent, &occlusion);
3164 Region expected_blurred_occlusion;
3165 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 200, 50 - outset_top));
3166 expected_blurred_occlusion.Union(gfx::Rect(
3167 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
3168 expected_blurred_occlusion.Union(
3169 gfx::Rect(100 + outset_right,
3170 50 - outset_top,
3171 100 - outset_right,
3172 50 + outset_top + outset_bottom));
3173 expected_blurred_occlusion.Union(
3174 gfx::Rect(0, 100 + outset_bottom, 200, 50 - outset_bottom));
3176 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3177 occlusion.occlusion_from_inside_target().ToString());
3178 EXPECT_EQ(gfx::Rect().ToString(),
3179 occlusion.occlusion_from_outside_target().ToString());
3181 gfx::Rect outset_rect;
3182 gfx::Rect test_rect;
3184 // Nothing in the blur outsets for the filtered_surface is occluded.
3185 outset_rect = gfx::Rect(50 - outset_left,
3186 50 - outset_top,
3187 50 + outset_left + outset_right,
3188 50 + outset_top + outset_bottom);
3189 test_rect = outset_rect;
3190 EXPECT_EQ(
3191 outset_rect.ToString(),
3192 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3194 // Stuff outside the blur outsets is still occluded though.
3195 test_rect = outset_rect;
3196 test_rect.Inset(0, 0, -1, 0);
3197 EXPECT_EQ(
3198 outset_rect.ToString(),
3199 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3200 test_rect = outset_rect;
3201 test_rect.Inset(0, 0, 0, -1);
3202 EXPECT_EQ(
3203 outset_rect.ToString(),
3204 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3205 test_rect = outset_rect;
3206 test_rect.Inset(-1, 0, 0, 0);
3207 EXPECT_EQ(
3208 outset_rect.ToString(),
3209 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3210 test_rect = outset_rect;
3211 test_rect.Inset(0, -1, 0, 0);
3212 EXPECT_EQ(
3213 outset_rect.ToString(),
3214 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3218 ALL_OCCLUSIONTRACKER_TEST(
3219 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
3221 template <class Types>
3222 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3223 : public OcclusionTrackerTest<Types> {
3224 protected:
3225 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3226 bool opaque_layers)
3227 : OcclusionTrackerTest<Types>(opaque_layers) {}
3228 void RunMyTest() {
3229 gfx::Transform scale_by_half;
3230 scale_by_half.Scale(0.5, 0.5);
3232 // Makes two surfaces that completely cover |parent|. The occlusion both
3233 // above and below the filters will be reduced by each of them.
3234 typename Types::ContentLayerType* root = this->CreateRoot(
3235 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
3236 typename Types::LayerType* parent = this->CreateSurface(
3237 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
3238 parent->SetMasksToBounds(true);
3239 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
3240 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3241 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
3242 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3243 typename Types::LayerType* occluding_layer_above =
3244 this->CreateDrawingLayer(parent,
3245 this->identity_matrix,
3246 gfx::PointF(100.f, 100.f),
3247 gfx::Size(50, 50),
3248 true);
3250 // Filters make the layers own surfaces.
3251 FilterOperations filters;
3252 filters.Append(FilterOperation::CreateBlurFilter(1.f));
3253 filtered_surface1->SetBackgroundFilters(filters);
3254 filtered_surface2->SetBackgroundFilters(filters);
3256 // Save the distance of influence for the blur effect.
3257 int outset_top, outset_right, outset_bottom, outset_left;
3258 filters.GetOutsets(
3259 &outset_top, &outset_right, &outset_bottom, &outset_left);
3261 this->CalcDrawEtc(root);
3263 TestOcclusionTrackerWithClip<typename Types::LayerType,
3264 typename Types::RenderSurfaceType> occlusion(
3265 gfx::Rect(0, 0, 1000, 1000));
3267 this->VisitLayer(occluding_layer_above, &occlusion);
3268 EXPECT_EQ(gfx::Rect().ToString(),
3269 occlusion.occlusion_from_outside_target().ToString());
3270 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3271 occlusion.occlusion_from_inside_target().ToString());
3273 this->VisitLayer(filtered_surface2, &occlusion);
3274 this->VisitContributingSurface(filtered_surface2, &occlusion);
3275 this->VisitLayer(filtered_surface1, &occlusion);
3276 this->VisitContributingSurface(filtered_surface1, &occlusion);
3278 // Test expectations in the target.
3279 gfx::Rect expected_occlusion =
3280 gfx::Rect(100 / 2 + outset_right * 2,
3281 100 / 2 + outset_bottom * 2,
3282 50 / 2 - (outset_left + outset_right) * 2,
3283 50 / 2 - (outset_top + outset_bottom) * 2);
3284 EXPECT_EQ(expected_occlusion.ToString(),
3285 occlusion.occlusion_from_inside_target().ToString());
3287 // Test expectations in the screen are the same as in the target, as the
3288 // render surface is 1:1 with the screen.
3289 EXPECT_EQ(expected_occlusion.ToString(),
3290 occlusion.occlusion_from_outside_target().ToString());
3294 ALL_OCCLUSIONTRACKER_TEST(
3295 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
3297 template <class Types>
3298 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3299 : public OcclusionTrackerTest<Types> {
3300 protected:
3301 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3302 bool opaque_layers)
3303 : OcclusionTrackerTest<Types>(opaque_layers) {}
3304 void RunMyTest() {
3305 gfx::Transform scale_by_half;
3306 scale_by_half.Scale(0.5, 0.5);
3308 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3309 // centered below each. The surface is scaled to test that the pixel moving
3310 // is done in the target space, where the background filter is applied, but
3311 // the surface appears at 50, 50 and the replica at 200, 50.
3312 typename Types::ContentLayerType* parent = this->CreateRoot(
3313 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3314 typename Types::LayerType* behind_surface_layer =
3315 this->CreateDrawingLayer(parent,
3316 this->identity_matrix,
3317 gfx::PointF(60.f, 60.f),
3318 gfx::Size(30, 30),
3319 true);
3320 typename Types::LayerType* behind_replica_layer =
3321 this->CreateDrawingLayer(parent,
3322 this->identity_matrix,
3323 gfx::PointF(210.f, 60.f),
3324 gfx::Size(30, 30),
3325 true);
3326 typename Types::LayerType* filtered_surface =
3327 this->CreateDrawingLayer(parent,
3328 scale_by_half,
3329 gfx::PointF(50.f, 50.f),
3330 gfx::Size(100, 100),
3331 false);
3332 this->CreateReplicaLayer(filtered_surface,
3333 this->identity_matrix,
3334 gfx::PointF(300.f, 0.f),
3335 gfx::Size());
3337 // Filters make the layer own a surface.
3338 FilterOperations filters;
3339 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3340 filtered_surface->SetBackgroundFilters(filters);
3342 this->CalcDrawEtc(parent);
3344 TestOcclusionTrackerWithClip<typename Types::LayerType,
3345 typename Types::RenderSurfaceType> occlusion(
3346 gfx::Rect(0, 0, 1000, 1000));
3348 // The surface has a background blur, so it blurs non-opaque pixels below
3349 // it.
3350 this->VisitLayer(filtered_surface, &occlusion);
3351 this->VisitContributingSurface(filtered_surface, &occlusion);
3353 this->VisitLayer(behind_replica_layer, &occlusion);
3354 this->VisitLayer(behind_surface_layer, &occlusion);
3356 // The layers behind the surface are not blurred, and their occlusion does
3357 // not change, until we leave the surface. So it should not be modified by
3358 // the filter here.
3359 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
3360 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
3362 Region expected_opaque_bounds =
3363 UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
3364 EXPECT_EQ(expected_opaque_bounds.ToString(),
3365 occlusion.occlusion_from_inside_target().ToString());
3367 EXPECT_EQ(gfx::Rect().ToString(),
3368 occlusion.occlusion_from_outside_target().ToString());
3372 ALL_OCCLUSIONTRACKER_TEST(
3373 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
3375 template <class Types>
3376 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3377 : public OcclusionTrackerTest<Types> {
3378 protected:
3379 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3380 bool opaque_layers)
3381 : OcclusionTrackerTest<Types>(opaque_layers) {}
3382 void RunMyTest() {
3383 gfx::Transform scale_by_half;
3384 scale_by_half.Scale(0.5, 0.5);
3386 // Make a 50x50 filtered surface that is completely occluded by an opaque
3387 // layer which is above it in the z-order. The surface is
3388 // scaled to test that the pixel moving is done in the target space, where
3389 // the background filter is applied, but the surface appears at 50, 50.
3390 typename Types::ContentLayerType* parent = this->CreateRoot(
3391 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
3392 typename Types::LayerType* filtered_surface =
3393 this->CreateDrawingLayer(parent,
3394 scale_by_half,
3395 gfx::PointF(50.f, 50.f),
3396 gfx::Size(100, 100),
3397 false);
3398 typename Types::LayerType* occluding_layer =
3399 this->CreateDrawingLayer(parent,
3400 this->identity_matrix,
3401 gfx::PointF(50.f, 50.f),
3402 gfx::Size(50, 50),
3403 true);
3405 // Filters make the layer own a surface.
3406 FilterOperations filters;
3407 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3408 filtered_surface->SetBackgroundFilters(filters);
3410 this->CalcDrawEtc(parent);
3412 TestOcclusionTrackerWithClip<typename Types::LayerType,
3413 typename Types::RenderSurfaceType> occlusion(
3414 gfx::Rect(0, 0, 1000, 1000));
3416 this->VisitLayer(occluding_layer, &occlusion);
3418 this->VisitLayer(filtered_surface, &occlusion);
3420 // The layers above the filtered surface occlude from outside.
3421 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
3423 EXPECT_EQ(gfx::Rect().ToString(),
3424 occlusion.occlusion_from_inside_target().ToString());
3425 EXPECT_EQ(occlusion_above_surface.ToString(),
3426 occlusion.occlusion_from_outside_target().ToString());
3429 // The surface has a background blur, so it blurs non-opaque pixels below
3430 // it.
3431 this->VisitContributingSurface(filtered_surface, &occlusion);
3433 // The filter is completely occluded, so it should not blur anything and
3434 // reduce any occlusion.
3435 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
3437 EXPECT_EQ(occlusion_above_surface.ToString(),
3438 occlusion.occlusion_from_inside_target().ToString());
3439 EXPECT_EQ(gfx::Rect().ToString(),
3440 occlusion.occlusion_from_outside_target().ToString());
3445 ALL_OCCLUSIONTRACKER_TEST(
3446 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
3448 template <class Types>
3449 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3450 : public OcclusionTrackerTest<Types> {
3451 protected:
3452 explicit
3453 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3454 bool opaque_layers)
3455 : OcclusionTrackerTest<Types>(opaque_layers) {}
3456 void RunMyTest() {
3457 gfx::Transform scale_by_half;
3458 scale_by_half.Scale(0.5, 0.5);
3460 // Make a surface and its replica, each 50x50, that are partially occluded
3461 // by opaque layers which are above them in the z-order. The surface is
3462 // scaled to test that the pixel moving is done in the target space, where
3463 // the background filter is applied, but the surface appears at 50, 50 and
3464 // the replica at 200, 50.
3465 typename Types::ContentLayerType* parent = this->CreateRoot(
3466 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3467 typename Types::LayerType* filtered_surface =
3468 this->CreateDrawingLayer(parent,
3469 scale_by_half,
3470 gfx::PointF(50.f, 50.f),
3471 gfx::Size(100, 100),
3472 false);
3473 this->CreateReplicaLayer(filtered_surface,
3474 this->identity_matrix,
3475 gfx::PointF(300.f, 0.f),
3476 gfx::Size());
3477 typename Types::LayerType* above_surface_layer =
3478 this->CreateDrawingLayer(parent,
3479 this->identity_matrix,
3480 gfx::PointF(70.f, 50.f),
3481 gfx::Size(30, 50),
3482 true);
3483 typename Types::LayerType* above_replica_layer =
3484 this->CreateDrawingLayer(parent,
3485 this->identity_matrix,
3486 gfx::PointF(200.f, 50.f),
3487 gfx::Size(30, 50),
3488 true);
3489 typename Types::LayerType* beside_surface_layer =
3490 this->CreateDrawingLayer(parent,
3491 this->identity_matrix,
3492 gfx::PointF(90.f, 40.f),
3493 gfx::Size(10, 10),
3494 true);
3495 typename Types::LayerType* beside_replica_layer =
3496 this->CreateDrawingLayer(parent,
3497 this->identity_matrix,
3498 gfx::PointF(200.f, 40.f),
3499 gfx::Size(10, 10),
3500 true);
3502 // Filters make the layer own a surface.
3503 FilterOperations filters;
3504 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3505 filtered_surface->SetBackgroundFilters(filters);
3507 // Save the distance of influence for the blur effect.
3508 int outset_top, outset_right, outset_bottom, outset_left;
3509 filters.GetOutsets(
3510 &outset_top, &outset_right, &outset_bottom, &outset_left);
3512 this->CalcDrawEtc(parent);
3514 TestOcclusionTrackerWithClip<typename Types::LayerType,
3515 typename Types::RenderSurfaceType> occlusion(
3516 gfx::Rect(0, 0, 1000, 1000));
3518 this->VisitLayer(beside_replica_layer, &occlusion);
3519 this->VisitLayer(beside_surface_layer, &occlusion);
3520 this->VisitLayer(above_replica_layer, &occlusion);
3521 this->VisitLayer(above_surface_layer, &occlusion);
3523 // The surface has a background blur, so it blurs non-opaque pixels below
3524 // it.
3525 this->VisitLayer(filtered_surface, &occlusion);
3526 this->VisitContributingSurface(filtered_surface, &occlusion);
3528 // The filter in the surface and replica are partially unoccluded. Only the
3529 // unoccluded parts should reduce occlusion. This means it will push back
3530 // the occlusion that touches the unoccluded part (occlusion_above___), but
3531 // it will not touch occlusion_beside____ since that is not beside the
3532 // unoccluded part of the surface, even though it is beside the occluded
3533 // part of the surface.
3534 gfx::Rect occlusion_above_surface =
3535 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
3536 gfx::Rect occlusion_above_replica =
3537 gfx::Rect(200, 50, 30 - outset_left, 50);
3538 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
3539 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
3541 Region expected_occlusion;
3542 expected_occlusion.Union(occlusion_above_surface);
3543 expected_occlusion.Union(occlusion_above_replica);
3544 expected_occlusion.Union(occlusion_beside_surface);
3545 expected_occlusion.Union(occlusion_beside_replica);
3547 ASSERT_EQ(expected_occlusion.ToString(),
3548 occlusion.occlusion_from_inside_target().ToString());
3549 EXPECT_EQ(gfx::Rect().ToString(),
3550 occlusion.occlusion_from_outside_target().ToString());
3552 Region::Iterator expected_rects(expected_occlusion);
3553 Region::Iterator target_surface_rects(
3554 occlusion.occlusion_from_inside_target());
3555 for (; expected_rects.has_rect();
3556 expected_rects.next(), target_surface_rects.next()) {
3557 ASSERT_TRUE(target_surface_rects.has_rect());
3558 EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
3563 ALL_OCCLUSIONTRACKER_TEST(
3564 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
3566 template <class Types>
3567 class OcclusionTrackerTestMinimumTrackingSize
3568 : public OcclusionTrackerTest<Types> {
3569 protected:
3570 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
3571 : OcclusionTrackerTest<Types>(opaque_layers) {}
3572 void RunMyTest() {
3573 gfx::Size tracking_size(100, 100);
3574 gfx::Size below_tracking_size(99, 99);
3576 typename Types::ContentLayerType* parent = this->CreateRoot(
3577 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3578 typename Types::LayerType* large = this->CreateDrawingLayer(
3579 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
3580 typename Types::LayerType* small =
3581 this->CreateDrawingLayer(parent,
3582 this->identity_matrix,
3583 gfx::PointF(),
3584 below_tracking_size,
3585 true);
3586 this->CalcDrawEtc(parent);
3588 TestOcclusionTrackerWithClip<typename Types::LayerType,
3589 typename Types::RenderSurfaceType> occlusion(
3590 gfx::Rect(0, 0, 1000, 1000));
3591 occlusion.set_minimum_tracking_size(tracking_size);
3593 // The small layer is not tracked because it is too small.
3594 this->VisitLayer(small, &occlusion);
3596 EXPECT_EQ(gfx::Rect().ToString(),
3597 occlusion.occlusion_from_outside_target().ToString());
3598 EXPECT_EQ(gfx::Rect().ToString(),
3599 occlusion.occlusion_from_inside_target().ToString());
3601 // The large layer is tracked as it is large enough.
3602 this->VisitLayer(large, &occlusion);
3604 EXPECT_EQ(gfx::Rect().ToString(),
3605 occlusion.occlusion_from_outside_target().ToString());
3606 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
3607 occlusion.occlusion_from_inside_target().ToString());
3611 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
3613 template <class Types>
3614 class OcclusionTrackerTestScaledLayerIsClipped
3615 : public OcclusionTrackerTest<Types> {
3616 protected:
3617 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
3618 : OcclusionTrackerTest<Types>(opaque_layers) {}
3619 void RunMyTest() {
3620 gfx::Transform scale_transform;
3621 scale_transform.Scale(512.0, 512.0);
3623 typename Types::ContentLayerType* parent = this->CreateRoot(
3624 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3625 typename Types::LayerType* clip = this->CreateLayer(parent,
3626 this->identity_matrix,
3627 gfx::PointF(10.f, 10.f),
3628 gfx::Size(50, 50));
3629 clip->SetMasksToBounds(true);
3630 typename Types::LayerType* scale = this->CreateLayer(
3631 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3632 typename Types::LayerType* scaled = this->CreateDrawingLayer(
3633 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3634 this->CalcDrawEtc(parent);
3636 TestOcclusionTrackerWithClip<typename Types::LayerType,
3637 typename Types::RenderSurfaceType> occlusion(
3638 gfx::Rect(0, 0, 1000, 1000));
3640 this->VisitLayer(scaled, &occlusion);
3642 EXPECT_EQ(gfx::Rect().ToString(),
3643 occlusion.occlusion_from_outside_target().ToString());
3644 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3645 occlusion.occlusion_from_inside_target().ToString());
3649 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
3651 template <class Types>
3652 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3653 : public OcclusionTrackerTest<Types> {
3654 protected:
3655 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
3656 : OcclusionTrackerTest<Types>(opaque_layers) {}
3657 void RunMyTest() {
3658 gfx::Transform scale_transform;
3659 scale_transform.Scale(512.0, 512.0);
3661 typename Types::ContentLayerType* parent = this->CreateRoot(
3662 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3663 typename Types::LayerType* clip = this->CreateLayer(parent,
3664 this->identity_matrix,
3665 gfx::PointF(10.f, 10.f),
3666 gfx::Size(50, 50));
3667 clip->SetMasksToBounds(true);
3668 typename Types::LayerType* surface = this->CreateDrawingSurface(
3669 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
3670 typename Types::LayerType* scale = this->CreateLayer(
3671 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3672 typename Types::LayerType* scaled = this->CreateDrawingLayer(
3673 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3674 this->CalcDrawEtc(parent);
3676 TestOcclusionTrackerWithClip<typename Types::LayerType,
3677 typename Types::RenderSurfaceType> occlusion(
3678 gfx::Rect(0, 0, 1000, 1000));
3680 this->VisitLayer(scaled, &occlusion);
3681 this->VisitLayer(surface, &occlusion);
3682 this->VisitContributingSurface(surface, &occlusion);
3684 EXPECT_EQ(gfx::Rect().ToString(),
3685 occlusion.occlusion_from_outside_target().ToString());
3686 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3687 occlusion.occlusion_from_inside_target().ToString());
3691 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
3693 template <class Types>
3694 class OcclusionTrackerTestCopyRequestDoesOcclude
3695 : public OcclusionTrackerTest<Types> {
3696 protected:
3697 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
3698 : OcclusionTrackerTest<Types>(opaque_layers) {}
3699 void RunMyTest() {
3700 typename Types::ContentLayerType* root = this->CreateRoot(
3701 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3702 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3703 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3704 typename Types::LayerType* copy = this->CreateLayer(parent,
3705 this->identity_matrix,
3706 gfx::Point(100, 0),
3707 gfx::Size(200, 400));
3708 this->AddCopyRequest(copy);
3709 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3710 copy,
3711 this->identity_matrix,
3712 gfx::PointF(),
3713 gfx::Size(200, 400),
3714 true);
3715 this->CalcDrawEtc(root);
3717 TestOcclusionTrackerWithClip<typename Types::LayerType,
3718 typename Types::RenderSurfaceType> occlusion(
3719 gfx::Rect(0, 0, 1000, 1000));
3721 this->VisitLayer(copy_child, &occlusion);
3722 EXPECT_EQ(gfx::Rect().ToString(),
3723 occlusion.occlusion_from_outside_target().ToString());
3724 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3725 occlusion.occlusion_from_inside_target().ToString());
3727 // CopyRequests cause the layer to own a surface.
3728 this->VisitContributingSurface(copy, &occlusion);
3730 // The occlusion from the copy should be kept.
3731 EXPECT_EQ(gfx::Rect().ToString(),
3732 occlusion.occlusion_from_outside_target().ToString());
3733 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3734 occlusion.occlusion_from_inside_target().ToString());
3738 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
3740 template <class Types>
3741 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3742 : public OcclusionTrackerTest<Types> {
3743 protected:
3744 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3745 bool opaque_layers)
3746 : OcclusionTrackerTest<Types>(opaque_layers) {}
3747 void RunMyTest() {
3748 typename Types::ContentLayerType* root = this->CreateRoot(
3749 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3750 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3751 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3752 typename Types::LayerType* hide = this->CreateLayer(
3753 parent, this->identity_matrix, gfx::Point(), gfx::Size());
3754 typename Types::LayerType* copy = this->CreateLayer(
3755 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
3756 this->AddCopyRequest(copy);
3757 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3758 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
3760 // The |copy| layer is hidden but since it is being copied, it will be
3761 // drawn.
3762 hide->SetHideLayerAndSubtree(true);
3764 this->CalcDrawEtc(root);
3766 TestOcclusionTrackerWithClip<typename Types::LayerType,
3767 typename Types::RenderSurfaceType> occlusion(
3768 gfx::Rect(0, 0, 1000, 1000));
3770 this->VisitLayer(copy_child, &occlusion);
3771 EXPECT_EQ(gfx::Rect().ToString(),
3772 occlusion.occlusion_from_outside_target().ToString());
3773 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3774 occlusion.occlusion_from_inside_target().ToString());
3776 // CopyRequests cause the layer to own a surface.
3777 this->VisitContributingSurface(copy, &occlusion);
3779 // The occlusion from the copy should be dropped since it is hidden.
3780 EXPECT_EQ(gfx::Rect().ToString(),
3781 occlusion.occlusion_from_outside_target().ToString());
3782 EXPECT_EQ(gfx::Rect().ToString(),
3783 occlusion.occlusion_from_inside_target().ToString());
3787 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
3789 template <class Types>
3790 class OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
3791 : public OcclusionTrackerTest<Types> {
3792 protected:
3793 explicit OcclusionTrackerTestEmptyEventLayerDoesNotOcclude(
3794 bool opaque_layers)
3795 : OcclusionTrackerTest<Types>(opaque_layers) {}
3796 void RunMyTest() {
3797 typename Types::ContentLayerType* root = this->CreateRoot(
3798 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3799 typename Types::ContentLayerType* empty_layer = this->CreateDrawingLayer(
3800 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), true);
3801 this->SetDrawsContent(empty_layer, false);
3802 empty_layer->SetTouchEventHandlerRegion(gfx::Rect(10, 10, 10, 10));
3804 this->CalcDrawEtc(root);
3806 TestOcclusionTrackerWithClip<typename Types::LayerType,
3807 typename Types::RenderSurfaceType> occlusion(
3808 gfx::Rect(0, 0, 1000, 1000), false);
3810 this->VisitLayer(empty_layer, &occlusion);
3812 EXPECT_EQ(gfx::Rect().ToString(),
3813 occlusion.occlusion_from_outside_target().ToString());
3814 EXPECT_EQ(gfx::Rect().ToString(),
3815 occlusion.occlusion_from_inside_target().ToString());
3819 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude)
3821 } // namespace
3822 } // namespace cc