Enable snappy for IndexedDB.
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob0e8b5d4c50f3d2260735df92b8635f94d39b55d2
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/occlusion_tracker.h"
7 #include "cc/animation/layer_animation_controller.h"
8 #include "cc/base/math_util.h"
9 #include "cc/debug/overdraw_metrics.h"
10 #include "cc/layers/layer.h"
11 #include "cc/layers/layer_impl.h"
12 #include "cc/output/copy_output_request.h"
13 #include "cc/output/copy_output_result.h"
14 #include "cc/output/filter_operation.h"
15 #include "cc/output/filter_operations.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_impl_proxy.h"
18 #include "cc/test/fake_layer_tree_host.h"
19 #include "cc/test/fake_layer_tree_host_impl.h"
20 #include "cc/test/geometry_test_utils.h"
21 #include "cc/test/occlusion_tracker_test_common.h"
22 #include "cc/trees/layer_tree_host_common.h"
23 #include "cc/trees/single_thread_proxy.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/transform.h"
28 namespace cc {
29 namespace {
31 class TestContentLayer : public Layer {
32 public:
33 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
34 SetIsDrawable(true);
37 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
38 if (override_opaque_contents_rect_)
39 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
40 return Layer::VisibleContentOpaqueRegion();
42 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
43 override_opaque_contents_rect_ = true;
44 opaque_contents_rect_ = opaque_contents_rect;
47 private:
48 virtual ~TestContentLayer() {}
50 bool override_opaque_contents_rect_;
51 gfx::Rect opaque_contents_rect_;
54 class TestContentLayerImpl : public LayerImpl {
55 public:
56 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
57 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
58 SetDrawsContent(true);
61 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
62 if (override_opaque_contents_rect_)
63 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
64 return LayerImpl::VisibleContentOpaqueRegion();
66 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
67 override_opaque_contents_rect_ = true;
68 opaque_contents_rect_ = opaque_contents_rect;
71 private:
72 bool override_opaque_contents_rect_;
73 gfx::Rect opaque_contents_rect_;
76 static inline bool LayerImplDrawTransformIsUnknown(const Layer* layer) {
77 return layer->draw_transform_is_animating();
79 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl* layer) {
80 return false;
83 template <typename LayerType, typename RenderSurfaceType>
84 class TestOcclusionTrackerWithClip
85 : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> {
86 public:
87 TestOcclusionTrackerWithClip(gfx::Rect viewport_rect,
88 bool record_metrics_for_frame)
89 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(
90 viewport_rect,
91 record_metrics_for_frame) {}
92 explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect)
93 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewport_rect,
94 false) {}
96 bool OccludedLayer(const LayerType* layer,
97 gfx::Rect content_rect) const {
98 DCHECK(layer->visible_content_rect().Contains(content_rect));
99 return this->Occluded(layer->render_target(),
100 content_rect,
101 layer->draw_transform(),
102 LayerImplDrawTransformIsUnknown(layer));
105 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
106 // layer. Simple wrapper around UnoccludedContentRect.
107 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
108 gfx::Rect content_rect) const {
109 DCHECK(layer->visible_content_rect().Contains(content_rect));
110 return this->UnoccludedContentRect(
111 layer->render_target(),
112 content_rect,
113 layer->draw_transform(),
114 LayerImplDrawTransformIsUnknown(layer));
118 struct OcclusionTrackerTestMainThreadTypes {
119 typedef Layer LayerType;
120 typedef FakeLayerTreeHost HostType;
121 typedef RenderSurface RenderSurfaceType;
122 typedef TestContentLayer ContentLayerType;
123 typedef scoped_refptr<Layer> LayerPtrType;
124 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
125 typedef LayerIterator<Layer,
126 RenderSurfaceLayerList,
127 RenderSurface,
128 LayerIteratorActions::FrontToBack> TestLayerIterator;
129 typedef OcclusionTracker OcclusionTrackerType;
131 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
132 static ContentLayerPtrType CreateContentLayer(HostType* host) {
133 return make_scoped_refptr(new ContentLayerType());
136 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
137 LayerPtrType ref(*layer);
138 *layer = NULL;
139 return ref;
142 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
143 LayerPtrType ref(*layer);
144 *layer = NULL;
145 return ref;
148 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
151 struct OcclusionTrackerTestImplThreadTypes {
152 typedef LayerImpl LayerType;
153 typedef LayerTreeImpl HostType;
154 typedef RenderSurfaceImpl RenderSurfaceType;
155 typedef TestContentLayerImpl ContentLayerType;
156 typedef scoped_ptr<LayerImpl> LayerPtrType;
157 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
158 typedef LayerIterator<LayerImpl,
159 LayerImplList,
160 RenderSurfaceImpl,
161 LayerIteratorActions::FrontToBack> TestLayerIterator;
162 typedef OcclusionTrackerImpl OcclusionTrackerType;
164 static LayerPtrType CreateLayer(HostType* host) {
165 return LayerImpl::Create(host, next_layer_impl_id++);
167 static ContentLayerPtrType CreateContentLayer(HostType* host) {
168 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
170 static int next_layer_impl_id;
172 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
173 return layer->Pass();
176 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
177 return layer->PassAs<LayerType>();
180 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
183 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
185 template <typename Types> class OcclusionTrackerTest : public testing::Test {
186 protected:
187 explicit OcclusionTrackerTest(bool opaque_layers)
188 : opaque_layers_(opaque_layers), host_(FakeLayerTreeHost::Create()) {}
190 virtual void RunMyTest() = 0;
192 virtual void TearDown() {
193 Types::DestroyLayer(&root_);
194 render_surface_layer_list_.reset();
195 render_surface_layer_list_impl_.clear();
196 replica_layers_.clear();
197 mask_layers_.clear();
200 typename Types::HostType* GetHost();
202 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
203 gfx::PointF position,
204 gfx::Size bounds) {
205 typename Types::ContentLayerPtrType layer(
206 Types::CreateContentLayer(GetHost()));
207 typename Types::ContentLayerType* layer_ptr = layer.get();
208 SetProperties(layer_ptr, transform, position, bounds);
210 DCHECK(!root_.get());
211 root_ = Types::PassLayerPtr(&layer);
213 SetRootLayerOnMainThread(layer_ptr);
215 return layer_ptr;
218 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
219 const gfx::Transform& transform,
220 gfx::PointF position,
221 gfx::Size bounds) {
222 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
223 typename Types::LayerType* layer_ptr = layer.get();
224 SetProperties(layer_ptr, transform, position, bounds);
225 parent->AddChild(Types::PassLayerPtr(&layer));
226 return layer_ptr;
229 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
230 const gfx::Transform& transform,
231 gfx::PointF position,
232 gfx::Size bounds) {
233 typename Types::LayerType* layer =
234 CreateLayer(parent, transform, position, bounds);
235 layer->SetForceRenderSurface(true);
236 return layer;
239 typename Types::ContentLayerType* CreateDrawingLayer(
240 typename Types::LayerType* parent,
241 const gfx::Transform& transform,
242 gfx::PointF position,
243 gfx::Size bounds,
244 bool opaque) {
245 typename Types::ContentLayerPtrType layer(
246 Types::CreateContentLayer(GetHost()));
247 typename Types::ContentLayerType* layer_ptr = layer.get();
248 SetProperties(layer_ptr, transform, position, bounds);
250 if (opaque_layers_) {
251 layer_ptr->SetContentsOpaque(opaque);
252 } else {
253 layer_ptr->SetContentsOpaque(false);
254 if (opaque)
255 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
256 else
257 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
260 parent->AddChild(Types::PassLayerPtr(&layer));
261 return layer_ptr;
264 typename Types::LayerType* CreateReplicaLayer(
265 typename Types::LayerType* owning_layer,
266 const gfx::Transform& transform,
267 gfx::PointF position,
268 gfx::Size bounds) {
269 typename Types::ContentLayerPtrType layer(
270 Types::CreateContentLayer(GetHost()));
271 typename Types::ContentLayerType* layer_ptr = layer.get();
272 SetProperties(layer_ptr, transform, position, bounds);
273 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
274 return layer_ptr;
277 typename Types::LayerType* CreateMaskLayer(
278 typename Types::LayerType* owning_layer,
279 gfx::Size bounds) {
280 typename Types::ContentLayerPtrType layer(
281 Types::CreateContentLayer(GetHost()));
282 typename Types::ContentLayerType* layer_ptr = layer.get();
283 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
284 SetMask(owning_layer, Types::PassLayerPtr(&layer));
285 return layer_ptr;
288 typename Types::ContentLayerType* CreateDrawingSurface(
289 typename Types::LayerType* parent,
290 const gfx::Transform& transform,
291 gfx::PointF position,
292 gfx::Size bounds,
293 bool opaque) {
294 typename Types::ContentLayerType* layer =
295 CreateDrawingLayer(parent, transform, position, bounds, opaque);
296 layer->SetForceRenderSurface(true);
297 return layer;
301 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
303 void AddCopyRequest(Layer* layer) {
304 layer->RequestCopyOfOutput(
305 CopyOutputRequest::CreateBitmapRequest(base::Bind(
306 &OcclusionTrackerTest<Types>::CopyOutputCallback,
307 base::Unretained(this))));
310 void AddCopyRequest(LayerImpl* layer) {
311 ScopedPtrVector<CopyOutputRequest> requests;
312 requests.push_back(
313 CopyOutputRequest::CreateBitmapRequest(base::Bind(
314 &OcclusionTrackerTest<Types>::CopyOutputCallback,
315 base::Unretained(this))));
316 layer->PassCopyRequests(&requests);
319 void CalcDrawEtc(TestContentLayerImpl* root) {
320 DCHECK(root == root_.get());
321 DCHECK(!root->render_surface());
323 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
324 root, root->bounds(), &render_surface_layer_list_impl_);
325 inputs.can_adjust_raster_scales = true;
326 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
328 layer_iterator_ = layer_iterator_begin_ =
329 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
332 void CalcDrawEtc(TestContentLayer* root) {
333 DCHECK(root == root_.get());
334 DCHECK(!root->render_surface());
336 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
337 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
338 root, root->bounds(), render_surface_layer_list_.get());
339 inputs.can_adjust_raster_scales = true;
340 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
342 layer_iterator_ = layer_iterator_begin_ =
343 Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
346 void SetDrawsContent(LayerImpl* layer_impl, bool draws_content) {
347 layer_impl->SetDrawsContent(draws_content);
350 void SetDrawsContent(Layer* layer, bool draws_content) {
351 layer->SetIsDrawable(draws_content);
354 void EnterLayer(typename Types::LayerType* layer,
355 typename Types::OcclusionTrackerType* occlusion,
356 bool prevent_occlusion) {
357 ASSERT_EQ(layer, *layer_iterator_);
358 ASSERT_TRUE(layer_iterator_.represents_itself());
359 occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
362 void LeaveLayer(typename Types::LayerType* layer,
363 typename Types::OcclusionTrackerType* occlusion) {
364 ASSERT_EQ(layer, *layer_iterator_);
365 ASSERT_TRUE(layer_iterator_.represents_itself());
366 occlusion->LeaveLayer(layer_iterator_);
367 ++layer_iterator_;
370 void VisitLayer(typename Types::LayerType* layer,
371 typename Types::OcclusionTrackerType* occlusion) {
372 EnterLayer(layer, occlusion, false);
373 LeaveLayer(layer, occlusion);
376 void EnterContributingSurface(
377 typename Types::LayerType* layer,
378 typename Types::OcclusionTrackerType* occlusion,
379 bool prevent_occlusion) {
380 ASSERT_EQ(layer, *layer_iterator_);
381 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
382 occlusion->EnterLayer(layer_iterator_, false);
383 occlusion->LeaveLayer(layer_iterator_);
384 ++layer_iterator_;
385 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
386 occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
389 void LeaveContributingSurface(
390 typename Types::LayerType* layer,
391 typename Types::OcclusionTrackerType* occlusion) {
392 ASSERT_EQ(layer, *layer_iterator_);
393 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
394 occlusion->LeaveLayer(layer_iterator_);
395 ++layer_iterator_;
398 void VisitContributingSurface(
399 typename Types::LayerType* layer,
400 typename Types::OcclusionTrackerType* occlusion) {
401 EnterContributingSurface(layer, occlusion, false);
402 LeaveContributingSurface(layer, occlusion);
405 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
407 const gfx::Transform identity_matrix;
409 private:
410 void SetRootLayerOnMainThread(Layer* root) {
411 host_->SetRootLayer(scoped_refptr<Layer>(root));
414 void SetRootLayerOnMainThread(LayerImpl* root) {}
416 void SetBaseProperties(typename Types::LayerType* layer,
417 const gfx::Transform& transform,
418 gfx::PointF position,
419 gfx::Size bounds) {
420 layer->SetTransform(transform);
421 layer->SetSublayerTransform(gfx::Transform());
422 layer->SetAnchorPoint(gfx::PointF());
423 layer->SetPosition(position);
424 layer->SetBounds(bounds);
427 void SetProperties(Layer* layer,
428 const gfx::Transform& transform,
429 gfx::PointF position,
430 gfx::Size bounds) {
431 SetBaseProperties(layer, transform, position, bounds);
434 void SetProperties(LayerImpl* layer,
435 const gfx::Transform& transform,
436 gfx::PointF position,
437 gfx::Size bounds) {
438 SetBaseProperties(layer, transform, position, bounds);
440 layer->SetContentBounds(layer->bounds());
443 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
444 owning_layer->SetReplicaLayer(layer.get());
445 replica_layers_.push_back(layer);
448 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
449 owning_layer->SetReplicaLayer(layer.Pass());
452 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
453 owning_layer->SetMaskLayer(layer.get());
454 mask_layers_.push_back(layer);
457 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
458 owning_layer->SetMaskLayer(layer.Pass());
461 bool opaque_layers_;
462 scoped_ptr<FakeLayerTreeHost> host_;
463 // These hold ownership of the layers for the duration of the test.
464 typename Types::LayerPtrType root_;
465 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
466 LayerImplList render_surface_layer_list_impl_;
467 typename Types::TestLayerIterator layer_iterator_begin_;
468 typename Types::TestLayerIterator layer_iterator_;
469 typename Types::LayerType* last_layer_visited_;
470 LayerList replica_layers_;
471 LayerList mask_layers_;
474 template <>
475 FakeLayerTreeHost*
476 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
477 return host_.get();
480 template <>
481 LayerTreeImpl*
482 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
483 return host_->host_impl()->active_tree();
486 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
487 class ClassName##MainThreadOpaqueLayers \
488 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
489 public: /* NOLINT(whitespace/indent) */ \
490 ClassName##MainThreadOpaqueLayers() \
491 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
492 }; \
493 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
494 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
495 class ClassName##MainThreadOpaquePaints \
496 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
497 public: /* NOLINT(whitespace/indent) */ \
498 ClassName##MainThreadOpaquePaints() \
499 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
500 }; \
501 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
503 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
504 class ClassName##ImplThreadOpaqueLayers \
505 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
506 public: /* NOLINT(whitespace/indent) */ \
507 ClassName##ImplThreadOpaqueLayers() \
508 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
509 }; \
510 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
511 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
512 class ClassName##ImplThreadOpaquePaints \
513 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
514 public: /* NOLINT(whitespace/indent) */ \
515 ClassName##ImplThreadOpaquePaints() \
516 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
517 }; \
518 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
520 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
521 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
522 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
523 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
524 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
526 #define MAIN_THREAD_TEST(ClassName) \
527 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
529 #define IMPL_THREAD_TEST(ClassName) \
530 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
532 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
533 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
534 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
536 template <class Types>
537 class OcclusionTrackerTestIdentityTransforms
538 : public OcclusionTrackerTest<Types> {
539 protected:
540 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
541 : OcclusionTrackerTest<Types>(opaque_layers) {}
543 void RunMyTest() {
544 typename Types::ContentLayerType* root = this->CreateRoot(
545 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
546 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
547 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
548 typename Types::ContentLayerType* layer =
549 this->CreateDrawingLayer(parent,
550 this->identity_matrix,
551 gfx::PointF(30.f, 30.f),
552 gfx::Size(500, 500),
553 true);
554 parent->SetMasksToBounds(true);
555 this->CalcDrawEtc(root);
557 TestOcclusionTrackerWithClip<typename Types::LayerType,
558 typename Types::RenderSurfaceType> occlusion(
559 gfx::Rect(0, 0, 1000, 1000), false);
561 this->VisitLayer(layer, &occlusion);
562 this->EnterLayer(parent, &occlusion, false);
564 EXPECT_EQ(gfx::Rect().ToString(),
565 occlusion.occlusion_from_outside_target().ToString());
566 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
567 occlusion.occlusion_from_inside_target().ToString());
569 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
570 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
571 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
572 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
573 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
575 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
576 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
577 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
578 occlusion.UnoccludedLayerContentRect(
579 parent, gfx::Rect(29, 30, 70, 70)));
580 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
581 occlusion.UnoccludedLayerContentRect(
582 parent, gfx::Rect(29, 29, 70, 70)));
583 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
584 occlusion.UnoccludedLayerContentRect(
585 parent, gfx::Rect(30, 29, 70, 70)));
586 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
587 occlusion.UnoccludedLayerContentRect(
588 parent, gfx::Rect(31, 29, 69, 70)));
589 EXPECT_RECT_EQ(gfx::Rect(),
590 occlusion.UnoccludedLayerContentRect(
591 parent, gfx::Rect(31, 30, 69, 70)));
592 EXPECT_RECT_EQ(gfx::Rect(),
593 occlusion.UnoccludedLayerContentRect(
594 parent, gfx::Rect(31, 31, 69, 69)));
595 EXPECT_RECT_EQ(gfx::Rect(),
596 occlusion.UnoccludedLayerContentRect(
597 parent, gfx::Rect(30, 31, 70, 69)));
598 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
599 occlusion.UnoccludedLayerContentRect(
600 parent, gfx::Rect(29, 31, 70, 69)));
604 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
606 template <class Types>
607 class OcclusionTrackerTestQuadsMismatchLayer
608 : public OcclusionTrackerTest<Types> {
609 protected:
610 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
611 : OcclusionTrackerTest<Types>(opaque_layers) {}
612 void RunMyTest() {
613 gfx::Transform layer_transform;
614 layer_transform.Translate(10.0, 10.0);
616 typename Types::ContentLayerType* parent = this->CreateRoot(
617 this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
618 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
619 parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
620 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
621 layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
622 this->CalcDrawEtc(parent);
624 TestOcclusionTrackerWithClip<typename Types::LayerType,
625 typename Types::RenderSurfaceType> occlusion(
626 gfx::Rect(0, 0, 1000, 1000));
628 this->VisitLayer(layer2, &occlusion);
629 this->EnterLayer(layer1, &occlusion, false);
631 EXPECT_EQ(gfx::Rect().ToString(),
632 occlusion.occlusion_from_outside_target().ToString());
633 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
634 occlusion.occlusion_from_inside_target().ToString());
636 // This checks cases where the quads don't match their "containing"
637 // layers, e.g. in terms of transforms or clip rect. This is typical for
638 // DelegatedRendererLayer.
640 gfx::Transform quad_transform;
641 quad_transform.Translate(30.0, 30.0);
643 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent,
644 gfx::Rect(0, 0, 10, 10),
645 quad_transform,
646 false).IsEmpty());
647 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
648 occlusion.UnoccludedContentRect(parent,
649 gfx::Rect(0, 0, 10, 10),
650 quad_transform,
651 true));
652 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
653 occlusion.UnoccludedContentRect(parent,
654 gfx::Rect(40, 40, 10, 10),
655 quad_transform,
656 false));
657 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
658 occlusion.UnoccludedContentRect(parent,
659 gfx::Rect(35, 30, 10, 10),
660 quad_transform,
661 false));
665 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
667 template <class Types>
668 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
669 protected:
670 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
671 : OcclusionTrackerTest<Types>(opaque_layers) {}
672 void RunMyTest() {
673 gfx::Transform layer_transform;
674 layer_transform.Translate(250.0, 250.0);
675 layer_transform.Rotate(90.0);
676 layer_transform.Translate(-250.0, -250.0);
678 typename Types::ContentLayerType* root = this->CreateRoot(
679 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
680 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
681 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
682 typename Types::ContentLayerType* layer =
683 this->CreateDrawingLayer(parent,
684 layer_transform,
685 gfx::PointF(30.f, 30.f),
686 gfx::Size(500, 500),
687 true);
688 parent->SetMasksToBounds(true);
689 this->CalcDrawEtc(root);
691 TestOcclusionTrackerWithClip<typename Types::LayerType,
692 typename Types::RenderSurfaceType> occlusion(
693 gfx::Rect(0, 0, 1000, 1000));
695 this->VisitLayer(layer, &occlusion);
696 this->EnterLayer(parent, &occlusion, false);
698 EXPECT_EQ(gfx::Rect().ToString(),
699 occlusion.occlusion_from_outside_target().ToString());
700 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
701 occlusion.occlusion_from_inside_target().ToString());
703 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
704 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
705 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
706 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
707 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
709 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
710 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
711 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
712 occlusion.UnoccludedLayerContentRect(
713 parent, gfx::Rect(29, 30, 69, 70)));
714 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
715 occlusion.UnoccludedLayerContentRect(
716 parent, gfx::Rect(29, 29, 70, 70)));
717 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
718 occlusion.UnoccludedLayerContentRect(
719 parent, gfx::Rect(30, 29, 70, 70)));
720 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
721 occlusion.UnoccludedLayerContentRect(
722 parent, gfx::Rect(31, 29, 69, 70)));
723 EXPECT_RECT_EQ(gfx::Rect(),
724 occlusion.UnoccludedLayerContentRect(
725 parent, gfx::Rect(31, 30, 69, 70)));
726 EXPECT_RECT_EQ(gfx::Rect(),
727 occlusion.UnoccludedLayerContentRect(
728 parent, gfx::Rect(31, 31, 69, 69)));
729 EXPECT_RECT_EQ(gfx::Rect(),
730 occlusion.UnoccludedLayerContentRect(
731 parent, gfx::Rect(30, 31, 70, 69)));
732 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
733 occlusion.UnoccludedLayerContentRect(
734 parent, gfx::Rect(29, 31, 70, 69)));
738 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
740 template <class Types>
741 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
742 protected:
743 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
744 : OcclusionTrackerTest<Types>(opaque_layers) {}
745 void RunMyTest() {
746 gfx::Transform layer_transform;
747 layer_transform.Translate(20.0, 20.0);
749 typename Types::ContentLayerType* root = this->CreateRoot(
750 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
751 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
752 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
753 typename Types::ContentLayerType* layer =
754 this->CreateDrawingLayer(parent,
755 layer_transform,
756 gfx::PointF(30.f, 30.f),
757 gfx::Size(500, 500),
758 true);
759 parent->SetMasksToBounds(true);
760 this->CalcDrawEtc(root);
762 TestOcclusionTrackerWithClip<typename Types::LayerType,
763 typename Types::RenderSurfaceType> occlusion(
764 gfx::Rect(0, 0, 1000, 1000));
766 this->VisitLayer(layer, &occlusion);
767 this->EnterLayer(parent, &occlusion, false);
769 EXPECT_EQ(gfx::Rect().ToString(),
770 occlusion.occlusion_from_outside_target().ToString());
771 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
772 occlusion.occlusion_from_inside_target().ToString());
774 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
775 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
776 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
777 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 49, 50)));
778 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 49)));
780 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
781 parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
782 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
783 occlusion.UnoccludedLayerContentRect(
784 parent, gfx::Rect(49, 50, 50, 50)));
785 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
786 occlusion.UnoccludedLayerContentRect(
787 parent, gfx::Rect(49, 49, 50, 50)));
788 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
789 occlusion.UnoccludedLayerContentRect(
790 parent, gfx::Rect(50, 49, 50, 50)));
791 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
792 occlusion.UnoccludedLayerContentRect(
793 parent, gfx::Rect(51, 49, 49, 50)));
794 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
795 parent, gfx::Rect(51, 50, 49, 50)).IsEmpty());
796 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
797 parent, gfx::Rect(51, 51, 49, 49)).IsEmpty());
798 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
799 parent, gfx::Rect(50, 51, 50, 49)).IsEmpty());
800 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
801 occlusion.UnoccludedLayerContentRect(
802 parent, gfx::Rect(49, 51, 50, 49)));
806 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
808 template <class Types>
809 class OcclusionTrackerTestChildInRotatedChild
810 : public OcclusionTrackerTest<Types> {
811 protected:
812 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
813 : OcclusionTrackerTest<Types>(opaque_layers) {}
814 void RunMyTest() {
815 gfx::Transform child_transform;
816 child_transform.Translate(250.0, 250.0);
817 child_transform.Rotate(90.0);
818 child_transform.Translate(-250.0, -250.0);
820 typename Types::ContentLayerType* parent = this->CreateRoot(
821 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
822 parent->SetMasksToBounds(true);
823 typename Types::LayerType* child = this->CreateSurface(
824 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
825 child->SetMasksToBounds(true);
826 typename Types::ContentLayerType* layer =
827 this->CreateDrawingLayer(child,
828 this->identity_matrix,
829 gfx::PointF(10.f, 10.f),
830 gfx::Size(500, 500),
831 true);
832 this->CalcDrawEtc(parent);
834 TestOcclusionTrackerWithClip<typename Types::LayerType,
835 typename Types::RenderSurfaceType> occlusion(
836 gfx::Rect(0, 0, 1000, 1000));
838 this->VisitLayer(layer, &occlusion);
839 this->EnterContributingSurface(child, &occlusion, false);
841 EXPECT_EQ(gfx::Rect().ToString(),
842 occlusion.occlusion_from_outside_target().ToString());
843 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
844 occlusion.occlusion_from_inside_target().ToString());
846 this->LeaveContributingSurface(child, &occlusion);
847 this->EnterLayer(parent, &occlusion, false);
849 EXPECT_EQ(gfx::Rect().ToString(),
850 occlusion.occlusion_from_outside_target().ToString());
851 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
852 occlusion.occlusion_from_inside_target().ToString());
854 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
855 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
856 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
857 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 69, 60)));
858 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 59)));
860 /* Justification for the above occlusion from |layer|:
862 +---------------------+
864 | 30 | rotate(90)
865 | 30 + ---------------------------------+
866 100 | | 10 | | ==>
867 | |10+---------------------------------+
868 | | | | | |
869 | | | | | |
870 | | | | | |
871 +----|--|-------------+ | |
872 | | | |
873 | | | |
874 | | | |500
875 | | | |
876 | | | |
877 | | | |
878 | | | |
879 +--|-------------------------------+ |
881 +---------------------------------+
884 +---------------------+
885 | |30 Visible region of |layer|: /////
887 | +---------------------------------+
888 100| | |10 |
889 | +---------------------------------+ |
890 | | |///////////////| 420 | |
891 | | |///////////////|60 | |
892 | | |///////////////| | |
893 +--|--|---------------+ | |
894 20|10| 70 | |
895 | | | |
896 | | | |
897 | | | |
898 | | | |
899 | | | |
900 | | |10|
901 | +------------------------------|--+
902 | 490 |
903 +---------------------------------+
910 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
912 template <class Types>
913 class OcclusionTrackerTestScaledRenderSurface
914 : public OcclusionTrackerTest<Types> {
915 protected:
916 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
917 : OcclusionTrackerTest<Types>(opaque_layers) {}
919 void RunMyTest() {
920 typename Types::ContentLayerType* parent = this->CreateRoot(
921 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
923 gfx::Transform layer1_matrix;
924 layer1_matrix.Scale(2.0, 2.0);
925 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
926 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
927 layer1->SetForceRenderSurface(true);
929 gfx::Transform layer2_matrix;
930 layer2_matrix.Translate(25.0, 25.0);
931 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
932 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
933 typename Types::ContentLayerType* occluder =
934 this->CreateDrawingLayer(parent,
935 this->identity_matrix,
936 gfx::PointF(100.f, 100.f),
937 gfx::Size(500, 500),
938 true);
939 this->CalcDrawEtc(parent);
941 TestOcclusionTrackerWithClip<typename Types::LayerType,
942 typename Types::RenderSurfaceType> occlusion(
943 gfx::Rect(0, 0, 1000, 1000));
945 this->VisitLayer(occluder, &occlusion);
946 this->EnterLayer(layer2, &occlusion, false);
948 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
949 occlusion.occlusion_from_outside_target().ToString());
950 EXPECT_EQ(gfx::Rect().ToString(),
951 occlusion.occlusion_from_inside_target().ToString());
953 EXPECT_RECT_EQ(
954 gfx::Rect(0, 0, 25, 25),
955 occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
956 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
957 occlusion.UnoccludedLayerContentRect(
958 layer2, gfx::Rect(10, 25, 25, 25)));
959 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
960 occlusion.UnoccludedLayerContentRect(
961 layer2, gfx::Rect(25, 10, 25, 25)));
962 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
963 layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
967 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
969 template <class Types>
970 class OcclusionTrackerTestVisitTargetTwoTimes
971 : public OcclusionTrackerTest<Types> {
972 protected:
973 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
974 : OcclusionTrackerTest<Types>(opaque_layers) {}
975 void RunMyTest() {
976 gfx::Transform child_transform;
977 child_transform.Translate(250.0, 250.0);
978 child_transform.Rotate(90.0);
979 child_transform.Translate(-250.0, -250.0);
981 typename Types::ContentLayerType* root = this->CreateRoot(
982 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
983 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
984 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
985 parent->SetMasksToBounds(true);
986 typename Types::LayerType* child = this->CreateSurface(
987 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
988 child->SetMasksToBounds(true);
989 typename Types::ContentLayerType* layer =
990 this->CreateDrawingLayer(child,
991 this->identity_matrix,
992 gfx::PointF(10.f, 10.f),
993 gfx::Size(500, 500),
994 true);
995 // |child2| makes |parent|'s surface get considered by OcclusionTracker
996 // first, instead of |child|'s. This exercises different code in
997 // LeaveToRenderTarget, as the target surface has already been seen.
998 typename Types::ContentLayerType* child2 =
999 this->CreateDrawingLayer(parent,
1000 this->identity_matrix,
1001 gfx::PointF(30.f, 30.f),
1002 gfx::Size(60, 20),
1003 true);
1004 this->CalcDrawEtc(root);
1006 TestOcclusionTrackerWithClip<typename Types::LayerType,
1007 typename Types::RenderSurfaceType> occlusion(
1008 gfx::Rect(0, 0, 1000, 1000));
1010 this->VisitLayer(child2, &occlusion);
1012 EXPECT_EQ(gfx::Rect().ToString(),
1013 occlusion.occlusion_from_outside_target().ToString());
1014 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1015 occlusion.occlusion_from_inside_target().ToString());
1017 this->VisitLayer(layer, &occlusion);
1019 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1020 occlusion.occlusion_from_outside_target().ToString());
1021 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1022 occlusion.occlusion_from_inside_target().ToString());
1024 this->EnterContributingSurface(child, &occlusion, false);
1026 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1027 occlusion.occlusion_from_outside_target().ToString());
1028 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1029 occlusion.occlusion_from_inside_target().ToString());
1031 // Occlusion in |child2| should get merged with the |child| surface we are
1032 // leaving now.
1033 this->LeaveContributingSurface(child, &occlusion);
1034 this->EnterLayer(parent, &occlusion, false);
1036 EXPECT_EQ(gfx::Rect().ToString(),
1037 occlusion.occlusion_from_outside_target().ToString());
1038 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1039 .ToString(),
1040 occlusion.occlusion_from_inside_target().ToString());
1042 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
1043 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1044 occlusion.UnoccludedLayerContentRect(
1045 parent, gfx::Rect(30, 30, 70, 70)));
1047 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
1048 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
1049 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
1050 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
1051 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
1053 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1054 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1055 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1057 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1058 parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1059 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1060 occlusion.UnoccludedLayerContentRect(
1061 parent, gfx::Rect(29, 30, 60, 10)));
1062 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1063 occlusion.UnoccludedLayerContentRect(
1064 parent, gfx::Rect(30, 29, 60, 10)));
1065 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1066 occlusion.UnoccludedLayerContentRect(
1067 parent, gfx::Rect(31, 30, 60, 10)));
1068 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1069 parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1071 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1072 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1073 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1074 occlusion.UnoccludedLayerContentRect(
1075 parent, gfx::Rect(29, 40, 70, 60)));
1076 // This rect is mostly occluded by |child2|.
1077 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1078 occlusion.UnoccludedLayerContentRect(
1079 parent, gfx::Rect(30, 39, 70, 60)));
1080 // This rect extends past top/right ends of |child2|.
1081 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1082 occlusion.UnoccludedLayerContentRect(
1083 parent, gfx::Rect(30, 29, 70, 70)));
1084 // This rect extends past left/right ends of |child2|.
1085 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1086 occlusion.UnoccludedLayerContentRect(
1087 parent, gfx::Rect(20, 39, 80, 60)));
1088 EXPECT_RECT_EQ(gfx::Rect(),
1089 occlusion.UnoccludedLayerContentRect(
1090 parent, gfx::Rect(31, 40, 69, 60)));
1091 EXPECT_RECT_EQ(gfx::Rect(),
1092 occlusion.UnoccludedLayerContentRect(
1093 parent, gfx::Rect(30, 41, 70, 59)));
1095 /* Justification for the above occlusion from |layer|:
1097 +---------------------+
1099 | 30 | rotate(90)
1100 | 30 + ------------+--------------------+
1101 100 | | 10 | | | ==>
1102 | |10+----------|----------------------+
1103 | + ------------+ | | |
1104 | | | | | |
1105 | | | | | |
1106 +----|--|-------------+ | |
1107 | | | |
1108 | | | |
1109 | | | |500
1110 | | | |
1111 | | | |
1112 | | | |
1113 | | | |
1114 +--|-------------------------------+ |
1116 +---------------------------------+
1120 +---------------------+
1121 | |30 Visible region of |layer|: /////
1122 | 30 60 | |child2|: \\\\\
1123 | 30 +------------+--------------------+
1124 | |\\\\\\\\\\\\| |10 |
1125 | +--|\\\\\\\\\\\\|-----------------+ |
1126 | | +------------+//| 420 | |
1127 | | |///////////////|60 | |
1128 | | |///////////////| | |
1129 +--|--|---------------+ | |
1130 20|10| 70 | |
1131 | | | |
1132 | | | |
1133 | | | |
1134 | | | |
1135 | | | |
1136 | | |10|
1137 | +------------------------------|--+
1138 | 490 |
1139 +---------------------------------+
1145 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
1147 template <class Types>
1148 class OcclusionTrackerTestSurfaceRotatedOffAxis
1149 : public OcclusionTrackerTest<Types> {
1150 protected:
1151 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
1152 : OcclusionTrackerTest<Types>(opaque_layers) {}
1153 void RunMyTest() {
1154 gfx::Transform child_transform;
1155 child_transform.Translate(250.0, 250.0);
1156 child_transform.Rotate(95.0);
1157 child_transform.Translate(-250.0, -250.0);
1159 gfx::Transform layer_transform;
1160 layer_transform.Translate(10.0, 10.0);
1162 typename Types::ContentLayerType* root = this->CreateRoot(
1163 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1164 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1165 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1166 typename Types::LayerType* child = this->CreateLayer(
1167 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1168 child->SetMasksToBounds(true);
1169 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1170 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
1171 this->CalcDrawEtc(root);
1173 TestOcclusionTrackerWithClip<typename Types::LayerType,
1174 typename Types::RenderSurfaceType> occlusion(
1175 gfx::Rect(0, 0, 1000, 1000));
1177 gfx::Rect clipped_layer_in_child = MathUtil::MapClippedRect(
1178 layer_transform, layer->visible_content_rect());
1180 this->VisitLayer(layer, &occlusion);
1181 this->EnterContributingSurface(child, &occlusion, false);
1183 EXPECT_EQ(gfx::Rect().ToString(),
1184 occlusion.occlusion_from_outside_target().ToString());
1185 EXPECT_EQ(clipped_layer_in_child.ToString(),
1186 occlusion.occlusion_from_inside_target().ToString());
1188 this->LeaveContributingSurface(child, &occlusion);
1189 this->EnterLayer(parent, &occlusion, false);
1191 EXPECT_EQ(gfx::Rect().ToString(),
1192 occlusion.occlusion_from_outside_target().ToString());
1193 EXPECT_EQ(gfx::Rect().ToString(),
1194 occlusion.occlusion_from_inside_target().ToString());
1196 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
1197 EXPECT_RECT_EQ(
1198 gfx::Rect(75, 55, 1, 1),
1199 occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
1203 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
1205 template <class Types>
1206 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1207 : public OcclusionTrackerTest<Types> {
1208 protected:
1209 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
1210 : OcclusionTrackerTest<Types>(opaque_layers) {}
1211 void RunMyTest() {
1212 gfx::Transform child_transform;
1213 child_transform.Translate(250.0, 250.0);
1214 child_transform.Rotate(90.0);
1215 child_transform.Translate(-250.0, -250.0);
1217 typename Types::ContentLayerType* root = this->CreateRoot(
1218 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1219 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1220 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1221 parent->SetMasksToBounds(true);
1222 typename Types::ContentLayerType* child =
1223 this->CreateDrawingSurface(parent,
1224 child_transform,
1225 gfx::PointF(30.f, 30.f),
1226 gfx::Size(500, 500),
1227 false);
1228 child->SetMasksToBounds(true);
1229 typename Types::ContentLayerType* layer1 =
1230 this->CreateDrawingLayer(child,
1231 this->identity_matrix,
1232 gfx::PointF(10.f, 10.f),
1233 gfx::Size(500, 500),
1234 true);
1235 typename Types::ContentLayerType* layer2 =
1236 this->CreateDrawingLayer(child,
1237 this->identity_matrix,
1238 gfx::PointF(10.f, 450.f),
1239 gfx::Size(500, 60),
1240 true);
1241 this->CalcDrawEtc(root);
1243 TestOcclusionTrackerWithClip<typename Types::LayerType,
1244 typename Types::RenderSurfaceType> occlusion(
1245 gfx::Rect(0, 0, 1000, 1000));
1247 this->VisitLayer(layer2, &occlusion);
1248 this->VisitLayer(layer1, &occlusion);
1249 this->VisitLayer(child, &occlusion);
1250 this->EnterContributingSurface(child, &occlusion, false);
1252 EXPECT_EQ(gfx::Rect().ToString(),
1253 occlusion.occlusion_from_outside_target().ToString());
1254 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1255 occlusion.occlusion_from_inside_target().ToString());
1257 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
1258 EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
1259 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 59, 70)));
1260 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 69)));
1262 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1263 child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1264 EXPECT_RECT_EQ(
1265 gfx::Rect(9, 430, 1, 70),
1266 occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
1267 EXPECT_RECT_EQ(gfx::Rect(),
1268 occlusion.UnoccludedLayerContentRect(
1269 child, gfx::Rect(11, 430, 59, 70)));
1270 EXPECT_RECT_EQ(gfx::Rect(),
1271 occlusion.UnoccludedLayerContentRect(
1272 child, gfx::Rect(10, 431, 60, 69)));
1274 this->LeaveContributingSurface(child, &occlusion);
1275 this->EnterLayer(parent, &occlusion, false);
1277 EXPECT_EQ(gfx::Rect().ToString(),
1278 occlusion.occlusion_from_outside_target().ToString());
1279 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1280 occlusion.occlusion_from_inside_target().ToString());
1282 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1283 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1284 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1286 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1287 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1288 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1289 occlusion.UnoccludedLayerContentRect(
1290 parent, gfx::Rect(29, 40, 70, 60)));
1291 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1292 occlusion.UnoccludedLayerContentRect(
1293 parent, gfx::Rect(30, 39, 70, 60)));
1294 EXPECT_RECT_EQ(gfx::Rect(),
1295 occlusion.UnoccludedLayerContentRect(
1296 parent, gfx::Rect(31, 40, 69, 60)));
1297 EXPECT_RECT_EQ(gfx::Rect(),
1298 occlusion.UnoccludedLayerContentRect(
1299 parent, gfx::Rect(30, 41, 70, 59)));
1301 /* Justification for the above occlusion from |layer1| and |layer2|:
1303 +---------------------+
1304 | |30 Visible region of |layer1|: /////
1305 | | Visible region of |layer2|: \\\\\
1306 | +---------------------------------+
1307 | | |10 |
1308 | +---------------+-----------------+ |
1309 | | |\\\\\\\\\\\\|//| 420 | |
1310 | | |\\\\\\\\\\\\|//|60 | |
1311 | | |\\\\\\\\\\\\|//| | |
1312 +--|--|------------|--+ | |
1313 20|10| 70 | | |
1314 | | | | |
1315 | | | | |
1316 | | | | |
1317 | | | | |
1318 | | | | |
1319 | | | |10|
1320 | +------------|-----------------|--+
1321 | | 490 |
1322 +---------------+-----------------+
1323 60 440
1328 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1330 template <class Types>
1331 class OcclusionTrackerTestOverlappingSurfaceSiblings
1332 : public OcclusionTrackerTest<Types> {
1333 protected:
1334 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
1335 : OcclusionTrackerTest<Types>(opaque_layers) {}
1336 void RunMyTest() {
1337 gfx::Transform child_transform;
1338 child_transform.Translate(250.0, 250.0);
1339 child_transform.Rotate(90.0);
1340 child_transform.Translate(-250.0, -250.0);
1342 typename Types::ContentLayerType* parent = this->CreateRoot(
1343 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1344 parent->SetMasksToBounds(true);
1345 typename Types::LayerType* child1 = this->CreateSurface(
1346 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
1347 typename Types::LayerType* child2 = this->CreateSurface(
1348 parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
1349 typename Types::ContentLayerType* layer1 =
1350 this->CreateDrawingLayer(child1,
1351 this->identity_matrix,
1352 gfx::PointF(-10.f, -10.f),
1353 gfx::Size(510, 510),
1354 true);
1355 typename Types::ContentLayerType* layer2 =
1356 this->CreateDrawingLayer(child2,
1357 this->identity_matrix,
1358 gfx::PointF(-10.f, -10.f),
1359 gfx::Size(510, 510),
1360 true);
1361 this->CalcDrawEtc(parent);
1363 TestOcclusionTrackerWithClip<typename Types::LayerType,
1364 typename Types::RenderSurfaceType> occlusion(
1365 gfx::Rect(0, 0, 1000, 1000));
1367 this->VisitLayer(layer2, &occlusion);
1368 this->EnterContributingSurface(child2, &occlusion, false);
1370 EXPECT_EQ(gfx::Rect().ToString(),
1371 occlusion.occlusion_from_outside_target().ToString());
1372 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1373 occlusion.occlusion_from_inside_target().ToString());
1375 // There is nothing above child2's surface in the z-order.
1376 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1377 occlusion.UnoccludedContributingSurfaceContentRect(
1378 child2, false, gfx::Rect(-10, 420, 70, 80)));
1380 this->LeaveContributingSurface(child2, &occlusion);
1381 this->VisitLayer(layer1, &occlusion);
1382 this->EnterContributingSurface(child1, &occlusion, false);
1384 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1385 occlusion.occlusion_from_outside_target().ToString());
1386 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1387 occlusion.occlusion_from_inside_target().ToString());
1389 // child2's contents will occlude child1 below it.
1390 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1391 occlusion.UnoccludedContributingSurfaceContentRect(
1392 child1, false, gfx::Rect(-10, 430, 80, 70)));
1394 this->LeaveContributingSurface(child1, &occlusion);
1395 this->EnterLayer(parent, &occlusion, false);
1397 EXPECT_EQ(gfx::Rect().ToString(),
1398 occlusion.occlusion_from_outside_target().ToString());
1399 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1400 .ToString(),
1401 occlusion.occlusion_from_inside_target().ToString());
1403 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1405 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1406 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1407 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1409 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1410 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1411 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1413 /* Justification for the above occlusion:
1415 +---------------------+
1416 | 20 | layer1
1417 | 30+ ---------------------------------+
1418 100 | 30| | layer2 |
1419 |20+----------------------------------+ |
1420 | | | | | |
1421 | | | | | |
1422 | | | | | |
1423 +--|-|----------------+ | |
1424 | | | | 510
1425 | | | |
1426 | | | |
1427 | | | |
1428 | | | |
1429 | | | |
1430 | | | |
1431 | +--------------------------------|-+
1433 +----------------------------------+
1439 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1441 template <class Types>
1442 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1443 : public OcclusionTrackerTest<Types> {
1444 protected:
1445 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1446 bool opaque_layers)
1447 : OcclusionTrackerTest<Types>(opaque_layers) {}
1448 void RunMyTest() {
1449 gfx::Transform child1_transform;
1450 child1_transform.Translate(250.0, 250.0);
1451 child1_transform.Rotate(-90.0);
1452 child1_transform.Translate(-250.0, -250.0);
1454 gfx::Transform child2_transform;
1455 child2_transform.Translate(250.0, 250.0);
1456 child2_transform.Rotate(90.0);
1457 child2_transform.Translate(-250.0, -250.0);
1459 typename Types::ContentLayerType* parent = this->CreateRoot(
1460 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1461 parent->SetMasksToBounds(true);
1462 typename Types::LayerType* child1 = this->CreateSurface(
1463 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1464 typename Types::LayerType* child2 =
1465 this->CreateDrawingSurface(parent,
1466 child2_transform,
1467 gfx::PointF(20.f, 40.f),
1468 gfx::Size(10, 10),
1469 false);
1470 typename Types::ContentLayerType* layer1 =
1471 this->CreateDrawingLayer(child1,
1472 this->identity_matrix,
1473 gfx::PointF(-10.f, -20.f),
1474 gfx::Size(510, 510),
1475 true);
1476 typename Types::ContentLayerType* layer2 =
1477 this->CreateDrawingLayer(child2,
1478 this->identity_matrix,
1479 gfx::PointF(-10.f, -10.f),
1480 gfx::Size(510, 510),
1481 true);
1482 this->CalcDrawEtc(parent);
1484 TestOcclusionTrackerWithClip<typename Types::LayerType,
1485 typename Types::RenderSurfaceType> occlusion(
1486 gfx::Rect(0, 0, 1000, 1000));
1488 this->VisitLayer(layer2, &occlusion);
1489 this->EnterLayer(child2, &occlusion, false);
1491 EXPECT_EQ(gfx::Rect().ToString(),
1492 occlusion.occlusion_from_outside_target().ToString());
1493 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1494 occlusion.occlusion_from_inside_target().ToString());
1496 this->LeaveLayer(child2, &occlusion);
1497 this->EnterContributingSurface(child2, &occlusion, false);
1499 // There is nothing above child2's surface in the z-order.
1500 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1501 occlusion.UnoccludedContributingSurfaceContentRect(
1502 child2, false, gfx::Rect(-10, 420, 70, 80)));
1504 this->LeaveContributingSurface(child2, &occlusion);
1505 this->VisitLayer(layer1, &occlusion);
1506 this->EnterContributingSurface(child1, &occlusion, false);
1508 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1509 occlusion.occlusion_from_outside_target().ToString());
1510 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1511 occlusion.occlusion_from_inside_target().ToString());
1513 // child2's contents will occlude child1 below it.
1514 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1515 occlusion.UnoccludedContributingSurfaceContentRect(
1516 child1, false, gfx::Rect(420, -20, 80, 90)));
1517 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1518 occlusion.UnoccludedContributingSurfaceContentRect(
1519 child1, false, gfx::Rect(420, -10, 80, 90)));
1520 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1521 occlusion.UnoccludedContributingSurfaceContentRect(
1522 child1, false, gfx::Rect(420, -20, 70, 90)));
1524 this->LeaveContributingSurface(child1, &occlusion);
1525 this->EnterLayer(parent, &occlusion, false);
1527 EXPECT_EQ(gfx::Rect().ToString(),
1528 occlusion.occlusion_from_outside_target().ToString());
1529 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1530 occlusion.occlusion_from_inside_target().ToString());
1532 /* Justification for the above occlusion:
1534 +---------------------+
1535 |20 | layer1
1536 10+----------------------------------+
1537 100 || 30 | layer2 |
1538 |20+----------------------------------+
1539 || | | | |
1540 || | | | |
1541 || | | | |
1542 +|-|------------------+ | |
1543 | | | | 510
1544 | | 510 | |
1545 | | | |
1546 | | | |
1547 | | | |
1548 | | | |
1549 | | 520 | |
1550 +----------------------------------+ |
1552 +----------------------------------+
1558 ALL_OCCLUSIONTRACKER_TEST(
1559 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1561 template <class Types>
1562 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1563 protected:
1564 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1565 : OcclusionTrackerTest<Types>(opaque_layers) {}
1566 void RunMyTest() {
1567 gfx::Transform layer_transform;
1568 layer_transform.Translate(250.0, 250.0);
1569 layer_transform.Rotate(90.0);
1570 layer_transform.Translate(-250.0, -250.0);
1572 typename Types::ContentLayerType* parent = this->CreateRoot(
1573 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1574 parent->SetMasksToBounds(true);
1575 typename Types::ContentLayerType* blur_layer =
1576 this->CreateDrawingLayer(parent,
1577 layer_transform,
1578 gfx::PointF(30.f, 30.f),
1579 gfx::Size(500, 500),
1580 true);
1581 typename Types::ContentLayerType* opaque_layer =
1582 this->CreateDrawingLayer(parent,
1583 layer_transform,
1584 gfx::PointF(30.f, 30.f),
1585 gfx::Size(500, 500),
1586 true);
1587 typename Types::ContentLayerType* opacity_layer =
1588 this->CreateDrawingLayer(parent,
1589 layer_transform,
1590 gfx::PointF(30.f, 30.f),
1591 gfx::Size(500, 500),
1592 true);
1594 FilterOperations filters;
1595 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1596 blur_layer->SetFilters(filters);
1598 filters.Clear();
1599 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1600 opaque_layer->SetFilters(filters);
1602 filters.Clear();
1603 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1604 opacity_layer->SetFilters(filters);
1606 this->CalcDrawEtc(parent);
1608 TestOcclusionTrackerWithClip<typename Types::LayerType,
1609 typename Types::RenderSurfaceType> occlusion(
1610 gfx::Rect(0, 0, 1000, 1000));
1612 // Opacity layer won't contribute to occlusion.
1613 this->VisitLayer(opacity_layer, &occlusion);
1614 this->EnterContributingSurface(opacity_layer, &occlusion, false);
1616 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1617 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1619 // And has nothing to contribute to its parent surface.
1620 this->LeaveContributingSurface(opacity_layer, &occlusion);
1621 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1622 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1624 // Opaque layer will contribute to occlusion.
1625 this->VisitLayer(opaque_layer, &occlusion);
1626 this->EnterContributingSurface(opaque_layer, &occlusion, false);
1628 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1629 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1630 occlusion.occlusion_from_inside_target().ToString());
1632 // And it gets translated to the parent surface.
1633 this->LeaveContributingSurface(opaque_layer, &occlusion);
1634 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1635 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1636 occlusion.occlusion_from_inside_target().ToString());
1638 // The blur layer needs to throw away any occlusion from outside its
1639 // subtree.
1640 this->EnterLayer(blur_layer, &occlusion, false);
1641 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1642 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1644 // And it won't contribute to occlusion.
1645 this->LeaveLayer(blur_layer, &occlusion);
1646 this->EnterContributingSurface(blur_layer, &occlusion, false);
1647 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1648 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1650 // But the opaque layer's occlusion is preserved on the parent.
1651 this->LeaveContributingSurface(blur_layer, &occlusion);
1652 this->EnterLayer(parent, &occlusion, false);
1653 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1654 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1655 occlusion.occlusion_from_inside_target().ToString());
1659 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1661 template <class Types>
1662 class OcclusionTrackerTestReplicaDoesOcclude
1663 : public OcclusionTrackerTest<Types> {
1664 protected:
1665 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1666 : OcclusionTrackerTest<Types>(opaque_layers) {}
1667 void RunMyTest() {
1668 typename Types::ContentLayerType* parent = this->CreateRoot(
1669 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1670 typename Types::LayerType* surface =
1671 this->CreateDrawingSurface(parent,
1672 this->identity_matrix,
1673 gfx::PointF(0.f, 100.f),
1674 gfx::Size(50, 50),
1675 true);
1676 this->CreateReplicaLayer(
1677 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1678 this->CalcDrawEtc(parent);
1680 TestOcclusionTrackerWithClip<typename Types::LayerType,
1681 typename Types::RenderSurfaceType> occlusion(
1682 gfx::Rect(0, 0, 1000, 1000));
1684 this->VisitLayer(surface, &occlusion);
1686 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1687 occlusion.occlusion_from_inside_target().ToString());
1689 this->VisitContributingSurface(surface, &occlusion);
1690 this->EnterLayer(parent, &occlusion, false);
1692 // The surface and replica should both be occluding the parent.
1693 EXPECT_EQ(
1694 UnionRegions(gfx::Rect(0, 100, 50, 50),
1695 gfx::Rect(50, 150, 50, 50)).ToString(),
1696 occlusion.occlusion_from_inside_target().ToString());
1700 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1702 template <class Types>
1703 class OcclusionTrackerTestReplicaWithClipping
1704 : public OcclusionTrackerTest<Types> {
1705 protected:
1706 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1707 : OcclusionTrackerTest<Types>(opaque_layers) {}
1708 void RunMyTest() {
1709 typename Types::ContentLayerType* parent = this->CreateRoot(
1710 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1711 parent->SetMasksToBounds(true);
1712 typename Types::LayerType* surface =
1713 this->CreateDrawingSurface(parent,
1714 this->identity_matrix,
1715 gfx::PointF(0.f, 100.f),
1716 gfx::Size(50, 50),
1717 true);
1718 this->CreateReplicaLayer(
1719 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1720 this->CalcDrawEtc(parent);
1722 TestOcclusionTrackerWithClip<typename Types::LayerType,
1723 typename Types::RenderSurfaceType> occlusion(
1724 gfx::Rect(0, 0, 1000, 1000));
1726 this->VisitLayer(surface, &occlusion);
1728 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1729 occlusion.occlusion_from_inside_target().ToString());
1731 this->VisitContributingSurface(surface, &occlusion);
1732 this->EnterLayer(parent, &occlusion, false);
1734 // The surface and replica should both be occluding the parent.
1735 EXPECT_EQ(
1736 UnionRegions(gfx::Rect(0, 100, 50, 50),
1737 gfx::Rect(50, 150, 50, 20)).ToString(),
1738 occlusion.occlusion_from_inside_target().ToString());
1742 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1744 template <class Types>
1745 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1746 protected:
1747 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1748 : OcclusionTrackerTest<Types>(opaque_layers) {}
1749 void RunMyTest() {
1750 typename Types::ContentLayerType* parent = this->CreateRoot(
1751 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1752 typename Types::LayerType* surface =
1753 this->CreateDrawingSurface(parent,
1754 this->identity_matrix,
1755 gfx::PointF(0.f, 100.f),
1756 gfx::Size(50, 50),
1757 true);
1758 typename Types::LayerType* replica = this->CreateReplicaLayer(
1759 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1760 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1761 this->CalcDrawEtc(parent);
1763 TestOcclusionTrackerWithClip<typename Types::LayerType,
1764 typename Types::RenderSurfaceType> occlusion(
1765 gfx::Rect(0, 0, 1000, 1000));
1767 this->VisitLayer(surface, &occlusion);
1769 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1770 occlusion.occlusion_from_inside_target().ToString());
1772 this->VisitContributingSurface(surface, &occlusion);
1773 this->EnterLayer(parent, &occlusion, false);
1775 // The replica should not be occluding the parent, since it has a mask
1776 // applied to it.
1777 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1778 occlusion.occlusion_from_inside_target().ToString());
1782 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1784 template <class Types>
1785 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1786 : public OcclusionTrackerTest<Types> {
1787 protected:
1788 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1789 : OcclusionTrackerTest<Types>(opaque_layers) {}
1790 void RunMyTest() {
1791 typename Types::ContentLayerType* parent = this->CreateRoot(
1792 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1793 typename Types::ContentLayerType* layer =
1794 this->CreateDrawingSurface(parent,
1795 this->identity_matrix,
1796 gfx::PointF(),
1797 gfx::Size(200, 200),
1798 false);
1799 this->CalcDrawEtc(parent);
1801 TestOcclusionTrackerWithClip<typename Types::LayerType,
1802 typename Types::RenderSurfaceType> occlusion(
1803 gfx::Rect(0, 0, 1000, 1000));
1804 this->EnterLayer(layer, &occlusion, false);
1806 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1807 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1808 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1809 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1811 this->LeaveLayer(layer, &occlusion);
1812 this->VisitContributingSurface(layer, &occlusion);
1813 this->EnterLayer(parent, &occlusion, false);
1815 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1819 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1821 template <class Types>
1822 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1823 : public OcclusionTrackerTest<Types> {
1824 protected:
1825 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1826 : OcclusionTrackerTest<Types>(opaque_layers) {}
1827 void RunMyTest() {
1828 typename Types::ContentLayerType* parent = this->CreateRoot(
1829 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1830 typename Types::ContentLayerType* layer =
1831 this->CreateDrawingLayer(parent,
1832 this->identity_matrix,
1833 gfx::PointF(100.f, 100.f),
1834 gfx::Size(200, 200),
1835 false);
1836 this->CalcDrawEtc(parent);
1838 TestOcclusionTrackerWithClip<typename Types::LayerType,
1839 typename Types::RenderSurfaceType> occlusion(
1840 gfx::Rect(0, 0, 1000, 1000));
1841 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1843 this->ResetLayerIterator();
1844 this->VisitLayer(layer, &occlusion);
1845 this->EnterLayer(parent, &occlusion, false);
1847 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1848 occlusion.occlusion_from_inside_target().ToString());
1850 EXPECT_FALSE(
1851 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1852 EXPECT_TRUE(
1853 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1854 EXPECT_FALSE(
1855 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1858 TestOcclusionTrackerWithClip<typename Types::LayerType,
1859 typename Types::RenderSurfaceType> occlusion(
1860 gfx::Rect(0, 0, 1000, 1000));
1861 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1863 this->ResetLayerIterator();
1864 this->VisitLayer(layer, &occlusion);
1865 this->EnterLayer(parent, &occlusion, false);
1867 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1868 occlusion.occlusion_from_inside_target().ToString());
1870 EXPECT_FALSE(
1871 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1872 EXPECT_FALSE(
1873 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1874 EXPECT_TRUE(
1875 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1878 TestOcclusionTrackerWithClip<typename Types::LayerType,
1879 typename Types::RenderSurfaceType> occlusion(
1880 gfx::Rect(0, 0, 1000, 1000));
1881 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1883 this->ResetLayerIterator();
1884 this->VisitLayer(layer, &occlusion);
1885 this->EnterLayer(parent, &occlusion, false);
1887 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1888 occlusion.occlusion_from_inside_target().ToString());
1890 EXPECT_FALSE(
1891 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1892 EXPECT_FALSE(
1893 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1894 EXPECT_FALSE(
1895 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1900 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1902 template <class Types>
1903 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
1904 protected:
1905 explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
1906 : OcclusionTrackerTest<Types>(opaque_layers) {}
1907 void RunMyTest() {
1908 gfx::Transform transform;
1909 transform.RotateAboutYAxis(30.0);
1911 typename Types::ContentLayerType* parent = this->CreateRoot(
1912 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1913 typename Types::LayerType* container = this->CreateLayer(
1914 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1915 typename Types::ContentLayerType* layer =
1916 this->CreateDrawingLayer(container,
1917 transform,
1918 gfx::PointF(100.f, 100.f),
1919 gfx::Size(200, 200),
1920 true);
1921 this->CalcDrawEtc(parent);
1923 TestOcclusionTrackerWithClip<typename Types::LayerType,
1924 typename Types::RenderSurfaceType> occlusion(
1925 gfx::Rect(0, 0, 1000, 1000));
1926 this->EnterLayer(layer, &occlusion, false);
1928 // The layer is rotated in 3d but without preserving 3d, so it only gets
1929 // resized.
1930 EXPECT_RECT_EQ(
1931 gfx::Rect(0, 0, 200, 200),
1932 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1936 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
1938 template <class Types>
1939 class OcclusionTrackerTestUnsorted3dLayers
1940 : public OcclusionTrackerTest<Types> {
1941 protected:
1942 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
1943 : OcclusionTrackerTest<Types>(opaque_layers) {}
1944 void RunMyTest() {
1945 // Currently, The main thread layer iterator does not iterate over 3d items
1946 // in sorted order, because layer sorting is not performed on the main
1947 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1948 // layer occludes other layers that have not yet been iterated over. For
1949 // now, the expected behavior is that a 3d layer simply does not add any
1950 // occlusion to the occlusion tracker.
1952 gfx::Transform translation_to_front;
1953 translation_to_front.Translate3d(0.0, 0.0, -10.0);
1954 gfx::Transform translation_to_back;
1955 translation_to_front.Translate3d(0.0, 0.0, -100.0);
1957 typename Types::ContentLayerType* parent = this->CreateRoot(
1958 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1959 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
1960 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
1961 typename Types::ContentLayerType* child2 =
1962 this->CreateDrawingLayer(parent,
1963 translation_to_front,
1964 gfx::PointF(50.f, 50.f),
1965 gfx::Size(100, 100),
1966 true);
1967 parent->SetPreserves3d(true);
1969 this->CalcDrawEtc(parent);
1971 TestOcclusionTrackerWithClip<typename Types::LayerType,
1972 typename Types::RenderSurfaceType> occlusion(
1973 gfx::Rect(0, 0, 1000, 1000));
1974 this->VisitLayer(child2, &occlusion);
1975 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1976 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1978 this->VisitLayer(child1, &occlusion);
1979 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1980 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1984 // This test will have different layer ordering on the impl thread; the test
1985 // will only work on the main thread.
1986 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1988 template <class Types>
1989 class OcclusionTrackerTestPerspectiveTransform
1990 : public OcclusionTrackerTest<Types> {
1991 protected:
1992 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
1993 : OcclusionTrackerTest<Types>(opaque_layers) {}
1994 void RunMyTest() {
1995 gfx::Transform transform;
1996 transform.Translate(150.0, 150.0);
1997 transform.ApplyPerspectiveDepth(400.0);
1998 transform.RotateAboutXAxis(-30.0);
1999 transform.Translate(-150.0, -150.0);
2001 typename Types::ContentLayerType* parent = this->CreateRoot(
2002 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2003 typename Types::LayerType* container = this->CreateLayer(
2004 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2005 typename Types::ContentLayerType* layer =
2006 this->CreateDrawingLayer(container,
2007 transform,
2008 gfx::PointF(100.f, 100.f),
2009 gfx::Size(200, 200),
2010 true);
2011 container->SetPreserves3d(true);
2012 layer->SetPreserves3d(true);
2013 this->CalcDrawEtc(parent);
2015 TestOcclusionTrackerWithClip<typename Types::LayerType,
2016 typename Types::RenderSurfaceType> occlusion(
2017 gfx::Rect(0, 0, 1000, 1000));
2018 this->EnterLayer(layer, &occlusion, false);
2020 EXPECT_RECT_EQ(
2021 gfx::Rect(0, 0, 200, 200),
2022 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2026 // This test requires accumulating occlusion of 3d layers, which are skipped by
2027 // the occlusion tracker on the main thread. So this test should run on the impl
2028 // thread.
2029 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
2031 template <class Types>
2032 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2033 : public OcclusionTrackerTest<Types> {
2034 protected:
2035 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2036 bool opaque_layers)
2037 : OcclusionTrackerTest<Types>(opaque_layers) {}
2038 void RunMyTest() {
2039 // This test is based on the platform/chromium/compositing/3d-corners.html
2040 // layout test.
2041 gfx::Transform transform;
2042 transform.Translate(250.0, 50.0);
2043 transform.ApplyPerspectiveDepth(10.0);
2044 transform.Translate(-250.0, -50.0);
2045 transform.Translate(250.0, 50.0);
2046 transform.RotateAboutXAxis(-167.0);
2047 transform.Translate(-250.0, -50.0);
2049 typename Types::ContentLayerType* parent = this->CreateRoot(
2050 this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
2051 typename Types::LayerType* container = this->CreateLayer(
2052 parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2053 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2054 container, transform, gfx::PointF(), gfx::Size(500, 500), true);
2055 container->SetPreserves3d(true);
2056 layer->SetPreserves3d(true);
2057 this->CalcDrawEtc(parent);
2059 TestOcclusionTrackerWithClip<typename Types::LayerType,
2060 typename Types::RenderSurfaceType> occlusion(
2061 gfx::Rect(0, 0, 1000, 1000));
2062 this->EnterLayer(layer, &occlusion, false);
2064 // The bottom 11 pixel rows of this layer remain visible inside the
2065 // container, after translation to the target surface. When translated back,
2066 // this will include many more pixels but must include at least the bottom
2067 // 11 rows.
2068 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2069 layer, gfx::Rect(0, 26, 500, 474)).
2070 Contains(gfx::Rect(0, 489, 500, 11)));
2074 // This test requires accumulating occlusion of 3d layers, which are skipped by
2075 // the occlusion tracker on the main thread. So this test should run on the impl
2076 // thread.
2077 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2079 template <class Types>
2080 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2081 : public OcclusionTrackerTest<Types> {
2082 protected:
2083 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2084 bool opaque_layers)
2085 : OcclusionTrackerTest<Types>(opaque_layers) {}
2086 void RunMyTest() {
2087 gfx::Transform transform;
2088 transform.Translate(50.0, 50.0);
2089 transform.ApplyPerspectiveDepth(100.0);
2090 transform.Translate3d(0.0, 0.0, 110.0);
2091 transform.Translate(-50.0, -50.0);
2093 typename Types::ContentLayerType* parent = this->CreateRoot(
2094 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2095 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2096 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2097 parent->SetPreserves3d(true);
2098 layer->SetPreserves3d(true);
2099 this->CalcDrawEtc(parent);
2101 TestOcclusionTrackerWithClip<typename Types::LayerType,
2102 typename Types::RenderSurfaceType> occlusion(
2103 gfx::Rect(0, 0, 1000, 1000));
2105 // The |layer| is entirely behind the camera and should not occlude.
2106 this->VisitLayer(layer, &occlusion);
2107 this->EnterLayer(parent, &occlusion, false);
2108 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2109 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2113 // This test requires accumulating occlusion of 3d layers, which are skipped by
2114 // the occlusion tracker on the main thread. So this test should run on the impl
2115 // thread.
2116 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2118 template <class Types>
2119 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2120 : public OcclusionTrackerTest<Types> {
2121 protected:
2122 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2123 bool opaque_layers)
2124 : OcclusionTrackerTest<Types>(opaque_layers) {}
2125 void RunMyTest() {
2126 gfx::Transform transform;
2127 transform.Translate(50.0, 50.0);
2128 transform.ApplyPerspectiveDepth(100.0);
2129 transform.Translate3d(0.0, 0.0, 99.0);
2130 transform.Translate(-50.0, -50.0);
2132 typename Types::ContentLayerType* parent = this->CreateRoot(
2133 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2134 parent->SetMasksToBounds(true);
2135 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2136 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2137 parent->SetPreserves3d(true);
2138 layer->SetPreserves3d(true);
2139 this->CalcDrawEtc(parent);
2141 TestOcclusionTrackerWithClip<typename Types::LayerType,
2142 typename Types::RenderSurfaceType> occlusion(
2143 gfx::Rect(0, 0, 1000, 1000));
2145 // This is very close to the camera, so pixels in its visible_content_rect()
2146 // will actually go outside of the layer's clip rect. Ensure that those
2147 // pixels don't occlude things outside the clip rect.
2148 this->VisitLayer(layer, &occlusion);
2149 this->EnterLayer(parent, &occlusion, false);
2150 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2151 occlusion.occlusion_from_inside_target().ToString());
2152 EXPECT_EQ(gfx::Rect().ToString(),
2153 occlusion.occlusion_from_outside_target().ToString());
2157 // This test requires accumulating occlusion of 3d layers, which are skipped by
2158 // the occlusion tracker on the main thread. So this test should run on the impl
2159 // thread.
2160 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2162 template <class Types>
2163 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2164 : public OcclusionTrackerTest<Types> {
2165 protected:
2166 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
2167 : OcclusionTrackerTest<Types>(opaque_layers) {}
2168 void RunMyTest() {
2169 // parent
2170 // +--layer
2171 // +--surface
2172 // | +--surface_child
2173 // | +--surface_child2
2174 // +--parent2
2175 // +--topmost
2177 typename Types::ContentLayerType* parent = this->CreateRoot(
2178 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2179 typename Types::ContentLayerType* layer =
2180 this->CreateDrawingLayer(parent,
2181 this->identity_matrix,
2182 gfx::PointF(),
2183 gfx::Size(300, 300),
2184 true);
2185 typename Types::ContentLayerType* surface =
2186 this->CreateDrawingSurface(parent,
2187 this->identity_matrix,
2188 gfx::PointF(),
2189 gfx::Size(300, 300),
2190 true);
2191 typename Types::ContentLayerType* surface_child =
2192 this->CreateDrawingLayer(surface,
2193 this->identity_matrix,
2194 gfx::PointF(),
2195 gfx::Size(200, 300),
2196 true);
2197 typename Types::ContentLayerType* surface_child2 =
2198 this->CreateDrawingLayer(surface,
2199 this->identity_matrix,
2200 gfx::PointF(),
2201 gfx::Size(100, 300),
2202 true);
2203 typename Types::ContentLayerType* parent2 =
2204 this->CreateDrawingLayer(parent,
2205 this->identity_matrix,
2206 gfx::PointF(),
2207 gfx::Size(300, 300),
2208 false);
2209 typename Types::ContentLayerType* topmost =
2210 this->CreateDrawingLayer(parent,
2211 this->identity_matrix,
2212 gfx::PointF(250.f, 0.f),
2213 gfx::Size(50, 300),
2214 true);
2216 AddOpacityTransitionToController(
2217 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2218 AddOpacityTransitionToController(
2219 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2220 this->CalcDrawEtc(parent);
2222 EXPECT_TRUE(layer->draw_opacity_is_animating());
2223 EXPECT_FALSE(surface->draw_opacity_is_animating());
2224 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2226 TestOcclusionTrackerWithClip<typename Types::LayerType,
2227 typename Types::RenderSurfaceType> occlusion(
2228 gfx::Rect(0, 0, 1000, 1000));
2230 this->VisitLayer(topmost, &occlusion);
2231 this->EnterLayer(parent2, &occlusion, false);
2232 // This occlusion will affect all surfaces.
2233 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2234 occlusion.occlusion_from_inside_target().ToString());
2235 EXPECT_EQ(gfx::Rect().ToString(),
2236 occlusion.occlusion_from_outside_target().ToString());
2237 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2238 occlusion.UnoccludedLayerContentRect(
2239 parent2, gfx::Rect(0, 0, 300, 300)).ToString());
2240 this->LeaveLayer(parent2, &occlusion);
2242 this->VisitLayer(surface_child2, &occlusion);
2243 this->EnterLayer(surface_child, &occlusion, false);
2244 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2245 occlusion.occlusion_from_inside_target().ToString());
2246 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2247 occlusion.occlusion_from_outside_target().ToString());
2248 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2249 occlusion.UnoccludedLayerContentRect(
2250 surface_child, gfx::Rect(0, 0, 200, 300)));
2251 this->LeaveLayer(surface_child, &occlusion);
2252 this->EnterLayer(surface, &occlusion, false);
2253 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2254 occlusion.occlusion_from_inside_target().ToString());
2255 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2256 occlusion.occlusion_from_outside_target().ToString());
2257 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2258 occlusion.UnoccludedLayerContentRect(
2259 surface, gfx::Rect(0, 0, 300, 300)));
2260 this->LeaveLayer(surface, &occlusion);
2262 this->EnterContributingSurface(surface, &occlusion, false);
2263 // Occlusion within the surface is lost when leaving the animating surface.
2264 EXPECT_EQ(gfx::Rect().ToString(),
2265 occlusion.occlusion_from_inside_target().ToString());
2266 EXPECT_EQ(gfx::Rect().ToString(),
2267 occlusion.occlusion_from_outside_target().ToString());
2268 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2269 occlusion.UnoccludedContributingSurfaceContentRect(
2270 surface, false, gfx::Rect(0, 0, 300, 300)));
2271 this->LeaveContributingSurface(surface, &occlusion);
2273 // Occlusion from outside the animating surface still exists.
2274 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2275 occlusion.occlusion_from_inside_target().ToString());
2276 EXPECT_EQ(gfx::Rect().ToString(),
2277 occlusion.occlusion_from_outside_target().ToString());
2279 this->VisitLayer(layer, &occlusion);
2280 this->EnterLayer(parent, &occlusion, false);
2282 // Occlusion is not added for the animating |layer|.
2283 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2284 occlusion.UnoccludedLayerContentRect(
2285 parent, gfx::Rect(0, 0, 300, 300)));
2289 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2291 template <class Types>
2292 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2293 : public OcclusionTrackerTest<Types> {
2294 protected:
2295 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
2296 : OcclusionTrackerTest<Types>(opaque_layers) {}
2297 void RunMyTest() {
2298 typename Types::ContentLayerType* parent = this->CreateRoot(
2299 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2300 typename Types::ContentLayerType* layer =
2301 this->CreateDrawingLayer(parent,
2302 this->identity_matrix,
2303 gfx::PointF(),
2304 gfx::Size(300, 300),
2305 true);
2306 typename Types::ContentLayerType* surface =
2307 this->CreateDrawingSurface(parent,
2308 this->identity_matrix,
2309 gfx::PointF(),
2310 gfx::Size(300, 300),
2311 true);
2312 typename Types::ContentLayerType* surface_child =
2313 this->CreateDrawingLayer(surface,
2314 this->identity_matrix,
2315 gfx::PointF(),
2316 gfx::Size(200, 300),
2317 true);
2318 typename Types::ContentLayerType* surface_child2 =
2319 this->CreateDrawingLayer(surface,
2320 this->identity_matrix,
2321 gfx::PointF(),
2322 gfx::Size(100, 300),
2323 true);
2324 typename Types::ContentLayerType* parent2 =
2325 this->CreateDrawingLayer(parent,
2326 this->identity_matrix,
2327 gfx::PointF(),
2328 gfx::Size(300, 300),
2329 false);
2330 typename Types::ContentLayerType* topmost =
2331 this->CreateDrawingLayer(parent,
2332 this->identity_matrix,
2333 gfx::PointF(250.f, 0.f),
2334 gfx::Size(50, 300),
2335 true);
2337 AddOpacityTransitionToController(
2338 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2339 AddOpacityTransitionToController(
2340 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2341 this->CalcDrawEtc(parent);
2343 EXPECT_TRUE(layer->draw_opacity_is_animating());
2344 EXPECT_FALSE(surface->draw_opacity_is_animating());
2345 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2347 TestOcclusionTrackerWithClip<typename Types::LayerType,
2348 typename Types::RenderSurfaceType> occlusion(
2349 gfx::Rect(0, 0, 1000, 1000));
2351 this->VisitLayer(topmost, &occlusion);
2352 this->EnterLayer(parent2, &occlusion, false);
2353 // This occlusion will affect all surfaces.
2354 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2355 occlusion.occlusion_from_inside_target().ToString());
2356 EXPECT_EQ(gfx::Rect().ToString(),
2357 occlusion.occlusion_from_outside_target().ToString());
2358 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2359 occlusion.UnoccludedLayerContentRect(
2360 parent, gfx::Rect(0, 0, 300, 300)));
2361 this->LeaveLayer(parent2, &occlusion);
2363 this->VisitLayer(surface_child2, &occlusion);
2364 this->EnterLayer(surface_child, &occlusion, false);
2365 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2366 occlusion.occlusion_from_inside_target().ToString());
2367 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2368 occlusion.occlusion_from_outside_target().ToString());
2369 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2370 occlusion.UnoccludedLayerContentRect(
2371 surface_child, gfx::Rect(0, 0, 200, 300)));
2372 this->LeaveLayer(surface_child, &occlusion);
2373 this->EnterLayer(surface, &occlusion, false);
2374 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2375 occlusion.occlusion_from_inside_target().ToString());
2376 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2377 occlusion.occlusion_from_outside_target().ToString());
2378 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2379 occlusion.UnoccludedLayerContentRect(
2380 surface, gfx::Rect(0, 0, 300, 300)));
2381 this->LeaveLayer(surface, &occlusion);
2383 this->EnterContributingSurface(surface, &occlusion, false);
2384 // Occlusion within the surface is lost when leaving the animating surface.
2385 EXPECT_EQ(gfx::Rect().ToString(),
2386 occlusion.occlusion_from_inside_target().ToString());
2387 EXPECT_EQ(gfx::Rect().ToString(),
2388 occlusion.occlusion_from_outside_target().ToString());
2389 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2390 occlusion.UnoccludedContributingSurfaceContentRect(
2391 surface, false, gfx::Rect(0, 0, 300, 300)));
2392 this->LeaveContributingSurface(surface, &occlusion);
2394 // Occlusion from outside the animating surface still exists.
2395 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2396 occlusion.occlusion_from_inside_target().ToString());
2397 EXPECT_EQ(gfx::Rect().ToString(),
2398 occlusion.occlusion_from_outside_target().ToString());
2400 this->VisitLayer(layer, &occlusion);
2401 this->EnterLayer(parent, &occlusion, false);
2403 // Occlusion is not added for the animating |layer|.
2404 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2405 occlusion.UnoccludedLayerContentRect(
2406 parent, gfx::Rect(0, 0, 300, 300)));
2410 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2412 template <class Types>
2413 class OcclusionTrackerTestAnimationTranslateOnMainThread
2414 : public OcclusionTrackerTest<Types> {
2415 protected:
2416 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2417 bool opaque_layers)
2418 : OcclusionTrackerTest<Types>(opaque_layers) {}
2419 void RunMyTest() {
2420 typename Types::ContentLayerType* parent = this->CreateRoot(
2421 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2422 typename Types::ContentLayerType* layer =
2423 this->CreateDrawingLayer(parent,
2424 this->identity_matrix,
2425 gfx::PointF(),
2426 gfx::Size(300, 300),
2427 true);
2428 typename Types::ContentLayerType* surface =
2429 this->CreateDrawingSurface(parent,
2430 this->identity_matrix,
2431 gfx::PointF(),
2432 gfx::Size(300, 300),
2433 true);
2434 typename Types::ContentLayerType* surface_child =
2435 this->CreateDrawingLayer(surface,
2436 this->identity_matrix,
2437 gfx::PointF(),
2438 gfx::Size(200, 300),
2439 true);
2440 typename Types::ContentLayerType* surface_child2 =
2441 this->CreateDrawingLayer(surface,
2442 this->identity_matrix,
2443 gfx::PointF(),
2444 gfx::Size(100, 300),
2445 true);
2446 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
2447 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
2449 AddAnimatedTransformToController(
2450 layer->layer_animation_controller(), 10.0, 30, 0);
2451 AddAnimatedTransformToController(
2452 surface->layer_animation_controller(), 10.0, 30, 0);
2453 AddAnimatedTransformToController(
2454 surface_child->layer_animation_controller(), 10.0, 30, 0);
2455 this->CalcDrawEtc(parent);
2457 EXPECT_TRUE(layer->draw_transform_is_animating());
2458 EXPECT_TRUE(layer->screen_space_transform_is_animating());
2459 EXPECT_TRUE(
2460 surface->render_surface()->target_surface_transforms_are_animating());
2461 EXPECT_TRUE(
2462 surface->render_surface()->screen_space_transforms_are_animating());
2463 // The surface owning layer doesn't animate against its own surface.
2464 EXPECT_FALSE(surface->draw_transform_is_animating());
2465 EXPECT_TRUE(surface->screen_space_transform_is_animating());
2466 EXPECT_TRUE(surface_child->draw_transform_is_animating());
2467 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
2469 TestOcclusionTrackerWithClip<typename Types::LayerType,
2470 typename Types::RenderSurfaceType> occlusion(
2471 gfx::Rect(0, 0, 1000, 1000));
2473 this->VisitLayer(surface2, &occlusion);
2474 this->EnterContributingSurface(surface2, &occlusion, false);
2476 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2477 occlusion.occlusion_from_inside_target().ToString());
2479 this->LeaveContributingSurface(surface2, &occlusion);
2480 this->EnterLayer(surface_child2, &occlusion, false);
2482 // surface_child2 is moving in screen space but not relative to its target,
2483 // so occlusion should happen in its target space only. It also means that
2484 // things occluding from outside the target (e.g. surface2) cannot occlude
2485 // this layer.
2486 EXPECT_EQ(gfx::Rect().ToString(),
2487 occlusion.occlusion_from_outside_target().ToString());
2489 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2490 occlusion.UnoccludedLayerContentRect(
2491 surface_child2, gfx::Rect(0, 0, 100, 300)));
2492 EXPECT_FALSE(
2493 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2495 this->LeaveLayer(surface_child2, &occlusion);
2496 this->EnterLayer(surface_child, &occlusion, false);
2497 EXPECT_FALSE(
2498 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300)));
2499 EXPECT_EQ(gfx::Rect().ToString(),
2500 occlusion.occlusion_from_outside_target().ToString());
2501 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2502 occlusion.occlusion_from_inside_target().ToString());
2503 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2504 occlusion.UnoccludedLayerContentRect(
2505 surface, gfx::Rect(0, 0, 300, 300)));
2507 // The surface_child is occluded by the surface_child2, but is moving
2508 // relative its target, so it can't be occluded.
2509 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2510 occlusion.UnoccludedLayerContentRect(
2511 surface_child, gfx::Rect(0, 0, 200, 300)));
2512 EXPECT_FALSE(
2513 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2515 this->LeaveLayer(surface_child, &occlusion);
2516 this->EnterLayer(surface, &occlusion, false);
2517 // The surface_child is moving in screen space but not relative to its
2518 // target, so occlusion should happen from within the target only.
2519 EXPECT_EQ(gfx::Rect().ToString(),
2520 occlusion.occlusion_from_outside_target().ToString());
2521 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2522 occlusion.occlusion_from_inside_target().ToString());
2523 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2524 occlusion.UnoccludedLayerContentRect(
2525 surface, gfx::Rect(0, 0, 300, 300)));
2527 this->LeaveLayer(surface, &occlusion);
2528 // The surface's owning layer is moving in screen space but not relative to
2529 // its target, so occlusion should happen within the target only.
2530 EXPECT_EQ(gfx::Rect().ToString(),
2531 occlusion.occlusion_from_outside_target().ToString());
2532 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2533 occlusion.occlusion_from_inside_target().ToString());
2534 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2535 occlusion.UnoccludedLayerContentRect(
2536 surface, gfx::Rect(0, 0, 300, 300)));
2538 this->EnterContributingSurface(surface, &occlusion, false);
2539 // The contributing |surface| is animating so it can't be occluded.
2540 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2541 occlusion.UnoccludedContributingSurfaceContentRect(
2542 surface, false, gfx::Rect(0, 0, 300, 300)));
2543 this->LeaveContributingSurface(surface, &occlusion);
2545 this->EnterLayer(layer, &occlusion, false);
2546 // The |surface| is moving in the screen and in its target, so all occlusion
2547 // within the surface is lost when leaving it.
2548 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2549 occlusion.UnoccludedLayerContentRect(
2550 parent, gfx::Rect(0, 0, 300, 300)));
2551 this->LeaveLayer(layer, &occlusion);
2553 this->EnterLayer(parent, &occlusion, false);
2554 // The |layer| is animating in the screen and in its target, so no occlusion
2555 // is added.
2556 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2557 occlusion.UnoccludedLayerContentRect(
2558 parent, gfx::Rect(0, 0, 300, 300)));
2562 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
2564 template <class Types>
2565 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2566 : public OcclusionTrackerTest<Types> {
2567 protected:
2568 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2569 bool opaque_layers)
2570 : OcclusionTrackerTest<Types>(opaque_layers) {}
2571 void RunMyTest() {
2572 gfx::Transform surface_transform;
2573 surface_transform.Translate(300.0, 300.0);
2574 surface_transform.Scale(2.0, 2.0);
2575 surface_transform.Translate(-150.0, -150.0);
2577 typename Types::ContentLayerType* parent = this->CreateRoot(
2578 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2579 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
2580 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
2581 typename Types::ContentLayerType* surface2 =
2582 this->CreateDrawingSurface(parent,
2583 this->identity_matrix,
2584 gfx::PointF(50.f, 50.f),
2585 gfx::Size(300, 300),
2586 false);
2587 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2588 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2589 this->CalcDrawEtc(parent);
2591 TestOcclusionTrackerWithClip<typename Types::LayerType,
2592 typename Types::RenderSurfaceType> occlusion(
2593 gfx::Rect(0, 0, 1000, 1000));
2595 this->VisitLayer(surface2, &occlusion);
2596 this->VisitContributingSurface(surface2, &occlusion);
2598 EXPECT_EQ(gfx::Rect().ToString(),
2599 occlusion.occlusion_from_outside_target().ToString());
2600 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2601 occlusion.occlusion_from_inside_target().ToString());
2603 // Clear any stored occlusion.
2604 occlusion.set_occlusion_from_outside_target(Region());
2605 occlusion.set_occlusion_from_inside_target(Region());
2607 this->VisitLayer(surface, &occlusion);
2608 this->VisitContributingSurface(surface, &occlusion);
2610 EXPECT_EQ(gfx::Rect().ToString(),
2611 occlusion.occlusion_from_outside_target().ToString());
2612 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2613 occlusion.occlusion_from_inside_target().ToString());
2617 MAIN_AND_IMPL_THREAD_TEST(
2618 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2620 template <class Types>
2621 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2622 : public OcclusionTrackerTest<Types> {
2623 protected:
2624 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2625 bool opaque_layers)
2626 : OcclusionTrackerTest<Types>(opaque_layers) {}
2627 void RunMyTest() {
2628 typename Types::ContentLayerType* parent = this->CreateRoot(
2629 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2630 parent->SetMasksToBounds(true);
2631 typename Types::ContentLayerType* surface =
2632 this->CreateDrawingSurface(parent,
2633 this->identity_matrix,
2634 gfx::PointF(),
2635 gfx::Size(500, 300),
2636 false);
2637 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2638 this->CalcDrawEtc(parent);
2640 TestOcclusionTrackerWithClip<typename Types::LayerType,
2641 typename Types::RenderSurfaceType> occlusion(
2642 gfx::Rect(0, 0, 1000, 1000));
2644 this->VisitLayer(surface, &occlusion);
2645 this->VisitContributingSurface(surface, &occlusion);
2647 EXPECT_EQ(gfx::Rect().ToString(),
2648 occlusion.occlusion_from_outside_target().ToString());
2649 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2650 occlusion.occlusion_from_inside_target().ToString());
2654 MAIN_AND_IMPL_THREAD_TEST(
2655 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2657 template <class Types>
2658 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
2659 protected:
2660 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
2661 : OcclusionTrackerTest<Types>(opaque_layers) {}
2662 void RunMyTest() {
2663 typename Types::ContentLayerType* parent = this->CreateRoot(
2664 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2665 typename Types::LayerType* surface =
2666 this->CreateDrawingSurface(parent,
2667 this->identity_matrix,
2668 gfx::PointF(),
2669 gfx::Size(100, 100),
2670 true);
2671 this->CreateReplicaLayer(surface,
2672 this->identity_matrix,
2673 gfx::PointF(0.f, 100.f),
2674 gfx::Size(100, 100));
2675 typename Types::LayerType* topmost =
2676 this->CreateDrawingLayer(parent,
2677 this->identity_matrix,
2678 gfx::PointF(0.f, 100.f),
2679 gfx::Size(100, 100),
2680 true);
2681 this->CalcDrawEtc(parent);
2683 TestOcclusionTrackerWithClip<typename Types::LayerType,
2684 typename Types::RenderSurfaceType> occlusion(
2685 gfx::Rect(0, 0, 1000, 1000));
2687 // |topmost| occludes the replica, but not the surface itself.
2688 this->VisitLayer(topmost, &occlusion);
2690 EXPECT_EQ(gfx::Rect().ToString(),
2691 occlusion.occlusion_from_outside_target().ToString());
2692 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2693 occlusion.occlusion_from_inside_target().ToString());
2695 this->VisitLayer(surface, &occlusion);
2697 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2698 occlusion.occlusion_from_outside_target().ToString());
2699 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2700 occlusion.occlusion_from_inside_target().ToString());
2702 this->EnterContributingSurface(surface, &occlusion, false);
2704 // Surface is not occluded so it shouldn't think it is.
2705 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2706 occlusion.UnoccludedContributingSurfaceContentRect(
2707 surface, false, gfx::Rect(0, 0, 100, 100)));
2711 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
2713 template <class Types>
2714 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2715 : public OcclusionTrackerTest<Types> {
2716 protected:
2717 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
2718 : OcclusionTrackerTest<Types>(opaque_layers) {}
2719 void RunMyTest() {
2720 typename Types::ContentLayerType* parent = this->CreateRoot(
2721 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2722 typename Types::LayerType* surface =
2723 this->CreateDrawingSurface(parent,
2724 this->identity_matrix,
2725 gfx::PointF(),
2726 gfx::Size(100, 100),
2727 true);
2728 this->CreateReplicaLayer(surface,
2729 this->identity_matrix,
2730 gfx::PointF(0.f, 100.f),
2731 gfx::Size(100, 100));
2732 typename Types::LayerType* topmost =
2733 this->CreateDrawingLayer(parent,
2734 this->identity_matrix,
2735 gfx::PointF(),
2736 gfx::Size(100, 110),
2737 true);
2738 this->CalcDrawEtc(parent);
2740 TestOcclusionTrackerWithClip<typename Types::LayerType,
2741 typename Types::RenderSurfaceType> occlusion(
2742 gfx::Rect(0, 0, 1000, 1000));
2744 // |topmost| occludes the surface, but not the entire surface's replica.
2745 this->VisitLayer(topmost, &occlusion);
2747 EXPECT_EQ(gfx::Rect().ToString(),
2748 occlusion.occlusion_from_outside_target().ToString());
2749 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2750 occlusion.occlusion_from_inside_target().ToString());
2752 this->VisitLayer(surface, &occlusion);
2754 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2755 occlusion.occlusion_from_outside_target().ToString());
2756 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2757 occlusion.occlusion_from_inside_target().ToString());
2759 this->EnterContributingSurface(surface, &occlusion, false);
2761 // Surface is occluded, but only the top 10px of the replica.
2762 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2763 occlusion.UnoccludedContributingSurfaceContentRect(
2764 surface, false, gfx::Rect(0, 0, 100, 100)));
2765 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2766 occlusion.UnoccludedContributingSurfaceContentRect(
2767 surface, true, gfx::Rect(0, 0, 100, 100)));
2771 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2773 template <class Types>
2774 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
2775 : public OcclusionTrackerTest<Types> {
2776 protected:
2777 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
2778 bool opaque_layers)
2779 : OcclusionTrackerTest<Types>(opaque_layers) {}
2780 void RunMyTest() {
2781 typename Types::ContentLayerType* parent = this->CreateRoot(
2782 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2783 typename Types::LayerType* surface =
2784 this->CreateDrawingSurface(parent,
2785 this->identity_matrix,
2786 gfx::PointF(),
2787 gfx::Size(100, 100),
2788 true);
2789 this->CreateReplicaLayer(surface,
2790 this->identity_matrix,
2791 gfx::PointF(0.f, 100.f),
2792 gfx::Size(100, 100));
2793 typename Types::LayerType* over_surface = this->CreateDrawingLayer(
2794 parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
2795 typename Types::LayerType* over_replica =
2796 this->CreateDrawingLayer(parent,
2797 this->identity_matrix,
2798 gfx::PointF(0.f, 100.f),
2799 gfx::Size(50, 100),
2800 true);
2801 this->CalcDrawEtc(parent);
2803 TestOcclusionTrackerWithClip<typename Types::LayerType,
2804 typename Types::RenderSurfaceType> occlusion(
2805 gfx::Rect(0, 0, 1000, 1000));
2807 // These occlude the surface and replica differently, so we can test each
2808 // one.
2809 this->VisitLayer(over_replica, &occlusion);
2810 this->VisitLayer(over_surface, &occlusion);
2812 EXPECT_EQ(gfx::Rect().ToString(),
2813 occlusion.occlusion_from_outside_target().ToString());
2814 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2815 .ToString(),
2816 occlusion.occlusion_from_inside_target().ToString());
2818 this->VisitLayer(surface, &occlusion);
2820 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2821 .ToString(),
2822 occlusion.occlusion_from_outside_target().ToString());
2823 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2824 occlusion.occlusion_from_inside_target().ToString());
2826 this->EnterContributingSurface(surface, &occlusion, false);
2828 // Surface and replica are occluded different amounts.
2829 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
2830 occlusion.UnoccludedContributingSurfaceContentRect(
2831 surface, false, gfx::Rect(0, 0, 100, 100)));
2832 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2833 occlusion.UnoccludedContributingSurfaceContentRect(
2834 surface, true, gfx::Rect(0, 0, 100, 100)));
2838 ALL_OCCLUSIONTRACKER_TEST(
2839 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2841 template <class Types>
2842 class OcclusionTrackerTestSurfaceChildOfSurface
2843 : public OcclusionTrackerTest<Types> {
2844 protected:
2845 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
2846 : OcclusionTrackerTest<Types>(opaque_layers) {}
2847 void RunMyTest() {
2848 // This test verifies that the surface cliprect does not end up empty and
2849 // clip away the entire unoccluded rect.
2851 typename Types::ContentLayerType* parent = this->CreateRoot(
2852 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2853 typename Types::LayerType* surface =
2854 this->CreateDrawingSurface(parent,
2855 this->identity_matrix,
2856 gfx::PointF(),
2857 gfx::Size(100, 100),
2858 true);
2859 typename Types::LayerType* surface_child =
2860 this->CreateDrawingSurface(surface,
2861 this->identity_matrix,
2862 gfx::PointF(0.f, 10.f),
2863 gfx::Size(100, 50),
2864 true);
2865 typename Types::LayerType* topmost = this->CreateDrawingLayer(
2866 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2867 this->CalcDrawEtc(parent);
2869 TestOcclusionTrackerWithClip<typename Types::LayerType,
2870 typename Types::RenderSurfaceType> occlusion(
2871 gfx::Rect(-100, -100, 1000, 1000));
2873 // |topmost| occludes everything partially so we know occlusion is happening
2874 // at all.
2875 this->VisitLayer(topmost, &occlusion);
2877 EXPECT_EQ(gfx::Rect().ToString(),
2878 occlusion.occlusion_from_outside_target().ToString());
2879 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2880 occlusion.occlusion_from_inside_target().ToString());
2882 this->VisitLayer(surface_child, &occlusion);
2884 // surface_child increases the occlusion in the screen by a narrow sliver.
2885 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2886 occlusion.occlusion_from_outside_target().ToString());
2887 // In its own surface, surface_child is at 0,0 as is its occlusion.
2888 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2889 occlusion.occlusion_from_inside_target().ToString());
2891 // The root layer always has a clip rect. So the parent of |surface| has a
2892 // clip rect. However, the owning layer for |surface| does not mask to
2893 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2894 // |surface_child| exercises different code paths as its parent does not
2895 // have a clip rect.
2897 this->EnterContributingSurface(surface_child, &occlusion, false);
2898 // The surface_child's parent does not have a clip rect as it owns a render
2899 // surface. Make sure the unoccluded rect does not get clipped away
2900 // inappropriately.
2901 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
2902 occlusion.UnoccludedContributingSurfaceContentRect(
2903 surface_child, false, gfx::Rect(0, 0, 100, 50)));
2904 this->LeaveContributingSurface(surface_child, &occlusion);
2906 // When the surface_child's occlusion is transformed up to its parent, make
2907 // sure it is not clipped away inappropriately also.
2908 this->EnterLayer(surface, &occlusion, false);
2909 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2910 occlusion.occlusion_from_outside_target().ToString());
2911 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2912 occlusion.occlusion_from_inside_target().ToString());
2913 this->LeaveLayer(surface, &occlusion);
2915 this->EnterContributingSurface(surface, &occlusion, false);
2916 // The surface's parent does have a clip rect as it is the root layer.
2917 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
2918 occlusion.UnoccludedContributingSurfaceContentRect(
2919 surface, false, gfx::Rect(0, 0, 100, 100)));
2923 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2925 template <class Types>
2926 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
2927 : public OcclusionTrackerTest<Types> {
2928 protected:
2929 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
2930 bool opaque_layers)
2931 : OcclusionTrackerTest<Types>(opaque_layers) {}
2932 void RunMyTest() {
2933 // This test verifies that the top-most surface is considered occluded
2934 // outside of its target's clip rect and outside the viewport rect.
2936 typename Types::ContentLayerType* parent = this->CreateRoot(
2937 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2938 typename Types::LayerType* surface =
2939 this->CreateDrawingSurface(parent,
2940 this->identity_matrix,
2941 gfx::PointF(),
2942 gfx::Size(100, 300),
2943 true);
2944 this->CalcDrawEtc(parent);
2946 // Make a viewport rect that is larger than the root layer.
2947 TestOcclusionTrackerWithClip<typename Types::LayerType,
2948 typename Types::RenderSurfaceType> occlusion(
2949 gfx::Rect(0, 0, 1000, 1000));
2951 this->VisitLayer(surface, &occlusion);
2953 // The root layer always has a clip rect. So the parent of |surface| has a
2954 // clip rect giving the surface itself a clip rect.
2955 this->EnterContributingSurface(surface, &occlusion, false);
2956 // Make sure the parent's clip rect clips the unoccluded region of the
2957 // child surface.
2958 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
2959 occlusion.UnoccludedContributingSurfaceContentRect(
2960 surface, false, gfx::Rect(0, 0, 100, 300)));
2962 this->ResetLayerIterator();
2964 // Make a viewport rect that is smaller than the root layer.
2965 TestOcclusionTrackerWithClip<typename Types::LayerType,
2966 typename Types::RenderSurfaceType> occlusion(
2967 gfx::Rect(0, 0, 100, 100));
2969 this->VisitLayer(surface, &occlusion);
2971 // The root layer always has a clip rect. So the parent of |surface| has a
2972 // clip rect giving the surface itself a clip rect.
2973 this->EnterContributingSurface(surface, &occlusion, false);
2974 // Make sure the viewport rect clips the unoccluded region of the child
2975 // surface.
2976 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2977 occlusion.UnoccludedContributingSurfaceContentRect(
2978 surface, false, gfx::Rect(0, 0, 100, 300)));
2983 ALL_OCCLUSIONTRACKER_TEST(
2984 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
2986 template <class Types>
2987 class OcclusionTrackerTestSurfaceChildOfClippingSurface
2988 : public OcclusionTrackerTest<Types> {
2989 protected:
2990 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers)
2991 : OcclusionTrackerTest<Types>(opaque_layers) {}
2992 void RunMyTest() {
2993 // This test verifies that the surface cliprect does not end up empty and
2994 // clip away the entire unoccluded rect.
2996 typename Types::ContentLayerType* parent = this->CreateRoot(
2997 this->identity_matrix, gfx::PointF(), gfx::Size(80, 200));
2998 parent->SetMasksToBounds(true);
2999 typename Types::LayerType* surface =
3000 this->CreateDrawingSurface(parent,
3001 this->identity_matrix,
3002 gfx::PointF(),
3003 gfx::Size(100, 100),
3004 true);
3005 typename Types::LayerType* surface_child =
3006 this->CreateDrawingSurface(surface,
3007 this->identity_matrix,
3008 gfx::PointF(),
3009 gfx::Size(100, 100),
3010 false);
3011 typename Types::LayerType* topmost = this->CreateDrawingLayer(
3012 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3013 this->CalcDrawEtc(parent);
3015 TestOcclusionTrackerWithClip<typename Types::LayerType,
3016 typename Types::RenderSurfaceType> occlusion(
3017 gfx::Rect(0, 0, 1000, 1000));
3019 // |topmost| occludes everything partially so we know occlusion is happening
3020 // at all.
3021 this->VisitLayer(topmost, &occlusion);
3023 EXPECT_EQ(gfx::Rect().ToString(),
3024 occlusion.occlusion_from_outside_target().ToString());
3025 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3026 occlusion.occlusion_from_inside_target().ToString());
3028 // surface_child is not opaque and does not occlude, so we have a non-empty
3029 // unoccluded area on surface.
3030 this->VisitLayer(surface_child, &occlusion);
3032 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3033 occlusion.occlusion_from_outside_target().ToString());
3034 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3035 occlusion.occlusion_from_inside_target().ToString());
3037 // The root layer always has a clip rect. So the parent of |surface| has a
3038 // clip rect. However, the owning layer for |surface| does not mask to
3039 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3040 // |surface_child| exercises different code paths as its parent does not
3041 // have a clip rect.
3043 this->EnterContributingSurface(surface_child, &occlusion, false);
3044 // The surface_child's parent does not have a clip rect as it owns a render
3045 // surface.
3046 EXPECT_EQ(
3047 gfx::Rect(0, 50, 80, 50).ToString(),
3048 occlusion.UnoccludedContributingSurfaceContentRect(
3049 surface_child, false, gfx::Rect(0, 0, 100, 100)).ToString());
3050 this->LeaveContributingSurface(surface_child, &occlusion);
3052 this->VisitLayer(surface, &occlusion);
3053 this->EnterContributingSurface(surface, &occlusion, false);
3054 // The surface's parent does have a clip rect as it is the root layer.
3055 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3056 occlusion.UnoccludedContributingSurfaceContentRect(
3057 surface, false, gfx::Rect(0, 0, 100, 100)).ToString());
3061 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
3063 template <class Types>
3064 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3065 : public OcclusionTrackerTest<Types> {
3066 protected:
3067 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3068 bool opaque_layers)
3069 : OcclusionTrackerTest<Types>(opaque_layers) {}
3070 void RunMyTest() {
3071 gfx::Transform scale_by_half;
3072 scale_by_half.Scale(0.5, 0.5);
3074 // Make a surface and its replica, each 50x50, that are completely
3075 // surrounded by opaque layers which are above them in the z-order. The
3076 // surface is scaled to test that the pixel moving is done in the target
3077 // space, where the background filter is applied, but the surface appears at
3078 // 50, 50 and the replica at 200, 50.
3079 typename Types::ContentLayerType* parent = this->CreateRoot(
3080 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3081 typename Types::LayerType* filtered_surface =
3082 this->CreateDrawingLayer(parent,
3083 scale_by_half,
3084 gfx::PointF(50.f, 50.f),
3085 gfx::Size(100, 100),
3086 false);
3087 this->CreateReplicaLayer(filtered_surface,
3088 this->identity_matrix,
3089 gfx::PointF(300.f, 0.f),
3090 gfx::Size());
3091 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3092 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
3093 typename Types::LayerType* occluding_layer2 =
3094 this->CreateDrawingLayer(parent,
3095 this->identity_matrix,
3096 gfx::PointF(0.f, 100.f),
3097 gfx::Size(300, 50),
3098 true);
3099 typename Types::LayerType* occluding_layer3 =
3100 this->CreateDrawingLayer(parent,
3101 this->identity_matrix,
3102 gfx::PointF(0.f, 50.f),
3103 gfx::Size(50, 50),
3104 true);
3105 typename Types::LayerType* occluding_layer4 =
3106 this->CreateDrawingLayer(parent,
3107 this->identity_matrix,
3108 gfx::PointF(100.f, 50.f),
3109 gfx::Size(100, 50),
3110 true);
3111 typename Types::LayerType* occluding_layer5 =
3112 this->CreateDrawingLayer(parent,
3113 this->identity_matrix,
3114 gfx::PointF(250.f, 50.f),
3115 gfx::Size(50, 50),
3116 true);
3118 // Filters make the layer own a surface.
3119 FilterOperations filters;
3120 filters.Append(FilterOperation::CreateBlurFilter(10.f));
3121 filtered_surface->SetBackgroundFilters(filters);
3123 // Save the distance of influence for the blur effect.
3124 int outset_top, outset_right, outset_bottom, outset_left;
3125 filters.GetOutsets(
3126 &outset_top, &outset_right, &outset_bottom, &outset_left);
3128 this->CalcDrawEtc(parent);
3130 TestOcclusionTrackerWithClip<typename Types::LayerType,
3131 typename Types::RenderSurfaceType> occlusion(
3132 gfx::Rect(0, 0, 1000, 1000));
3134 // These layers occlude pixels directly beside the filtered_surface. Because
3135 // filtered surface blends pixels in a radius, it will need to see some of
3136 // the pixels (up to radius far) underneath the occluding layers.
3137 this->VisitLayer(occluding_layer5, &occlusion);
3138 this->VisitLayer(occluding_layer4, &occlusion);
3139 this->VisitLayer(occluding_layer3, &occlusion);
3140 this->VisitLayer(occluding_layer2, &occlusion);
3141 this->VisitLayer(occluding_layer1, &occlusion);
3143 Region expected_occlusion;
3144 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
3145 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3146 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3147 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
3148 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));
3150 EXPECT_EQ(expected_occlusion.ToString(),
3151 occlusion.occlusion_from_inside_target().ToString());
3152 EXPECT_EQ(gfx::Rect().ToString(),
3153 occlusion.occlusion_from_outside_target().ToString());
3155 this->VisitLayer(filtered_surface, &occlusion);
3157 // The filtered layer/replica does not occlude.
3158 Region expected_occlusion_outside_surface;
3159 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
3160 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3161 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3162 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
3163 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));
3165 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3166 occlusion.occlusion_from_outside_target().ToString());
3167 EXPECT_EQ(gfx::Rect().ToString(),
3168 occlusion.occlusion_from_inside_target().ToString());
3170 // The surface has a background blur, so it needs pixels that are currently
3171 // considered occluded in order to be drawn. So the pixels it needs should
3172 // be removed some the occluded area so that when we get to the parent they
3173 // are drawn.
3174 this->VisitContributingSurface(filtered_surface, &occlusion);
3176 this->EnterLayer(parent, &occlusion, false);
3178 Region expected_blurred_occlusion;
3179 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
3180 expected_blurred_occlusion.Union(gfx::Rect(
3181 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
3182 expected_blurred_occlusion.Union(
3183 gfx::Rect(100 + outset_right,
3184 50 - outset_top,
3185 100 - outset_right - outset_left,
3186 50 + outset_top + outset_bottom));
3187 expected_blurred_occlusion.Union(
3188 gfx::Rect(250 + outset_right,
3189 50 - outset_top,
3190 50 - outset_right,
3191 50 + outset_top + outset_bottom));
3192 expected_blurred_occlusion.Union(
3193 gfx::Rect(0, 100 + outset_bottom, 300, 50 - outset_bottom));
3195 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3196 occlusion.occlusion_from_inside_target().ToString());
3197 EXPECT_EQ(gfx::Rect().ToString(),
3198 occlusion.occlusion_from_outside_target().ToString());
3200 gfx::Rect outset_rect;
3201 gfx::Rect test_rect;
3203 // Nothing in the blur outsets for the filtered_surface is occluded.
3204 outset_rect = gfx::Rect(50 - outset_left,
3205 50 - outset_top,
3206 50 + outset_left + outset_right,
3207 50 + outset_top + outset_bottom);
3208 test_rect = outset_rect;
3209 EXPECT_EQ(
3210 outset_rect.ToString(),
3211 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3213 // Stuff outside the blur outsets is still occluded though.
3214 test_rect = outset_rect;
3215 test_rect.Inset(0, 0, -1, 0);
3216 EXPECT_EQ(
3217 outset_rect.ToString(),
3218 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3219 test_rect = outset_rect;
3220 test_rect.Inset(0, 0, 0, -1);
3221 EXPECT_EQ(
3222 outset_rect.ToString(),
3223 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3224 test_rect = outset_rect;
3225 test_rect.Inset(-1, 0, 0, 0);
3226 EXPECT_EQ(
3227 outset_rect.ToString(),
3228 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3229 test_rect = outset_rect;
3230 test_rect.Inset(0, -1, 0, 0);
3231 EXPECT_EQ(
3232 outset_rect.ToString(),
3233 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3235 // Nothing in the blur outsets for the filtered_surface's replica is
3236 // occluded.
3237 outset_rect = gfx::Rect(200 - outset_left,
3238 50 - outset_top,
3239 50 + outset_left + outset_right,
3240 50 + outset_top + outset_bottom);
3241 test_rect = outset_rect;
3242 EXPECT_EQ(
3243 outset_rect.ToString(),
3244 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3246 // Stuff outside the blur outsets is still occluded though.
3247 test_rect = outset_rect;
3248 test_rect.Inset(0, 0, -1, 0);
3249 EXPECT_EQ(
3250 outset_rect.ToString(),
3251 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3252 test_rect = outset_rect;
3253 test_rect.Inset(0, 0, 0, -1);
3254 EXPECT_EQ(
3255 outset_rect.ToString(),
3256 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3257 test_rect = outset_rect;
3258 test_rect.Inset(-1, 0, 0, 0);
3259 EXPECT_EQ(
3260 outset_rect.ToString(),
3261 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3262 test_rect = outset_rect;
3263 test_rect.Inset(0, -1, 0, 0);
3264 EXPECT_EQ(
3265 outset_rect.ToString(),
3266 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3270 ALL_OCCLUSIONTRACKER_TEST(
3271 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
3273 template <class Types>
3274 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3275 : public OcclusionTrackerTest<Types> {
3276 protected:
3277 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3278 bool opaque_layers)
3279 : OcclusionTrackerTest<Types>(opaque_layers) {}
3280 void RunMyTest() {
3281 gfx::Transform scale_by_half;
3282 scale_by_half.Scale(0.5, 0.5);
3284 // Makes two surfaces that completely cover |parent|. The occlusion both
3285 // above and below the filters will be reduced by each of them.
3286 typename Types::ContentLayerType* root = this->CreateRoot(
3287 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
3288 typename Types::LayerType* parent = this->CreateSurface(
3289 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
3290 parent->SetMasksToBounds(true);
3291 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
3292 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3293 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
3294 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3295 typename Types::LayerType* occluding_layer_above =
3296 this->CreateDrawingLayer(parent,
3297 this->identity_matrix,
3298 gfx::PointF(100.f, 100.f),
3299 gfx::Size(50, 50),
3300 true);
3302 // Filters make the layers own surfaces.
3303 FilterOperations filters;
3304 filters.Append(FilterOperation::CreateBlurFilter(1.f));
3305 filtered_surface1->SetBackgroundFilters(filters);
3306 filtered_surface2->SetBackgroundFilters(filters);
3308 // Save the distance of influence for the blur effect.
3309 int outset_top, outset_right, outset_bottom, outset_left;
3310 filters.GetOutsets(
3311 &outset_top, &outset_right, &outset_bottom, &outset_left);
3313 this->CalcDrawEtc(root);
3315 TestOcclusionTrackerWithClip<typename Types::LayerType,
3316 typename Types::RenderSurfaceType> occlusion(
3317 gfx::Rect(0, 0, 1000, 1000));
3319 this->VisitLayer(occluding_layer_above, &occlusion);
3320 EXPECT_EQ(gfx::Rect().ToString(),
3321 occlusion.occlusion_from_outside_target().ToString());
3322 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3323 occlusion.occlusion_from_inside_target().ToString());
3325 this->VisitLayer(filtered_surface2, &occlusion);
3326 this->VisitContributingSurface(filtered_surface2, &occlusion);
3327 this->VisitLayer(filtered_surface1, &occlusion);
3328 this->VisitContributingSurface(filtered_surface1, &occlusion);
3330 // Test expectations in the target.
3331 gfx::Rect expected_occlusion =
3332 gfx::Rect(100 / 2 + outset_right * 2,
3333 100 / 2 + outset_bottom * 2,
3334 50 / 2 - (outset_left + outset_right) * 2,
3335 50 / 2 - (outset_top + outset_bottom) * 2);
3336 EXPECT_EQ(expected_occlusion.ToString(),
3337 occlusion.occlusion_from_inside_target().ToString());
3339 // Test expectations in the screen are the same as in the target, as the
3340 // render surface is 1:1 with the screen.
3341 EXPECT_EQ(expected_occlusion.ToString(),
3342 occlusion.occlusion_from_outside_target().ToString());
3346 ALL_OCCLUSIONTRACKER_TEST(
3347 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
3349 template <class Types>
3350 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3351 : public OcclusionTrackerTest<Types> {
3352 protected:
3353 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3354 bool opaque_layers)
3355 : OcclusionTrackerTest<Types>(opaque_layers) {}
3356 void RunMyTest() {
3357 gfx::Transform scale_by_half;
3358 scale_by_half.Scale(0.5, 0.5);
3360 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3361 // centered below each. The surface is scaled to test that the pixel moving
3362 // is done in the target space, where the background filter is applied, but
3363 // the surface appears at 50, 50 and the replica at 200, 50.
3364 typename Types::ContentLayerType* parent = this->CreateRoot(
3365 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3366 typename Types::LayerType* behind_surface_layer =
3367 this->CreateDrawingLayer(parent,
3368 this->identity_matrix,
3369 gfx::PointF(60.f, 60.f),
3370 gfx::Size(30, 30),
3371 true);
3372 typename Types::LayerType* behind_replica_layer =
3373 this->CreateDrawingLayer(parent,
3374 this->identity_matrix,
3375 gfx::PointF(210.f, 60.f),
3376 gfx::Size(30, 30),
3377 true);
3378 typename Types::LayerType* filtered_surface =
3379 this->CreateDrawingLayer(parent,
3380 scale_by_half,
3381 gfx::PointF(50.f, 50.f),
3382 gfx::Size(100, 100),
3383 false);
3384 this->CreateReplicaLayer(filtered_surface,
3385 this->identity_matrix,
3386 gfx::PointF(300.f, 0.f),
3387 gfx::Size());
3389 // Filters make the layer own a surface.
3390 FilterOperations filters;
3391 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3392 filtered_surface->SetBackgroundFilters(filters);
3394 this->CalcDrawEtc(parent);
3396 TestOcclusionTrackerWithClip<typename Types::LayerType,
3397 typename Types::RenderSurfaceType> occlusion(
3398 gfx::Rect(0, 0, 1000, 1000));
3400 // The surface has a background blur, so it blurs non-opaque pixels below
3401 // it.
3402 this->VisitLayer(filtered_surface, &occlusion);
3403 this->VisitContributingSurface(filtered_surface, &occlusion);
3405 this->VisitLayer(behind_replica_layer, &occlusion);
3406 this->VisitLayer(behind_surface_layer, &occlusion);
3408 // The layers behind the surface are not blurred, and their occlusion does
3409 // not change, until we leave the surface. So it should not be modified by
3410 // the filter here.
3411 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
3412 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
3414 Region expected_opaque_bounds =
3415 UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
3416 EXPECT_EQ(expected_opaque_bounds.ToString(),
3417 occlusion.occlusion_from_inside_target().ToString());
3419 EXPECT_EQ(gfx::Rect().ToString(),
3420 occlusion.occlusion_from_outside_target().ToString());
3424 ALL_OCCLUSIONTRACKER_TEST(
3425 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
3427 template <class Types>
3428 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3429 : public OcclusionTrackerTest<Types> {
3430 protected:
3431 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3432 bool opaque_layers)
3433 : OcclusionTrackerTest<Types>(opaque_layers) {}
3434 void RunMyTest() {
3435 gfx::Transform scale_by_half;
3436 scale_by_half.Scale(0.5, 0.5);
3438 // Make a surface and its replica, each 50x50, that are completely occluded
3439 // by opaque layers which are above them in the z-order. The surface is
3440 // scaled to test that the pixel moving is done in the target space, where
3441 // the background filter is applied, but the surface appears at 50, 50 and
3442 // the replica at 200, 50.
3443 typename Types::ContentLayerType* parent = this->CreateRoot(
3444 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3445 typename Types::LayerType* filtered_surface =
3446 this->CreateDrawingLayer(parent,
3447 scale_by_half,
3448 gfx::PointF(50.f, 50.f),
3449 gfx::Size(100, 100),
3450 false);
3451 this->CreateReplicaLayer(filtered_surface,
3452 this->identity_matrix,
3453 gfx::PointF(300.f, 0.f),
3454 gfx::Size());
3455 typename Types::LayerType* above_surface_layer =
3456 this->CreateDrawingLayer(parent,
3457 this->identity_matrix,
3458 gfx::PointF(50.f, 50.f),
3459 gfx::Size(50, 50),
3460 true);
3461 typename Types::LayerType* above_replica_layer =
3462 this->CreateDrawingLayer(parent,
3463 this->identity_matrix,
3464 gfx::PointF(200.f, 50.f),
3465 gfx::Size(50, 50),
3466 true);
3468 // Filters make the layer own a surface.
3469 FilterOperations filters;
3470 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3471 filtered_surface->SetBackgroundFilters(filters);
3473 this->CalcDrawEtc(parent);
3475 TestOcclusionTrackerWithClip<typename Types::LayerType,
3476 typename Types::RenderSurfaceType> occlusion(
3477 gfx::Rect(0, 0, 1000, 1000));
3479 this->VisitLayer(above_replica_layer, &occlusion);
3480 this->VisitLayer(above_surface_layer, &occlusion);
3482 this->VisitLayer(filtered_surface, &occlusion);
3484 // The layers above the filtered surface occlude from outside.
3485 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
3486 gfx::Rect occlusion_above_replica = gfx::Rect(150, 0, 50, 50);
3487 Region expected_opaque_region =
3488 UnionRegions(occlusion_above_surface, occlusion_above_replica);
3490 EXPECT_EQ(gfx::Rect().ToString(),
3491 occlusion.occlusion_from_inside_target().ToString());
3492 EXPECT_EQ(expected_opaque_region.ToString(),
3493 occlusion.occlusion_from_outside_target().ToString());
3496 // The surface has a background blur, so it blurs non-opaque pixels below
3497 // it.
3498 this->VisitContributingSurface(filtered_surface, &occlusion);
3500 // The filter is completely occluded, so it should not blur anything and
3501 // reduce any occlusion.
3502 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
3503 gfx::Rect occlusion_above_replica = gfx::Rect(200, 50, 50, 50);
3504 Region expected_opaque_region =
3505 UnionRegions(occlusion_above_surface, occlusion_above_replica);
3507 EXPECT_EQ(expected_opaque_region.ToString(),
3508 occlusion.occlusion_from_inside_target().ToString());
3509 EXPECT_EQ(gfx::Rect().ToString(),
3510 occlusion.occlusion_from_outside_target().ToString());
3515 ALL_OCCLUSIONTRACKER_TEST(
3516 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
3518 template <class Types>
3519 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3520 : public OcclusionTrackerTest<Types> {
3521 protected:
3522 explicit
3523 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3524 bool opaque_layers)
3525 : OcclusionTrackerTest<Types>(opaque_layers) {}
3526 void RunMyTest() {
3527 gfx::Transform scale_by_half;
3528 scale_by_half.Scale(0.5, 0.5);
3530 // Make a surface and its replica, each 50x50, that are partially occluded
3531 // by opaque layers which are above them in the z-order. The surface is
3532 // scaled to test that the pixel moving is done in the target space, where
3533 // the background filter is applied, but the surface appears at 50, 50 and
3534 // the replica at 200, 50.
3535 typename Types::ContentLayerType* parent = this->CreateRoot(
3536 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3537 typename Types::LayerType* filtered_surface =
3538 this->CreateDrawingLayer(parent,
3539 scale_by_half,
3540 gfx::PointF(50.f, 50.f),
3541 gfx::Size(100, 100),
3542 false);
3543 this->CreateReplicaLayer(filtered_surface,
3544 this->identity_matrix,
3545 gfx::PointF(300.f, 0.f),
3546 gfx::Size());
3547 typename Types::LayerType* above_surface_layer =
3548 this->CreateDrawingLayer(parent,
3549 this->identity_matrix,
3550 gfx::PointF(70.f, 50.f),
3551 gfx::Size(30, 50),
3552 true);
3553 typename Types::LayerType* above_replica_layer =
3554 this->CreateDrawingLayer(parent,
3555 this->identity_matrix,
3556 gfx::PointF(200.f, 50.f),
3557 gfx::Size(30, 50),
3558 true);
3559 typename Types::LayerType* beside_surface_layer =
3560 this->CreateDrawingLayer(parent,
3561 this->identity_matrix,
3562 gfx::PointF(90.f, 40.f),
3563 gfx::Size(10, 10),
3564 true);
3565 typename Types::LayerType* beside_replica_layer =
3566 this->CreateDrawingLayer(parent,
3567 this->identity_matrix,
3568 gfx::PointF(200.f, 40.f),
3569 gfx::Size(10, 10),
3570 true);
3572 // Filters make the layer own a surface.
3573 FilterOperations filters;
3574 filters.Append(FilterOperation::CreateBlurFilter(3.f));
3575 filtered_surface->SetBackgroundFilters(filters);
3577 // Save the distance of influence for the blur effect.
3578 int outset_top, outset_right, outset_bottom, outset_left;
3579 filters.GetOutsets(
3580 &outset_top, &outset_right, &outset_bottom, &outset_left);
3582 this->CalcDrawEtc(parent);
3584 TestOcclusionTrackerWithClip<typename Types::LayerType,
3585 typename Types::RenderSurfaceType> occlusion(
3586 gfx::Rect(0, 0, 1000, 1000));
3588 this->VisitLayer(beside_replica_layer, &occlusion);
3589 this->VisitLayer(beside_surface_layer, &occlusion);
3590 this->VisitLayer(above_replica_layer, &occlusion);
3591 this->VisitLayer(above_surface_layer, &occlusion);
3593 // The surface has a background blur, so it blurs non-opaque pixels below
3594 // it.
3595 this->VisitLayer(filtered_surface, &occlusion);
3596 this->VisitContributingSurface(filtered_surface, &occlusion);
3598 // The filter in the surface and replica are partially unoccluded. Only the
3599 // unoccluded parts should reduce occlusion. This means it will push back
3600 // the occlusion that touches the unoccluded part (occlusion_above___), but
3601 // it will not touch occlusion_beside____ since that is not beside the
3602 // unoccluded part of the surface, even though it is beside the occluded
3603 // part of the surface.
3604 gfx::Rect occlusion_above_surface =
3605 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
3606 gfx::Rect occlusion_above_replica =
3607 gfx::Rect(200, 50, 30 - outset_left, 50);
3608 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
3609 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
3611 Region expected_occlusion;
3612 expected_occlusion.Union(occlusion_above_surface);
3613 expected_occlusion.Union(occlusion_above_replica);
3614 expected_occlusion.Union(occlusion_beside_surface);
3615 expected_occlusion.Union(occlusion_beside_replica);
3617 ASSERT_EQ(expected_occlusion.ToString(),
3618 occlusion.occlusion_from_inside_target().ToString());
3619 EXPECT_EQ(gfx::Rect().ToString(),
3620 occlusion.occlusion_from_outside_target().ToString());
3622 Region::Iterator expected_rects(expected_occlusion);
3623 Region::Iterator target_surface_rects(
3624 occlusion.occlusion_from_inside_target());
3625 for (; expected_rects.has_rect();
3626 expected_rects.next(), target_surface_rects.next()) {
3627 ASSERT_TRUE(target_surface_rects.has_rect());
3628 EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
3633 ALL_OCCLUSIONTRACKER_TEST(
3634 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
3636 template <class Types>
3637 class OcclusionTrackerTestMinimumTrackingSize
3638 : public OcclusionTrackerTest<Types> {
3639 protected:
3640 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
3641 : OcclusionTrackerTest<Types>(opaque_layers) {}
3642 void RunMyTest() {
3643 gfx::Size tracking_size(100, 100);
3644 gfx::Size below_tracking_size(99, 99);
3646 typename Types::ContentLayerType* parent = this->CreateRoot(
3647 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3648 typename Types::LayerType* large = this->CreateDrawingLayer(
3649 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
3650 typename Types::LayerType* small =
3651 this->CreateDrawingLayer(parent,
3652 this->identity_matrix,
3653 gfx::PointF(),
3654 below_tracking_size,
3655 true);
3656 this->CalcDrawEtc(parent);
3658 TestOcclusionTrackerWithClip<typename Types::LayerType,
3659 typename Types::RenderSurfaceType> occlusion(
3660 gfx::Rect(0, 0, 1000, 1000));
3661 occlusion.set_minimum_tracking_size(tracking_size);
3663 // The small layer is not tracked because it is too small.
3664 this->VisitLayer(small, &occlusion);
3666 EXPECT_EQ(gfx::Rect().ToString(),
3667 occlusion.occlusion_from_outside_target().ToString());
3668 EXPECT_EQ(gfx::Rect().ToString(),
3669 occlusion.occlusion_from_inside_target().ToString());
3671 // The large layer is tracked as it is large enough.
3672 this->VisitLayer(large, &occlusion);
3674 EXPECT_EQ(gfx::Rect().ToString(),
3675 occlusion.occlusion_from_outside_target().ToString());
3676 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
3677 occlusion.occlusion_from_inside_target().ToString());
3681 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
3683 template <class Types>
3684 class OcclusionTrackerTestPreventOcclusionOnLayer
3685 : public OcclusionTrackerTest<Types> {
3686 protected:
3687 explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers)
3688 : OcclusionTrackerTest<Types>(opaque_layers) {}
3689 void RunMyTest() {
3690 typename Types::ContentLayerType* parent = this->CreateRoot(
3691 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3692 typename Types::LayerType* unprevented = this->CreateDrawingLayer(
3693 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
3694 typename Types::LayerType* prevented = this->CreateDrawingLayer(
3695 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
3696 typename Types::LayerType* occluding = this->CreateDrawingLayer(
3697 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
3698 this->CalcDrawEtc(parent);
3700 TestOcclusionTrackerWithClip<typename Types::LayerType,
3701 typename Types::RenderSurfaceType> occlusion(
3702 gfx::Rect(0, 0, 1000, 1000));
3704 this->VisitLayer(occluding, &occlusion);
3705 this->EnterLayer(prevented, &occlusion, true);
3707 // This layer is not occluded because it is prevented.
3708 EXPECT_FALSE(occlusion.OccludedLayer(prevented,
3709 gfx::Rect(50, 50)));
3711 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3712 occlusion.UnoccludedLayerContentRect(
3713 prevented,
3714 gfx::Rect(50, 50)).ToString());
3716 this->LeaveLayer(prevented, &occlusion);
3717 this->EnterLayer(unprevented, &occlusion, false);
3719 // This layer is fully occluded.
3720 EXPECT_TRUE(occlusion.OccludedLayer(unprevented,
3721 gfx::Rect(50, 50)));
3723 EXPECT_EQ(gfx::Rect().ToString(),
3724 occlusion.UnoccludedLayerContentRect(
3725 unprevented,
3726 gfx::Rect(50, 50)).ToString());
3728 this->LeaveLayer(unprevented, &occlusion);
3732 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer)
3734 template <class Types>
3735 class OcclusionTrackerTestPreventOcclusionOnContributingSurface
3736 : public OcclusionTrackerTest<Types> {
3737 protected:
3738 explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface(
3739 bool opaque_layers)
3740 : OcclusionTrackerTest<Types>(opaque_layers) {}
3741 void RunMyTest() {
3742 typename Types::ContentLayerType* parent = this->CreateRoot(
3743 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3744 typename Types::LayerType* unprevented = this->CreateDrawingSurface(
3745 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
3746 typename Types::LayerType* prevented = this->CreateDrawingSurface(
3747 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
3748 typename Types::LayerType* occluding = this->CreateDrawingLayer(
3749 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
3750 this->CalcDrawEtc(parent);
3752 TestOcclusionTrackerWithClip<typename Types::LayerType,
3753 typename Types::RenderSurfaceType> occlusion(
3754 gfx::Rect(0, 0, 1000, 1000));
3756 this->VisitLayer(occluding, &occlusion);
3757 this->EnterLayer(prevented, &occlusion, true);
3759 // This layer is not occluded because it is prevented.
3760 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3761 occlusion.UnoccludedLayerContentRect(
3762 prevented,
3763 gfx::Rect(50, 50)).ToString());
3765 this->LeaveLayer(prevented, &occlusion);
3766 this->EnterContributingSurface(prevented, &occlusion, true);
3768 // This contributing surface is not occluded because it is prevented.
3769 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3770 occlusion.UnoccludedContributingSurfaceContentRect(
3771 prevented,
3772 false, // is_replica
3773 gfx::Rect(50, 50)).ToString());
3775 this->LeaveContributingSurface(prevented, &occlusion);
3776 this->EnterLayer(unprevented, &occlusion, false);
3778 // This layer is fully occluded from outside its surface.
3779 EXPECT_EQ(gfx::Rect().ToString(),
3780 occlusion.UnoccludedLayerContentRect(
3781 unprevented,
3782 gfx::Rect(50, 50)).ToString());
3784 this->LeaveLayer(unprevented, &occlusion);
3785 this->EnterContributingSurface(unprevented, &occlusion, false);
3787 // This contributing surface is fully occluded.
3788 EXPECT_EQ(gfx::Rect().ToString(),
3789 occlusion.UnoccludedContributingSurfaceContentRect(
3790 unprevented,
3791 false, // is_replica
3792 gfx::Rect(50, 50)).ToString());
3794 this->LeaveContributingSurface(unprevented, &occlusion);
3798 ALL_OCCLUSIONTRACKER_TEST(
3799 OcclusionTrackerTestPreventOcclusionOnContributingSurface)
3801 template <class Types>
3802 class OcclusionTrackerTestScaledLayerIsClipped
3803 : public OcclusionTrackerTest<Types> {
3804 protected:
3805 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
3806 : OcclusionTrackerTest<Types>(opaque_layers) {}
3807 void RunMyTest() {
3808 gfx::Transform scale_transform;
3809 scale_transform.Scale(512.0, 512.0);
3811 typename Types::ContentLayerType* parent = this->CreateRoot(
3812 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3813 typename Types::LayerType* clip = this->CreateLayer(parent,
3814 this->identity_matrix,
3815 gfx::PointF(10.f, 10.f),
3816 gfx::Size(50, 50));
3817 clip->SetMasksToBounds(true);
3818 typename Types::LayerType* scale = this->CreateLayer(
3819 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3820 typename Types::LayerType* scaled = this->CreateDrawingLayer(
3821 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3822 this->CalcDrawEtc(parent);
3824 TestOcclusionTrackerWithClip<typename Types::LayerType,
3825 typename Types::RenderSurfaceType> occlusion(
3826 gfx::Rect(0, 0, 1000, 1000));
3828 this->VisitLayer(scaled, &occlusion);
3830 EXPECT_EQ(gfx::Rect().ToString(),
3831 occlusion.occlusion_from_outside_target().ToString());
3832 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3833 occlusion.occlusion_from_inside_target().ToString());
3837 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
3839 template <class Types>
3840 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3841 : public OcclusionTrackerTest<Types> {
3842 protected:
3843 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
3844 : OcclusionTrackerTest<Types>(opaque_layers) {}
3845 void RunMyTest() {
3846 gfx::Transform scale_transform;
3847 scale_transform.Scale(512.0, 512.0);
3849 typename Types::ContentLayerType* parent = this->CreateRoot(
3850 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3851 typename Types::LayerType* clip = this->CreateLayer(parent,
3852 this->identity_matrix,
3853 gfx::PointF(10.f, 10.f),
3854 gfx::Size(50, 50));
3855 clip->SetMasksToBounds(true);
3856 typename Types::LayerType* surface = this->CreateDrawingSurface(
3857 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
3858 typename Types::LayerType* scale = this->CreateLayer(
3859 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3860 typename Types::LayerType* scaled = this->CreateDrawingLayer(
3861 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3862 this->CalcDrawEtc(parent);
3864 TestOcclusionTrackerWithClip<typename Types::LayerType,
3865 typename Types::RenderSurfaceType> occlusion(
3866 gfx::Rect(0, 0, 1000, 1000));
3868 this->VisitLayer(scaled, &occlusion);
3869 this->VisitLayer(surface, &occlusion);
3870 this->VisitContributingSurface(surface, &occlusion);
3872 EXPECT_EQ(gfx::Rect().ToString(),
3873 occlusion.occlusion_from_outside_target().ToString());
3874 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3875 occlusion.occlusion_from_inside_target().ToString());
3879 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
3881 template <class Types>
3882 class OcclusionTrackerTestCopyRequestDoesOcclude
3883 : public OcclusionTrackerTest<Types> {
3884 protected:
3885 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
3886 : OcclusionTrackerTest<Types>(opaque_layers) {}
3887 void RunMyTest() {
3888 typename Types::ContentLayerType* root = this->CreateRoot(
3889 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3890 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3891 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3892 typename Types::LayerType* copy = this->CreateLayer(parent,
3893 this->identity_matrix,
3894 gfx::Point(100, 0),
3895 gfx::Size(200, 400));
3896 this->AddCopyRequest(copy);
3897 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3898 copy,
3899 this->identity_matrix,
3900 gfx::PointF(),
3901 gfx::Size(200, 400),
3902 true);
3903 this->CalcDrawEtc(root);
3905 TestOcclusionTrackerWithClip<typename Types::LayerType,
3906 typename Types::RenderSurfaceType> occlusion(
3907 gfx::Rect(0, 0, 1000, 1000));
3909 this->VisitLayer(copy_child, &occlusion);
3910 EXPECT_EQ(gfx::Rect().ToString(),
3911 occlusion.occlusion_from_outside_target().ToString());
3912 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3913 occlusion.occlusion_from_inside_target().ToString());
3915 // CopyRequests cause the layer to own a surface.
3916 this->VisitContributingSurface(copy, &occlusion);
3918 // The occlusion from the copy should be kept.
3919 EXPECT_EQ(gfx::Rect().ToString(),
3920 occlusion.occlusion_from_outside_target().ToString());
3921 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3922 occlusion.occlusion_from_inside_target().ToString());
3926 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
3928 template <class Types>
3929 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3930 : public OcclusionTrackerTest<Types> {
3931 protected:
3932 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3933 bool opaque_layers)
3934 : OcclusionTrackerTest<Types>(opaque_layers) {}
3935 void RunMyTest() {
3936 typename Types::ContentLayerType* root = this->CreateRoot(
3937 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3938 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3939 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3940 typename Types::LayerType* hide = this->CreateLayer(
3941 parent, this->identity_matrix, gfx::Point(), gfx::Size());
3942 typename Types::LayerType* copy = this->CreateLayer(
3943 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
3944 this->AddCopyRequest(copy);
3945 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3946 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
3948 // The |copy| layer is hidden but since it is being copied, it will be
3949 // drawn.
3950 hide->SetHideLayerAndSubtree(true);
3952 this->CalcDrawEtc(root);
3954 TestOcclusionTrackerWithClip<typename Types::LayerType,
3955 typename Types::RenderSurfaceType> occlusion(
3956 gfx::Rect(0, 0, 1000, 1000));
3958 this->VisitLayer(copy_child, &occlusion);
3959 EXPECT_EQ(gfx::Rect().ToString(),
3960 occlusion.occlusion_from_outside_target().ToString());
3961 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3962 occlusion.occlusion_from_inside_target().ToString());
3964 // CopyRequests cause the layer to own a surface.
3965 this->VisitContributingSurface(copy, &occlusion);
3967 // The occlusion from the copy should be dropped since it is hidden.
3968 EXPECT_EQ(gfx::Rect().ToString(),
3969 occlusion.occlusion_from_outside_target().ToString());
3970 EXPECT_EQ(gfx::Rect().ToString(),
3971 occlusion.occlusion_from_inside_target().ToString());
3975 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
3977 template <class Types>
3978 class OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
3979 : public OcclusionTrackerTest<Types> {
3980 protected:
3981 explicit OcclusionTrackerTestEmptyEventLayerDoesNotOcclude(
3982 bool opaque_layers)
3983 : OcclusionTrackerTest<Types>(opaque_layers) {}
3984 void RunMyTest() {
3985 typename Types::ContentLayerType* root = this->CreateRoot(
3986 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3987 typename Types::ContentLayerType* empty_layer = this->CreateDrawingLayer(
3988 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), true);
3989 this->SetDrawsContent(empty_layer, false);
3990 empty_layer->SetTouchEventHandlerRegion(gfx::Rect(10, 10, 10, 10));
3992 this->CalcDrawEtc(root);
3994 TestOcclusionTrackerWithClip<typename Types::LayerType,
3995 typename Types::RenderSurfaceType> occlusion(
3996 gfx::Rect(0, 0, 1000, 1000), false);
3998 this->VisitLayer(empty_layer, &occlusion);
4000 EXPECT_EQ(gfx::Rect().ToString(),
4001 occlusion.occlusion_from_outside_target().ToString());
4002 EXPECT_EQ(gfx::Rect().ToString(),
4003 occlusion.occlusion_from_inside_target().ToString());
4007 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude)
4009 } // namespace
4010 } // namespace cc