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