Lots of random cleanups, mostly for native_theme_win.cc:
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob1a6529bc557f1dfeaf8c330bd89e6eb8747d6311
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(content_rect, layer->draw_transform());
96 gfx::Rect UnoccludedSurfaceContentRect(const LayerType* layer,
97 bool for_replica,
98 const gfx::Rect& content_rect) const {
99 typename LayerType::RenderSurfaceType* surface = layer->render_surface();
100 gfx::Transform draw_transform = for_replica
101 ? surface->replica_draw_transform()
102 : surface->draw_transform();
103 return this->UnoccludedContributingSurfaceContentRect(content_rect,
104 draw_transform);
108 struct OcclusionTrackerTestMainThreadTypes {
109 typedef Layer LayerType;
110 typedef FakeLayerTreeHost HostType;
111 typedef RenderSurface RenderSurfaceType;
112 typedef TestContentLayer ContentLayerType;
113 typedef scoped_refptr<Layer> LayerPtrType;
114 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
115 typedef LayerIterator<Layer> TestLayerIterator;
116 typedef OcclusionTracker<Layer> OcclusionTrackerType;
118 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
119 static ContentLayerPtrType CreateContentLayer(HostType* host) {
120 return make_scoped_refptr(new ContentLayerType());
123 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
124 LayerPtrType ref(*layer);
125 *layer = NULL;
126 return ref;
129 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
130 LayerPtrType ref(*layer);
131 *layer = NULL;
132 return ref;
135 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
138 struct OcclusionTrackerTestImplThreadTypes {
139 typedef LayerImpl LayerType;
140 typedef LayerTreeImpl HostType;
141 typedef RenderSurfaceImpl RenderSurfaceType;
142 typedef TestContentLayerImpl ContentLayerType;
143 typedef scoped_ptr<LayerImpl> LayerPtrType;
144 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
145 typedef LayerIterator<LayerImpl> TestLayerIterator;
146 typedef OcclusionTracker<LayerImpl> OcclusionTrackerType;
148 static LayerPtrType CreateLayer(HostType* host) {
149 return LayerImpl::Create(host, next_layer_impl_id++);
151 static ContentLayerPtrType CreateContentLayer(HostType* host) {
152 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
154 static int next_layer_impl_id;
156 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
157 return layer->Pass();
160 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
161 return layer->PassAs<LayerType>();
164 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
167 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
169 template <typename Types> class OcclusionTrackerTest : public testing::Test {
170 protected:
171 explicit OcclusionTrackerTest(bool opaque_layers)
172 : opaque_layers_(opaque_layers), host_(FakeLayerTreeHost::Create()) {}
174 virtual void RunMyTest() = 0;
176 virtual void TearDown() {
177 Types::DestroyLayer(&root_);
178 render_surface_layer_list_.reset();
179 render_surface_layer_list_impl_.clear();
180 replica_layers_.clear();
181 mask_layers_.clear();
184 typename Types::HostType* GetHost();
186 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
187 const gfx::PointF& position,
188 const gfx::Size& bounds) {
189 typename Types::ContentLayerPtrType layer(
190 Types::CreateContentLayer(GetHost()));
191 typename Types::ContentLayerType* layer_ptr = layer.get();
192 SetProperties(layer_ptr, transform, position, bounds);
194 DCHECK(!root_.get());
195 root_ = Types::PassLayerPtr(&layer);
197 SetRootLayerOnMainThread(layer_ptr);
199 return layer_ptr;
202 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
203 const gfx::Transform& transform,
204 const gfx::PointF& position,
205 const gfx::Size& bounds) {
206 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
207 typename Types::LayerType* layer_ptr = layer.get();
208 SetProperties(layer_ptr, transform, position, bounds);
209 parent->AddChild(Types::PassLayerPtr(&layer));
210 return layer_ptr;
213 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
214 const gfx::Transform& transform,
215 const gfx::PointF& position,
216 const gfx::Size& bounds) {
217 typename Types::LayerType* layer =
218 CreateLayer(parent, transform, position, bounds);
219 layer->SetForceRenderSurface(true);
220 return layer;
223 typename Types::ContentLayerType* CreateDrawingLayer(
224 typename Types::LayerType* parent,
225 const gfx::Transform& transform,
226 const gfx::PointF& position,
227 const gfx::Size& bounds,
228 bool opaque) {
229 typename Types::ContentLayerPtrType layer(
230 Types::CreateContentLayer(GetHost()));
231 typename Types::ContentLayerType* layer_ptr = layer.get();
232 SetProperties(layer_ptr, transform, position, bounds);
234 if (opaque_layers_) {
235 layer_ptr->SetContentsOpaque(opaque);
236 } else {
237 layer_ptr->SetContentsOpaque(false);
238 if (opaque)
239 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
240 else
241 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
244 parent->AddChild(Types::PassLayerPtr(&layer));
245 return layer_ptr;
248 typename Types::LayerType* CreateReplicaLayer(
249 typename Types::LayerType* owning_layer,
250 const gfx::Transform& transform,
251 const gfx::PointF& position,
252 const gfx::Size& bounds) {
253 typename Types::ContentLayerPtrType layer(
254 Types::CreateContentLayer(GetHost()));
255 typename Types::ContentLayerType* layer_ptr = layer.get();
256 SetProperties(layer_ptr, transform, position, bounds);
257 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
258 return layer_ptr;
261 typename Types::LayerType* CreateMaskLayer(
262 typename Types::LayerType* owning_layer,
263 const gfx::Size& bounds) {
264 typename Types::ContentLayerPtrType layer(
265 Types::CreateContentLayer(GetHost()));
266 typename Types::ContentLayerType* layer_ptr = layer.get();
267 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
268 SetMask(owning_layer, Types::PassLayerPtr(&layer));
269 return layer_ptr;
272 typename Types::ContentLayerType* CreateDrawingSurface(
273 typename Types::LayerType* parent,
274 const gfx::Transform& transform,
275 const gfx::PointF& position,
276 const gfx::Size& bounds,
277 bool opaque) {
278 typename Types::ContentLayerType* layer =
279 CreateDrawingLayer(parent, transform, position, bounds, opaque);
280 layer->SetForceRenderSurface(true);
281 return layer;
285 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
287 void AddCopyRequest(Layer* layer) {
288 layer->RequestCopyOfOutput(
289 CopyOutputRequest::CreateBitmapRequest(base::Bind(
290 &OcclusionTrackerTest<Types>::CopyOutputCallback,
291 base::Unretained(this))));
294 void AddCopyRequest(LayerImpl* layer) {
295 ScopedPtrVector<CopyOutputRequest> requests;
296 requests.push_back(
297 CopyOutputRequest::CreateBitmapRequest(base::Bind(
298 &OcclusionTrackerTest<Types>::CopyOutputCallback,
299 base::Unretained(this))));
300 layer->PassCopyRequests(&requests);
303 void CalcDrawEtc(TestContentLayerImpl* root) {
304 DCHECK(root == root_.get());
305 DCHECK(!root->render_surface());
307 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
308 root, root->bounds(), &render_surface_layer_list_impl_);
309 inputs.can_adjust_raster_scales = true;
310 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
312 layer_iterator_ = layer_iterator_begin_ =
313 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
316 void CalcDrawEtc(TestContentLayer* root) {
317 DCHECK(root == root_.get());
318 DCHECK(!root->render_surface());
320 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
321 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
322 root, root->bounds(), render_surface_layer_list_.get());
323 inputs.can_adjust_raster_scales = true;
324 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
326 layer_iterator_ = layer_iterator_begin_ =
327 Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
330 void EnterLayer(typename Types::LayerType* layer,
331 typename Types::OcclusionTrackerType* occlusion) {
332 ASSERT_EQ(layer, *layer_iterator_);
333 ASSERT_TRUE(layer_iterator_.represents_itself());
334 occlusion->EnterLayer(layer_iterator_);
337 void LeaveLayer(typename Types::LayerType* layer,
338 typename Types::OcclusionTrackerType* occlusion) {
339 ASSERT_EQ(layer, *layer_iterator_);
340 ASSERT_TRUE(layer_iterator_.represents_itself());
341 occlusion->LeaveLayer(layer_iterator_);
342 ++layer_iterator_;
345 void VisitLayer(typename Types::LayerType* layer,
346 typename Types::OcclusionTrackerType* occlusion) {
347 EnterLayer(layer, occlusion);
348 LeaveLayer(layer, occlusion);
351 void EnterContributingSurface(
352 typename Types::LayerType* layer,
353 typename Types::OcclusionTrackerType* occlusion) {
354 ASSERT_EQ(layer, *layer_iterator_);
355 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
356 occlusion->EnterLayer(layer_iterator_);
357 occlusion->LeaveLayer(layer_iterator_);
358 ++layer_iterator_;
359 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
360 occlusion->EnterLayer(layer_iterator_);
363 void LeaveContributingSurface(
364 typename Types::LayerType* layer,
365 typename Types::OcclusionTrackerType* occlusion) {
366 ASSERT_EQ(layer, *layer_iterator_);
367 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
368 occlusion->LeaveLayer(layer_iterator_);
369 ++layer_iterator_;
372 void VisitContributingSurface(
373 typename Types::LayerType* layer,
374 typename Types::OcclusionTrackerType* occlusion) {
375 EnterContributingSurface(layer, occlusion);
376 LeaveContributingSurface(layer, occlusion);
379 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
381 const gfx::Transform identity_matrix;
383 private:
384 void SetRootLayerOnMainThread(Layer* root) {
385 host_->SetRootLayer(scoped_refptr<Layer>(root));
388 void SetRootLayerOnMainThread(LayerImpl* root) {}
390 void SetBaseProperties(typename Types::LayerType* layer,
391 const gfx::Transform& transform,
392 const gfx::PointF& position,
393 const gfx::Size& bounds) {
394 layer->SetTransform(transform);
395 layer->SetPosition(position);
396 layer->SetBounds(bounds);
399 void SetProperties(Layer* layer,
400 const gfx::Transform& transform,
401 const gfx::PointF& position,
402 const gfx::Size& bounds) {
403 SetBaseProperties(layer, transform, position, bounds);
406 void SetProperties(LayerImpl* layer,
407 const gfx::Transform& transform,
408 const gfx::PointF& position,
409 const gfx::Size& bounds) {
410 SetBaseProperties(layer, transform, position, bounds);
412 layer->SetContentBounds(layer->bounds());
415 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
416 owning_layer->SetReplicaLayer(layer.get());
417 replica_layers_.push_back(layer);
420 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
421 owning_layer->SetReplicaLayer(layer.Pass());
424 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
425 owning_layer->SetMaskLayer(layer.get());
426 mask_layers_.push_back(layer);
429 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
430 owning_layer->SetMaskLayer(layer.Pass());
433 bool opaque_layers_;
434 scoped_ptr<FakeLayerTreeHost> host_;
435 // These hold ownership of the layers for the duration of the test.
436 typename Types::LayerPtrType root_;
437 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
438 LayerImplList render_surface_layer_list_impl_;
439 typename Types::TestLayerIterator layer_iterator_begin_;
440 typename Types::TestLayerIterator layer_iterator_;
441 typename Types::LayerType* last_layer_visited_;
442 LayerList replica_layers_;
443 LayerList mask_layers_;
446 template <>
447 FakeLayerTreeHost*
448 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
449 return host_.get();
452 template <>
453 LayerTreeImpl*
454 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
455 return host_->host_impl()->active_tree();
458 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
459 class ClassName##MainThreadOpaqueLayers \
460 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
461 public: /* NOLINT(whitespace/indent) */ \
462 ClassName##MainThreadOpaqueLayers() \
463 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
464 }; \
465 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
466 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
467 class ClassName##MainThreadOpaquePaints \
468 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
469 public: /* NOLINT(whitespace/indent) */ \
470 ClassName##MainThreadOpaquePaints() \
471 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
472 }; \
473 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
475 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
476 class ClassName##ImplThreadOpaqueLayers \
477 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
478 public: /* NOLINT(whitespace/indent) */ \
479 ClassName##ImplThreadOpaqueLayers() \
480 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
481 }; \
482 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
483 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
484 class ClassName##ImplThreadOpaquePaints \
485 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
486 public: /* NOLINT(whitespace/indent) */ \
487 ClassName##ImplThreadOpaquePaints() \
488 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
489 }; \
490 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
492 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
493 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
494 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
495 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
496 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
498 #define MAIN_THREAD_TEST(ClassName) \
499 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
501 #define IMPL_THREAD_TEST(ClassName) \
502 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
504 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
505 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
506 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
508 template <class Types>
509 class OcclusionTrackerTestIdentityTransforms
510 : public OcclusionTrackerTest<Types> {
511 protected:
512 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
513 : OcclusionTrackerTest<Types>(opaque_layers) {}
515 void RunMyTest() {
516 typename Types::ContentLayerType* root = this->CreateRoot(
517 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
518 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
519 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
520 typename Types::ContentLayerType* layer =
521 this->CreateDrawingLayer(parent,
522 this->identity_matrix,
523 gfx::PointF(30.f, 30.f),
524 gfx::Size(500, 500),
525 true);
526 parent->SetMasksToBounds(true);
527 this->CalcDrawEtc(root);
529 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
530 gfx::Rect(0, 0, 1000, 1000));
532 this->VisitLayer(layer, &occlusion);
533 this->EnterLayer(parent, &occlusion);
535 EXPECT_EQ(gfx::Rect().ToString(),
536 occlusion.occlusion_from_outside_target().ToString());
537 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
538 occlusion.occlusion_from_inside_target().ToString());
540 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
541 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
542 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
543 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
544 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
546 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
547 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
548 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
549 occlusion.UnoccludedLayerContentRect(
550 parent, gfx::Rect(29, 30, 70, 70)));
551 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
552 occlusion.UnoccludedLayerContentRect(
553 parent, gfx::Rect(29, 29, 70, 70)));
554 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
555 occlusion.UnoccludedLayerContentRect(
556 parent, gfx::Rect(30, 29, 70, 70)));
557 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
558 occlusion.UnoccludedLayerContentRect(
559 parent, gfx::Rect(31, 29, 69, 70)));
560 EXPECT_RECT_EQ(gfx::Rect(),
561 occlusion.UnoccludedLayerContentRect(
562 parent, gfx::Rect(31, 30, 69, 70)));
563 EXPECT_RECT_EQ(gfx::Rect(),
564 occlusion.UnoccludedLayerContentRect(
565 parent, gfx::Rect(31, 31, 69, 69)));
566 EXPECT_RECT_EQ(gfx::Rect(),
567 occlusion.UnoccludedLayerContentRect(
568 parent, gfx::Rect(30, 31, 70, 69)));
569 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
570 occlusion.UnoccludedLayerContentRect(
571 parent, gfx::Rect(29, 31, 70, 69)));
575 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
577 template <class Types>
578 class OcclusionTrackerTestQuadsMismatchLayer
579 : public OcclusionTrackerTest<Types> {
580 protected:
581 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
582 : OcclusionTrackerTest<Types>(opaque_layers) {}
583 void RunMyTest() {
584 gfx::Transform layer_transform;
585 layer_transform.Translate(10.0, 10.0);
587 typename Types::ContentLayerType* parent = this->CreateRoot(
588 this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
589 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
590 parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
591 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
592 layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
593 this->CalcDrawEtc(parent);
595 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
596 gfx::Rect(0, 0, 1000, 1000));
598 this->VisitLayer(layer2, &occlusion);
599 this->EnterLayer(layer1, &occlusion);
601 EXPECT_EQ(gfx::Rect().ToString(),
602 occlusion.occlusion_from_outside_target().ToString());
603 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
604 occlusion.occlusion_from_inside_target().ToString());
606 // This checks cases where the quads don't match their "containing"
607 // layers, e.g. in terms of transforms or clip rect. This is typical for
608 // DelegatedRendererLayer.
610 gfx::Transform quad_transform;
611 quad_transform.Translate(30.0, 30.0);
613 EXPECT_TRUE(occlusion.UnoccludedContentRect(gfx::Rect(0, 0, 10, 10),
614 quad_transform).IsEmpty());
615 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
616 occlusion.UnoccludedContentRect(gfx::Rect(40, 40, 10, 10),
617 quad_transform));
618 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
619 occlusion.UnoccludedContentRect(gfx::Rect(35, 30, 10, 10),
620 quad_transform));
624 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
626 template <class Types>
627 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
628 protected:
629 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
630 : OcclusionTrackerTest<Types>(opaque_layers) {}
631 void RunMyTest() {
632 gfx::Transform layer_transform;
633 layer_transform.Translate(250.0, 250.0);
634 layer_transform.Rotate(90.0);
635 layer_transform.Translate(-250.0, -250.0);
637 typename Types::ContentLayerType* root = this->CreateRoot(
638 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
639 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
640 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
641 typename Types::ContentLayerType* layer =
642 this->CreateDrawingLayer(parent,
643 layer_transform,
644 gfx::PointF(30.f, 30.f),
645 gfx::Size(500, 500),
646 true);
647 parent->SetMasksToBounds(true);
648 this->CalcDrawEtc(root);
650 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
651 gfx::Rect(0, 0, 1000, 1000));
653 this->VisitLayer(layer, &occlusion);
654 this->EnterLayer(parent, &occlusion);
656 EXPECT_EQ(gfx::Rect().ToString(),
657 occlusion.occlusion_from_outside_target().ToString());
658 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
659 occlusion.occlusion_from_inside_target().ToString());
661 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
662 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
663 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
664 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
665 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
667 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
668 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
669 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
670 occlusion.UnoccludedLayerContentRect(
671 parent, gfx::Rect(29, 30, 69, 70)));
672 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
673 occlusion.UnoccludedLayerContentRect(
674 parent, gfx::Rect(29, 29, 70, 70)));
675 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
676 occlusion.UnoccludedLayerContentRect(
677 parent, gfx::Rect(30, 29, 70, 70)));
678 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
679 occlusion.UnoccludedLayerContentRect(
680 parent, gfx::Rect(31, 29, 69, 70)));
681 EXPECT_RECT_EQ(gfx::Rect(),
682 occlusion.UnoccludedLayerContentRect(
683 parent, gfx::Rect(31, 30, 69, 70)));
684 EXPECT_RECT_EQ(gfx::Rect(),
685 occlusion.UnoccludedLayerContentRect(
686 parent, gfx::Rect(31, 31, 69, 69)));
687 EXPECT_RECT_EQ(gfx::Rect(),
688 occlusion.UnoccludedLayerContentRect(
689 parent, gfx::Rect(30, 31, 70, 69)));
690 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
691 occlusion.UnoccludedLayerContentRect(
692 parent, gfx::Rect(29, 31, 70, 69)));
696 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
698 template <class Types>
699 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
700 protected:
701 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
702 : OcclusionTrackerTest<Types>(opaque_layers) {}
703 void RunMyTest() {
704 gfx::Transform layer_transform;
705 layer_transform.Translate(20.0, 20.0);
707 typename Types::ContentLayerType* root = this->CreateRoot(
708 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
709 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
710 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
711 typename Types::ContentLayerType* layer =
712 this->CreateDrawingLayer(parent,
713 layer_transform,
714 gfx::PointF(30.f, 30.f),
715 gfx::Size(500, 500),
716 true);
717 parent->SetMasksToBounds(true);
718 this->CalcDrawEtc(root);
720 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
721 gfx::Rect(0, 0, 1000, 1000));
723 this->VisitLayer(layer, &occlusion);
724 this->EnterLayer(parent, &occlusion);
726 EXPECT_EQ(gfx::Rect().ToString(),
727 occlusion.occlusion_from_outside_target().ToString());
728 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
729 occlusion.occlusion_from_inside_target().ToString());
731 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
732 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
733 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
734 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 49, 50)));
735 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 49)));
737 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
738 parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
739 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
740 occlusion.UnoccludedLayerContentRect(
741 parent, gfx::Rect(49, 50, 50, 50)));
742 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
743 occlusion.UnoccludedLayerContentRect(
744 parent, gfx::Rect(49, 49, 50, 50)));
745 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
746 occlusion.UnoccludedLayerContentRect(
747 parent, gfx::Rect(50, 49, 50, 50)));
748 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
749 occlusion.UnoccludedLayerContentRect(
750 parent, gfx::Rect(51, 49, 49, 50)));
751 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
752 parent, gfx::Rect(51, 50, 49, 50)).IsEmpty());
753 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
754 parent, gfx::Rect(51, 51, 49, 49)).IsEmpty());
755 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
756 parent, gfx::Rect(50, 51, 50, 49)).IsEmpty());
757 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
758 occlusion.UnoccludedLayerContentRect(
759 parent, gfx::Rect(49, 51, 50, 49)));
763 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
765 template <class Types>
766 class OcclusionTrackerTestChildInRotatedChild
767 : public OcclusionTrackerTest<Types> {
768 protected:
769 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
770 : OcclusionTrackerTest<Types>(opaque_layers) {}
771 void RunMyTest() {
772 gfx::Transform child_transform;
773 child_transform.Translate(250.0, 250.0);
774 child_transform.Rotate(90.0);
775 child_transform.Translate(-250.0, -250.0);
777 typename Types::ContentLayerType* parent = this->CreateRoot(
778 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
779 parent->SetMasksToBounds(true);
780 typename Types::LayerType* child = this->CreateSurface(
781 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
782 child->SetMasksToBounds(true);
783 typename Types::ContentLayerType* layer =
784 this->CreateDrawingLayer(child,
785 this->identity_matrix,
786 gfx::PointF(10.f, 10.f),
787 gfx::Size(500, 500),
788 true);
789 this->CalcDrawEtc(parent);
791 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
792 gfx::Rect(0, 0, 1000, 1000));
794 this->VisitLayer(layer, &occlusion);
795 this->EnterContributingSurface(child, &occlusion);
797 EXPECT_EQ(gfx::Rect().ToString(),
798 occlusion.occlusion_from_outside_target().ToString());
799 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
800 occlusion.occlusion_from_inside_target().ToString());
802 this->LeaveContributingSurface(child, &occlusion);
803 this->EnterLayer(parent, &occlusion);
805 EXPECT_EQ(gfx::Rect().ToString(),
806 occlusion.occlusion_from_outside_target().ToString());
807 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
808 occlusion.occlusion_from_inside_target().ToString());
810 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
811 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
812 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
813 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 69, 60)));
814 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 59)));
816 /* Justification for the above occlusion from |layer|:
818 +---------------------+
820 | 30 | rotate(90)
821 | 30 + ---------------------------------+
822 100 | | 10 | | ==>
823 | |10+---------------------------------+
824 | | | | | |
825 | | | | | |
826 | | | | | |
827 +----|--|-------------+ | |
828 | | | |
829 | | | |
830 | | | |500
831 | | | |
832 | | | |
833 | | | |
834 | | | |
835 +--|-------------------------------+ |
837 +---------------------------------+
840 +---------------------+
841 | |30 Visible region of |layer|: /////
843 | +---------------------------------+
844 100| | |10 |
845 | +---------------------------------+ |
846 | | |///////////////| 420 | |
847 | | |///////////////|60 | |
848 | | |///////////////| | |
849 +--|--|---------------+ | |
850 20|10| 70 | |
851 | | | |
852 | | | |
853 | | | |
854 | | | |
855 | | | |
856 | | |10|
857 | +------------------------------|--+
858 | 490 |
859 +---------------------------------+
866 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
868 template <class Types>
869 class OcclusionTrackerTestScaledRenderSurface
870 : public OcclusionTrackerTest<Types> {
871 protected:
872 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
873 : OcclusionTrackerTest<Types>(opaque_layers) {}
875 void RunMyTest() {
876 typename Types::ContentLayerType* parent = this->CreateRoot(
877 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
879 gfx::Transform layer1_matrix;
880 layer1_matrix.Scale(2.0, 2.0);
881 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
882 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
883 layer1->SetForceRenderSurface(true);
885 gfx::Transform layer2_matrix;
886 layer2_matrix.Translate(25.0, 25.0);
887 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
888 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
889 typename Types::ContentLayerType* occluder =
890 this->CreateDrawingLayer(parent,
891 this->identity_matrix,
892 gfx::PointF(100.f, 100.f),
893 gfx::Size(500, 500),
894 true);
895 this->CalcDrawEtc(parent);
897 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
898 gfx::Rect(0, 0, 1000, 1000));
900 this->VisitLayer(occluder, &occlusion);
901 this->EnterLayer(layer2, &occlusion);
903 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
904 occlusion.occlusion_from_outside_target().ToString());
905 EXPECT_EQ(gfx::Rect().ToString(),
906 occlusion.occlusion_from_inside_target().ToString());
908 EXPECT_RECT_EQ(
909 gfx::Rect(0, 0, 25, 25),
910 occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
911 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
912 occlusion.UnoccludedLayerContentRect(
913 layer2, gfx::Rect(10, 25, 25, 25)));
914 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
915 occlusion.UnoccludedLayerContentRect(
916 layer2, gfx::Rect(25, 10, 25, 25)));
917 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
918 layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
922 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
924 template <class Types>
925 class OcclusionTrackerTestVisitTargetTwoTimes
926 : public OcclusionTrackerTest<Types> {
927 protected:
928 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
929 : OcclusionTrackerTest<Types>(opaque_layers) {}
930 void RunMyTest() {
931 gfx::Transform child_transform;
932 child_transform.Translate(250.0, 250.0);
933 child_transform.Rotate(90.0);
934 child_transform.Translate(-250.0, -250.0);
936 typename Types::ContentLayerType* root = this->CreateRoot(
937 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
938 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
939 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
940 parent->SetMasksToBounds(true);
941 typename Types::LayerType* child = this->CreateSurface(
942 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
943 child->SetMasksToBounds(true);
944 typename Types::ContentLayerType* layer =
945 this->CreateDrawingLayer(child,
946 this->identity_matrix,
947 gfx::PointF(10.f, 10.f),
948 gfx::Size(500, 500),
949 true);
950 // |child2| makes |parent|'s surface get considered by OcclusionTracker
951 // first, instead of |child|'s. This exercises different code in
952 // LeaveToRenderTarget, as the target surface has already been seen.
953 typename Types::ContentLayerType* child2 =
954 this->CreateDrawingLayer(parent,
955 this->identity_matrix,
956 gfx::PointF(30.f, 30.f),
957 gfx::Size(60, 20),
958 true);
959 this->CalcDrawEtc(root);
961 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
962 gfx::Rect(0, 0, 1000, 1000));
964 this->VisitLayer(child2, &occlusion);
966 EXPECT_EQ(gfx::Rect().ToString(),
967 occlusion.occlusion_from_outside_target().ToString());
968 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
969 occlusion.occlusion_from_inside_target().ToString());
971 this->VisitLayer(layer, &occlusion);
973 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
974 occlusion.occlusion_from_outside_target().ToString());
975 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
976 occlusion.occlusion_from_inside_target().ToString());
978 this->EnterContributingSurface(child, &occlusion);
980 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
981 occlusion.occlusion_from_outside_target().ToString());
982 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
983 occlusion.occlusion_from_inside_target().ToString());
985 // Occlusion in |child2| should get merged with the |child| surface we are
986 // leaving now.
987 this->LeaveContributingSurface(child, &occlusion);
988 this->EnterLayer(parent, &occlusion);
990 EXPECT_EQ(gfx::Rect().ToString(),
991 occlusion.occlusion_from_outside_target().ToString());
992 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
993 .ToString(),
994 occlusion.occlusion_from_inside_target().ToString());
996 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
997 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
998 occlusion.UnoccludedLayerContentRect(
999 parent, gfx::Rect(30, 30, 70, 70)));
1001 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
1002 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
1003 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
1004 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
1005 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
1007 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1008 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1009 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1011 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1012 parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1013 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1014 occlusion.UnoccludedLayerContentRect(
1015 parent, gfx::Rect(29, 30, 60, 10)));
1016 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1017 occlusion.UnoccludedLayerContentRect(
1018 parent, gfx::Rect(30, 29, 60, 10)));
1019 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1020 occlusion.UnoccludedLayerContentRect(
1021 parent, gfx::Rect(31, 30, 60, 10)));
1022 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1023 parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1025 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1026 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1027 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1028 occlusion.UnoccludedLayerContentRect(
1029 parent, gfx::Rect(29, 40, 70, 60)));
1030 // This rect is mostly occluded by |child2|.
1031 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1032 occlusion.UnoccludedLayerContentRect(
1033 parent, gfx::Rect(30, 39, 70, 60)));
1034 // This rect extends past top/right ends of |child2|.
1035 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1036 occlusion.UnoccludedLayerContentRect(
1037 parent, gfx::Rect(30, 29, 70, 70)));
1038 // This rect extends past left/right ends of |child2|.
1039 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1040 occlusion.UnoccludedLayerContentRect(
1041 parent, gfx::Rect(20, 39, 80, 60)));
1042 EXPECT_RECT_EQ(gfx::Rect(),
1043 occlusion.UnoccludedLayerContentRect(
1044 parent, gfx::Rect(31, 40, 69, 60)));
1045 EXPECT_RECT_EQ(gfx::Rect(),
1046 occlusion.UnoccludedLayerContentRect(
1047 parent, gfx::Rect(30, 41, 70, 59)));
1049 /* Justification for the above occlusion from |layer|:
1051 +---------------------+
1053 | 30 | rotate(90)
1054 | 30 + ------------+--------------------+
1055 100 | | 10 | | | ==>
1056 | |10+----------|----------------------+
1057 | + ------------+ | | |
1058 | | | | | |
1059 | | | | | |
1060 +----|--|-------------+ | |
1061 | | | |
1062 | | | |
1063 | | | |500
1064 | | | |
1065 | | | |
1066 | | | |
1067 | | | |
1068 +--|-------------------------------+ |
1070 +---------------------------------+
1074 +---------------------+
1075 | |30 Visible region of |layer|: /////
1076 | 30 60 | |child2|: \\\\\
1077 | 30 +------------+--------------------+
1078 | |\\\\\\\\\\\\| |10 |
1079 | +--|\\\\\\\\\\\\|-----------------+ |
1080 | | +------------+//| 420 | |
1081 | | |///////////////|60 | |
1082 | | |///////////////| | |
1083 +--|--|---------------+ | |
1084 20|10| 70 | |
1085 | | | |
1086 | | | |
1087 | | | |
1088 | | | |
1089 | | | |
1090 | | |10|
1091 | +------------------------------|--+
1092 | 490 |
1093 +---------------------------------+
1099 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
1101 template <class Types>
1102 class OcclusionTrackerTestSurfaceRotatedOffAxis
1103 : public OcclusionTrackerTest<Types> {
1104 protected:
1105 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
1106 : OcclusionTrackerTest<Types>(opaque_layers) {}
1107 void RunMyTest() {
1108 gfx::Transform child_transform;
1109 child_transform.Translate(250.0, 250.0);
1110 child_transform.Rotate(95.0);
1111 child_transform.Translate(-250.0, -250.0);
1113 gfx::Transform layer_transform;
1114 layer_transform.Translate(10.0, 10.0);
1116 typename Types::ContentLayerType* root = this->CreateRoot(
1117 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1118 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1119 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1120 typename Types::LayerType* child = this->CreateLayer(
1121 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1122 child->SetMasksToBounds(true);
1123 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1124 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
1125 this->CalcDrawEtc(root);
1127 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1128 gfx::Rect(0, 0, 1000, 1000));
1130 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect(
1131 layer_transform, layer->visible_content_rect());
1133 this->VisitLayer(layer, &occlusion);
1134 this->EnterContributingSurface(child, &occlusion);
1136 EXPECT_EQ(gfx::Rect().ToString(),
1137 occlusion.occlusion_from_outside_target().ToString());
1138 EXPECT_EQ(clipped_layer_in_child.ToString(),
1139 occlusion.occlusion_from_inside_target().ToString());
1141 this->LeaveContributingSurface(child, &occlusion);
1142 this->EnterLayer(parent, &occlusion);
1144 EXPECT_EQ(gfx::Rect().ToString(),
1145 occlusion.occlusion_from_outside_target().ToString());
1146 EXPECT_EQ(gfx::Rect().ToString(),
1147 occlusion.occlusion_from_inside_target().ToString());
1149 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
1150 EXPECT_RECT_EQ(
1151 gfx::Rect(75, 55, 1, 1),
1152 occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
1156 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
1158 template <class Types>
1159 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1160 : public OcclusionTrackerTest<Types> {
1161 protected:
1162 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
1163 : OcclusionTrackerTest<Types>(opaque_layers) {}
1164 void RunMyTest() {
1165 gfx::Transform child_transform;
1166 child_transform.Translate(250.0, 250.0);
1167 child_transform.Rotate(90.0);
1168 child_transform.Translate(-250.0, -250.0);
1170 typename Types::ContentLayerType* root = this->CreateRoot(
1171 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1172 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1173 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1174 parent->SetMasksToBounds(true);
1175 typename Types::ContentLayerType* child =
1176 this->CreateDrawingSurface(parent,
1177 child_transform,
1178 gfx::PointF(30.f, 30.f),
1179 gfx::Size(500, 500),
1180 false);
1181 child->SetMasksToBounds(true);
1182 typename Types::ContentLayerType* layer1 =
1183 this->CreateDrawingLayer(child,
1184 this->identity_matrix,
1185 gfx::PointF(10.f, 10.f),
1186 gfx::Size(500, 500),
1187 true);
1188 typename Types::ContentLayerType* layer2 =
1189 this->CreateDrawingLayer(child,
1190 this->identity_matrix,
1191 gfx::PointF(10.f, 450.f),
1192 gfx::Size(500, 60),
1193 true);
1194 this->CalcDrawEtc(root);
1196 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1197 gfx::Rect(0, 0, 1000, 1000));
1199 this->VisitLayer(layer2, &occlusion);
1200 this->VisitLayer(layer1, &occlusion);
1201 this->VisitLayer(child, &occlusion);
1202 this->EnterContributingSurface(child, &occlusion);
1204 EXPECT_EQ(gfx::Rect().ToString(),
1205 occlusion.occlusion_from_outside_target().ToString());
1206 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1207 occlusion.occlusion_from_inside_target().ToString());
1209 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
1210 EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
1211 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 59, 70)));
1212 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 69)));
1214 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1215 child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1216 EXPECT_RECT_EQ(
1217 gfx::Rect(9, 430, 1, 70),
1218 occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
1219 EXPECT_RECT_EQ(gfx::Rect(),
1220 occlusion.UnoccludedLayerContentRect(
1221 child, gfx::Rect(11, 430, 59, 70)));
1222 EXPECT_RECT_EQ(gfx::Rect(),
1223 occlusion.UnoccludedLayerContentRect(
1224 child, gfx::Rect(10, 431, 60, 69)));
1226 this->LeaveContributingSurface(child, &occlusion);
1227 this->EnterLayer(parent, &occlusion);
1229 EXPECT_EQ(gfx::Rect().ToString(),
1230 occlusion.occlusion_from_outside_target().ToString());
1231 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1232 occlusion.occlusion_from_inside_target().ToString());
1234 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1235 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1236 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1238 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1239 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1240 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1241 occlusion.UnoccludedLayerContentRect(
1242 parent, gfx::Rect(29, 40, 70, 60)));
1243 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1244 occlusion.UnoccludedLayerContentRect(
1245 parent, gfx::Rect(30, 39, 70, 60)));
1246 EXPECT_RECT_EQ(gfx::Rect(),
1247 occlusion.UnoccludedLayerContentRect(
1248 parent, gfx::Rect(31, 40, 69, 60)));
1249 EXPECT_RECT_EQ(gfx::Rect(),
1250 occlusion.UnoccludedLayerContentRect(
1251 parent, gfx::Rect(30, 41, 70, 59)));
1253 /* Justification for the above occlusion from |layer1| and |layer2|:
1255 +---------------------+
1256 | |30 Visible region of |layer1|: /////
1257 | | Visible region of |layer2|: \\\\\
1258 | +---------------------------------+
1259 | | |10 |
1260 | +---------------+-----------------+ |
1261 | | |\\\\\\\\\\\\|//| 420 | |
1262 | | |\\\\\\\\\\\\|//|60 | |
1263 | | |\\\\\\\\\\\\|//| | |
1264 +--|--|------------|--+ | |
1265 20|10| 70 | | |
1266 | | | | |
1267 | | | | |
1268 | | | | |
1269 | | | | |
1270 | | | | |
1271 | | | |10|
1272 | +------------|-----------------|--+
1273 | | 490 |
1274 +---------------+-----------------+
1275 60 440
1280 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1282 template <class Types>
1283 class OcclusionTrackerTestOverlappingSurfaceSiblings
1284 : public OcclusionTrackerTest<Types> {
1285 protected:
1286 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
1287 : OcclusionTrackerTest<Types>(opaque_layers) {}
1288 void RunMyTest() {
1289 gfx::Transform child_transform;
1290 child_transform.Translate(250.0, 250.0);
1291 child_transform.Rotate(90.0);
1292 child_transform.Translate(-250.0, -250.0);
1294 typename Types::ContentLayerType* parent = this->CreateRoot(
1295 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1296 parent->SetMasksToBounds(true);
1297 typename Types::LayerType* child1 = this->CreateSurface(
1298 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
1299 typename Types::LayerType* child2 = this->CreateSurface(
1300 parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
1301 typename Types::ContentLayerType* layer1 =
1302 this->CreateDrawingLayer(child1,
1303 this->identity_matrix,
1304 gfx::PointF(-10.f, -10.f),
1305 gfx::Size(510, 510),
1306 true);
1307 typename Types::ContentLayerType* layer2 =
1308 this->CreateDrawingLayer(child2,
1309 this->identity_matrix,
1310 gfx::PointF(-10.f, -10.f),
1311 gfx::Size(510, 510),
1312 true);
1313 this->CalcDrawEtc(parent);
1315 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1316 gfx::Rect(0, 0, 1000, 1000));
1318 this->VisitLayer(layer2, &occlusion);
1319 this->EnterContributingSurface(child2, &occlusion);
1321 EXPECT_EQ(gfx::Rect().ToString(),
1322 occlusion.occlusion_from_outside_target().ToString());
1323 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1324 occlusion.occlusion_from_inside_target().ToString());
1326 // There is nothing above child2's surface in the z-order.
1327 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1328 occlusion.UnoccludedSurfaceContentRect(
1329 child2, false, gfx::Rect(-10, 420, 70, 80)));
1331 this->LeaveContributingSurface(child2, &occlusion);
1332 this->VisitLayer(layer1, &occlusion);
1333 this->EnterContributingSurface(child1, &occlusion);
1335 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1336 occlusion.occlusion_from_outside_target().ToString());
1337 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1338 occlusion.occlusion_from_inside_target().ToString());
1340 // child2's contents will occlude child1 below it.
1341 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1342 occlusion.UnoccludedSurfaceContentRect(
1343 child1, false, gfx::Rect(-10, 430, 80, 70)));
1345 this->LeaveContributingSurface(child1, &occlusion);
1346 this->EnterLayer(parent, &occlusion);
1348 EXPECT_EQ(gfx::Rect().ToString(),
1349 occlusion.occlusion_from_outside_target().ToString());
1350 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1351 .ToString(),
1352 occlusion.occlusion_from_inside_target().ToString());
1354 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1356 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1357 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1358 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1360 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1361 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1362 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1364 /* Justification for the above occlusion:
1366 +---------------------+
1367 | 20 | layer1
1368 | 30+ ---------------------------------+
1369 100 | 30| | layer2 |
1370 |20+----------------------------------+ |
1371 | | | | | |
1372 | | | | | |
1373 | | | | | |
1374 +--|-|----------------+ | |
1375 | | | | 510
1376 | | | |
1377 | | | |
1378 | | | |
1379 | | | |
1380 | | | |
1381 | | | |
1382 | +--------------------------------|-+
1384 +----------------------------------+
1390 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1392 template <class Types>
1393 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1394 : public OcclusionTrackerTest<Types> {
1395 protected:
1396 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1397 bool opaque_layers)
1398 : OcclusionTrackerTest<Types>(opaque_layers) {}
1399 void RunMyTest() {
1400 gfx::Transform child1_transform;
1401 child1_transform.Translate(250.0, 250.0);
1402 child1_transform.Rotate(-90.0);
1403 child1_transform.Translate(-250.0, -250.0);
1405 gfx::Transform child2_transform;
1406 child2_transform.Translate(250.0, 250.0);
1407 child2_transform.Rotate(90.0);
1408 child2_transform.Translate(-250.0, -250.0);
1410 typename Types::ContentLayerType* parent = this->CreateRoot(
1411 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1412 parent->SetMasksToBounds(true);
1413 typename Types::LayerType* child1 = this->CreateSurface(
1414 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1415 typename Types::LayerType* child2 =
1416 this->CreateDrawingSurface(parent,
1417 child2_transform,
1418 gfx::PointF(20.f, 40.f),
1419 gfx::Size(10, 10),
1420 false);
1421 typename Types::ContentLayerType* layer1 =
1422 this->CreateDrawingLayer(child1,
1423 this->identity_matrix,
1424 gfx::PointF(-10.f, -20.f),
1425 gfx::Size(510, 510),
1426 true);
1427 typename Types::ContentLayerType* layer2 =
1428 this->CreateDrawingLayer(child2,
1429 this->identity_matrix,
1430 gfx::PointF(-10.f, -10.f),
1431 gfx::Size(510, 510),
1432 true);
1433 this->CalcDrawEtc(parent);
1435 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1436 gfx::Rect(0, 0, 1000, 1000));
1438 this->VisitLayer(layer2, &occlusion);
1439 this->EnterLayer(child2, &occlusion);
1441 EXPECT_EQ(gfx::Rect().ToString(),
1442 occlusion.occlusion_from_outside_target().ToString());
1443 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1444 occlusion.occlusion_from_inside_target().ToString());
1446 this->LeaveLayer(child2, &occlusion);
1447 this->EnterContributingSurface(child2, &occlusion);
1449 // There is nothing above child2's surface in the z-order.
1450 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1451 occlusion.UnoccludedSurfaceContentRect(
1452 child2, false, gfx::Rect(-10, 420, 70, 80)));
1454 this->LeaveContributingSurface(child2, &occlusion);
1455 this->VisitLayer(layer1, &occlusion);
1456 this->EnterContributingSurface(child1, &occlusion);
1458 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1459 occlusion.occlusion_from_outside_target().ToString());
1460 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1461 occlusion.occlusion_from_inside_target().ToString());
1463 // child2's contents will occlude child1 below it.
1464 EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(),
1465 occlusion.occlusion_on_contributing_surface_from_inside_target()
1466 .ToString());
1467 EXPECT_EQ(gfx::Rect().ToString(),
1468 occlusion.occlusion_on_contributing_surface_from_outside_target()
1469 .ToString());
1471 this->LeaveContributingSurface(child1, &occlusion);
1472 this->EnterLayer(parent, &occlusion);
1474 EXPECT_EQ(gfx::Rect().ToString(),
1475 occlusion.occlusion_from_outside_target().ToString());
1476 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1477 occlusion.occlusion_from_inside_target().ToString());
1479 /* Justification for the above occlusion:
1481 +---------------------+
1482 |20 | layer1
1483 10+----------------------------------+
1484 100 || 30 | layer2 |
1485 |20+----------------------------------+
1486 || | | | |
1487 || | | | |
1488 || | | | |
1489 +|-|------------------+ | |
1490 | | | | 510
1491 | | 510 | |
1492 | | | |
1493 | | | |
1494 | | | |
1495 | | | |
1496 | | 520 | |
1497 +----------------------------------+ |
1499 +----------------------------------+
1505 ALL_OCCLUSIONTRACKER_TEST(
1506 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1508 template <class Types>
1509 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1510 protected:
1511 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1512 : OcclusionTrackerTest<Types>(opaque_layers) {}
1513 void RunMyTest() {
1514 gfx::Transform layer_transform;
1515 layer_transform.Translate(250.0, 250.0);
1516 layer_transform.Rotate(90.0);
1517 layer_transform.Translate(-250.0, -250.0);
1519 typename Types::ContentLayerType* parent = this->CreateRoot(
1520 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1521 parent->SetMasksToBounds(true);
1522 typename Types::ContentLayerType* blur_layer =
1523 this->CreateDrawingLayer(parent,
1524 layer_transform,
1525 gfx::PointF(30.f, 30.f),
1526 gfx::Size(500, 500),
1527 true);
1528 typename Types::ContentLayerType* opaque_layer =
1529 this->CreateDrawingLayer(parent,
1530 layer_transform,
1531 gfx::PointF(30.f, 30.f),
1532 gfx::Size(500, 500),
1533 true);
1534 typename Types::ContentLayerType* opacity_layer =
1535 this->CreateDrawingLayer(parent,
1536 layer_transform,
1537 gfx::PointF(30.f, 30.f),
1538 gfx::Size(500, 500),
1539 true);
1541 FilterOperations filters;
1542 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1543 blur_layer->SetFilters(filters);
1545 filters.Clear();
1546 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1547 opaque_layer->SetFilters(filters);
1549 filters.Clear();
1550 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1551 opacity_layer->SetFilters(filters);
1553 this->CalcDrawEtc(parent);
1555 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1556 gfx::Rect(0, 0, 1000, 1000));
1558 // Opacity layer won't contribute to occlusion.
1559 this->VisitLayer(opacity_layer, &occlusion);
1560 this->EnterContributingSurface(opacity_layer, &occlusion);
1562 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1563 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1565 // And has nothing to contribute to its parent surface.
1566 this->LeaveContributingSurface(opacity_layer, &occlusion);
1567 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1568 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1570 // Opaque layer will contribute to occlusion.
1571 this->VisitLayer(opaque_layer, &occlusion);
1572 this->EnterContributingSurface(opaque_layer, &occlusion);
1574 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1575 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1576 occlusion.occlusion_from_inside_target().ToString());
1578 // And it gets translated to the parent surface.
1579 this->LeaveContributingSurface(opaque_layer, &occlusion);
1580 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1581 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1582 occlusion.occlusion_from_inside_target().ToString());
1584 // The blur layer needs to throw away any occlusion from outside its
1585 // subtree.
1586 this->EnterLayer(blur_layer, &occlusion);
1587 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1588 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1590 // And it won't contribute to occlusion.
1591 this->LeaveLayer(blur_layer, &occlusion);
1592 this->EnterContributingSurface(blur_layer, &occlusion);
1593 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1594 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1596 // But the opaque layer's occlusion is preserved on the parent.
1597 this->LeaveContributingSurface(blur_layer, &occlusion);
1598 this->EnterLayer(parent, &occlusion);
1599 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1600 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1601 occlusion.occlusion_from_inside_target().ToString());
1605 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1607 template <class Types>
1608 class OcclusionTrackerTestReplicaDoesOcclude
1609 : public OcclusionTrackerTest<Types> {
1610 protected:
1611 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1612 : OcclusionTrackerTest<Types>(opaque_layers) {}
1613 void RunMyTest() {
1614 typename Types::ContentLayerType* parent = this->CreateRoot(
1615 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1616 typename Types::LayerType* surface =
1617 this->CreateDrawingSurface(parent,
1618 this->identity_matrix,
1619 gfx::PointF(0.f, 100.f),
1620 gfx::Size(50, 50),
1621 true);
1622 this->CreateReplicaLayer(
1623 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1624 this->CalcDrawEtc(parent);
1626 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1627 gfx::Rect(0, 0, 1000, 1000));
1629 this->VisitLayer(surface, &occlusion);
1631 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1632 occlusion.occlusion_from_inside_target().ToString());
1634 this->VisitContributingSurface(surface, &occlusion);
1635 this->EnterLayer(parent, &occlusion);
1637 // The surface and replica should both be occluding the parent.
1638 EXPECT_EQ(
1639 UnionRegions(gfx::Rect(0, 100, 50, 50),
1640 gfx::Rect(50, 150, 50, 50)).ToString(),
1641 occlusion.occlusion_from_inside_target().ToString());
1645 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1647 template <class Types>
1648 class OcclusionTrackerTestReplicaWithClipping
1649 : public OcclusionTrackerTest<Types> {
1650 protected:
1651 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1652 : OcclusionTrackerTest<Types>(opaque_layers) {}
1653 void RunMyTest() {
1654 typename Types::ContentLayerType* parent = this->CreateRoot(
1655 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1656 parent->SetMasksToBounds(true);
1657 typename Types::LayerType* surface =
1658 this->CreateDrawingSurface(parent,
1659 this->identity_matrix,
1660 gfx::PointF(0.f, 100.f),
1661 gfx::Size(50, 50),
1662 true);
1663 this->CreateReplicaLayer(
1664 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1665 this->CalcDrawEtc(parent);
1667 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1668 gfx::Rect(0, 0, 1000, 1000));
1670 this->VisitLayer(surface, &occlusion);
1672 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1673 occlusion.occlusion_from_inside_target().ToString());
1675 this->VisitContributingSurface(surface, &occlusion);
1676 this->EnterLayer(parent, &occlusion);
1678 // The surface and replica should both be occluding the parent.
1679 EXPECT_EQ(
1680 UnionRegions(gfx::Rect(0, 100, 50, 50),
1681 gfx::Rect(50, 150, 50, 20)).ToString(),
1682 occlusion.occlusion_from_inside_target().ToString());
1686 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1688 template <class Types>
1689 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1690 protected:
1691 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1692 : OcclusionTrackerTest<Types>(opaque_layers) {}
1693 void RunMyTest() {
1694 typename Types::ContentLayerType* parent = this->CreateRoot(
1695 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1696 typename Types::LayerType* surface =
1697 this->CreateDrawingSurface(parent,
1698 this->identity_matrix,
1699 gfx::PointF(0.f, 100.f),
1700 gfx::Size(50, 50),
1701 true);
1702 typename Types::LayerType* replica = this->CreateReplicaLayer(
1703 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1704 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1705 this->CalcDrawEtc(parent);
1707 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1708 gfx::Rect(0, 0, 1000, 1000));
1710 this->VisitLayer(surface, &occlusion);
1712 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1713 occlusion.occlusion_from_inside_target().ToString());
1715 this->VisitContributingSurface(surface, &occlusion);
1716 this->EnterLayer(parent, &occlusion);
1718 // The replica should not be occluding the parent, since it has a mask
1719 // applied to it.
1720 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1721 occlusion.occlusion_from_inside_target().ToString());
1725 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1727 template <class Types>
1728 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1729 : public OcclusionTrackerTest<Types> {
1730 protected:
1731 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1732 : OcclusionTrackerTest<Types>(opaque_layers) {}
1733 void RunMyTest() {
1734 typename Types::ContentLayerType* parent = this->CreateRoot(
1735 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1736 typename Types::ContentLayerType* layer =
1737 this->CreateDrawingSurface(parent,
1738 this->identity_matrix,
1739 gfx::PointF(),
1740 gfx::Size(200, 200),
1741 false);
1742 this->CalcDrawEtc(parent);
1744 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1745 gfx::Rect(0, 0, 1000, 1000));
1746 this->EnterLayer(layer, &occlusion);
1748 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1749 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1750 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1751 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1753 this->LeaveLayer(layer, &occlusion);
1754 this->VisitContributingSurface(layer, &occlusion);
1755 this->EnterLayer(parent, &occlusion);
1757 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1761 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1763 template <class Types>
1764 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1765 : public OcclusionTrackerTest<Types> {
1766 protected:
1767 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1768 : OcclusionTrackerTest<Types>(opaque_layers) {}
1769 void RunMyTest() {
1770 typename Types::ContentLayerType* parent = this->CreateRoot(
1771 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1772 typename Types::ContentLayerType* layer =
1773 this->CreateDrawingLayer(parent,
1774 this->identity_matrix,
1775 gfx::PointF(100.f, 100.f),
1776 gfx::Size(200, 200),
1777 false);
1778 this->CalcDrawEtc(parent);
1780 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1781 gfx::Rect(0, 0, 1000, 1000));
1782 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1784 this->ResetLayerIterator();
1785 this->VisitLayer(layer, &occlusion);
1786 this->EnterLayer(parent, &occlusion);
1788 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1789 occlusion.occlusion_from_inside_target().ToString());
1791 EXPECT_FALSE(
1792 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1793 EXPECT_TRUE(
1794 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1795 EXPECT_FALSE(
1796 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1799 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1800 gfx::Rect(0, 0, 1000, 1000));
1801 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1803 this->ResetLayerIterator();
1804 this->VisitLayer(layer, &occlusion);
1805 this->EnterLayer(parent, &occlusion);
1807 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1808 occlusion.occlusion_from_inside_target().ToString());
1810 EXPECT_FALSE(
1811 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1812 EXPECT_FALSE(
1813 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1814 EXPECT_TRUE(
1815 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1818 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1819 gfx::Rect(0, 0, 1000, 1000));
1820 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1822 this->ResetLayerIterator();
1823 this->VisitLayer(layer, &occlusion);
1824 this->EnterLayer(parent, &occlusion);
1826 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1827 occlusion.occlusion_from_inside_target().ToString());
1829 EXPECT_FALSE(
1830 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1831 EXPECT_FALSE(
1832 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1833 EXPECT_FALSE(
1834 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1839 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1841 template <class Types>
1842 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
1843 protected:
1844 explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
1845 : OcclusionTrackerTest<Types>(opaque_layers) {}
1846 void RunMyTest() {
1847 gfx::Transform transform;
1848 transform.RotateAboutYAxis(30.0);
1850 typename Types::ContentLayerType* parent = this->CreateRoot(
1851 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1852 typename Types::LayerType* container = this->CreateLayer(
1853 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1854 typename Types::ContentLayerType* layer =
1855 this->CreateDrawingLayer(container,
1856 transform,
1857 gfx::PointF(100.f, 100.f),
1858 gfx::Size(200, 200),
1859 true);
1860 this->CalcDrawEtc(parent);
1862 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1863 gfx::Rect(0, 0, 1000, 1000));
1864 this->EnterLayer(layer, &occlusion);
1866 // The layer is rotated in 3d but without preserving 3d, so it only gets
1867 // resized.
1868 EXPECT_RECT_EQ(
1869 gfx::Rect(0, 0, 200, 200),
1870 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1874 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
1876 template <class Types>
1877 class OcclusionTrackerTestUnsorted3dLayers
1878 : public OcclusionTrackerTest<Types> {
1879 protected:
1880 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
1881 : OcclusionTrackerTest<Types>(opaque_layers) {}
1882 void RunMyTest() {
1883 // Currently, The main thread layer iterator does not iterate over 3d items
1884 // in sorted order, because layer sorting is not performed on the main
1885 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1886 // layer occludes other layers that have not yet been iterated over. For
1887 // now, the expected behavior is that a 3d layer simply does not add any
1888 // occlusion to the occlusion tracker.
1890 gfx::Transform translation_to_front;
1891 translation_to_front.Translate3d(0.0, 0.0, -10.0);
1892 gfx::Transform translation_to_back;
1893 translation_to_front.Translate3d(0.0, 0.0, -100.0);
1895 typename Types::ContentLayerType* parent = this->CreateRoot(
1896 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1897 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
1898 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
1899 typename Types::ContentLayerType* child2 =
1900 this->CreateDrawingLayer(parent,
1901 translation_to_front,
1902 gfx::PointF(50.f, 50.f),
1903 gfx::Size(100, 100),
1904 true);
1905 parent->SetShouldFlattenTransform(false);
1906 parent->Set3dSortingContextId(1);
1907 child1->Set3dSortingContextId(1);
1908 child2->Set3dSortingContextId(1);
1910 this->CalcDrawEtc(parent);
1912 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1913 gfx::Rect(0, 0, 1000, 1000));
1914 this->VisitLayer(child2, &occlusion);
1915 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1916 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1918 this->VisitLayer(child1, &occlusion);
1919 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1920 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1924 // This test will have different layer ordering on the impl thread; the test
1925 // will only work on the main thread.
1926 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1928 template <class Types>
1929 class OcclusionTrackerTestPerspectiveTransform
1930 : public OcclusionTrackerTest<Types> {
1931 protected:
1932 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
1933 : OcclusionTrackerTest<Types>(opaque_layers) {}
1934 void RunMyTest() {
1935 gfx::Transform transform;
1936 transform.Translate(150.0, 150.0);
1937 transform.ApplyPerspectiveDepth(400.0);
1938 transform.RotateAboutXAxis(-30.0);
1939 transform.Translate(-150.0, -150.0);
1941 typename Types::ContentLayerType* parent = this->CreateRoot(
1942 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1943 typename Types::LayerType* container = this->CreateLayer(
1944 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1945 typename Types::ContentLayerType* layer =
1946 this->CreateDrawingLayer(container,
1947 transform,
1948 gfx::PointF(100.f, 100.f),
1949 gfx::Size(200, 200),
1950 true);
1951 container->SetShouldFlattenTransform(false);
1952 container->Set3dSortingContextId(1);
1953 layer->Set3dSortingContextId(1);
1954 layer->SetShouldFlattenTransform(false);
1956 this->CalcDrawEtc(parent);
1958 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1959 gfx::Rect(0, 0, 1000, 1000));
1960 this->EnterLayer(layer, &occlusion);
1962 EXPECT_RECT_EQ(
1963 gfx::Rect(0, 0, 200, 200),
1964 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1968 // This test requires accumulating occlusion of 3d layers, which are skipped by
1969 // the occlusion tracker on the main thread. So this test should run on the impl
1970 // thread.
1971 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
1972 template <class Types>
1973 class OcclusionTrackerTestPerspectiveTransformBehindCamera
1974 : public OcclusionTrackerTest<Types> {
1975 protected:
1976 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
1977 bool opaque_layers)
1978 : OcclusionTrackerTest<Types>(opaque_layers) {}
1979 void RunMyTest() {
1980 // This test is based on the platform/chromium/compositing/3d-corners.html
1981 // layout test.
1982 gfx::Transform transform;
1983 transform.Translate(250.0, 50.0);
1984 transform.ApplyPerspectiveDepth(10.0);
1985 transform.Translate(-250.0, -50.0);
1986 transform.Translate(250.0, 50.0);
1987 transform.RotateAboutXAxis(-167.0);
1988 transform.Translate(-250.0, -50.0);
1990 typename Types::ContentLayerType* parent = this->CreateRoot(
1991 this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
1992 typename Types::LayerType* container = this->CreateLayer(
1993 parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
1994 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1995 container, transform, gfx::PointF(), gfx::Size(500, 500), true);
1996 container->SetShouldFlattenTransform(false);
1997 container->Set3dSortingContextId(1);
1998 layer->SetShouldFlattenTransform(false);
1999 layer->Set3dSortingContextId(1);
2000 this->CalcDrawEtc(parent);
2002 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2003 gfx::Rect(0, 0, 1000, 1000));
2004 this->EnterLayer(layer, &occlusion);
2006 // The bottom 11 pixel rows of this layer remain visible inside the
2007 // container, after translation to the target surface. When translated back,
2008 // this will include many more pixels but must include at least the bottom
2009 // 11 rows.
2010 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2011 layer, gfx::Rect(0, 26, 500, 474)).
2012 Contains(gfx::Rect(0, 489, 500, 11)));
2016 // This test requires accumulating occlusion of 3d layers, which are skipped by
2017 // the occlusion tracker on the main thread. So this test should run on the impl
2018 // thread.
2019 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2021 template <class Types>
2022 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2023 : public OcclusionTrackerTest<Types> {
2024 protected:
2025 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2026 bool opaque_layers)
2027 : OcclusionTrackerTest<Types>(opaque_layers) {}
2028 void RunMyTest() {
2029 gfx::Transform transform;
2030 transform.Translate(50.0, 50.0);
2031 transform.ApplyPerspectiveDepth(100.0);
2032 transform.Translate3d(0.0, 0.0, 110.0);
2033 transform.Translate(-50.0, -50.0);
2035 typename Types::ContentLayerType* parent = this->CreateRoot(
2036 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2037 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2038 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2039 parent->SetShouldFlattenTransform(false);
2040 parent->Set3dSortingContextId(1);
2041 layer->SetShouldFlattenTransform(false);
2042 layer->Set3dSortingContextId(1);
2043 this->CalcDrawEtc(parent);
2045 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2046 gfx::Rect(0, 0, 1000, 1000));
2048 // The |layer| is entirely behind the camera and should not occlude.
2049 this->VisitLayer(layer, &occlusion);
2050 this->EnterLayer(parent, &occlusion);
2051 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2052 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2056 // This test requires accumulating occlusion of 3d layers, which are skipped by
2057 // the occlusion tracker on the main thread. So this test should run on the impl
2058 // thread.
2059 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2061 template <class Types>
2062 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2063 : public OcclusionTrackerTest<Types> {
2064 protected:
2065 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2066 bool opaque_layers)
2067 : OcclusionTrackerTest<Types>(opaque_layers) {}
2068 void RunMyTest() {
2069 gfx::Transform transform;
2070 transform.Translate(50.0, 50.0);
2071 transform.ApplyPerspectiveDepth(100.0);
2072 transform.Translate3d(0.0, 0.0, 99.0);
2073 transform.Translate(-50.0, -50.0);
2075 typename Types::ContentLayerType* parent = this->CreateRoot(
2076 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2077 parent->SetMasksToBounds(true);
2078 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2079 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2080 parent->SetShouldFlattenTransform(false);
2081 parent->Set3dSortingContextId(1);
2082 layer->SetShouldFlattenTransform(false);
2083 layer->Set3dSortingContextId(1);
2084 this->CalcDrawEtc(parent);
2086 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2087 gfx::Rect(0, 0, 1000, 1000));
2089 // This is very close to the camera, so pixels in its visible_content_rect()
2090 // will actually go outside of the layer's clip rect. Ensure that those
2091 // pixels don't occlude things outside the clip rect.
2092 this->VisitLayer(layer, &occlusion);
2093 this->EnterLayer(parent, &occlusion);
2094 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2095 occlusion.occlusion_from_inside_target().ToString());
2096 EXPECT_EQ(gfx::Rect().ToString(),
2097 occlusion.occlusion_from_outside_target().ToString());
2101 // This test requires accumulating occlusion of 3d layers, which are skipped by
2102 // the occlusion tracker on the main thread. So this test should run on the impl
2103 // thread.
2104 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2106 template <class Types>
2107 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2108 : public OcclusionTrackerTest<Types> {
2109 protected:
2110 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
2111 : OcclusionTrackerTest<Types>(opaque_layers) {}
2112 void RunMyTest() {
2113 // parent
2114 // +--layer
2115 // +--surface
2116 // | +--surface_child
2117 // | +--surface_child2
2118 // +--parent2
2119 // +--topmost
2121 typename Types::ContentLayerType* parent = this->CreateRoot(
2122 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2123 typename Types::ContentLayerType* layer =
2124 this->CreateDrawingLayer(parent,
2125 this->identity_matrix,
2126 gfx::PointF(),
2127 gfx::Size(300, 300),
2128 true);
2129 typename Types::ContentLayerType* surface =
2130 this->CreateDrawingSurface(parent,
2131 this->identity_matrix,
2132 gfx::PointF(),
2133 gfx::Size(300, 300),
2134 true);
2135 typename Types::ContentLayerType* surface_child =
2136 this->CreateDrawingLayer(surface,
2137 this->identity_matrix,
2138 gfx::PointF(),
2139 gfx::Size(200, 300),
2140 true);
2141 typename Types::ContentLayerType* surface_child2 =
2142 this->CreateDrawingLayer(surface,
2143 this->identity_matrix,
2144 gfx::PointF(),
2145 gfx::Size(100, 300),
2146 true);
2147 typename Types::ContentLayerType* parent2 =
2148 this->CreateDrawingLayer(parent,
2149 this->identity_matrix,
2150 gfx::PointF(),
2151 gfx::Size(300, 300),
2152 false);
2153 typename Types::ContentLayerType* topmost =
2154 this->CreateDrawingLayer(parent,
2155 this->identity_matrix,
2156 gfx::PointF(250.f, 0.f),
2157 gfx::Size(50, 300),
2158 true);
2160 AddOpacityTransitionToController(
2161 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2162 AddOpacityTransitionToController(
2163 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2164 this->CalcDrawEtc(parent);
2166 EXPECT_TRUE(layer->draw_opacity_is_animating());
2167 EXPECT_FALSE(surface->draw_opacity_is_animating());
2168 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2170 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2171 gfx::Rect(0, 0, 1000, 1000));
2173 this->VisitLayer(topmost, &occlusion);
2174 this->EnterLayer(parent2, &occlusion);
2175 // This occlusion will affect all surfaces.
2176 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2177 occlusion.occlusion_from_inside_target().ToString());
2178 EXPECT_EQ(gfx::Rect().ToString(),
2179 occlusion.occlusion_from_outside_target().ToString());
2180 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2181 occlusion.UnoccludedLayerContentRect(
2182 parent2, gfx::Rect(0, 0, 300, 300)).ToString());
2183 this->LeaveLayer(parent2, &occlusion);
2185 this->VisitLayer(surface_child2, &occlusion);
2186 this->EnterLayer(surface_child, &occlusion);
2187 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2188 occlusion.occlusion_from_inside_target().ToString());
2189 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2190 occlusion.occlusion_from_outside_target().ToString());
2191 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2192 occlusion.UnoccludedLayerContentRect(
2193 surface_child, gfx::Rect(0, 0, 200, 300)));
2194 this->LeaveLayer(surface_child, &occlusion);
2195 this->EnterLayer(surface, &occlusion);
2196 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2197 occlusion.occlusion_from_inside_target().ToString());
2198 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2199 occlusion.occlusion_from_outside_target().ToString());
2200 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2201 occlusion.UnoccludedLayerContentRect(
2202 surface, gfx::Rect(0, 0, 300, 300)));
2203 this->LeaveLayer(surface, &occlusion);
2205 this->EnterContributingSurface(surface, &occlusion);
2206 // Occlusion within the surface is lost when leaving the animating surface.
2207 EXPECT_EQ(gfx::Rect().ToString(),
2208 occlusion.occlusion_from_inside_target().ToString());
2209 EXPECT_EQ(gfx::Rect().ToString(),
2210 occlusion.occlusion_from_outside_target().ToString());
2211 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2212 occlusion.UnoccludedSurfaceContentRect(
2213 surface, false, gfx::Rect(0, 0, 300, 300)));
2214 this->LeaveContributingSurface(surface, &occlusion);
2216 // Occlusion from outside the animating surface still exists.
2217 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2218 occlusion.occlusion_from_inside_target().ToString());
2219 EXPECT_EQ(gfx::Rect().ToString(),
2220 occlusion.occlusion_from_outside_target().ToString());
2222 this->VisitLayer(layer, &occlusion);
2223 this->EnterLayer(parent, &occlusion);
2225 // Occlusion is not added for the animating |layer|.
2226 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2227 occlusion.UnoccludedLayerContentRect(
2228 parent, gfx::Rect(0, 0, 300, 300)));
2232 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2234 template <class Types>
2235 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2236 : public OcclusionTrackerTest<Types> {
2237 protected:
2238 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
2239 : OcclusionTrackerTest<Types>(opaque_layers) {}
2240 void RunMyTest() {
2241 typename Types::ContentLayerType* parent = this->CreateRoot(
2242 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2243 typename Types::ContentLayerType* layer =
2244 this->CreateDrawingLayer(parent,
2245 this->identity_matrix,
2246 gfx::PointF(),
2247 gfx::Size(300, 300),
2248 true);
2249 typename Types::ContentLayerType* surface =
2250 this->CreateDrawingSurface(parent,
2251 this->identity_matrix,
2252 gfx::PointF(),
2253 gfx::Size(300, 300),
2254 true);
2255 typename Types::ContentLayerType* surface_child =
2256 this->CreateDrawingLayer(surface,
2257 this->identity_matrix,
2258 gfx::PointF(),
2259 gfx::Size(200, 300),
2260 true);
2261 typename Types::ContentLayerType* surface_child2 =
2262 this->CreateDrawingLayer(surface,
2263 this->identity_matrix,
2264 gfx::PointF(),
2265 gfx::Size(100, 300),
2266 true);
2267 typename Types::ContentLayerType* parent2 =
2268 this->CreateDrawingLayer(parent,
2269 this->identity_matrix,
2270 gfx::PointF(),
2271 gfx::Size(300, 300),
2272 false);
2273 typename Types::ContentLayerType* topmost =
2274 this->CreateDrawingLayer(parent,
2275 this->identity_matrix,
2276 gfx::PointF(250.f, 0.f),
2277 gfx::Size(50, 300),
2278 true);
2280 AddOpacityTransitionToController(
2281 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2282 AddOpacityTransitionToController(
2283 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2284 this->CalcDrawEtc(parent);
2286 EXPECT_TRUE(layer->draw_opacity_is_animating());
2287 EXPECT_FALSE(surface->draw_opacity_is_animating());
2288 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2290 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2291 gfx::Rect(0, 0, 1000, 1000));
2293 this->VisitLayer(topmost, &occlusion);
2294 this->EnterLayer(parent2, &occlusion);
2295 // This occlusion will affect all surfaces.
2296 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2297 occlusion.occlusion_from_inside_target().ToString());
2298 EXPECT_EQ(gfx::Rect().ToString(),
2299 occlusion.occlusion_from_outside_target().ToString());
2300 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2301 occlusion.UnoccludedLayerContentRect(
2302 parent, gfx::Rect(0, 0, 300, 300)));
2303 this->LeaveLayer(parent2, &occlusion);
2305 this->VisitLayer(surface_child2, &occlusion);
2306 this->EnterLayer(surface_child, &occlusion);
2307 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2308 occlusion.occlusion_from_inside_target().ToString());
2309 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2310 occlusion.occlusion_from_outside_target().ToString());
2311 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2312 occlusion.UnoccludedLayerContentRect(
2313 surface_child, gfx::Rect(0, 0, 200, 300)));
2314 this->LeaveLayer(surface_child, &occlusion);
2315 this->EnterLayer(surface, &occlusion);
2316 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2317 occlusion.occlusion_from_inside_target().ToString());
2318 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2319 occlusion.occlusion_from_outside_target().ToString());
2320 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2321 occlusion.UnoccludedLayerContentRect(
2322 surface, gfx::Rect(0, 0, 300, 300)));
2323 this->LeaveLayer(surface, &occlusion);
2325 this->EnterContributingSurface(surface, &occlusion);
2326 // Occlusion within the surface is lost when leaving the animating surface.
2327 EXPECT_EQ(gfx::Rect().ToString(),
2328 occlusion.occlusion_from_inside_target().ToString());
2329 EXPECT_EQ(gfx::Rect().ToString(),
2330 occlusion.occlusion_from_outside_target().ToString());
2331 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2332 occlusion.UnoccludedSurfaceContentRect(
2333 surface, false, gfx::Rect(0, 0, 300, 300)));
2334 this->LeaveContributingSurface(surface, &occlusion);
2336 // Occlusion from outside the animating surface still exists.
2337 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2338 occlusion.occlusion_from_inside_target().ToString());
2339 EXPECT_EQ(gfx::Rect().ToString(),
2340 occlusion.occlusion_from_outside_target().ToString());
2342 this->VisitLayer(layer, &occlusion);
2343 this->EnterLayer(parent, &occlusion);
2345 // Occlusion is not added for the animating |layer|.
2346 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2347 occlusion.UnoccludedLayerContentRect(
2348 parent, gfx::Rect(0, 0, 300, 300)));
2352 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2354 template <class Types>
2355 class OcclusionTrackerTestAnimationTranslateOnMainThread
2356 : public OcclusionTrackerTest<Types> {
2357 protected:
2358 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2359 bool opaque_layers)
2360 : OcclusionTrackerTest<Types>(opaque_layers) {}
2361 void RunMyTest() {
2362 typename Types::ContentLayerType* parent = this->CreateRoot(
2363 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2364 typename Types::ContentLayerType* layer =
2365 this->CreateDrawingLayer(parent,
2366 this->identity_matrix,
2367 gfx::PointF(),
2368 gfx::Size(300, 300),
2369 true);
2370 typename Types::ContentLayerType* surface =
2371 this->CreateDrawingSurface(parent,
2372 this->identity_matrix,
2373 gfx::PointF(),
2374 gfx::Size(300, 300),
2375 true);
2376 typename Types::ContentLayerType* surface_child =
2377 this->CreateDrawingLayer(surface,
2378 this->identity_matrix,
2379 gfx::PointF(),
2380 gfx::Size(200, 300),
2381 true);
2382 typename Types::ContentLayerType* surface_child2 =
2383 this->CreateDrawingLayer(surface,
2384 this->identity_matrix,
2385 gfx::PointF(),
2386 gfx::Size(100, 300),
2387 true);
2388 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
2389 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
2391 AddAnimatedTransformToController(
2392 layer->layer_animation_controller(), 10.0, 30, 0);
2393 AddAnimatedTransformToController(
2394 surface->layer_animation_controller(), 10.0, 30, 0);
2395 AddAnimatedTransformToController(
2396 surface_child->layer_animation_controller(), 10.0, 30, 0);
2397 this->CalcDrawEtc(parent);
2399 EXPECT_TRUE(layer->draw_transform_is_animating());
2400 EXPECT_TRUE(layer->screen_space_transform_is_animating());
2401 EXPECT_TRUE(
2402 surface->render_surface()->target_surface_transforms_are_animating());
2403 EXPECT_TRUE(
2404 surface->render_surface()->screen_space_transforms_are_animating());
2405 // The surface owning layer doesn't animate against its own surface.
2406 EXPECT_FALSE(surface->draw_transform_is_animating());
2407 EXPECT_TRUE(surface->screen_space_transform_is_animating());
2408 EXPECT_TRUE(surface_child->draw_transform_is_animating());
2409 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
2411 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2412 gfx::Rect(0, 0, 1000, 1000));
2414 this->VisitLayer(surface2, &occlusion);
2415 this->EnterContributingSurface(surface2, &occlusion);
2417 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2418 occlusion.occlusion_from_inside_target().ToString());
2420 this->LeaveContributingSurface(surface2, &occlusion);
2421 this->EnterLayer(surface_child2, &occlusion);
2422 // surface_child2 is moving in screen space but not relative to its target,
2423 // so occlusion should happen in its target space only. It also means that
2424 // things occluding from outside the target (e.g. surface2) cannot occlude
2425 // this layer.
2426 EXPECT_EQ(gfx::Rect().ToString(),
2427 occlusion.occlusion_from_outside_target().ToString());
2428 EXPECT_EQ(gfx::Rect().ToString(),
2429 occlusion.occlusion_from_inside_target().ToString());
2431 this->LeaveLayer(surface_child2, &occlusion);
2432 this->EnterLayer(surface_child, &occlusion);
2433 // surface_child2 added to the occlusion since it is not moving relative
2434 // to its target.
2435 EXPECT_EQ(gfx::Rect().ToString(),
2436 occlusion.occlusion_from_outside_target().ToString());
2437 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2438 occlusion.occlusion_from_inside_target().ToString());
2440 this->LeaveLayer(surface_child, &occlusion);
2441 // surface_child is moving relative to its target, so it does not add
2442 // occlusion.
2443 EXPECT_EQ(gfx::Rect().ToString(),
2444 occlusion.occlusion_from_outside_target().ToString());
2445 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2446 occlusion.occlusion_from_inside_target().ToString());
2448 this->EnterLayer(surface, &occlusion);
2449 EXPECT_EQ(gfx::Rect().ToString(),
2450 occlusion.occlusion_from_outside_target().ToString());
2451 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2452 occlusion.occlusion_from_inside_target().ToString());
2454 this->LeaveLayer(surface, &occlusion);
2455 // The surface's owning layer is moving in screen space but not relative to
2456 // its target, so it adds to the occlusion.
2457 EXPECT_EQ(gfx::Rect().ToString(),
2458 occlusion.occlusion_from_outside_target().ToString());
2459 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2460 occlusion.occlusion_from_inside_target().ToString());
2462 this->EnterContributingSurface(surface, &occlusion);
2463 this->LeaveContributingSurface(surface, &occlusion);
2464 // The |surface| is moving in the screen and in its target, so all occlusion
2465 // within the surface is lost when leaving it. Only the |surface2| occlusion
2466 // is left.
2467 EXPECT_EQ(gfx::Rect().ToString(),
2468 occlusion.occlusion_from_outside_target().ToString());
2469 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2470 occlusion.occlusion_from_inside_target().ToString());
2472 this->VisitLayer(layer, &occlusion);
2473 // The |layer| is animating in the screen and in its target, so no occlusion
2474 // is added.
2475 EXPECT_EQ(gfx::Rect().ToString(),
2476 occlusion.occlusion_from_outside_target().ToString());
2477 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2478 occlusion.occlusion_from_inside_target().ToString());
2482 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
2484 template <class Types>
2485 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2486 : public OcclusionTrackerTest<Types> {
2487 protected:
2488 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2489 bool opaque_layers)
2490 : OcclusionTrackerTest<Types>(opaque_layers) {}
2491 void RunMyTest() {
2492 gfx::Transform surface_transform;
2493 surface_transform.Translate(300.0, 300.0);
2494 surface_transform.Scale(2.0, 2.0);
2495 surface_transform.Translate(-150.0, -150.0);
2497 typename Types::ContentLayerType* parent = this->CreateRoot(
2498 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2499 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
2500 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
2501 typename Types::ContentLayerType* surface2 =
2502 this->CreateDrawingSurface(parent,
2503 this->identity_matrix,
2504 gfx::PointF(50.f, 50.f),
2505 gfx::Size(300, 300),
2506 false);
2507 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2508 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2509 this->CalcDrawEtc(parent);
2511 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2512 gfx::Rect(0, 0, 1000, 1000));
2514 this->VisitLayer(surface2, &occlusion);
2515 this->VisitContributingSurface(surface2, &occlusion);
2517 EXPECT_EQ(gfx::Rect().ToString(),
2518 occlusion.occlusion_from_outside_target().ToString());
2519 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2520 occlusion.occlusion_from_inside_target().ToString());
2522 // Clear any stored occlusion.
2523 occlusion.set_occlusion_from_outside_target(Region());
2524 occlusion.set_occlusion_from_inside_target(Region());
2526 this->VisitLayer(surface, &occlusion);
2527 this->VisitContributingSurface(surface, &occlusion);
2529 EXPECT_EQ(gfx::Rect().ToString(),
2530 occlusion.occlusion_from_outside_target().ToString());
2531 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2532 occlusion.occlusion_from_inside_target().ToString());
2536 MAIN_AND_IMPL_THREAD_TEST(
2537 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2539 template <class Types>
2540 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2541 : public OcclusionTrackerTest<Types> {
2542 protected:
2543 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2544 bool opaque_layers)
2545 : OcclusionTrackerTest<Types>(opaque_layers) {}
2546 void RunMyTest() {
2547 typename Types::ContentLayerType* parent = this->CreateRoot(
2548 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2549 parent->SetMasksToBounds(true);
2550 typename Types::ContentLayerType* surface =
2551 this->CreateDrawingSurface(parent,
2552 this->identity_matrix,
2553 gfx::PointF(),
2554 gfx::Size(500, 300),
2555 false);
2556 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2557 this->CalcDrawEtc(parent);
2559 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2560 gfx::Rect(0, 0, 1000, 1000));
2562 this->VisitLayer(surface, &occlusion);
2563 this->VisitContributingSurface(surface, &occlusion);
2565 EXPECT_EQ(gfx::Rect().ToString(),
2566 occlusion.occlusion_from_outside_target().ToString());
2567 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2568 occlusion.occlusion_from_inside_target().ToString());
2572 MAIN_AND_IMPL_THREAD_TEST(
2573 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2575 template <class Types>
2576 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
2577 protected:
2578 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
2579 : OcclusionTrackerTest<Types>(opaque_layers) {}
2580 void RunMyTest() {
2581 typename Types::ContentLayerType* parent = this->CreateRoot(
2582 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2583 typename Types::LayerType* surface =
2584 this->CreateDrawingSurface(parent,
2585 this->identity_matrix,
2586 gfx::PointF(),
2587 gfx::Size(100, 100),
2588 true);
2589 this->CreateReplicaLayer(surface,
2590 this->identity_matrix,
2591 gfx::PointF(0.f, 100.f),
2592 gfx::Size(100, 100));
2593 typename Types::LayerType* topmost =
2594 this->CreateDrawingLayer(parent,
2595 this->identity_matrix,
2596 gfx::PointF(0.f, 100.f),
2597 gfx::Size(100, 100),
2598 true);
2599 this->CalcDrawEtc(parent);
2601 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2602 gfx::Rect(0, 0, 1000, 1000));
2604 // |topmost| occludes the replica, but not the surface itself.
2605 this->VisitLayer(topmost, &occlusion);
2607 EXPECT_EQ(gfx::Rect().ToString(),
2608 occlusion.occlusion_from_outside_target().ToString());
2609 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2610 occlusion.occlusion_from_inside_target().ToString());
2612 this->VisitLayer(surface, &occlusion);
2614 // Render target with replica ignores occlusion from outside.
2615 EXPECT_EQ(gfx::Rect().ToString(),
2616 occlusion.occlusion_from_outside_target().ToString());
2617 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2618 occlusion.occlusion_from_inside_target().ToString());
2620 this->EnterContributingSurface(surface, &occlusion);
2622 // Surface is not occluded so it shouldn't think it is.
2623 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2624 occlusion.UnoccludedSurfaceContentRect(
2625 surface, false, gfx::Rect(0, 0, 100, 100)));
2629 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
2631 template <class Types>
2632 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2633 : public OcclusionTrackerTest<Types> {
2634 protected:
2635 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
2636 : OcclusionTrackerTest<Types>(opaque_layers) {}
2637 void RunMyTest() {
2638 typename Types::ContentLayerType* parent = this->CreateRoot(
2639 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2640 typename Types::LayerType* surface =
2641 this->CreateDrawingSurface(parent,
2642 this->identity_matrix,
2643 gfx::PointF(),
2644 gfx::Size(100, 100),
2645 true);
2646 this->CreateReplicaLayer(surface,
2647 this->identity_matrix,
2648 gfx::PointF(0.f, 100.f),
2649 gfx::Size(100, 100));
2650 typename Types::LayerType* topmost =
2651 this->CreateDrawingLayer(parent,
2652 this->identity_matrix,
2653 gfx::PointF(),
2654 gfx::Size(100, 110),
2655 true);
2656 this->CalcDrawEtc(parent);
2658 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2659 gfx::Rect(0, 0, 1000, 1000));
2661 // |topmost| occludes the surface, but not the entire surface's replica.
2662 this->VisitLayer(topmost, &occlusion);
2664 EXPECT_EQ(gfx::Rect().ToString(),
2665 occlusion.occlusion_from_outside_target().ToString());
2666 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2667 occlusion.occlusion_from_inside_target().ToString());
2669 this->VisitLayer(surface, &occlusion);
2671 // Render target with replica ignores occlusion from outside.
2672 EXPECT_EQ(gfx::Rect().ToString(),
2673 occlusion.occlusion_from_outside_target().ToString());
2674 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2675 occlusion.occlusion_from_inside_target().ToString());
2677 this->EnterContributingSurface(surface, &occlusion);
2679 // Surface is occluded, but only the top 10px of the replica.
2680 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2681 occlusion.UnoccludedSurfaceContentRect(
2682 surface, false, gfx::Rect(0, 0, 100, 100)));
2683 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2684 occlusion.UnoccludedSurfaceContentRect(
2685 surface, true, gfx::Rect(0, 0, 100, 100)));
2689 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2691 template <class Types>
2692 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
2693 : public OcclusionTrackerTest<Types> {
2694 protected:
2695 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
2696 bool opaque_layers)
2697 : OcclusionTrackerTest<Types>(opaque_layers) {}
2698 void RunMyTest() {
2699 typename Types::ContentLayerType* parent = this->CreateRoot(
2700 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2701 typename Types::LayerType* surface =
2702 this->CreateDrawingSurface(parent,
2703 this->identity_matrix,
2704 gfx::PointF(),
2705 gfx::Size(100, 100),
2706 true);
2707 this->CreateReplicaLayer(surface,
2708 this->identity_matrix,
2709 gfx::PointF(0.f, 100.f),
2710 gfx::Size(100, 100));
2711 typename Types::LayerType* over_surface = this->CreateDrawingLayer(
2712 parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
2713 typename Types::LayerType* over_replica =
2714 this->CreateDrawingLayer(parent,
2715 this->identity_matrix,
2716 gfx::PointF(0.f, 100.f),
2717 gfx::Size(50, 100),
2718 true);
2719 this->CalcDrawEtc(parent);
2721 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2722 gfx::Rect(0, 0, 1000, 1000));
2724 // These occlude the surface and replica differently, so we can test each
2725 // one.
2726 this->VisitLayer(over_replica, &occlusion);
2727 this->VisitLayer(over_surface, &occlusion);
2729 EXPECT_EQ(gfx::Rect().ToString(),
2730 occlusion.occlusion_from_outside_target().ToString());
2731 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2732 .ToString(),
2733 occlusion.occlusion_from_inside_target().ToString());
2735 this->VisitLayer(surface, &occlusion);
2737 // Render target with replica ignores occlusion from outside.
2738 EXPECT_EQ(gfx::Rect().ToString(),
2739 occlusion.occlusion_from_outside_target().ToString());
2740 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2741 occlusion.occlusion_from_inside_target().ToString());
2743 this->EnterContributingSurface(surface, &occlusion);
2745 // Surface and replica are occluded different amounts.
2746 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
2747 occlusion.UnoccludedSurfaceContentRect(
2748 surface, false, gfx::Rect(0, 0, 100, 100)));
2749 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2750 occlusion.UnoccludedSurfaceContentRect(
2751 surface, true, gfx::Rect(0, 0, 100, 100)));
2755 ALL_OCCLUSIONTRACKER_TEST(
2756 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2758 template <class Types>
2759 class OcclusionTrackerTestSurfaceChildOfSurface
2760 : public OcclusionTrackerTest<Types> {
2761 protected:
2762 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
2763 : OcclusionTrackerTest<Types>(opaque_layers) {}
2764 void RunMyTest() {
2765 // This test verifies that the surface cliprect does not end up empty and
2766 // clip away the entire unoccluded rect.
2768 typename Types::ContentLayerType* parent = this->CreateRoot(
2769 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2770 typename Types::LayerType* surface =
2771 this->CreateDrawingSurface(parent,
2772 this->identity_matrix,
2773 gfx::PointF(),
2774 gfx::Size(100, 100),
2775 true);
2776 typename Types::LayerType* surface_child =
2777 this->CreateDrawingSurface(surface,
2778 this->identity_matrix,
2779 gfx::PointF(0.f, 10.f),
2780 gfx::Size(100, 50),
2781 true);
2782 typename Types::LayerType* topmost = this->CreateDrawingLayer(
2783 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2784 this->CalcDrawEtc(parent);
2786 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2787 gfx::Rect(-100, -100, 1000, 1000));
2789 // |topmost| occludes everything partially so we know occlusion is happening
2790 // at all.
2791 this->VisitLayer(topmost, &occlusion);
2793 EXPECT_EQ(gfx::Rect().ToString(),
2794 occlusion.occlusion_from_outside_target().ToString());
2795 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2796 occlusion.occlusion_from_inside_target().ToString());
2798 this->VisitLayer(surface_child, &occlusion);
2800 // surface_child increases the occlusion in the screen by a narrow sliver.
2801 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2802 occlusion.occlusion_from_outside_target().ToString());
2803 // In its own surface, surface_child is at 0,0 as is its occlusion.
2804 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2805 occlusion.occlusion_from_inside_target().ToString());
2807 // The root layer always has a clip rect. So the parent of |surface| has a
2808 // clip rect. However, the owning layer for |surface| does not mask to
2809 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2810 // |surface_child| exercises different code paths as its parent does not
2811 // have a clip rect.
2813 this->EnterContributingSurface(surface_child, &occlusion);
2814 // The surface_child's parent does not have a clip rect as it owns a render
2815 // surface. Make sure the unoccluded rect does not get clipped away
2816 // inappropriately.
2817 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
2818 occlusion.UnoccludedSurfaceContentRect(
2819 surface_child, false, gfx::Rect(0, 0, 100, 50)));
2820 this->LeaveContributingSurface(surface_child, &occlusion);
2822 // When the surface_child's occlusion is transformed up to its parent, make
2823 // sure it is not clipped away inappropriately also.
2824 this->EnterLayer(surface, &occlusion);
2825 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2826 occlusion.occlusion_from_outside_target().ToString());
2827 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2828 occlusion.occlusion_from_inside_target().ToString());
2829 this->LeaveLayer(surface, &occlusion);
2831 this->EnterContributingSurface(surface, &occlusion);
2832 // The surface's parent does have a clip rect as it is the root layer.
2833 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
2834 occlusion.UnoccludedSurfaceContentRect(
2835 surface, false, gfx::Rect(0, 0, 100, 100)));
2839 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2841 template <class Types>
2842 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2843 : public OcclusionTrackerTest<Types> {
2844 protected:
2845 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2846 bool opaque_layers)
2847 : OcclusionTrackerTest<Types>(opaque_layers) {}
2848 void RunMyTest() {
2849 gfx::Transform scale_by_half;
2850 scale_by_half.Scale(0.5, 0.5);
2852 // Make a 50x50 filtered surface that is completely surrounded by opaque
2853 // layers which are above it in the z-order. The surface is scaled to test
2854 // that the pixel moving is done in the target space, where the background
2855 // filter is applied.
2856 typename Types::ContentLayerType* parent = this->CreateRoot(
2857 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
2858 typename Types::LayerType* filtered_surface =
2859 this->CreateDrawingLayer(parent,
2860 scale_by_half,
2861 gfx::PointF(50.f, 50.f),
2862 gfx::Size(100, 100),
2863 false);
2864 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
2865 parent, this->identity_matrix, gfx::PointF(), gfx::Size(200, 50), true);
2866 typename Types::LayerType* occluding_layer2 =
2867 this->CreateDrawingLayer(parent,
2868 this->identity_matrix,
2869 gfx::PointF(0.f, 100.f),
2870 gfx::Size(200, 50),
2871 true);
2872 typename Types::LayerType* occluding_layer3 =
2873 this->CreateDrawingLayer(parent,
2874 this->identity_matrix,
2875 gfx::PointF(0.f, 50.f),
2876 gfx::Size(50, 50),
2877 true);
2878 typename Types::LayerType* occluding_layer4 =
2879 this->CreateDrawingLayer(parent,
2880 this->identity_matrix,
2881 gfx::PointF(100.f, 50.f),
2882 gfx::Size(100, 50),
2883 true);
2885 // Filters make the layer own a surface.
2886 FilterOperations filters;
2887 filters.Append(FilterOperation::CreateBlurFilter(10.f));
2888 filtered_surface->SetBackgroundFilters(filters);
2890 // Save the distance of influence for the blur effect.
2891 int outset_top, outset_right, outset_bottom, outset_left;
2892 filters.GetOutsets(
2893 &outset_top, &outset_right, &outset_bottom, &outset_left);
2895 this->CalcDrawEtc(parent);
2897 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2898 gfx::Rect(0, 0, 1000, 1000));
2900 // These layers occlude pixels directly beside the filtered_surface. Because
2901 // filtered surface blends pixels in a radius, it will need to see some of
2902 // the pixels (up to radius far) underneath the occluding layers.
2903 this->VisitLayer(occluding_layer4, &occlusion);
2904 this->VisitLayer(occluding_layer3, &occlusion);
2905 this->VisitLayer(occluding_layer2, &occlusion);
2906 this->VisitLayer(occluding_layer1, &occlusion);
2908 Region expected_occlusion;
2909 expected_occlusion.Union(gfx::Rect(0, 0, 200, 50));
2910 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
2911 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
2912 expected_occlusion.Union(gfx::Rect(0, 100, 200, 50));
2914 EXPECT_EQ(expected_occlusion.ToString(),
2915 occlusion.occlusion_from_inside_target().ToString());
2916 EXPECT_EQ(gfx::Rect().ToString(),
2917 occlusion.occlusion_from_outside_target().ToString());
2919 this->VisitLayer(filtered_surface, &occlusion);
2921 // The filtered layer does not occlude.
2922 Region expected_occlusion_outside_surface;
2923 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 200, 50));
2924 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
2925 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
2926 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 200, 50));
2928 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
2929 occlusion.occlusion_from_outside_target().ToString());
2930 EXPECT_EQ(gfx::Rect().ToString(),
2931 occlusion.occlusion_from_inside_target().ToString());
2933 // The surface has a background blur, so it needs pixels that are currently
2934 // considered occluded in order to be drawn. So the pixels it needs should
2935 // be removed some the occluded area so that when we get to the parent they
2936 // are drawn.
2937 this->VisitContributingSurface(filtered_surface, &occlusion);
2939 this->EnterLayer(parent, &occlusion);
2941 Region expected_blurred_occlusion;
2942 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 200, 50 - outset_top));
2943 expected_blurred_occlusion.Union(gfx::Rect(
2944 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
2945 expected_blurred_occlusion.Union(
2946 gfx::Rect(100 + outset_right,
2947 50 - outset_top,
2948 100 - outset_right,
2949 50 + outset_top + outset_bottom));
2950 expected_blurred_occlusion.Union(
2951 gfx::Rect(0, 100 + outset_bottom, 200, 50 - outset_bottom));
2953 EXPECT_EQ(expected_blurred_occlusion.ToString(),
2954 occlusion.occlusion_from_inside_target().ToString());
2955 EXPECT_EQ(gfx::Rect().ToString(),
2956 occlusion.occlusion_from_outside_target().ToString());
2958 gfx::Rect outset_rect;
2959 gfx::Rect test_rect;
2961 // Nothing in the blur outsets for the filtered_surface is occluded.
2962 outset_rect = gfx::Rect(50 - outset_left,
2963 50 - outset_top,
2964 50 + outset_left + outset_right,
2965 50 + outset_top + outset_bottom);
2966 test_rect = outset_rect;
2967 EXPECT_EQ(
2968 outset_rect.ToString(),
2969 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
2971 // Stuff outside the blur outsets is still occluded though.
2972 test_rect = outset_rect;
2973 test_rect.Inset(0, 0, -1, 0);
2974 EXPECT_EQ(
2975 outset_rect.ToString(),
2976 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
2977 test_rect = outset_rect;
2978 test_rect.Inset(0, 0, 0, -1);
2979 EXPECT_EQ(
2980 outset_rect.ToString(),
2981 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
2982 test_rect = outset_rect;
2983 test_rect.Inset(-1, 0, 0, 0);
2984 EXPECT_EQ(
2985 outset_rect.ToString(),
2986 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
2987 test_rect = outset_rect;
2988 test_rect.Inset(0, -1, 0, 0);
2989 EXPECT_EQ(
2990 outset_rect.ToString(),
2991 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
2995 ALL_OCCLUSIONTRACKER_TEST(
2996 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2998 template <class Types>
2999 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3000 : public OcclusionTrackerTest<Types> {
3001 protected:
3002 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3003 bool opaque_layers)
3004 : OcclusionTrackerTest<Types>(opaque_layers) {}
3005 void RunMyTest() {
3006 gfx::Transform scale_by_half;
3007 scale_by_half.Scale(0.5, 0.5);
3009 // Makes two surfaces that completely cover |parent|. The occlusion both
3010 // above and below the filters will be reduced by each of them.
3011 typename Types::ContentLayerType* root = this->CreateRoot(
3012 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
3013 typename Types::LayerType* parent = this->CreateSurface(
3014 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
3015 parent->SetMasksToBounds(true);
3016 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
3017 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3018 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
3019 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3020 typename Types::LayerType* occluding_layer_above =
3021 this->CreateDrawingLayer(parent,
3022 this->identity_matrix,
3023 gfx::PointF(100.f, 100.f),
3024 gfx::Size(50, 50),
3025 true);
3027 // Filters make the layers own surfaces.
3028 FilterOperations filters;
3029 filters.Append(FilterOperation::CreateBlurFilter(1.f));
3030 filtered_surface1->SetBackgroundFilters(filters);
3031 filtered_surface2->SetBackgroundFilters(filters);
3033 // Save the distance of influence for the blur effect.
3034 int outset_top, outset_right, outset_bottom, outset_left;
3035 filters.GetOutsets(
3036 &outset_top, &outset_right, &outset_bottom, &outset_left);
3038 this->CalcDrawEtc(root);
3040 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3041 gfx::Rect(0, 0, 1000, 1000));
3043 this->VisitLayer(occluding_layer_above, &occlusion);
3044 EXPECT_EQ(gfx::Rect().ToString(),
3045 occlusion.occlusion_from_outside_target().ToString());
3046 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3047 occlusion.occlusion_from_inside_target().ToString());
3049 this->VisitLayer(filtered_surface2, &occlusion);
3050 this->VisitContributingSurface(filtered_surface2, &occlusion);
3051 this->VisitLayer(filtered_surface1, &occlusion);
3052 this->VisitContributingSurface(filtered_surface1, &occlusion);
3054 // Test expectations in the target.
3055 gfx::Rect expected_occlusion =
3056 gfx::Rect(100 / 2 + outset_right * 2,
3057 100 / 2 + outset_bottom * 2,
3058 50 / 2 - (outset_left + outset_right) * 2,
3059 50 / 2 - (outset_top + outset_bottom) * 2);
3060 EXPECT_EQ(expected_occlusion.ToString(),
3061 occlusion.occlusion_from_inside_target().ToString());
3063 // Test expectations in the screen are the same as in the target, as the
3064 // render surface is 1:1 with the screen.
3065 EXPECT_EQ(expected_occlusion.ToString(),
3066 occlusion.occlusion_from_outside_target().ToString());
3070 ALL_OCCLUSIONTRACKER_TEST(
3071 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
3073 template <class Types>
3074 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3075 : public OcclusionTrackerTest<Types> {
3076 protected:
3077 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3078 bool opaque_layers)
3079 : OcclusionTrackerTest<Types>(opaque_layers) {}
3080 void RunMyTest() {
3081 gfx::Transform scale_by_half;
3082 scale_by_half.Scale(0.5, 0.5);
3084 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3085 // centered below each. The surface is scaled to test that the pixel moving
3086 // is done in the target space, where the background filter is applied, but
3087 // the surface appears at 50, 50 and the replica at 200, 50.
3088 typename Types::ContentLayerType* parent = this->CreateRoot(
3089 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3090 typename Types::LayerType* behind_surface_layer =
3091 this->CreateDrawingLayer(parent,
3092 this->identity_matrix,
3093 gfx::PointF(60.f, 60.f),
3094 gfx::Size(30, 30),
3095 true);
3096 typename Types::LayerType* behind_replica_layer =
3097 this->CreateDrawingLayer(parent,
3098 this->identity_matrix,
3099 gfx::PointF(210.f, 60.f),
3100 gfx::Size(30, 30),
3101 true);
3102 typename Types::LayerType* filtered_surface =
3103 this->CreateDrawingLayer(parent,
3104 scale_by_half,
3105 gfx::PointF(50.f, 50.f),
3106 gfx::Size(100, 100),
3107 false);
3108 this->CreateReplicaLayer(filtered_surface,
3109 this->identity_matrix,
3110 gfx::PointF(300.f, 0.f),
3111 gfx::Size());
3113 // Filters make the layer own a surface.
3114 FilterOperations filters;
3115 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3116 filtered_surface->SetBackgroundFilters(filters);
3118 this->CalcDrawEtc(parent);
3120 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3121 gfx::Rect(0, 0, 1000, 1000));
3123 // The surface has a background blur, so it blurs non-opaque pixels below
3124 // it.
3125 this->VisitLayer(filtered_surface, &occlusion);
3126 this->VisitContributingSurface(filtered_surface, &occlusion);
3128 this->VisitLayer(behind_replica_layer, &occlusion);
3129 this->VisitLayer(behind_surface_layer, &occlusion);
3131 // The layers behind the surface are not blurred, and their occlusion does
3132 // not change, until we leave the surface. So it should not be modified by
3133 // the filter here.
3134 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
3135 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
3137 Region expected_opaque_bounds =
3138 UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
3139 EXPECT_EQ(expected_opaque_bounds.ToString(),
3140 occlusion.occlusion_from_inside_target().ToString());
3142 EXPECT_EQ(gfx::Rect().ToString(),
3143 occlusion.occlusion_from_outside_target().ToString());
3147 ALL_OCCLUSIONTRACKER_TEST(
3148 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
3150 template <class Types>
3151 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3152 : public OcclusionTrackerTest<Types> {
3153 protected:
3154 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3155 bool opaque_layers)
3156 : OcclusionTrackerTest<Types>(opaque_layers) {}
3157 void RunMyTest() {
3158 gfx::Transform scale_by_half;
3159 scale_by_half.Scale(0.5, 0.5);
3161 // Make a 50x50 filtered surface that is completely occluded by an opaque
3162 // layer which is above it in the z-order. The surface is
3163 // scaled to test that the pixel moving is done in the target space, where
3164 // the background filter is applied, but the surface appears at 50, 50.
3165 typename Types::ContentLayerType* parent = this->CreateRoot(
3166 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
3167 typename Types::LayerType* filtered_surface =
3168 this->CreateDrawingLayer(parent,
3169 scale_by_half,
3170 gfx::PointF(50.f, 50.f),
3171 gfx::Size(100, 100),
3172 false);
3173 typename Types::LayerType* occluding_layer =
3174 this->CreateDrawingLayer(parent,
3175 this->identity_matrix,
3176 gfx::PointF(50.f, 50.f),
3177 gfx::Size(50, 50),
3178 true);
3180 // Filters make the layer own a surface.
3181 FilterOperations filters;
3182 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3183 filtered_surface->SetBackgroundFilters(filters);
3185 this->CalcDrawEtc(parent);
3187 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3188 gfx::Rect(0, 0, 1000, 1000));
3190 this->VisitLayer(occluding_layer, &occlusion);
3192 this->VisitLayer(filtered_surface, &occlusion);
3194 // The layers above the filtered surface occlude from outside.
3195 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
3197 EXPECT_EQ(gfx::Rect().ToString(),
3198 occlusion.occlusion_from_inside_target().ToString());
3199 EXPECT_EQ(occlusion_above_surface.ToString(),
3200 occlusion.occlusion_from_outside_target().ToString());
3203 // The surface has a background blur, so it blurs non-opaque pixels below
3204 // it.
3205 this->VisitContributingSurface(filtered_surface, &occlusion);
3207 // The filter is completely occluded, so it should not blur anything and
3208 // reduce any occlusion.
3209 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
3211 EXPECT_EQ(occlusion_above_surface.ToString(),
3212 occlusion.occlusion_from_inside_target().ToString());
3213 EXPECT_EQ(gfx::Rect().ToString(),
3214 occlusion.occlusion_from_outside_target().ToString());
3219 ALL_OCCLUSIONTRACKER_TEST(
3220 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
3222 template <class Types>
3223 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3224 : public OcclusionTrackerTest<Types> {
3225 protected:
3226 explicit
3227 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3228 bool opaque_layers)
3229 : OcclusionTrackerTest<Types>(opaque_layers) {}
3230 void RunMyTest() {
3231 gfx::Transform scale_by_half;
3232 scale_by_half.Scale(0.5, 0.5);
3234 // Make a surface and its replica, each 50x50, that are partially occluded
3235 // by opaque layers which are above them in the z-order. The surface is
3236 // scaled to test that the pixel moving is done in the target space, where
3237 // the background filter is applied, but the surface appears at 50, 50 and
3238 // the replica at 200, 50.
3239 typename Types::ContentLayerType* parent = this->CreateRoot(
3240 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3241 typename Types::LayerType* filtered_surface =
3242 this->CreateDrawingLayer(parent,
3243 scale_by_half,
3244 gfx::PointF(50.f, 50.f),
3245 gfx::Size(100, 100),
3246 false);
3247 this->CreateReplicaLayer(filtered_surface,
3248 this->identity_matrix,
3249 gfx::PointF(300.f, 0.f),
3250 gfx::Size());
3251 typename Types::LayerType* above_surface_layer =
3252 this->CreateDrawingLayer(parent,
3253 this->identity_matrix,
3254 gfx::PointF(70.f, 50.f),
3255 gfx::Size(30, 50),
3256 true);
3257 typename Types::LayerType* above_replica_layer =
3258 this->CreateDrawingLayer(parent,
3259 this->identity_matrix,
3260 gfx::PointF(200.f, 50.f),
3261 gfx::Size(30, 50),
3262 true);
3263 typename Types::LayerType* beside_surface_layer =
3264 this->CreateDrawingLayer(parent,
3265 this->identity_matrix,
3266 gfx::PointF(90.f, 40.f),
3267 gfx::Size(10, 10),
3268 true);
3269 typename Types::LayerType* beside_replica_layer =
3270 this->CreateDrawingLayer(parent,
3271 this->identity_matrix,
3272 gfx::PointF(200.f, 40.f),
3273 gfx::Size(10, 10),
3274 true);
3276 // Filters make the layer own a surface.
3277 FilterOperations filters;
3278 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3279 filtered_surface->SetBackgroundFilters(filters);
3281 // Save the distance of influence for the blur effect.
3282 int outset_top, outset_right, outset_bottom, outset_left;
3283 filters.GetOutsets(
3284 &outset_top, &outset_right, &outset_bottom, &outset_left);
3286 this->CalcDrawEtc(parent);
3288 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3289 gfx::Rect(0, 0, 1000, 1000));
3291 this->VisitLayer(beside_replica_layer, &occlusion);
3292 this->VisitLayer(beside_surface_layer, &occlusion);
3293 this->VisitLayer(above_replica_layer, &occlusion);
3294 this->VisitLayer(above_surface_layer, &occlusion);
3296 // The surface has a background blur, so it blurs non-opaque pixels below
3297 // it.
3298 this->VisitLayer(filtered_surface, &occlusion);
3299 this->VisitContributingSurface(filtered_surface, &occlusion);
3301 // The filter in the surface and replica are partially unoccluded. Only the
3302 // unoccluded parts should reduce occlusion. This means it will push back
3303 // the occlusion that touches the unoccluded part (occlusion_above___), but
3304 // it will not touch occlusion_beside____ since that is not beside the
3305 // unoccluded part of the surface, even though it is beside the occluded
3306 // part of the surface.
3307 gfx::Rect occlusion_above_surface =
3308 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
3309 gfx::Rect occlusion_above_replica =
3310 gfx::Rect(200, 50, 30 - outset_left, 50);
3311 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
3312 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
3314 Region expected_occlusion;
3315 expected_occlusion.Union(occlusion_above_surface);
3316 expected_occlusion.Union(occlusion_above_replica);
3317 expected_occlusion.Union(occlusion_beside_surface);
3318 expected_occlusion.Union(occlusion_beside_replica);
3320 ASSERT_EQ(expected_occlusion.ToString(),
3321 occlusion.occlusion_from_inside_target().ToString());
3322 EXPECT_EQ(gfx::Rect().ToString(),
3323 occlusion.occlusion_from_outside_target().ToString());
3325 Region::Iterator expected_rects(expected_occlusion);
3326 Region::Iterator target_surface_rects(
3327 occlusion.occlusion_from_inside_target());
3328 for (; expected_rects.has_rect();
3329 expected_rects.next(), target_surface_rects.next()) {
3330 ASSERT_TRUE(target_surface_rects.has_rect());
3331 EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
3336 ALL_OCCLUSIONTRACKER_TEST(
3337 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
3339 template <class Types>
3340 class OcclusionTrackerTestMinimumTrackingSize
3341 : public OcclusionTrackerTest<Types> {
3342 protected:
3343 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
3344 : OcclusionTrackerTest<Types>(opaque_layers) {}
3345 void RunMyTest() {
3346 gfx::Size tracking_size(100, 100);
3347 gfx::Size below_tracking_size(99, 99);
3349 typename Types::ContentLayerType* parent = this->CreateRoot(
3350 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3351 typename Types::LayerType* large = this->CreateDrawingLayer(
3352 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
3353 typename Types::LayerType* small =
3354 this->CreateDrawingLayer(parent,
3355 this->identity_matrix,
3356 gfx::PointF(),
3357 below_tracking_size,
3358 true);
3359 this->CalcDrawEtc(parent);
3361 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3362 gfx::Rect(0, 0, 1000, 1000));
3363 occlusion.set_minimum_tracking_size(tracking_size);
3365 // The small layer is not tracked because it is too small.
3366 this->VisitLayer(small, &occlusion);
3368 EXPECT_EQ(gfx::Rect().ToString(),
3369 occlusion.occlusion_from_outside_target().ToString());
3370 EXPECT_EQ(gfx::Rect().ToString(),
3371 occlusion.occlusion_from_inside_target().ToString());
3373 // The large layer is tracked as it is large enough.
3374 this->VisitLayer(large, &occlusion);
3376 EXPECT_EQ(gfx::Rect().ToString(),
3377 occlusion.occlusion_from_outside_target().ToString());
3378 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
3379 occlusion.occlusion_from_inside_target().ToString());
3383 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
3385 template <class Types>
3386 class OcclusionTrackerTestScaledLayerIsClipped
3387 : public OcclusionTrackerTest<Types> {
3388 protected:
3389 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
3390 : OcclusionTrackerTest<Types>(opaque_layers) {}
3391 void RunMyTest() {
3392 gfx::Transform scale_transform;
3393 scale_transform.Scale(512.0, 512.0);
3395 typename Types::ContentLayerType* parent = this->CreateRoot(
3396 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3397 typename Types::LayerType* clip = this->CreateLayer(parent,
3398 this->identity_matrix,
3399 gfx::PointF(10.f, 10.f),
3400 gfx::Size(50, 50));
3401 clip->SetMasksToBounds(true);
3402 typename Types::LayerType* scale = this->CreateLayer(
3403 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3404 typename Types::LayerType* scaled = this->CreateDrawingLayer(
3405 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3406 this->CalcDrawEtc(parent);
3408 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3409 gfx::Rect(0, 0, 1000, 1000));
3411 this->VisitLayer(scaled, &occlusion);
3413 EXPECT_EQ(gfx::Rect().ToString(),
3414 occlusion.occlusion_from_outside_target().ToString());
3415 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3416 occlusion.occlusion_from_inside_target().ToString());
3420 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
3422 template <class Types>
3423 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3424 : public OcclusionTrackerTest<Types> {
3425 protected:
3426 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
3427 : OcclusionTrackerTest<Types>(opaque_layers) {}
3428 void RunMyTest() {
3429 gfx::Transform scale_transform;
3430 scale_transform.Scale(512.0, 512.0);
3432 typename Types::ContentLayerType* parent = this->CreateRoot(
3433 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3434 typename Types::LayerType* clip = this->CreateLayer(parent,
3435 this->identity_matrix,
3436 gfx::PointF(10.f, 10.f),
3437 gfx::Size(50, 50));
3438 clip->SetMasksToBounds(true);
3439 typename Types::LayerType* surface = this->CreateDrawingSurface(
3440 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
3441 typename Types::LayerType* scale = this->CreateLayer(
3442 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3443 typename Types::LayerType* scaled = this->CreateDrawingLayer(
3444 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3445 this->CalcDrawEtc(parent);
3447 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3448 gfx::Rect(0, 0, 1000, 1000));
3450 this->VisitLayer(scaled, &occlusion);
3451 this->VisitLayer(surface, &occlusion);
3452 this->VisitContributingSurface(surface, &occlusion);
3454 EXPECT_EQ(gfx::Rect().ToString(),
3455 occlusion.occlusion_from_outside_target().ToString());
3456 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3457 occlusion.occlusion_from_inside_target().ToString());
3461 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
3463 template <class Types>
3464 class OcclusionTrackerTestCopyRequestDoesOcclude
3465 : public OcclusionTrackerTest<Types> {
3466 protected:
3467 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
3468 : OcclusionTrackerTest<Types>(opaque_layers) {}
3469 void RunMyTest() {
3470 typename Types::ContentLayerType* root = this->CreateRoot(
3471 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3472 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3473 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3474 typename Types::LayerType* copy = this->CreateLayer(parent,
3475 this->identity_matrix,
3476 gfx::Point(100, 0),
3477 gfx::Size(200, 400));
3478 this->AddCopyRequest(copy);
3479 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3480 copy,
3481 this->identity_matrix,
3482 gfx::PointF(),
3483 gfx::Size(200, 400),
3484 true);
3485 this->CalcDrawEtc(root);
3487 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3488 gfx::Rect(0, 0, 1000, 1000));
3490 this->VisitLayer(copy_child, &occlusion);
3491 EXPECT_EQ(gfx::Rect().ToString(),
3492 occlusion.occlusion_from_outside_target().ToString());
3493 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3494 occlusion.occlusion_from_inside_target().ToString());
3496 // CopyRequests cause the layer to own a surface.
3497 this->VisitContributingSurface(copy, &occlusion);
3499 // The occlusion from the copy should be kept.
3500 EXPECT_EQ(gfx::Rect().ToString(),
3501 occlusion.occlusion_from_outside_target().ToString());
3502 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3503 occlusion.occlusion_from_inside_target().ToString());
3507 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
3509 template <class Types>
3510 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3511 : public OcclusionTrackerTest<Types> {
3512 protected:
3513 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3514 bool opaque_layers)
3515 : OcclusionTrackerTest<Types>(opaque_layers) {}
3516 void RunMyTest() {
3517 typename Types::ContentLayerType* root = this->CreateRoot(
3518 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3519 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3520 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3521 typename Types::LayerType* hide = this->CreateLayer(
3522 parent, this->identity_matrix, gfx::Point(), gfx::Size());
3523 typename Types::LayerType* copy = this->CreateLayer(
3524 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
3525 this->AddCopyRequest(copy);
3526 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3527 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
3529 // The |copy| layer is hidden but since it is being copied, it will be
3530 // drawn.
3531 hide->SetHideLayerAndSubtree(true);
3533 this->CalcDrawEtc(root);
3535 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3536 gfx::Rect(0, 0, 1000, 1000));
3538 this->VisitLayer(copy_child, &occlusion);
3539 EXPECT_EQ(gfx::Rect().ToString(),
3540 occlusion.occlusion_from_outside_target().ToString());
3541 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3542 occlusion.occlusion_from_inside_target().ToString());
3544 // CopyRequests cause the layer to own a surface.
3545 this->VisitContributingSurface(copy, &occlusion);
3547 // The occlusion from the copy should be dropped since it is hidden.
3548 EXPECT_EQ(gfx::Rect().ToString(),
3549 occlusion.occlusion_from_outside_target().ToString());
3550 EXPECT_EQ(gfx::Rect().ToString(),
3551 occlusion.occlusion_from_inside_target().ToString());
3555 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
3557 } // namespace
3558 } // namespace cc