Fix revert "[chromeos] Remove dependencies of StatisticsProvider on chrome."
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob72e0ea052d025a3b0c200a5a85d0df529533c2f2
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/test/animation_test_common.h"
13 #include "cc/test/fake_impl_proxy.h"
14 #include "cc/test/fake_layer_tree_host_impl.h"
15 #include "cc/test/geometry_test_utils.h"
16 #include "cc/test/occlusion_tracker_test_common.h"
17 #include "cc/trees/layer_tree_host_common.h"
18 #include "cc/trees/single_thread_proxy.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.h"
22 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h"
23 #include "ui/gfx/transform.h"
25 namespace cc {
26 namespace {
28 class TestContentLayer : public Layer {
29 public:
30 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {}
32 virtual bool DrawsContent() const OVERRIDE { return true; }
33 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
34 if (override_opaque_contents_rect_)
35 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
36 return Layer::VisibleContentOpaqueRegion();
38 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
39 override_opaque_contents_rect_ = true;
40 opaque_contents_rect_ = opaque_contents_rect;
43 private:
44 virtual ~TestContentLayer() {}
46 bool override_opaque_contents_rect_;
47 gfx::Rect opaque_contents_rect_;
50 class TestContentLayerImpl : public LayerImpl {
51 public:
52 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
53 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
54 SetDrawsContent(true);
57 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
58 if (override_opaque_contents_rect_)
59 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
60 return LayerImpl::VisibleContentOpaqueRegion();
62 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
63 override_opaque_contents_rect_ = true;
64 opaque_contents_rect_ = opaque_contents_rect;
67 private:
68 bool override_opaque_contents_rect_;
69 gfx::Rect opaque_contents_rect_;
72 static inline bool LayerImplDrawTransformIsUnknown(const Layer* layer) {
73 return layer->draw_transform_is_animating();
75 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl* layer) {
76 return false;
79 template <typename LayerType, typename RenderSurfaceType>
80 class TestOcclusionTrackerWithClip
81 : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> {
82 public:
83 TestOcclusionTrackerWithClip(gfx::Rect viewport_rect,
84 bool record_metrics_for_frame)
85 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(
86 viewport_rect,
87 record_metrics_for_frame) {}
88 explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect)
89 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewport_rect,
90 false) {}
92 bool OccludedLayer(const LayerType* layer, gfx::Rect content_rect) {
93 bool temp;
94 return OccludedLayer(layer, content_rect, &temp);
97 bool OccludedLayer(const LayerType* layer,
98 gfx::Rect content_rect,
99 bool* has_occlusion_from_outside_target_surface) const {
100 return this->Occluded(layer->render_target(),
101 content_rect,
102 layer->draw_transform(),
103 LayerImplDrawTransformIsUnknown(layer),
104 layer->is_clipped(),
105 layer->clip_rect(),
106 has_occlusion_from_outside_target_surface);
108 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
109 // layer. Simple wrapper around UnoccludedContentRect.
110 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
111 gfx::Rect content_rect) const {
112 bool temp;
113 return UnoccludedLayerContentRect(layer, content_rect, &temp);
116 gfx::Rect UnoccludedLayerContentRect(
117 const LayerType* layer,
118 gfx::Rect content_rect,
119 bool* has_occlusion_from_outside_target_surface) const {
120 return this->UnoccludedContentRect(
121 layer->render_target(),
122 content_rect,
123 layer->draw_transform(),
124 LayerImplDrawTransformIsUnknown(layer),
125 layer->is_clipped(),
126 layer->clip_rect(),
127 has_occlusion_from_outside_target_surface);
131 struct OcclusionTrackerTestMainThreadTypes {
132 typedef Layer LayerType;
133 typedef LayerTreeHost HostType;
134 typedef RenderSurface RenderSurfaceType;
135 typedef TestContentLayer ContentLayerType;
136 typedef scoped_refptr<Layer> LayerPtrType;
137 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
138 typedef LayerIterator<Layer,
139 LayerList,
140 RenderSurface,
141 LayerIteratorActions::FrontToBack> TestLayerIterator;
142 typedef OcclusionTracker OcclusionTrackerType;
144 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
145 static ContentLayerPtrType CreateContentLayer(HostType* host) {
146 return make_scoped_refptr(new ContentLayerType());
149 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
150 LayerPtrType ref(*layer);
151 *layer = NULL;
152 return ref;
155 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
156 LayerPtrType ref(*layer);
157 *layer = NULL;
158 return ref;
161 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
164 struct OcclusionTrackerTestImplThreadTypes {
165 typedef LayerImpl LayerType;
166 typedef LayerTreeImpl HostType;
167 typedef RenderSurfaceImpl RenderSurfaceType;
168 typedef TestContentLayerImpl ContentLayerType;
169 typedef scoped_ptr<LayerImpl> LayerPtrType;
170 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
171 typedef LayerIterator<LayerImpl,
172 LayerImplList,
173 RenderSurfaceImpl,
174 LayerIteratorActions::FrontToBack> TestLayerIterator;
175 typedef OcclusionTrackerImpl OcclusionTrackerType;
177 static LayerPtrType CreateLayer(HostType* host) {
178 return LayerImpl::Create(host, next_layer_impl_id++);
180 static ContentLayerPtrType CreateContentLayer(HostType* host) {
181 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
183 static int next_layer_impl_id;
185 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
186 return layer->Pass();
189 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
190 return layer->PassAs<LayerType>();
193 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
196 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
198 template <typename Types> class OcclusionTrackerTest : public testing::Test {
199 protected:
200 explicit OcclusionTrackerTest(bool opaque_layers)
201 : host_impl_(&proxy_), opaque_layers_(opaque_layers) {}
203 virtual void RunMyTest() = 0;
205 virtual void TearDown() {
206 Types::DestroyLayer(&root_);
207 render_surface_layer_list_.clear();
208 render_surface_layer_list_impl_.clear();
209 replica_layers_.clear();
210 mask_layers_.clear();
213 typename Types::HostType* GetHost();
215 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
216 gfx::PointF position,
217 gfx::Size bounds) {
218 typename Types::ContentLayerPtrType layer(
219 Types::CreateContentLayer(GetHost()));
220 typename Types::ContentLayerType* layer_ptr = layer.get();
221 SetProperties(layer_ptr, transform, position, bounds);
223 DCHECK(!root_);
224 root_ = Types::PassLayerPtr(&layer);
225 return layer_ptr;
228 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
229 const gfx::Transform& transform,
230 gfx::PointF position,
231 gfx::Size bounds) {
232 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
233 typename Types::LayerType* layer_ptr = layer.get();
234 SetProperties(layer_ptr, transform, position, bounds);
235 parent->AddChild(Types::PassLayerPtr(&layer));
236 return layer_ptr;
239 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
240 const gfx::Transform& transform,
241 gfx::PointF position,
242 gfx::Size bounds) {
243 typename Types::LayerType* layer =
244 CreateLayer(parent, transform, position, bounds);
245 layer->SetForceRenderSurface(true);
246 return layer;
249 typename Types::ContentLayerType* CreateDrawingLayer(
250 typename Types::LayerType* parent,
251 const gfx::Transform& transform,
252 gfx::PointF position,
253 gfx::Size bounds,
254 bool opaque) {
255 typename Types::ContentLayerPtrType layer(
256 Types::CreateContentLayer(GetHost()));
257 typename Types::ContentLayerType* layer_ptr = layer.get();
258 SetProperties(layer_ptr, transform, position, bounds);
260 if (opaque_layers_) {
261 layer_ptr->SetContentsOpaque(opaque);
262 } else {
263 layer_ptr->SetContentsOpaque(false);
264 if (opaque)
265 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
266 else
267 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
270 parent->AddChild(Types::PassLayerPtr(&layer));
271 return layer_ptr;
274 typename Types::LayerType* CreateReplicaLayer(
275 typename Types::LayerType* owning_layer,
276 const gfx::Transform& transform,
277 gfx::PointF position,
278 gfx::Size bounds) {
279 typename Types::ContentLayerPtrType layer(
280 Types::CreateContentLayer(GetHost()));
281 typename Types::ContentLayerType* layer_ptr = layer.get();
282 SetProperties(layer_ptr, transform, position, bounds);
283 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
284 return layer_ptr;
287 typename Types::LayerType* CreateMaskLayer(
288 typename Types::LayerType* owning_layer,
289 gfx::Size bounds) {
290 typename Types::ContentLayerPtrType layer(
291 Types::CreateContentLayer(GetHost()));
292 typename Types::ContentLayerType* layer_ptr = layer.get();
293 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
294 SetMask(owning_layer, Types::PassLayerPtr(&layer));
295 return layer_ptr;
298 typename Types::ContentLayerType* CreateDrawingSurface(
299 typename Types::LayerType* parent,
300 const gfx::Transform& transform,
301 gfx::PointF position,
302 gfx::Size bounds,
303 bool opaque) {
304 typename Types::ContentLayerType* layer =
305 CreateDrawingLayer(parent, transform, position, bounds, opaque);
306 layer->SetForceRenderSurface(true);
307 return layer;
310 void CalcDrawEtc(TestContentLayerImpl* root) {
311 DCHECK(root == root_.get());
312 int dummy_max_texture_size = 512;
314 DCHECK(!root->render_surface());
316 LayerTreeHostCommon::CalculateDrawProperties(
317 root,
318 root->bounds(),
319 1.f,
320 1.f,
321 NULL,
322 dummy_max_texture_size,
323 false,
324 &render_surface_layer_list_impl_,
325 false);
327 layer_iterator_ = layer_iterator_begin_ =
328 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
331 void CalcDrawEtc(TestContentLayer* root) {
332 DCHECK(root == root_.get());
333 int dummy_max_texture_size = 512;
335 DCHECK(!root->render_surface());
337 LayerTreeHostCommon::CalculateDrawProperties(root,
338 root->bounds(),
339 1.f,
340 1.f,
341 NULL,
342 dummy_max_texture_size,
343 false,
344 &render_surface_layer_list_);
346 layer_iterator_ = layer_iterator_begin_ =
347 Types::TestLayerIterator::Begin(&render_surface_layer_list_);
350 void EnterLayer(typename Types::LayerType* layer,
351 typename Types::OcclusionTrackerType* occlusion,
352 bool prevent_occlusion) {
353 ASSERT_EQ(layer, *layer_iterator_);
354 ASSERT_TRUE(layer_iterator_.represents_itself());
355 occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
358 void LeaveLayer(typename Types::LayerType* layer,
359 typename Types::OcclusionTrackerType* occlusion) {
360 ASSERT_EQ(layer, *layer_iterator_);
361 ASSERT_TRUE(layer_iterator_.represents_itself());
362 occlusion->LeaveLayer(layer_iterator_);
363 ++layer_iterator_;
366 void VisitLayer(typename Types::LayerType* layer,
367 typename Types::OcclusionTrackerType* occlusion) {
368 EnterLayer(layer, occlusion, false);
369 LeaveLayer(layer, occlusion);
372 void EnterContributingSurface(
373 typename Types::LayerType* layer,
374 typename Types::OcclusionTrackerType* occlusion,
375 bool prevent_occlusion) {
376 ASSERT_EQ(layer, *layer_iterator_);
377 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
378 occlusion->EnterLayer(layer_iterator_, false);
379 occlusion->LeaveLayer(layer_iterator_);
380 ++layer_iterator_;
381 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
382 occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
385 void LeaveContributingSurface(
386 typename Types::LayerType* layer,
387 typename Types::OcclusionTrackerType* occlusion) {
388 ASSERT_EQ(layer, *layer_iterator_);
389 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
390 occlusion->LeaveLayer(layer_iterator_);
391 ++layer_iterator_;
394 void VisitContributingSurface(
395 typename Types::LayerType* layer,
396 typename Types::OcclusionTrackerType* occlusion) {
397 EnterContributingSurface(layer, occlusion, false);
398 LeaveContributingSurface(layer, occlusion);
401 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
403 const gfx::Transform identity_matrix;
405 private:
406 void SetBaseProperties(typename Types::LayerType* layer,
407 const gfx::Transform& transform,
408 gfx::PointF position,
409 gfx::Size bounds) {
410 layer->SetTransform(transform);
411 layer->SetSublayerTransform(gfx::Transform());
412 layer->SetAnchorPoint(gfx::PointF());
413 layer->SetPosition(position);
414 layer->SetBounds(bounds);
417 void SetProperties(Layer* layer,
418 const gfx::Transform& transform,
419 gfx::PointF position,
420 gfx::Size bounds) {
421 SetBaseProperties(layer, transform, position, bounds);
424 void SetProperties(LayerImpl* layer,
425 const gfx::Transform& transform,
426 gfx::PointF position,
427 gfx::Size bounds) {
428 SetBaseProperties(layer, transform, position, bounds);
430 layer->SetContentBounds(layer->bounds());
433 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
434 owning_layer->SetReplicaLayer(layer.get());
435 replica_layers_.push_back(layer);
438 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
439 owning_layer->SetReplicaLayer(layer.Pass());
442 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
443 owning_layer->SetMaskLayer(layer.get());
444 mask_layers_.push_back(layer);
447 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
448 owning_layer->SetMaskLayer(layer.Pass());
451 FakeImplProxy proxy_;
452 FakeLayerTreeHostImpl host_impl_;
453 bool opaque_layers_;
454 // These hold ownership of the layers for the duration of the test.
455 typename Types::LayerPtrType root_;
456 LayerList render_surface_layer_list_;
457 LayerImplList render_surface_layer_list_impl_;
458 typename Types::TestLayerIterator layer_iterator_begin_;
459 typename Types::TestLayerIterator layer_iterator_;
460 typename Types::LayerType* last_layer_visited_;
461 LayerList replica_layers_;
462 LayerList mask_layers_;
465 template <>
466 LayerTreeHost*
467 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
468 return NULL;
471 template <>
472 LayerTreeImpl*
473 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
474 return host_impl_.active_tree();
477 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
478 class ClassName##MainThreadOpaqueLayers \
479 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
480 public: /* NOLINT(whitespace/indent) */ \
481 ClassName##MainThreadOpaqueLayers() \
482 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
483 }; \
484 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
485 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
486 class ClassName##MainThreadOpaquePaints \
487 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
488 public: /* NOLINT(whitespace/indent) */ \
489 ClassName##MainThreadOpaquePaints() \
490 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
491 }; \
492 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
494 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
495 class ClassName##ImplThreadOpaqueLayers \
496 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
497 public: /* NOLINT(whitespace/indent) */ \
498 ClassName##ImplThreadOpaqueLayers() \
499 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
500 }; \
501 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
502 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
503 class ClassName##ImplThreadOpaquePaints \
504 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
505 public: /* NOLINT(whitespace/indent) */ \
506 ClassName##ImplThreadOpaquePaints() \
507 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
508 }; \
509 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
511 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
512 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
513 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
514 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
515 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
517 #define MAIN_THREAD_TEST(ClassName) \
518 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
520 #define IMPL_THREAD_TEST(ClassName) \
521 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
523 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
524 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
525 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
527 template <class Types>
528 class OcclusionTrackerTestIdentityTransforms
529 : public OcclusionTrackerTest<Types> {
530 protected:
531 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
532 : OcclusionTrackerTest<Types>(opaque_layers) {}
534 void RunMyTest() {
535 typename Types::ContentLayerType* root = this->CreateRoot(
536 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
537 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
538 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
539 typename Types::ContentLayerType* layer =
540 this->CreateDrawingLayer(parent,
541 this->identity_matrix,
542 gfx::PointF(30.f, 30.f),
543 gfx::Size(500, 500),
544 true);
545 parent->SetMasksToBounds(true);
546 this->CalcDrawEtc(root);
548 TestOcclusionTrackerWithClip<typename Types::LayerType,
549 typename Types::RenderSurfaceType> occlusion(
550 gfx::Rect(0, 0, 1000, 1000), false);
552 this->VisitLayer(layer, &occlusion);
553 this->EnterLayer(parent, &occlusion, false);
555 EXPECT_EQ(gfx::Rect().ToString(),
556 occlusion.occlusion_from_outside_target().ToString());
557 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
558 occlusion.occlusion_from_inside_target().ToString());
560 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
561 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
562 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
563 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
564 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
566 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
567 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
568 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
569 occlusion.UnoccludedLayerContentRect(
570 parent, gfx::Rect(29, 30, 70, 70)));
571 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
572 occlusion.UnoccludedLayerContentRect(
573 parent, gfx::Rect(29, 29, 70, 70)));
574 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
575 occlusion.UnoccludedLayerContentRect(
576 parent, gfx::Rect(30, 29, 70, 70)));
577 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
578 occlusion.UnoccludedLayerContentRect(
579 parent, gfx::Rect(31, 29, 70, 70)));
580 EXPECT_RECT_EQ(gfx::Rect(),
581 occlusion.UnoccludedLayerContentRect(
582 parent, gfx::Rect(31, 30, 70, 70)));
583 EXPECT_RECT_EQ(gfx::Rect(),
584 occlusion.UnoccludedLayerContentRect(
585 parent, gfx::Rect(31, 31, 70, 70)));
586 EXPECT_RECT_EQ(gfx::Rect(),
587 occlusion.UnoccludedLayerContentRect(
588 parent, gfx::Rect(30, 31, 70, 70)));
589 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
590 occlusion.UnoccludedLayerContentRect(
591 parent, gfx::Rect(29, 31, 70, 70)));
595 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
597 template <class Types>
598 class OcclusionTrackerTestQuadsMismatchLayer
599 : public OcclusionTrackerTest<Types> {
600 protected:
601 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
602 : OcclusionTrackerTest<Types>(opaque_layers) {}
603 void RunMyTest() {
604 gfx::Transform layer_transform;
605 layer_transform.Translate(10.0, 10.0);
607 typename Types::ContentLayerType* parent = this->CreateRoot(
608 this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
609 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
610 parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
611 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
612 layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
613 this->CalcDrawEtc(parent);
615 TestOcclusionTrackerWithClip<typename Types::LayerType,
616 typename Types::RenderSurfaceType> occlusion(
617 gfx::Rect(0, 0, 1000, 1000));
619 this->VisitLayer(layer2, &occlusion);
620 this->EnterLayer(layer1, &occlusion, false);
622 EXPECT_EQ(gfx::Rect().ToString(),
623 occlusion.occlusion_from_outside_target().ToString());
624 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
625 occlusion.occlusion_from_inside_target().ToString());
627 // This checks cases where the quads don't match their "containing"
628 // layers, e.g. in terms of transforms or clip rect. This is typical for
629 // DelegatedRendererLayer.
631 gfx::Transform quad_transform;
632 quad_transform.Translate(30.0, 30.0);
633 gfx::Rect clip_rect_in_target(0, 0, 100, 100);
635 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent,
636 gfx::Rect(0, 0, 10, 10),
637 quad_transform,
638 false,
639 true,
640 clip_rect_in_target,
641 NULL).IsEmpty());
642 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
643 occlusion.UnoccludedContentRect(parent,
644 gfx::Rect(0, 0, 10, 10),
645 quad_transform,
646 true,
647 true,
648 clip_rect_in_target,
649 NULL));
650 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
651 occlusion.UnoccludedContentRect(parent,
652 gfx::Rect(40, 40, 10, 10),
653 quad_transform,
654 false,
655 true,
656 clip_rect_in_target,
657 NULL));
658 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
659 occlusion.UnoccludedContentRect(parent,
660 gfx::Rect(35, 30, 10, 10),
661 quad_transform,
662 false,
663 true,
664 clip_rect_in_target,
665 NULL));
666 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5),
667 occlusion.UnoccludedContentRect(parent,
668 gfx::Rect(40, 40, 10, 10),
669 quad_transform,
670 false,
671 true,
672 gfx::Rect(0, 0, 75, 75),
673 NULL));
677 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
679 template <class Types>
680 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
681 protected:
682 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
683 : OcclusionTrackerTest<Types>(opaque_layers) {}
684 void RunMyTest() {
685 gfx::Transform layer_transform;
686 layer_transform.Translate(250.0, 250.0);
687 layer_transform.Rotate(90.0);
688 layer_transform.Translate(-250.0, -250.0);
690 typename Types::ContentLayerType* root = this->CreateRoot(
691 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
692 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
693 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
694 typename Types::ContentLayerType* layer =
695 this->CreateDrawingLayer(parent,
696 layer_transform,
697 gfx::PointF(30.f, 30.f),
698 gfx::Size(500, 500),
699 true);
700 parent->SetMasksToBounds(true);
701 this->CalcDrawEtc(root);
703 TestOcclusionTrackerWithClip<typename Types::LayerType,
704 typename Types::RenderSurfaceType> occlusion(
705 gfx::Rect(0, 0, 1000, 1000));
707 this->VisitLayer(layer, &occlusion);
708 this->EnterLayer(parent, &occlusion, false);
710 EXPECT_EQ(gfx::Rect().ToString(),
711 occlusion.occlusion_from_outside_target().ToString());
712 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
713 occlusion.occlusion_from_inside_target().ToString());
715 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
716 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
717 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
718 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
719 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
721 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
722 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
723 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
724 occlusion.UnoccludedLayerContentRect(
725 parent, gfx::Rect(29, 30, 70, 70)));
726 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
727 occlusion.UnoccludedLayerContentRect(
728 parent, gfx::Rect(29, 29, 70, 70)));
729 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
730 occlusion.UnoccludedLayerContentRect(
731 parent, gfx::Rect(30, 29, 70, 70)));
732 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
733 occlusion.UnoccludedLayerContentRect(
734 parent, gfx::Rect(31, 29, 70, 70)));
735 EXPECT_RECT_EQ(gfx::Rect(),
736 occlusion.UnoccludedLayerContentRect(
737 parent, gfx::Rect(31, 30, 70, 70)));
738 EXPECT_RECT_EQ(gfx::Rect(),
739 occlusion.UnoccludedLayerContentRect(
740 parent, gfx::Rect(31, 31, 70, 70)));
741 EXPECT_RECT_EQ(gfx::Rect(),
742 occlusion.UnoccludedLayerContentRect(
743 parent, gfx::Rect(30, 31, 70, 70)));
744 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
745 occlusion.UnoccludedLayerContentRect(
746 parent, gfx::Rect(29, 31, 70, 70)));
750 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
752 template <class Types>
753 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
754 protected:
755 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
756 : OcclusionTrackerTest<Types>(opaque_layers) {}
757 void RunMyTest() {
758 gfx::Transform layer_transform;
759 layer_transform.Translate(20.0, 20.0);
761 typename Types::ContentLayerType* root = this->CreateRoot(
762 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
763 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
764 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
765 typename Types::ContentLayerType* layer =
766 this->CreateDrawingLayer(parent,
767 layer_transform,
768 gfx::PointF(30.f, 30.f),
769 gfx::Size(500, 500),
770 true);
771 parent->SetMasksToBounds(true);
772 this->CalcDrawEtc(root);
774 TestOcclusionTrackerWithClip<typename Types::LayerType,
775 typename Types::RenderSurfaceType> occlusion(
776 gfx::Rect(0, 0, 1000, 1000));
778 this->VisitLayer(layer, &occlusion);
779 this->EnterLayer(parent, &occlusion, false);
781 EXPECT_EQ(gfx::Rect().ToString(),
782 occlusion.occlusion_from_outside_target().ToString());
783 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
784 occlusion.occlusion_from_inside_target().ToString());
786 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
787 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
788 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
789 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 50, 50)));
790 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 50)));
792 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
793 parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
794 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
795 occlusion.UnoccludedLayerContentRect(
796 parent, gfx::Rect(49, 50, 50, 50)));
797 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
798 occlusion.UnoccludedLayerContentRect(
799 parent, gfx::Rect(49, 49, 50, 50)));
800 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
801 occlusion.UnoccludedLayerContentRect(
802 parent, gfx::Rect(50, 49, 50, 50)));
803 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
804 occlusion.UnoccludedLayerContentRect(
805 parent, gfx::Rect(51, 49, 50, 50)));
806 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
807 parent, gfx::Rect(51, 50, 50, 50)).IsEmpty());
808 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
809 parent, gfx::Rect(51, 51, 50, 50)).IsEmpty());
810 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
811 parent, gfx::Rect(50, 51, 50, 50)).IsEmpty());
812 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
813 occlusion.UnoccludedLayerContentRect(
814 parent, gfx::Rect(49, 51, 50, 50)));
818 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
820 template <class Types>
821 class OcclusionTrackerTestChildInRotatedChild
822 : public OcclusionTrackerTest<Types> {
823 protected:
824 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
825 : OcclusionTrackerTest<Types>(opaque_layers) {}
826 void RunMyTest() {
827 gfx::Transform child_transform;
828 child_transform.Translate(250.0, 250.0);
829 child_transform.Rotate(90.0);
830 child_transform.Translate(-250.0, -250.0);
832 typename Types::ContentLayerType* parent = this->CreateRoot(
833 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
834 parent->SetMasksToBounds(true);
835 typename Types::LayerType* child = this->CreateLayer(
836 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
837 child->SetMasksToBounds(true);
838 typename Types::ContentLayerType* layer =
839 this->CreateDrawingLayer(child,
840 this->identity_matrix,
841 gfx::PointF(10.f, 10.f),
842 gfx::Size(500, 500),
843 true);
844 this->CalcDrawEtc(parent);
846 TestOcclusionTrackerWithClip<typename Types::LayerType,
847 typename Types::RenderSurfaceType> occlusion(
848 gfx::Rect(0, 0, 1000, 1000));
850 this->VisitLayer(layer, &occlusion);
851 this->EnterContributingSurface(child, &occlusion, false);
853 EXPECT_EQ(gfx::Rect().ToString(),
854 occlusion.occlusion_from_outside_target().ToString());
855 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
856 occlusion.occlusion_from_inside_target().ToString());
858 this->LeaveContributingSurface(child, &occlusion);
859 this->EnterLayer(parent, &occlusion, false);
861 EXPECT_EQ(gfx::Rect().ToString(),
862 occlusion.occlusion_from_outside_target().ToString());
863 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
864 occlusion.occlusion_from_inside_target().ToString());
866 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
867 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
868 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
869 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 70, 60)));
870 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 60)));
872 /* Justification for the above occlusion from |layer|:
874 +---------------------+
876 | 30 | rotate(90)
877 | 30 + ---------------------------------+
878 100 | | 10 | | ==>
879 | |10+---------------------------------+
880 | | | | | |
881 | | | | | |
882 | | | | | |
883 +----|--|-------------+ | |
884 | | | |
885 | | | |
886 | | | |500
887 | | | |
888 | | | |
889 | | | |
890 | | | |
891 +--|-------------------------------+ |
893 +---------------------------------+
896 +---------------------+
897 | |30 Visible region of |layer|: /////
899 | +---------------------------------+
900 100| | |10 |
901 | +---------------------------------+ |
902 | | |///////////////| 420 | |
903 | | |///////////////|60 | |
904 | | |///////////////| | |
905 +--|--|---------------+ | |
906 20|10| 70 | |
907 | | | |
908 | | | |
909 | | | |
910 | | | |
911 | | | |
912 | | |10|
913 | +------------------------------|--+
914 | 490 |
915 +---------------------------------+
922 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
924 template <class Types>
925 class OcclusionTrackerTestScaledRenderSurface
926 : public OcclusionTrackerTest<Types> {
927 protected:
928 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
929 : OcclusionTrackerTest<Types>(opaque_layers) {}
931 void RunMyTest() {
932 typename Types::ContentLayerType* parent = this->CreateRoot(
933 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
935 gfx::Transform layer1_matrix;
936 layer1_matrix.Scale(2.0, 2.0);
937 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
938 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
939 layer1->SetForceRenderSurface(true);
941 gfx::Transform layer2_matrix;
942 layer2_matrix.Translate(25.0, 25.0);
943 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
944 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
945 typename Types::ContentLayerType* occluder =
946 this->CreateDrawingLayer(parent,
947 this->identity_matrix,
948 gfx::PointF(100.f, 100.f),
949 gfx::Size(500, 500),
950 true);
951 this->CalcDrawEtc(parent);
953 TestOcclusionTrackerWithClip<typename Types::LayerType,
954 typename Types::RenderSurfaceType> occlusion(
955 gfx::Rect(0, 0, 1000, 1000));
957 this->VisitLayer(occluder, &occlusion);
958 this->EnterLayer(layer2, &occlusion, false);
960 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
961 occlusion.occlusion_from_outside_target().ToString());
962 EXPECT_EQ(gfx::Rect().ToString(),
963 occlusion.occlusion_from_inside_target().ToString());
965 EXPECT_RECT_EQ(
966 gfx::Rect(0, 0, 25, 25),
967 occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
968 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
969 occlusion.UnoccludedLayerContentRect(
970 layer2, gfx::Rect(10, 25, 25, 25)));
971 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
972 occlusion.UnoccludedLayerContentRect(
973 layer2, gfx::Rect(25, 10, 25, 25)));
974 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
975 layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
979 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
981 template <class Types>
982 class OcclusionTrackerTestVisitTargetTwoTimes
983 : public OcclusionTrackerTest<Types> {
984 protected:
985 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
986 : OcclusionTrackerTest<Types>(opaque_layers) {}
987 void RunMyTest() {
988 gfx::Transform child_transform;
989 child_transform.Translate(250.0, 250.0);
990 child_transform.Rotate(90.0);
991 child_transform.Translate(-250.0, -250.0);
993 typename Types::ContentLayerType* root = this->CreateRoot(
994 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
995 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
996 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
997 parent->SetMasksToBounds(true);
998 typename Types::LayerType* child = this->CreateLayer(
999 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1000 child->SetMasksToBounds(true);
1001 typename Types::ContentLayerType* layer =
1002 this->CreateDrawingLayer(child,
1003 this->identity_matrix,
1004 gfx::PointF(10.f, 10.f),
1005 gfx::Size(500, 500),
1006 true);
1007 // |child2| makes |parent|'s surface get considered by OcclusionTracker
1008 // first, instead of |child|'s. This exercises different code in
1009 // LeaveToRenderTarget, as the target surface has already been seen.
1010 typename Types::ContentLayerType* child2 =
1011 this->CreateDrawingLayer(parent,
1012 this->identity_matrix,
1013 gfx::PointF(30.f, 30.f),
1014 gfx::Size(60, 20),
1015 true);
1016 this->CalcDrawEtc(root);
1018 TestOcclusionTrackerWithClip<typename Types::LayerType,
1019 typename Types::RenderSurfaceType> occlusion(
1020 gfx::Rect(0, 0, 1000, 1000));
1022 this->VisitLayer(child2, &occlusion);
1024 EXPECT_EQ(gfx::Rect().ToString(),
1025 occlusion.occlusion_from_outside_target().ToString());
1026 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1027 occlusion.occlusion_from_inside_target().ToString());
1029 this->VisitLayer(layer, &occlusion);
1031 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1032 occlusion.occlusion_from_outside_target().ToString());
1033 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1034 occlusion.occlusion_from_inside_target().ToString());
1036 this->EnterContributingSurface(child, &occlusion, false);
1038 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1039 occlusion.occlusion_from_outside_target().ToString());
1040 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1041 occlusion.occlusion_from_inside_target().ToString());
1043 // Occlusion in |child2| should get merged with the |child| surface we are
1044 // leaving now.
1045 this->LeaveContributingSurface(child, &occlusion);
1046 this->EnterLayer(parent, &occlusion, false);
1048 EXPECT_EQ(gfx::Rect().ToString(),
1049 occlusion.occlusion_from_outside_target().ToString());
1050 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1051 .ToString(),
1052 occlusion.occlusion_from_inside_target().ToString());
1054 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
1055 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1056 occlusion.UnoccludedLayerContentRect(
1057 parent, gfx::Rect(30, 30, 70, 70)));
1059 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
1060 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
1061 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
1062 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
1063 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
1065 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1066 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1067 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1069 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1070 parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1071 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1072 occlusion.UnoccludedLayerContentRect(
1073 parent, gfx::Rect(29, 30, 60, 10)));
1074 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1075 occlusion.UnoccludedLayerContentRect(
1076 parent, gfx::Rect(30, 29, 60, 10)));
1077 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1078 occlusion.UnoccludedLayerContentRect(
1079 parent, gfx::Rect(31, 30, 60, 10)));
1080 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1081 parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1083 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1084 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1085 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1086 occlusion.UnoccludedLayerContentRect(
1087 parent, gfx::Rect(29, 40, 70, 60)));
1088 // This rect is mostly occluded by |child2|.
1089 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1090 occlusion.UnoccludedLayerContentRect(
1091 parent, gfx::Rect(30, 39, 70, 60)));
1092 // This rect extends past top/right ends of |child2|.
1093 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1094 occlusion.UnoccludedLayerContentRect(
1095 parent, gfx::Rect(30, 29, 70, 70)));
1096 // This rect extends past left/right ends of |child2|.
1097 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1098 occlusion.UnoccludedLayerContentRect(
1099 parent, gfx::Rect(20, 39, 80, 60)));
1100 EXPECT_RECT_EQ(gfx::Rect(),
1101 occlusion.UnoccludedLayerContentRect(
1102 parent, gfx::Rect(31, 40, 70, 60)));
1103 EXPECT_RECT_EQ(gfx::Rect(),
1104 occlusion.UnoccludedLayerContentRect(
1105 parent, gfx::Rect(30, 41, 70, 60)));
1107 /* Justification for the above occlusion from |layer|:
1109 +---------------------+
1111 | 30 | rotate(90)
1112 | 30 + ------------+--------------------+
1113 100 | | 10 | | | ==>
1114 | |10+----------|----------------------+
1115 | + ------------+ | | |
1116 | | | | | |
1117 | | | | | |
1118 +----|--|-------------+ | |
1119 | | | |
1120 | | | |
1121 | | | |500
1122 | | | |
1123 | | | |
1124 | | | |
1125 | | | |
1126 +--|-------------------------------+ |
1128 +---------------------------------+
1132 +---------------------+
1133 | |30 Visible region of |layer|: /////
1134 | 30 60 | |child2|: \\\\\
1135 | 30 +------------+--------------------+
1136 | |\\\\\\\\\\\\| |10 |
1137 | +--|\\\\\\\\\\\\|-----------------+ |
1138 | | +------------+//| 420 | |
1139 | | |///////////////|60 | |
1140 | | |///////////////| | |
1141 +--|--|---------------+ | |
1142 20|10| 70 | |
1143 | | | |
1144 | | | |
1145 | | | |
1146 | | | |
1147 | | | |
1148 | | |10|
1149 | +------------------------------|--+
1150 | 490 |
1151 +---------------------------------+
1157 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
1159 template <class Types>
1160 class OcclusionTrackerTestSurfaceRotatedOffAxis
1161 : public OcclusionTrackerTest<Types> {
1162 protected:
1163 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
1164 : OcclusionTrackerTest<Types>(opaque_layers) {}
1165 void RunMyTest() {
1166 gfx::Transform child_transform;
1167 child_transform.Translate(250.0, 250.0);
1168 child_transform.Rotate(95.0);
1169 child_transform.Translate(-250.0, -250.0);
1171 gfx::Transform layer_transform;
1172 layer_transform.Translate(10.0, 10.0);
1174 typename Types::ContentLayerType* root = this->CreateRoot(
1175 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1176 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1177 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1178 typename Types::LayerType* child = this->CreateLayer(
1179 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1180 child->SetMasksToBounds(true);
1181 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1182 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
1183 this->CalcDrawEtc(root);
1185 TestOcclusionTrackerWithClip<typename Types::LayerType,
1186 typename Types::RenderSurfaceType> occlusion(
1187 gfx::Rect(0, 0, 1000, 1000));
1189 gfx::Rect clipped_layer_in_child = MathUtil::MapClippedRect(
1190 layer_transform, layer->visible_content_rect());
1192 this->VisitLayer(layer, &occlusion);
1193 this->EnterContributingSurface(child, &occlusion, false);
1195 EXPECT_EQ(gfx::Rect().ToString(),
1196 occlusion.occlusion_from_outside_target().ToString());
1197 EXPECT_EQ(clipped_layer_in_child.ToString(),
1198 occlusion.occlusion_from_inside_target().ToString());
1200 this->LeaveContributingSurface(child, &occlusion);
1201 this->EnterLayer(parent, &occlusion, false);
1203 EXPECT_EQ(gfx::Rect().ToString(),
1204 occlusion.occlusion_from_outside_target().ToString());
1205 EXPECT_EQ(gfx::Rect().ToString(),
1206 occlusion.occlusion_from_inside_target().ToString());
1208 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
1209 EXPECT_RECT_EQ(
1210 gfx::Rect(75, 55, 1, 1),
1211 occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
1215 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
1217 template <class Types>
1218 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1219 : public OcclusionTrackerTest<Types> {
1220 protected:
1221 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
1222 : OcclusionTrackerTest<Types>(opaque_layers) {}
1223 void RunMyTest() {
1224 gfx::Transform child_transform;
1225 child_transform.Translate(250.0, 250.0);
1226 child_transform.Rotate(90.0);
1227 child_transform.Translate(-250.0, -250.0);
1229 typename Types::ContentLayerType* root = this->CreateRoot(
1230 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1231 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1232 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1233 parent->SetMasksToBounds(true);
1234 typename Types::ContentLayerType* child =
1235 this->CreateDrawingLayer(parent,
1236 child_transform,
1237 gfx::PointF(30.f, 30.f),
1238 gfx::Size(500, 500),
1239 false);
1240 child->SetMasksToBounds(true);
1241 typename Types::ContentLayerType* layer1 =
1242 this->CreateDrawingLayer(child,
1243 this->identity_matrix,
1244 gfx::PointF(10.f, 10.f),
1245 gfx::Size(500, 500),
1246 true);
1247 typename Types::ContentLayerType* layer2 =
1248 this->CreateDrawingLayer(child,
1249 this->identity_matrix,
1250 gfx::PointF(10.f, 450.f),
1251 gfx::Size(500, 60),
1252 true);
1253 this->CalcDrawEtc(root);
1255 TestOcclusionTrackerWithClip<typename Types::LayerType,
1256 typename Types::RenderSurfaceType> occlusion(
1257 gfx::Rect(0, 0, 1000, 1000));
1259 this->VisitLayer(layer2, &occlusion);
1260 this->VisitLayer(layer1, &occlusion);
1261 this->VisitLayer(child, &occlusion);
1262 this->EnterContributingSurface(child, &occlusion, false);
1264 EXPECT_EQ(gfx::Rect().ToString(),
1265 occlusion.occlusion_from_outside_target().ToString());
1266 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1267 occlusion.occlusion_from_inside_target().ToString());
1269 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
1270 EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
1271 // These rects are occluded except for the part outside the bounds of the
1272 // target surface.
1273 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 429, 60, 70)));
1274 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 60, 70)));
1275 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 70)));
1277 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1278 child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1279 EXPECT_RECT_EQ(
1280 gfx::Rect(9, 430, 1, 70),
1281 occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
1282 // These rects are occluded except for the part outside the bounds of the
1283 // target surface.
1284 EXPECT_RECT_EQ(gfx::Rect(),
1285 occlusion.UnoccludedLayerContentRect(
1286 child, gfx::Rect(10, 429, 60, 70)));
1287 EXPECT_RECT_EQ(gfx::Rect(),
1288 occlusion.UnoccludedLayerContentRect(
1289 child, gfx::Rect(11, 430, 60, 70)));
1290 EXPECT_RECT_EQ(gfx::Rect(),
1291 occlusion.UnoccludedLayerContentRect(
1292 child, gfx::Rect(10, 431, 60, 70)));
1294 this->LeaveContributingSurface(child, &occlusion);
1295 this->EnterLayer(parent, &occlusion, false);
1297 EXPECT_EQ(gfx::Rect().ToString(),
1298 occlusion.occlusion_from_outside_target().ToString());
1299 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1300 occlusion.occlusion_from_inside_target().ToString());
1302 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1303 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1304 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1306 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1307 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1308 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1309 occlusion.UnoccludedLayerContentRect(
1310 parent, gfx::Rect(29, 40, 70, 60)));
1311 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1312 occlusion.UnoccludedLayerContentRect(
1313 parent, gfx::Rect(30, 39, 70, 60)));
1314 EXPECT_RECT_EQ(gfx::Rect(),
1315 occlusion.UnoccludedLayerContentRect(
1316 parent, gfx::Rect(31, 40, 70, 60)));
1317 EXPECT_RECT_EQ(gfx::Rect(),
1318 occlusion.UnoccludedLayerContentRect(
1319 parent, gfx::Rect(30, 41, 70, 60)));
1321 /* Justification for the above occlusion from |layer1| and |layer2|:
1323 +---------------------+
1324 | |30 Visible region of |layer1|: /////
1325 | | Visible region of |layer2|: \\\\\
1326 | +---------------------------------+
1327 | | |10 |
1328 | +---------------+-----------------+ |
1329 | | |\\\\\\\\\\\\|//| 420 | |
1330 | | |\\\\\\\\\\\\|//|60 | |
1331 | | |\\\\\\\\\\\\|//| | |
1332 +--|--|------------|--+ | |
1333 20|10| 70 | | |
1334 | | | | |
1335 | | | | |
1336 | | | | |
1337 | | | | |
1338 | | | | |
1339 | | | |10|
1340 | +------------|-----------------|--+
1341 | | 490 |
1342 +---------------+-----------------+
1343 60 440
1348 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1350 template <class Types>
1351 class OcclusionTrackerTestOverlappingSurfaceSiblings
1352 : public OcclusionTrackerTest<Types> {
1353 protected:
1354 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
1355 : OcclusionTrackerTest<Types>(opaque_layers) {}
1356 void RunMyTest() {
1357 gfx::Transform child_transform;
1358 child_transform.Translate(250.0, 250.0);
1359 child_transform.Rotate(90.0);
1360 child_transform.Translate(-250.0, -250.0);
1362 typename Types::ContentLayerType* parent = this->CreateRoot(
1363 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1364 parent->SetMasksToBounds(true);
1365 typename Types::LayerType* child1 = this->CreateSurface(
1366 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
1367 typename Types::LayerType* child2 = this->CreateSurface(
1368 parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
1369 typename Types::ContentLayerType* layer1 =
1370 this->CreateDrawingLayer(child1,
1371 this->identity_matrix,
1372 gfx::PointF(-10.f, -10.f),
1373 gfx::Size(510, 510),
1374 true);
1375 typename Types::ContentLayerType* layer2 =
1376 this->CreateDrawingLayer(child2,
1377 this->identity_matrix,
1378 gfx::PointF(-10.f, -10.f),
1379 gfx::Size(510, 510),
1380 true);
1381 this->CalcDrawEtc(parent);
1383 TestOcclusionTrackerWithClip<typename Types::LayerType,
1384 typename Types::RenderSurfaceType> occlusion(
1385 gfx::Rect(0, 0, 1000, 1000));
1387 this->VisitLayer(layer2, &occlusion);
1388 this->EnterContributingSurface(child2, &occlusion, false);
1390 EXPECT_EQ(gfx::Rect().ToString(),
1391 occlusion.occlusion_from_outside_target().ToString());
1392 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1393 occlusion.occlusion_from_inside_target().ToString());
1395 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1396 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1397 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1398 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1399 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1401 // There is nothing above child2's surface in the z-order.
1402 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1403 occlusion.UnoccludedContributingSurfaceContentRect(
1404 child2, false, gfx::Rect(-10, 420, 70, 80), NULL));
1406 this->LeaveContributingSurface(child2, &occlusion);
1407 this->VisitLayer(layer1, &occlusion);
1408 this->EnterContributingSurface(child1, &occlusion, false);
1410 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1411 occlusion.occlusion_from_outside_target().ToString());
1412 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1413 occlusion.occlusion_from_inside_target().ToString());
1415 // child2's contents will occlude child1 below it.
1416 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1417 occlusion.UnoccludedContributingSurfaceContentRect(
1418 child1, false, gfx::Rect(-10, 430, 80, 70), NULL));
1420 this->LeaveContributingSurface(child1, &occlusion);
1421 this->EnterLayer(parent, &occlusion, false);
1423 EXPECT_EQ(gfx::Rect().ToString(),
1424 occlusion.occlusion_from_outside_target().ToString());
1425 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1426 .ToString(),
1427 occlusion.occlusion_from_inside_target().ToString());
1429 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1431 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1432 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1433 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1435 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1436 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1437 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1439 /* Justification for the above occlusion:
1441 +---------------------+
1442 | 20 | layer1
1443 | 30+ ---------------------------------+
1444 100 | 30| | layer2 |
1445 |20+----------------------------------+ |
1446 | | | | | |
1447 | | | | | |
1448 | | | | | |
1449 +--|-|----------------+ | |
1450 | | | | 510
1451 | | | |
1452 | | | |
1453 | | | |
1454 | | | |
1455 | | | |
1456 | | | |
1457 | +--------------------------------|-+
1459 +----------------------------------+
1465 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1467 template <class Types>
1468 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1469 : public OcclusionTrackerTest<Types> {
1470 protected:
1471 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1472 bool opaque_layers)
1473 : OcclusionTrackerTest<Types>(opaque_layers) {}
1474 void RunMyTest() {
1475 gfx::Transform child1_transform;
1476 child1_transform.Translate(250.0, 250.0);
1477 child1_transform.Rotate(-90.0);
1478 child1_transform.Translate(-250.0, -250.0);
1480 gfx::Transform child2_transform;
1481 child2_transform.Translate(250.0, 250.0);
1482 child2_transform.Rotate(90.0);
1483 child2_transform.Translate(-250.0, -250.0);
1485 typename Types::ContentLayerType* parent = this->CreateRoot(
1486 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1487 parent->SetMasksToBounds(true);
1488 typename Types::LayerType* child1 = this->CreateSurface(
1489 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1490 typename Types::LayerType* child2 =
1491 this->CreateDrawingSurface(parent,
1492 child2_transform,
1493 gfx::PointF(20.f, 40.f),
1494 gfx::Size(10, 10),
1495 false);
1496 typename Types::ContentLayerType* layer1 =
1497 this->CreateDrawingLayer(child1,
1498 this->identity_matrix,
1499 gfx::PointF(-10.f, -20.f),
1500 gfx::Size(510, 510),
1501 true);
1502 typename Types::ContentLayerType* layer2 =
1503 this->CreateDrawingLayer(child2,
1504 this->identity_matrix,
1505 gfx::PointF(-10.f, -10.f),
1506 gfx::Size(510, 510),
1507 true);
1508 this->CalcDrawEtc(parent);
1510 TestOcclusionTrackerWithClip<typename Types::LayerType,
1511 typename Types::RenderSurfaceType> occlusion(
1512 gfx::Rect(0, 0, 1000, 1000));
1514 this->VisitLayer(layer2, &occlusion);
1515 this->EnterLayer(child2, &occlusion, false);
1517 EXPECT_EQ(gfx::Rect().ToString(),
1518 occlusion.occlusion_from_outside_target().ToString());
1519 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1520 occlusion.occlusion_from_inside_target().ToString());
1522 this->LeaveLayer(child2, &occlusion);
1523 this->EnterContributingSurface(child2, &occlusion, false);
1525 // There is nothing above child2's surface in the z-order.
1526 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1527 occlusion.UnoccludedContributingSurfaceContentRect(
1528 child2, false, gfx::Rect(-10, 420, 70, 80), NULL));
1530 this->LeaveContributingSurface(child2, &occlusion);
1531 this->VisitLayer(layer1, &occlusion);
1532 this->EnterContributingSurface(child1, &occlusion, false);
1534 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1535 occlusion.occlusion_from_outside_target().ToString());
1536 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1537 occlusion.occlusion_from_inside_target().ToString());
1539 // child2's contents will occlude child1 below it.
1540 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1541 occlusion.UnoccludedContributingSurfaceContentRect(
1542 child1, false, gfx::Rect(420, -20, 80, 90), NULL));
1543 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1544 occlusion.UnoccludedContributingSurfaceContentRect(
1545 child1, false, gfx::Rect(420, -10, 80, 90), NULL));
1546 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1547 occlusion.UnoccludedContributingSurfaceContentRect(
1548 child1, false, gfx::Rect(420, -20, 70, 90), NULL));
1550 this->LeaveContributingSurface(child1, &occlusion);
1551 this->EnterLayer(parent, &occlusion, false);
1553 EXPECT_EQ(gfx::Rect().ToString(),
1554 occlusion.occlusion_from_outside_target().ToString());
1555 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1556 occlusion.occlusion_from_inside_target().ToString());
1558 /* Justification for the above occlusion:
1560 +---------------------+
1561 |20 | layer1
1562 10+----------------------------------+
1563 100 || 30 | layer2 |
1564 |20+----------------------------------+
1565 || | | | |
1566 || | | | |
1567 || | | | |
1568 +|-|------------------+ | |
1569 | | | | 510
1570 | | 510 | |
1571 | | | |
1572 | | | |
1573 | | | |
1574 | | | |
1575 | | 520 | |
1576 +----------------------------------+ |
1578 +----------------------------------+
1584 ALL_OCCLUSIONTRACKER_TEST(
1585 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1587 template <class Types>
1588 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1589 protected:
1590 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1591 : OcclusionTrackerTest<Types>(opaque_layers) {}
1592 void RunMyTest() {
1593 gfx::Transform layer_transform;
1594 layer_transform.Translate(250.0, 250.0);
1595 layer_transform.Rotate(90.0);
1596 layer_transform.Translate(-250.0, -250.0);
1598 typename Types::ContentLayerType* parent = this->CreateRoot(
1599 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1600 parent->SetMasksToBounds(true);
1601 typename Types::ContentLayerType* blur_layer =
1602 this->CreateDrawingLayer(parent,
1603 layer_transform,
1604 gfx::PointF(30.f, 30.f),
1605 gfx::Size(500, 500),
1606 true);
1607 typename Types::ContentLayerType* opaque_layer =
1608 this->CreateDrawingLayer(parent,
1609 layer_transform,
1610 gfx::PointF(30.f, 30.f),
1611 gfx::Size(500, 500),
1612 true);
1613 typename Types::ContentLayerType* opacity_layer =
1614 this->CreateDrawingLayer(parent,
1615 layer_transform,
1616 gfx::PointF(30.f, 30.f),
1617 gfx::Size(500, 500),
1618 true);
1620 WebKit::WebFilterOperations filters;
1621 filters.append(WebKit::WebFilterOperation::createBlurFilter(10.f));
1622 blur_layer->SetFilters(filters);
1624 filters.clear();
1625 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5f));
1626 opaque_layer->SetFilters(filters);
1628 filters.clear();
1629 filters.append(WebKit::WebFilterOperation::createOpacityFilter(0.5f));
1630 opacity_layer->SetFilters(filters);
1632 this->CalcDrawEtc(parent);
1634 TestOcclusionTrackerWithClip<typename Types::LayerType,
1635 typename Types::RenderSurfaceType> occlusion(
1636 gfx::Rect(0, 0, 1000, 1000));
1638 // Opacity layer won't contribute to occlusion.
1639 this->VisitLayer(opacity_layer, &occlusion);
1640 this->EnterContributingSurface(opacity_layer, &occlusion, false);
1642 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1643 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1645 // And has nothing to contribute to its parent surface.
1646 this->LeaveContributingSurface(opacity_layer, &occlusion);
1647 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1648 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1650 // Opaque layer will contribute to occlusion.
1651 this->VisitLayer(opaque_layer, &occlusion);
1652 this->EnterContributingSurface(opaque_layer, &occlusion, false);
1654 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1655 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1656 occlusion.occlusion_from_inside_target().ToString());
1658 // And it gets translated to the parent surface.
1659 this->LeaveContributingSurface(opaque_layer, &occlusion);
1660 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1661 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1662 occlusion.occlusion_from_inside_target().ToString());
1664 // The blur layer needs to throw away any occlusion from outside its
1665 // subtree.
1666 this->EnterLayer(blur_layer, &occlusion, false);
1667 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1668 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1670 // And it won't contribute to occlusion.
1671 this->LeaveLayer(blur_layer, &occlusion);
1672 this->EnterContributingSurface(blur_layer, &occlusion, false);
1673 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1674 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1676 // But the opaque layer's occlusion is preserved on the parent.
1677 this->LeaveContributingSurface(blur_layer, &occlusion);
1678 this->EnterLayer(parent, &occlusion, false);
1679 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1680 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1681 occlusion.occlusion_from_inside_target().ToString());
1685 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1687 template <class Types>
1688 class OcclusionTrackerTestReplicaDoesOcclude
1689 : public OcclusionTrackerTest<Types> {
1690 protected:
1691 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1692 : OcclusionTrackerTest<Types>(opaque_layers) {}
1693 void RunMyTest() {
1694 typename Types::ContentLayerType* parent = this->CreateRoot(
1695 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1696 typename Types::LayerType* surface =
1697 this->CreateDrawingSurface(parent,
1698 this->identity_matrix,
1699 gfx::PointF(0.f, 100.f),
1700 gfx::Size(50, 50),
1701 true);
1702 this->CreateReplicaLayer(
1703 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1704 this->CalcDrawEtc(parent);
1706 TestOcclusionTrackerWithClip<typename Types::LayerType,
1707 typename Types::RenderSurfaceType> occlusion(
1708 gfx::Rect(0, 0, 1000, 1000));
1710 this->VisitLayer(surface, &occlusion);
1712 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1713 occlusion.occlusion_from_inside_target().ToString());
1715 this->VisitContributingSurface(surface, &occlusion);
1716 this->EnterLayer(parent, &occlusion, false);
1718 // The surface and replica should both be occluding the parent.
1719 EXPECT_EQ(
1720 UnionRegions(gfx::Rect(0, 100, 50, 50),
1721 gfx::Rect(50, 150, 50, 50)).ToString(),
1722 occlusion.occlusion_from_inside_target().ToString());
1726 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1728 template <class Types>
1729 class OcclusionTrackerTestReplicaWithClipping
1730 : public OcclusionTrackerTest<Types> {
1731 protected:
1732 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1733 : OcclusionTrackerTest<Types>(opaque_layers) {}
1734 void RunMyTest() {
1735 typename Types::ContentLayerType* parent = this->CreateRoot(
1736 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1737 parent->SetMasksToBounds(true);
1738 typename Types::LayerType* surface =
1739 this->CreateDrawingSurface(parent,
1740 this->identity_matrix,
1741 gfx::PointF(0.f, 100.f),
1742 gfx::Size(50, 50),
1743 true);
1744 this->CreateReplicaLayer(
1745 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1746 this->CalcDrawEtc(parent);
1748 TestOcclusionTrackerWithClip<typename Types::LayerType,
1749 typename Types::RenderSurfaceType> occlusion(
1750 gfx::Rect(0, 0, 1000, 1000));
1752 this->VisitLayer(surface, &occlusion);
1754 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1755 occlusion.occlusion_from_inside_target().ToString());
1757 this->VisitContributingSurface(surface, &occlusion);
1758 this->EnterLayer(parent, &occlusion, false);
1760 // The surface and replica should both be occluding the parent.
1761 EXPECT_EQ(
1762 UnionRegions(gfx::Rect(0, 100, 50, 50),
1763 gfx::Rect(50, 150, 50, 20)).ToString(),
1764 occlusion.occlusion_from_inside_target().ToString());
1768 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1770 template <class Types>
1771 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1772 protected:
1773 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1774 : OcclusionTrackerTest<Types>(opaque_layers) {}
1775 void RunMyTest() {
1776 typename Types::ContentLayerType* parent = this->CreateRoot(
1777 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1778 typename Types::LayerType* surface =
1779 this->CreateDrawingSurface(parent,
1780 this->identity_matrix,
1781 gfx::PointF(0.f, 100.f),
1782 gfx::Size(50, 50),
1783 true);
1784 typename Types::LayerType* replica = this->CreateReplicaLayer(
1785 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1786 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1787 this->CalcDrawEtc(parent);
1789 TestOcclusionTrackerWithClip<typename Types::LayerType,
1790 typename Types::RenderSurfaceType> occlusion(
1791 gfx::Rect(0, 0, 1000, 1000));
1793 this->VisitLayer(surface, &occlusion);
1795 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1796 occlusion.occlusion_from_inside_target().ToString());
1798 this->VisitContributingSurface(surface, &occlusion);
1799 this->EnterLayer(parent, &occlusion, false);
1801 // The replica should not be occluding the parent, since it has a mask
1802 // applied to it.
1803 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1804 occlusion.occlusion_from_inside_target().ToString());
1808 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1810 template <class Types>
1811 class OcclusionTrackerTestLayerClipRectOutsideChild
1812 : public OcclusionTrackerTest<Types> {
1813 protected:
1814 explicit OcclusionTrackerTestLayerClipRectOutsideChild(bool opaque_layers)
1815 : OcclusionTrackerTest<Types>(opaque_layers) {}
1816 void RunMyTest() {
1817 typename Types::ContentLayerType* parent = this->CreateRoot(
1818 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1819 typename Types::ContentLayerType* clip =
1820 this->CreateDrawingLayer(parent,
1821 this->identity_matrix,
1822 gfx::PointF(200.f, 100.f),
1823 gfx::Size(100, 100),
1824 false);
1825 clip->SetMasksToBounds(true);
1826 typename Types::ContentLayerType* layer =
1827 this->CreateDrawingLayer(clip,
1828 this->identity_matrix,
1829 gfx::PointF(-200.f, -100.f),
1830 gfx::Size(200, 200),
1831 false);
1832 this->CalcDrawEtc(parent);
1834 TestOcclusionTrackerWithClip<typename Types::LayerType,
1835 typename Types::RenderSurfaceType> occlusion(
1836 gfx::Rect(0, 0, 1000, 1000));
1838 this->EnterLayer(layer, &occlusion, false);
1840 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1841 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1842 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1843 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1844 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1846 this->LeaveLayer(layer, &occlusion);
1847 this->EnterLayer(clip, &occlusion, false);
1849 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(-100, 0, 100, 100)));
1850 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, -100, 100, 100)));
1851 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100)));
1852 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100)));
1853 EXPECT_FALSE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100)));
1855 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
1856 occlusion.UnoccludedLayerContentRect(
1857 clip, gfx::Rect(-100, -100, 300, 300)));
1861 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild);
1863 template <class Types>
1864 class OcclusionTrackerTestViewportRectOutsideChild
1865 : public OcclusionTrackerTest<Types> {
1866 protected:
1867 explicit OcclusionTrackerTestViewportRectOutsideChild(bool opaque_layers)
1868 : OcclusionTrackerTest<Types>(opaque_layers) {}
1869 void RunMyTest() {
1870 typename Types::ContentLayerType* parent = this->CreateRoot(
1871 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1872 typename Types::ContentLayerType* layer =
1873 this->CreateDrawingSurface(parent,
1874 this->identity_matrix,
1875 gfx::PointF(),
1876 gfx::Size(200, 200),
1877 true);
1878 this->CalcDrawEtc(parent);
1880 TestOcclusionTrackerWithClip<typename Types::LayerType,
1881 typename Types::RenderSurfaceType> occlusion(
1882 gfx::Rect(200, 100, 100, 100));
1884 this->EnterLayer(layer, &occlusion, false);
1886 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1887 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1888 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1889 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1890 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1892 this->LeaveLayer(layer, &occlusion);
1893 this->VisitContributingSurface(layer, &occlusion);
1894 this->EnterLayer(parent, &occlusion, false);
1896 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1897 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1898 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1899 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1900 EXPECT_FALSE(
1901 occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1902 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1903 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1904 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1905 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1907 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100),
1908 occlusion.UnoccludedLayerContentRect(
1909 parent, gfx::Rect(0, 0, 300, 300)));
1913 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild);
1915 template <class Types>
1916 class OcclusionTrackerTestLayerClipRectOverChild
1917 : public OcclusionTrackerTest<Types> {
1918 protected:
1919 explicit OcclusionTrackerTestLayerClipRectOverChild(bool opaque_layers)
1920 : OcclusionTrackerTest<Types>(opaque_layers) {}
1921 void RunMyTest() {
1922 typename Types::ContentLayerType* parent = this->CreateRoot(
1923 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1924 typename Types::ContentLayerType* clip =
1925 this->CreateDrawingLayer(parent,
1926 this->identity_matrix,
1927 gfx::PointF(100.f, 100.f),
1928 gfx::Size(100, 100),
1929 false);
1930 clip->SetMasksToBounds(true);
1931 typename Types::ContentLayerType* layer =
1932 this->CreateDrawingSurface(clip,
1933 this->identity_matrix,
1934 gfx::PointF(-100.f, -100.f),
1935 gfx::Size(200, 200),
1936 true);
1937 this->CalcDrawEtc(parent);
1939 TestOcclusionTrackerWithClip<typename Types::LayerType,
1940 typename Types::RenderSurfaceType> occlusion(
1941 gfx::Rect(0, 0, 1000, 1000));
1943 this->EnterLayer(layer, &occlusion, false);
1945 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1946 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1947 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1948 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1950 this->LeaveLayer(layer, &occlusion);
1951 this->VisitContributingSurface(layer, &occlusion);
1953 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1954 occlusion.occlusion_from_inside_target().ToString());
1956 this->EnterLayer(clip, &occlusion, false);
1958 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100)));
1959 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100)));
1960 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100)));
1961 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 100, 100, 100)));
1962 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 100, 100, 100)));
1963 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 0, 100, 100)));
1964 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 200, 100, 100)));
1965 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 200, 100, 100)));
1966 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 200, 100, 100)));
1968 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1969 clip, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1973 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild);
1975 template <class Types>
1976 class OcclusionTrackerTestViewportRectOverChild
1977 : public OcclusionTrackerTest<Types> {
1978 protected:
1979 explicit OcclusionTrackerTestViewportRectOverChild(bool opaque_layers)
1980 : OcclusionTrackerTest<Types>(opaque_layers) {}
1981 void RunMyTest() {
1982 typename Types::ContentLayerType* parent = this->CreateRoot(
1983 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1984 typename Types::ContentLayerType* layer =
1985 this->CreateDrawingSurface(parent,
1986 this->identity_matrix,
1987 gfx::PointF(),
1988 gfx::Size(200, 200),
1989 true);
1990 this->CalcDrawEtc(parent);
1992 TestOcclusionTrackerWithClip<typename Types::LayerType,
1993 typename Types::RenderSurfaceType> occlusion(
1994 gfx::Rect(100, 100, 100, 100));
1996 this->EnterLayer(layer, &occlusion, false);
1998 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1999 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2000 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2001 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2003 this->LeaveLayer(layer, &occlusion);
2004 this->VisitContributingSurface(layer, &occlusion);
2005 this->EnterLayer(parent, &occlusion, false);
2007 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2008 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2009 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2010 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2011 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2012 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2013 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2014 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2015 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2017 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2018 parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2022 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild);
2024 template <class Types>
2025 class OcclusionTrackerTestLayerClipRectPartlyOverChild
2026 : public OcclusionTrackerTest<Types> {
2027 protected:
2028 explicit OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaque_layers)
2029 : OcclusionTrackerTest<Types>(opaque_layers) {}
2030 void RunMyTest() {
2031 typename Types::ContentLayerType* parent = this->CreateRoot(
2032 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2033 typename Types::ContentLayerType* clip =
2034 this->CreateDrawingLayer(parent,
2035 this->identity_matrix,
2036 gfx::PointF(50.f, 50.f),
2037 gfx::Size(200, 200),
2038 false);
2039 clip->SetMasksToBounds(true);
2040 typename Types::ContentLayerType* layer =
2041 this->CreateDrawingSurface(clip,
2042 this->identity_matrix,
2043 gfx::PointF(-50.f, -50.f),
2044 gfx::Size(200, 200),
2045 true);
2046 this->CalcDrawEtc(parent);
2048 TestOcclusionTrackerWithClip<typename Types::LayerType,
2049 typename Types::RenderSurfaceType> occlusion(
2050 gfx::Rect(0, 0, 1000, 1000));
2052 this->EnterLayer(layer, &occlusion, false);
2054 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2055 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2056 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2057 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2059 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 50)));
2060 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 50, 100)));
2061 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 50)));
2062 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 50, 100)));
2064 this->LeaveLayer(layer, &occlusion);
2065 this->VisitContributingSurface(layer, &occlusion);
2066 this->EnterLayer(clip, &occlusion, false);
2068 EXPECT_EQ(gfx::Rect(50, 50, 150, 150).ToString(),
2069 occlusion.occlusion_from_inside_target().ToString());
2073 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild);
2075 template <class Types>
2076 class OcclusionTrackerTestViewportRectPartlyOverChild
2077 : public OcclusionTrackerTest<Types> {
2078 protected:
2079 explicit OcclusionTrackerTestViewportRectPartlyOverChild(bool opaque_layers)
2080 : OcclusionTrackerTest<Types>(opaque_layers) {}
2081 void RunMyTest() {
2082 typename Types::ContentLayerType* parent = this->CreateRoot(
2083 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2084 typename Types::ContentLayerType* layer =
2085 this->CreateDrawingSurface(parent,
2086 this->identity_matrix,
2087 gfx::PointF(),
2088 gfx::Size(200, 200),
2089 true);
2090 this->CalcDrawEtc(parent);
2092 TestOcclusionTrackerWithClip<typename Types::LayerType,
2093 typename Types::RenderSurfaceType> occlusion(
2094 gfx::Rect(50, 50, 200, 200));
2096 this->EnterLayer(layer, &occlusion, false);
2098 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2099 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2100 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2101 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2103 this->LeaveLayer(layer, &occlusion);
2104 this->VisitContributingSurface(layer, &occlusion);
2105 this->EnterLayer(parent, &occlusion, false);
2107 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2108 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2109 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2110 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2111 EXPECT_FALSE(
2112 occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2113 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2114 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2115 EXPECT_FALSE(
2116 occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2117 EXPECT_FALSE(
2118 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2120 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200),
2121 occlusion.UnoccludedLayerContentRect(
2122 parent, gfx::Rect(0, 0, 300, 300)));
2123 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50),
2124 occlusion.UnoccludedLayerContentRect(
2125 parent, gfx::Rect(0, 0, 300, 100)));
2126 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2127 occlusion.UnoccludedLayerContentRect(
2128 parent, gfx::Rect(0, 100, 300, 100)));
2129 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2130 occlusion.UnoccludedLayerContentRect(
2131 parent, gfx::Rect(200, 100, 100, 100)));
2132 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50),
2133 occlusion.UnoccludedLayerContentRect(
2134 parent, gfx::Rect(100, 200, 100, 100)));
2138 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild);
2140 template <class Types>
2141 class OcclusionTrackerTestViewportRectOverNothing
2142 : public OcclusionTrackerTest<Types> {
2143 protected:
2144 explicit OcclusionTrackerTestViewportRectOverNothing(bool opaque_layers)
2145 : OcclusionTrackerTest<Types>(opaque_layers) {}
2146 void RunMyTest() {
2147 typename Types::ContentLayerType* parent = this->CreateRoot(
2148 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2149 typename Types::ContentLayerType* layer =
2150 this->CreateDrawingSurface(parent,
2151 this->identity_matrix,
2152 gfx::PointF(),
2153 gfx::Size(200, 200),
2154 true);
2155 this->CalcDrawEtc(parent);
2157 TestOcclusionTrackerWithClip<typename Types::LayerType,
2158 typename Types::RenderSurfaceType> occlusion(
2159 gfx::Rect(500, 500, 100, 100));
2161 this->EnterLayer(layer, &occlusion, false);
2163 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2164 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2165 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2166 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2168 this->LeaveLayer(layer, &occlusion);
2169 this->VisitContributingSurface(layer, &occlusion);
2170 this->EnterLayer(parent, &occlusion, false);
2172 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2173 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2174 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2175 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2176 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2177 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2178 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2179 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2180 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2182 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2183 parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2184 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2185 parent, gfx::Rect(0, 0, 300, 100)).IsEmpty());
2186 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2187 parent, gfx::Rect(0, 100, 300, 100)).IsEmpty());
2188 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2189 parent, gfx::Rect(200, 100, 100, 100)).IsEmpty());
2190 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2191 parent, gfx::Rect(100, 200, 100, 100)).IsEmpty());
2195 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing);
2197 template <class Types>
2198 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
2199 : public OcclusionTrackerTest<Types> {
2200 protected:
2201 explicit OcclusionTrackerTestLayerClipRectForLayerOffOrigin(
2202 bool opaque_layers)
2203 : OcclusionTrackerTest<Types>(opaque_layers) {}
2204 void RunMyTest() {
2205 typename Types::ContentLayerType* parent = this->CreateRoot(
2206 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2207 typename Types::ContentLayerType* layer =
2208 this->CreateDrawingSurface(parent,
2209 this->identity_matrix,
2210 gfx::PointF(),
2211 gfx::Size(200, 200),
2212 true);
2213 this->CalcDrawEtc(parent);
2215 TestOcclusionTrackerWithClip<typename Types::LayerType,
2216 typename Types::RenderSurfaceType> occlusion(
2217 gfx::Rect(0, 0, 1000, 1000));
2218 this->EnterLayer(layer, &occlusion, false);
2220 // This layer is translated when drawn into its target. So if the clip rect
2221 // given from the target surface is not in that target space, then after
2222 // translating these query rects into the target, they will fall outside the
2223 // clip and be considered occluded.
2224 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2225 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2226 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2227 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2231 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin);
2233 template <class Types>
2234 class OcclusionTrackerTestOpaqueContentsRegionEmpty
2235 : public OcclusionTrackerTest<Types> {
2236 protected:
2237 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
2238 : OcclusionTrackerTest<Types>(opaque_layers) {}
2239 void RunMyTest() {
2240 typename Types::ContentLayerType* parent = this->CreateRoot(
2241 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2242 typename Types::ContentLayerType* layer =
2243 this->CreateDrawingSurface(parent,
2244 this->identity_matrix,
2245 gfx::PointF(),
2246 gfx::Size(200, 200),
2247 false);
2248 this->CalcDrawEtc(parent);
2250 TestOcclusionTrackerWithClip<typename Types::LayerType,
2251 typename Types::RenderSurfaceType> occlusion(
2252 gfx::Rect(0, 0, 1000, 1000));
2253 this->EnterLayer(layer, &occlusion, false);
2255 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2256 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2257 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2258 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2260 // Occluded since its outside the surface bounds.
2261 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
2263 this->LeaveLayer(layer, &occlusion);
2264 this->VisitContributingSurface(layer, &occlusion);
2265 this->EnterLayer(parent, &occlusion, false);
2267 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2271 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
2273 template <class Types>
2274 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
2275 : public OcclusionTrackerTest<Types> {
2276 protected:
2277 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
2278 : OcclusionTrackerTest<Types>(opaque_layers) {}
2279 void RunMyTest() {
2280 typename Types::ContentLayerType* parent = this->CreateRoot(
2281 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2282 typename Types::ContentLayerType* layer =
2283 this->CreateDrawingLayer(parent,
2284 this->identity_matrix,
2285 gfx::PointF(100.f, 100.f),
2286 gfx::Size(200, 200),
2287 false);
2288 this->CalcDrawEtc(parent);
2290 TestOcclusionTrackerWithClip<typename Types::LayerType,
2291 typename Types::RenderSurfaceType> occlusion(
2292 gfx::Rect(0, 0, 1000, 1000));
2293 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
2295 this->ResetLayerIterator();
2296 this->VisitLayer(layer, &occlusion);
2297 this->EnterLayer(parent, &occlusion, false);
2299 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
2300 occlusion.occlusion_from_inside_target().ToString());
2302 EXPECT_FALSE(
2303 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2304 EXPECT_TRUE(
2305 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2306 EXPECT_FALSE(
2307 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2310 TestOcclusionTrackerWithClip<typename Types::LayerType,
2311 typename Types::RenderSurfaceType> occlusion(
2312 gfx::Rect(0, 0, 1000, 1000));
2313 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
2315 this->ResetLayerIterator();
2316 this->VisitLayer(layer, &occlusion);
2317 this->EnterLayer(parent, &occlusion, false);
2319 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
2320 occlusion.occlusion_from_inside_target().ToString());
2322 EXPECT_FALSE(
2323 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2324 EXPECT_FALSE(
2325 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2326 EXPECT_TRUE(
2327 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2330 TestOcclusionTrackerWithClip<typename Types::LayerType,
2331 typename Types::RenderSurfaceType> occlusion(
2332 gfx::Rect(0, 0, 1000, 1000));
2333 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
2335 this->ResetLayerIterator();
2336 this->VisitLayer(layer, &occlusion);
2337 this->EnterLayer(parent, &occlusion, false);
2339 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
2340 occlusion.occlusion_from_inside_target().ToString());
2342 EXPECT_FALSE(
2343 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2344 EXPECT_FALSE(
2345 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2346 EXPECT_FALSE(
2347 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2352 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
2354 template <class Types>
2355 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
2356 protected:
2357 explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
2358 : OcclusionTrackerTest<Types>(opaque_layers) {}
2359 void RunMyTest() {
2360 gfx::Transform transform;
2361 transform.RotateAboutYAxis(30.0);
2363 typename Types::ContentLayerType* parent = this->CreateRoot(
2364 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2365 typename Types::LayerType* container = this->CreateLayer(
2366 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2367 typename Types::ContentLayerType* layer =
2368 this->CreateDrawingLayer(container,
2369 transform,
2370 gfx::PointF(100.f, 100.f),
2371 gfx::Size(200, 200),
2372 true);
2373 this->CalcDrawEtc(parent);
2375 TestOcclusionTrackerWithClip<typename Types::LayerType,
2376 typename Types::RenderSurfaceType> occlusion(
2377 gfx::Rect(0, 0, 1000, 1000));
2378 this->EnterLayer(layer, &occlusion, false);
2380 // The layer is rotated in 3d but without preserving 3d, so it only gets
2381 // resized.
2382 EXPECT_RECT_EQ(
2383 gfx::Rect(0, 0, 200, 200),
2384 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2388 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
2390 template <class Types>
2391 class OcclusionTrackerTestUnsorted3dLayers
2392 : public OcclusionTrackerTest<Types> {
2393 protected:
2394 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
2395 : OcclusionTrackerTest<Types>(opaque_layers) {}
2396 void RunMyTest() {
2397 // Currently, The main thread layer iterator does not iterate over 3d items
2398 // in sorted order, because layer sorting is not performed on the main
2399 // thread. Because of this, the occlusion tracker cannot assume that a 3d
2400 // layer occludes other layers that have not yet been iterated over. For
2401 // now, the expected behavior is that a 3d layer simply does not add any
2402 // occlusion to the occlusion tracker.
2404 gfx::Transform translation_to_front;
2405 translation_to_front.Translate3d(0.0, 0.0, -10.0);
2406 gfx::Transform translation_to_back;
2407 translation_to_front.Translate3d(0.0, 0.0, -100.0);
2409 typename Types::ContentLayerType* parent = this->CreateRoot(
2410 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2411 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
2412 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
2413 typename Types::ContentLayerType* child2 =
2414 this->CreateDrawingLayer(parent,
2415 translation_to_front,
2416 gfx::PointF(50.f, 50.f),
2417 gfx::Size(100, 100),
2418 true);
2419 parent->SetPreserves3d(true);
2421 this->CalcDrawEtc(parent);
2423 TestOcclusionTrackerWithClip<typename Types::LayerType,
2424 typename Types::RenderSurfaceType> occlusion(
2425 gfx::Rect(0, 0, 1000, 1000));
2426 this->VisitLayer(child2, &occlusion);
2427 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2428 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2430 this->VisitLayer(child1, &occlusion);
2431 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2432 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2436 // This test will have different layer ordering on the impl thread; the test
2437 // will only work on the main thread.
2438 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
2440 template <class Types>
2441 class OcclusionTrackerTestPerspectiveTransform
2442 : public OcclusionTrackerTest<Types> {
2443 protected:
2444 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
2445 : OcclusionTrackerTest<Types>(opaque_layers) {}
2446 void RunMyTest() {
2447 gfx::Transform transform;
2448 transform.Translate(150.0, 150.0);
2449 transform.ApplyPerspectiveDepth(400.0);
2450 transform.RotateAboutXAxis(-30.0);
2451 transform.Translate(-150.0, -150.0);
2453 typename Types::ContentLayerType* parent = this->CreateRoot(
2454 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2455 typename Types::LayerType* container = this->CreateLayer(
2456 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2457 typename Types::ContentLayerType* layer =
2458 this->CreateDrawingLayer(container,
2459 transform,
2460 gfx::PointF(100.f, 100.f),
2461 gfx::Size(200, 200),
2462 true);
2463 container->SetPreserves3d(true);
2464 layer->SetPreserves3d(true);
2465 this->CalcDrawEtc(parent);
2467 TestOcclusionTrackerWithClip<typename Types::LayerType,
2468 typename Types::RenderSurfaceType> occlusion(
2469 gfx::Rect(0, 0, 1000, 1000));
2470 this->EnterLayer(layer, &occlusion, false);
2472 EXPECT_RECT_EQ(
2473 gfx::Rect(0, 0, 200, 200),
2474 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2478 // This test requires accumulating occlusion of 3d layers, which are skipped by
2479 // the occlusion tracker on the main thread. So this test should run on the impl
2480 // thread.
2481 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
2483 template <class Types>
2484 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2485 : public OcclusionTrackerTest<Types> {
2486 protected:
2487 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2488 bool opaque_layers)
2489 : OcclusionTrackerTest<Types>(opaque_layers) {}
2490 void RunMyTest() {
2491 // This test is based on the platform/chromium/compositing/3d-corners.html
2492 // layout test.
2493 gfx::Transform transform;
2494 transform.Translate(250.0, 50.0);
2495 transform.ApplyPerspectiveDepth(10.0);
2496 transform.Translate(-250.0, -50.0);
2497 transform.Translate(250.0, 50.0);
2498 transform.RotateAboutXAxis(-167.0);
2499 transform.Translate(-250.0, -50.0);
2501 typename Types::ContentLayerType* parent = this->CreateRoot(
2502 this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
2503 typename Types::LayerType* container = this->CreateLayer(
2504 parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2505 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2506 container, transform, gfx::PointF(), gfx::Size(500, 500), true);
2507 container->SetPreserves3d(true);
2508 layer->SetPreserves3d(true);
2509 this->CalcDrawEtc(parent);
2511 TestOcclusionTrackerWithClip<typename Types::LayerType,
2512 typename Types::RenderSurfaceType> occlusion(
2513 gfx::Rect(0, 0, 1000, 1000));
2514 this->EnterLayer(layer, &occlusion, false);
2516 // The bottom 11 pixel rows of this layer remain visible inside the
2517 // container, after translation to the target surface. When translated back,
2518 // this will include many more pixels but must include at least the bottom
2519 // 11 rows.
2520 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2521 layer, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
2525 // This test requires accumulating occlusion of 3d layers, which are skipped by
2526 // the occlusion tracker on the main thread. So this test should run on the impl
2527 // thread.
2528 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2530 template <class Types>
2531 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2532 : public OcclusionTrackerTest<Types> {
2533 protected:
2534 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2535 bool opaque_layers)
2536 : OcclusionTrackerTest<Types>(opaque_layers) {}
2537 void RunMyTest() {
2538 gfx::Transform transform;
2539 transform.Translate(50.0, 50.0);
2540 transform.ApplyPerspectiveDepth(100.0);
2541 transform.Translate3d(0.0, 0.0, 110.0);
2542 transform.Translate(-50.0, -50.0);
2544 typename Types::ContentLayerType* parent = this->CreateRoot(
2545 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2546 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2547 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2548 parent->SetPreserves3d(true);
2549 layer->SetPreserves3d(true);
2550 this->CalcDrawEtc(parent);
2552 TestOcclusionTrackerWithClip<typename Types::LayerType,
2553 typename Types::RenderSurfaceType> occlusion(
2554 gfx::Rect(0, 0, 1000, 1000));
2556 // The |layer| is entirely behind the camera and should not occlude.
2557 this->VisitLayer(layer, &occlusion);
2558 this->EnterLayer(parent, &occlusion, false);
2559 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2560 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2564 // This test requires accumulating occlusion of 3d layers, which are skipped by
2565 // the occlusion tracker on the main thread. So this test should run on the impl
2566 // thread.
2567 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2569 template <class Types>
2570 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2571 : public OcclusionTrackerTest<Types> {
2572 protected:
2573 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2574 bool opaque_layers)
2575 : OcclusionTrackerTest<Types>(opaque_layers) {}
2576 void RunMyTest() {
2577 gfx::Transform transform;
2578 transform.Translate(50.0, 50.0);
2579 transform.ApplyPerspectiveDepth(100.0);
2580 transform.Translate3d(0.0, 0.0, 99.0);
2581 transform.Translate(-50.0, -50.0);
2583 typename Types::ContentLayerType* parent = this->CreateRoot(
2584 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2585 parent->SetMasksToBounds(true);
2586 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2587 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2588 parent->SetPreserves3d(true);
2589 layer->SetPreserves3d(true);
2590 this->CalcDrawEtc(parent);
2592 TestOcclusionTrackerWithClip<typename Types::LayerType,
2593 typename Types::RenderSurfaceType> occlusion(
2594 gfx::Rect(0, 0, 1000, 1000));
2596 // This is very close to the camera, so pixels in its visible_content_rect()
2597 // will actually go outside of the layer's clip rect. Ensure that those
2598 // pixels don't occlude things outside the clip rect.
2599 this->VisitLayer(layer, &occlusion);
2600 this->EnterLayer(parent, &occlusion, false);
2601 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2602 occlusion.occlusion_from_inside_target().ToString());
2603 EXPECT_EQ(gfx::Rect().ToString(),
2604 occlusion.occlusion_from_outside_target().ToString());
2608 // This test requires accumulating occlusion of 3d layers, which are skipped by
2609 // the occlusion tracker on the main thread. So this test should run on the impl
2610 // thread.
2611 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2613 template <class Types>
2614 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2615 : public OcclusionTrackerTest<Types> {
2616 protected:
2617 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
2618 : OcclusionTrackerTest<Types>(opaque_layers) {}
2619 void RunMyTest() {
2620 // parent
2621 // +--layer
2622 // +--surface
2623 // | +--surface_child
2624 // | +--surface_child2
2625 // +--parent2
2626 // +--topmost
2628 typename Types::ContentLayerType* parent = this->CreateRoot(
2629 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2630 typename Types::ContentLayerType* layer =
2631 this->CreateDrawingLayer(parent,
2632 this->identity_matrix,
2633 gfx::PointF(),
2634 gfx::Size(300, 300),
2635 true);
2636 typename Types::ContentLayerType* surface =
2637 this->CreateDrawingSurface(parent,
2638 this->identity_matrix,
2639 gfx::PointF(),
2640 gfx::Size(300, 300),
2641 true);
2642 typename Types::ContentLayerType* surface_child =
2643 this->CreateDrawingLayer(surface,
2644 this->identity_matrix,
2645 gfx::PointF(),
2646 gfx::Size(200, 300),
2647 true);
2648 typename Types::ContentLayerType* surface_child2 =
2649 this->CreateDrawingLayer(surface,
2650 this->identity_matrix,
2651 gfx::PointF(),
2652 gfx::Size(100, 300),
2653 true);
2654 typename Types::ContentLayerType* parent2 =
2655 this->CreateDrawingLayer(parent,
2656 this->identity_matrix,
2657 gfx::PointF(),
2658 gfx::Size(300, 300),
2659 false);
2660 typename Types::ContentLayerType* topmost =
2661 this->CreateDrawingLayer(parent,
2662 this->identity_matrix,
2663 gfx::PointF(250.f, 0.f),
2664 gfx::Size(50, 300),
2665 true);
2667 AddOpacityTransitionToController(
2668 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2669 AddOpacityTransitionToController(
2670 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2671 this->CalcDrawEtc(parent);
2673 EXPECT_TRUE(layer->draw_opacity_is_animating());
2674 EXPECT_FALSE(surface->draw_opacity_is_animating());
2675 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2677 TestOcclusionTrackerWithClip<typename Types::LayerType,
2678 typename Types::RenderSurfaceType> occlusion(
2679 gfx::Rect(0, 0, 1000, 1000));
2681 this->VisitLayer(topmost, &occlusion);
2682 this->EnterLayer(parent2, &occlusion, false);
2683 // This occlusion will affect all surfaces.
2684 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2685 occlusion.occlusion_from_inside_target().ToString());
2686 EXPECT_EQ(gfx::Rect().ToString(),
2687 occlusion.occlusion_from_outside_target().ToString());
2688 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2689 occlusion.UnoccludedLayerContentRect(
2690 parent2, gfx::Rect(0, 0, 300, 300)).ToString());
2691 this->LeaveLayer(parent2, &occlusion);
2693 this->VisitLayer(surface_child2, &occlusion);
2694 this->EnterLayer(surface_child, &occlusion, false);
2695 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2696 occlusion.occlusion_from_inside_target().ToString());
2697 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2698 occlusion.occlusion_from_outside_target().ToString());
2699 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2700 occlusion.UnoccludedLayerContentRect(
2701 surface_child, gfx::Rect(0, 0, 200, 300)));
2702 this->LeaveLayer(surface_child, &occlusion);
2703 this->EnterLayer(surface, &occlusion, false);
2704 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2705 occlusion.occlusion_from_inside_target().ToString());
2706 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2707 occlusion.occlusion_from_outside_target().ToString());
2708 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2709 occlusion.UnoccludedLayerContentRect(
2710 surface, gfx::Rect(0, 0, 300, 300)));
2711 this->LeaveLayer(surface, &occlusion);
2713 this->EnterContributingSurface(surface, &occlusion, false);
2714 // Occlusion within the surface is lost when leaving the animating surface.
2715 EXPECT_EQ(gfx::Rect().ToString(),
2716 occlusion.occlusion_from_inside_target().ToString());
2717 EXPECT_EQ(gfx::Rect().ToString(),
2718 occlusion.occlusion_from_outside_target().ToString());
2719 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2720 occlusion.UnoccludedContributingSurfaceContentRect(
2721 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
2722 this->LeaveContributingSurface(surface, &occlusion);
2724 // Occlusion from outside the animating surface still exists.
2725 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2726 occlusion.occlusion_from_inside_target().ToString());
2727 EXPECT_EQ(gfx::Rect().ToString(),
2728 occlusion.occlusion_from_outside_target().ToString());
2730 this->VisitLayer(layer, &occlusion);
2731 this->EnterLayer(parent, &occlusion, false);
2733 // Occlusion is not added for the animating |layer|.
2734 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2735 occlusion.UnoccludedLayerContentRect(
2736 parent, gfx::Rect(0, 0, 300, 300)));
2740 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2742 template <class Types>
2743 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2744 : public OcclusionTrackerTest<Types> {
2745 protected:
2746 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
2747 : OcclusionTrackerTest<Types>(opaque_layers) {}
2748 void RunMyTest() {
2749 typename Types::ContentLayerType* parent = this->CreateRoot(
2750 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2751 typename Types::ContentLayerType* layer =
2752 this->CreateDrawingLayer(parent,
2753 this->identity_matrix,
2754 gfx::PointF(),
2755 gfx::Size(300, 300),
2756 true);
2757 typename Types::ContentLayerType* surface =
2758 this->CreateDrawingSurface(parent,
2759 this->identity_matrix,
2760 gfx::PointF(),
2761 gfx::Size(300, 300),
2762 true);
2763 typename Types::ContentLayerType* surface_child =
2764 this->CreateDrawingLayer(surface,
2765 this->identity_matrix,
2766 gfx::PointF(),
2767 gfx::Size(200, 300),
2768 true);
2769 typename Types::ContentLayerType* surface_child2 =
2770 this->CreateDrawingLayer(surface,
2771 this->identity_matrix,
2772 gfx::PointF(),
2773 gfx::Size(100, 300),
2774 true);
2775 typename Types::ContentLayerType* parent2 =
2776 this->CreateDrawingLayer(parent,
2777 this->identity_matrix,
2778 gfx::PointF(),
2779 gfx::Size(300, 300),
2780 false);
2781 typename Types::ContentLayerType* topmost =
2782 this->CreateDrawingLayer(parent,
2783 this->identity_matrix,
2784 gfx::PointF(250.f, 0.f),
2785 gfx::Size(50, 300),
2786 true);
2788 AddOpacityTransitionToController(
2789 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2790 AddOpacityTransitionToController(
2791 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2792 this->CalcDrawEtc(parent);
2794 EXPECT_TRUE(layer->draw_opacity_is_animating());
2795 EXPECT_FALSE(surface->draw_opacity_is_animating());
2796 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2798 TestOcclusionTrackerWithClip<typename Types::LayerType,
2799 typename Types::RenderSurfaceType> occlusion(
2800 gfx::Rect(0, 0, 1000, 1000));
2802 this->VisitLayer(topmost, &occlusion);
2803 this->EnterLayer(parent2, &occlusion, false);
2804 // This occlusion will affect all surfaces.
2805 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2806 occlusion.occlusion_from_inside_target().ToString());
2807 EXPECT_EQ(gfx::Rect().ToString(),
2808 occlusion.occlusion_from_outside_target().ToString());
2809 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2810 occlusion.UnoccludedLayerContentRect(
2811 parent, gfx::Rect(0, 0, 300, 300)));
2812 this->LeaveLayer(parent2, &occlusion);
2814 this->VisitLayer(surface_child2, &occlusion);
2815 this->EnterLayer(surface_child, &occlusion, false);
2816 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2817 occlusion.occlusion_from_inside_target().ToString());
2818 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2819 occlusion.occlusion_from_outside_target().ToString());
2820 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2821 occlusion.UnoccludedLayerContentRect(
2822 surface_child, gfx::Rect(0, 0, 200, 300)));
2823 this->LeaveLayer(surface_child, &occlusion);
2824 this->EnterLayer(surface, &occlusion, false);
2825 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2826 occlusion.occlusion_from_inside_target().ToString());
2827 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2828 occlusion.occlusion_from_outside_target().ToString());
2829 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2830 occlusion.UnoccludedLayerContentRect(
2831 surface, gfx::Rect(0, 0, 300, 300)));
2832 this->LeaveLayer(surface, &occlusion);
2834 this->EnterContributingSurface(surface, &occlusion, false);
2835 // Occlusion within the surface is lost when leaving the animating surface.
2836 EXPECT_EQ(gfx::Rect().ToString(),
2837 occlusion.occlusion_from_inside_target().ToString());
2838 EXPECT_EQ(gfx::Rect().ToString(),
2839 occlusion.occlusion_from_outside_target().ToString());
2840 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2841 occlusion.UnoccludedContributingSurfaceContentRect(
2842 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
2843 this->LeaveContributingSurface(surface, &occlusion);
2845 // Occlusion from outside the animating surface still exists.
2846 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2847 occlusion.occlusion_from_inside_target().ToString());
2848 EXPECT_EQ(gfx::Rect().ToString(),
2849 occlusion.occlusion_from_outside_target().ToString());
2851 this->VisitLayer(layer, &occlusion);
2852 this->EnterLayer(parent, &occlusion, false);
2854 // Occlusion is not added for the animating |layer|.
2855 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2856 occlusion.UnoccludedLayerContentRect(
2857 parent, gfx::Rect(0, 0, 300, 300)));
2861 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2863 template <class Types>
2864 class OcclusionTrackerTestAnimationTranslateOnMainThread
2865 : public OcclusionTrackerTest<Types> {
2866 protected:
2867 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2868 bool opaque_layers)
2869 : OcclusionTrackerTest<Types>(opaque_layers) {}
2870 void RunMyTest() {
2871 typename Types::ContentLayerType* parent = this->CreateRoot(
2872 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2873 typename Types::ContentLayerType* layer =
2874 this->CreateDrawingLayer(parent,
2875 this->identity_matrix,
2876 gfx::PointF(),
2877 gfx::Size(300, 300),
2878 true);
2879 typename Types::ContentLayerType* surface =
2880 this->CreateDrawingSurface(parent,
2881 this->identity_matrix,
2882 gfx::PointF(),
2883 gfx::Size(300, 300),
2884 true);
2885 typename Types::ContentLayerType* surface_child =
2886 this->CreateDrawingLayer(surface,
2887 this->identity_matrix,
2888 gfx::PointF(),
2889 gfx::Size(200, 300),
2890 true);
2891 typename Types::ContentLayerType* surface_child2 =
2892 this->CreateDrawingLayer(surface,
2893 this->identity_matrix,
2894 gfx::PointF(),
2895 gfx::Size(100, 300),
2896 true);
2897 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
2898 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
2900 AddAnimatedTransformToController(
2901 layer->layer_animation_controller(), 10.0, 30, 0);
2902 AddAnimatedTransformToController(
2903 surface->layer_animation_controller(), 10.0, 30, 0);
2904 AddAnimatedTransformToController(
2905 surface_child->layer_animation_controller(), 10.0, 30, 0);
2906 this->CalcDrawEtc(parent);
2908 EXPECT_TRUE(layer->draw_transform_is_animating());
2909 EXPECT_TRUE(layer->screen_space_transform_is_animating());
2910 EXPECT_TRUE(
2911 surface->render_surface()->target_surface_transforms_are_animating());
2912 EXPECT_TRUE(
2913 surface->render_surface()->screen_space_transforms_are_animating());
2914 // The surface owning layer doesn't animate against its own surface.
2915 EXPECT_FALSE(surface->draw_transform_is_animating());
2916 EXPECT_TRUE(surface->screen_space_transform_is_animating());
2917 EXPECT_TRUE(surface_child->draw_transform_is_animating());
2918 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
2920 TestOcclusionTrackerWithClip<typename Types::LayerType,
2921 typename Types::RenderSurfaceType> occlusion(
2922 gfx::Rect(0, 0, 1000, 1000));
2924 this->VisitLayer(surface2, &occlusion);
2925 this->EnterContributingSurface(surface2, &occlusion, false);
2927 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2928 occlusion.occlusion_from_inside_target().ToString());
2930 this->LeaveContributingSurface(surface2, &occlusion);
2931 this->EnterLayer(surface_child2, &occlusion, false);
2933 // surface_child2 is moving in screen space but not relative to its target,
2934 // so occlusion should happen in its target space only. It also means that
2935 // things occluding from outside the target (e.g. surface2) cannot occlude
2936 // this layer.
2937 EXPECT_EQ(gfx::Rect().ToString(),
2938 occlusion.occlusion_from_outside_target().ToString());
2940 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2941 occlusion.UnoccludedLayerContentRect(
2942 surface_child2, gfx::Rect(0, 0, 100, 300)));
2943 EXPECT_FALSE(
2944 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2946 this->LeaveLayer(surface_child2, &occlusion);
2947 this->EnterLayer(surface_child, &occlusion, false);
2948 EXPECT_FALSE(
2949 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300)));
2950 EXPECT_EQ(gfx::Rect().ToString(),
2951 occlusion.occlusion_from_outside_target().ToString());
2952 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2953 occlusion.occlusion_from_inside_target().ToString());
2954 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2955 occlusion.UnoccludedLayerContentRect(
2956 surface, gfx::Rect(0, 0, 300, 300)));
2958 // The surface_child is occluded by the surface_child2, but is moving
2959 // relative its target, so it can't be occluded.
2960 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2961 occlusion.UnoccludedLayerContentRect(
2962 surface_child, gfx::Rect(0, 0, 200, 300)));
2963 EXPECT_FALSE(
2964 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2966 this->LeaveLayer(surface_child, &occlusion);
2967 this->EnterLayer(surface, &occlusion, false);
2968 // The surface_child is moving in screen space but not relative to its
2969 // target, so occlusion should happen from within the target only.
2970 EXPECT_EQ(gfx::Rect().ToString(),
2971 occlusion.occlusion_from_outside_target().ToString());
2972 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2973 occlusion.occlusion_from_inside_target().ToString());
2974 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2975 occlusion.UnoccludedLayerContentRect(
2976 surface, gfx::Rect(0, 0, 300, 300)));
2978 this->LeaveLayer(surface, &occlusion);
2979 // The surface's owning layer is moving in screen space but not relative to
2980 // its target, so occlusion should happen within the target only.
2981 EXPECT_EQ(gfx::Rect().ToString(),
2982 occlusion.occlusion_from_outside_target().ToString());
2983 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2984 occlusion.occlusion_from_inside_target().ToString());
2985 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2986 occlusion.UnoccludedLayerContentRect(
2987 surface, gfx::Rect(0, 0, 300, 300)));
2989 this->EnterContributingSurface(surface, &occlusion, false);
2990 // The contributing |surface| is animating so it can't be occluded.
2991 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2992 occlusion.UnoccludedContributingSurfaceContentRect(
2993 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
2994 this->LeaveContributingSurface(surface, &occlusion);
2996 this->EnterLayer(layer, &occlusion, false);
2997 // The |surface| is moving in the screen and in its target, so all occlusion
2998 // within the surface is lost when leaving it.
2999 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3000 occlusion.UnoccludedLayerContentRect(
3001 parent, gfx::Rect(0, 0, 300, 300)));
3002 this->LeaveLayer(layer, &occlusion);
3004 this->EnterLayer(parent, &occlusion, false);
3005 // The |layer| is animating in the screen and in its target, so no occlusion
3006 // is added.
3007 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3008 occlusion.UnoccludedLayerContentRect(
3009 parent, gfx::Rect(0, 0, 300, 300)));
3013 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
3015 template <class Types>
3016 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
3017 : public OcclusionTrackerTest<Types> {
3018 protected:
3019 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
3020 bool opaque_layers)
3021 : OcclusionTrackerTest<Types>(opaque_layers) {}
3022 void RunMyTest() {
3023 gfx::Transform surface_transform;
3024 surface_transform.Translate(300.0, 300.0);
3025 surface_transform.Scale(2.0, 2.0);
3026 surface_transform.Translate(-150.0, -150.0);
3028 typename Types::ContentLayerType* parent = this->CreateRoot(
3029 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
3030 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
3031 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
3032 typename Types::ContentLayerType* surface2 =
3033 this->CreateDrawingSurface(parent,
3034 this->identity_matrix,
3035 gfx::PointF(50.f, 50.f),
3036 gfx::Size(300, 300),
3037 false);
3038 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3039 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3040 this->CalcDrawEtc(parent);
3042 TestOcclusionTrackerWithClip<typename Types::LayerType,
3043 typename Types::RenderSurfaceType> occlusion(
3044 gfx::Rect(0, 0, 1000, 1000));
3046 this->VisitLayer(surface2, &occlusion);
3047 this->VisitContributingSurface(surface2, &occlusion);
3049 EXPECT_EQ(gfx::Rect().ToString(),
3050 occlusion.occlusion_from_outside_target().ToString());
3051 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
3052 occlusion.occlusion_from_inside_target().ToString());
3054 // Clear any stored occlusion.
3055 occlusion.set_occlusion_from_outside_target(Region());
3056 occlusion.set_occlusion_from_inside_target(Region());
3058 this->VisitLayer(surface, &occlusion);
3059 this->VisitContributingSurface(surface, &occlusion);
3061 EXPECT_EQ(gfx::Rect().ToString(),
3062 occlusion.occlusion_from_outside_target().ToString());
3063 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
3064 occlusion.occlusion_from_inside_target().ToString());
3068 MAIN_AND_IMPL_THREAD_TEST(
3069 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
3071 template <class Types>
3072 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
3073 : public OcclusionTrackerTest<Types> {
3074 protected:
3075 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
3076 bool opaque_layers)
3077 : OcclusionTrackerTest<Types>(opaque_layers) {}
3078 void RunMyTest() {
3079 typename Types::ContentLayerType* parent = this->CreateRoot(
3080 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
3081 parent->SetMasksToBounds(true);
3082 typename Types::ContentLayerType* surface =
3083 this->CreateDrawingSurface(parent,
3084 this->identity_matrix,
3085 gfx::PointF(),
3086 gfx::Size(500, 300),
3087 false);
3088 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
3089 this->CalcDrawEtc(parent);
3091 TestOcclusionTrackerWithClip<typename Types::LayerType,
3092 typename Types::RenderSurfaceType> occlusion(
3093 gfx::Rect(0, 0, 1000, 1000));
3095 this->VisitLayer(surface, &occlusion);
3096 this->VisitContributingSurface(surface, &occlusion);
3098 EXPECT_EQ(gfx::Rect().ToString(),
3099 occlusion.occlusion_from_outside_target().ToString());
3100 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
3101 occlusion.occlusion_from_inside_target().ToString());
3105 MAIN_AND_IMPL_THREAD_TEST(
3106 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
3108 template <class Types>
3109 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
3110 protected:
3111 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
3112 : OcclusionTrackerTest<Types>(opaque_layers) {}
3113 void RunMyTest() {
3114 typename Types::ContentLayerType* parent = this->CreateRoot(
3115 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3116 typename Types::LayerType* surface =
3117 this->CreateDrawingSurface(parent,
3118 this->identity_matrix,
3119 gfx::PointF(),
3120 gfx::Size(100, 100),
3121 true);
3122 this->CreateReplicaLayer(surface,
3123 this->identity_matrix,
3124 gfx::PointF(0.f, 100.f),
3125 gfx::Size(100, 100));
3126 typename Types::LayerType* topmost =
3127 this->CreateDrawingLayer(parent,
3128 this->identity_matrix,
3129 gfx::PointF(0.f, 100.f),
3130 gfx::Size(100, 100),
3131 true);
3132 this->CalcDrawEtc(parent);
3134 TestOcclusionTrackerWithClip<typename Types::LayerType,
3135 typename Types::RenderSurfaceType> occlusion(
3136 gfx::Rect(0, 0, 1000, 1000));
3138 // |topmost| occludes the replica, but not the surface itself.
3139 this->VisitLayer(topmost, &occlusion);
3141 EXPECT_EQ(gfx::Rect().ToString(),
3142 occlusion.occlusion_from_outside_target().ToString());
3143 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3144 occlusion.occlusion_from_inside_target().ToString());
3146 this->VisitLayer(surface, &occlusion);
3148 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3149 occlusion.occlusion_from_outside_target().ToString());
3150 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3151 occlusion.occlusion_from_inside_target().ToString());
3153 this->EnterContributingSurface(surface, &occlusion, false);
3155 // Surface is not occluded so it shouldn't think it is.
3156 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3157 occlusion.UnoccludedContributingSurfaceContentRect(
3158 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3162 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
3164 template <class Types>
3165 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
3166 : public OcclusionTrackerTest<Types> {
3167 protected:
3168 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
3169 : OcclusionTrackerTest<Types>(opaque_layers) {}
3170 void RunMyTest() {
3171 typename Types::ContentLayerType* parent = this->CreateRoot(
3172 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3173 typename Types::LayerType* surface =
3174 this->CreateDrawingSurface(parent,
3175 this->identity_matrix,
3176 gfx::PointF(),
3177 gfx::Size(100, 100),
3178 true);
3179 this->CreateReplicaLayer(surface,
3180 this->identity_matrix,
3181 gfx::PointF(0.f, 100.f),
3182 gfx::Size(100, 100));
3183 typename Types::LayerType* topmost =
3184 this->CreateDrawingLayer(parent,
3185 this->identity_matrix,
3186 gfx::PointF(),
3187 gfx::Size(100, 110),
3188 true);
3189 this->CalcDrawEtc(parent);
3191 TestOcclusionTrackerWithClip<typename Types::LayerType,
3192 typename Types::RenderSurfaceType> occlusion(
3193 gfx::Rect(0, 0, 1000, 1000));
3195 // |topmost| occludes the surface, but not the entire surface's replica.
3196 this->VisitLayer(topmost, &occlusion);
3198 EXPECT_EQ(gfx::Rect().ToString(),
3199 occlusion.occlusion_from_outside_target().ToString());
3200 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3201 occlusion.occlusion_from_inside_target().ToString());
3203 this->VisitLayer(surface, &occlusion);
3205 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3206 occlusion.occlusion_from_outside_target().ToString());
3207 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3208 occlusion.occlusion_from_inside_target().ToString());
3210 this->EnterContributingSurface(surface, &occlusion, false);
3212 // Surface is occluded, but only the top 10px of the replica.
3213 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3214 occlusion.UnoccludedContributingSurfaceContentRect(
3215 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3216 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
3217 occlusion.UnoccludedContributingSurfaceContentRect(
3218 surface, true, gfx::Rect(0, 0, 100, 100), NULL));
3222 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
3224 template <class Types>
3225 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
3226 : public OcclusionTrackerTest<Types> {
3227 protected:
3228 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
3229 bool opaque_layers)
3230 : OcclusionTrackerTest<Types>(opaque_layers) {}
3231 void RunMyTest() {
3232 typename Types::ContentLayerType* parent = this->CreateRoot(
3233 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3234 typename Types::LayerType* surface =
3235 this->CreateDrawingSurface(parent,
3236 this->identity_matrix,
3237 gfx::PointF(),
3238 gfx::Size(100, 100),
3239 true);
3240 this->CreateReplicaLayer(surface,
3241 this->identity_matrix,
3242 gfx::PointF(0.f, 100.f),
3243 gfx::Size(100, 100));
3244 typename Types::LayerType* over_surface = this->CreateDrawingLayer(
3245 parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
3246 typename Types::LayerType* over_replica =
3247 this->CreateDrawingLayer(parent,
3248 this->identity_matrix,
3249 gfx::PointF(0.f, 100.f),
3250 gfx::Size(50, 100),
3251 true);
3252 this->CalcDrawEtc(parent);
3254 TestOcclusionTrackerWithClip<typename Types::LayerType,
3255 typename Types::RenderSurfaceType> occlusion(
3256 gfx::Rect(0, 0, 1000, 1000));
3258 // These occlude the surface and replica differently, so we can test each
3259 // one.
3260 this->VisitLayer(over_replica, &occlusion);
3261 this->VisitLayer(over_surface, &occlusion);
3263 EXPECT_EQ(gfx::Rect().ToString(),
3264 occlusion.occlusion_from_outside_target().ToString());
3265 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3266 .ToString(),
3267 occlusion.occlusion_from_inside_target().ToString());
3269 this->VisitLayer(surface, &occlusion);
3271 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3272 .ToString(),
3273 occlusion.occlusion_from_outside_target().ToString());
3274 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3275 occlusion.occlusion_from_inside_target().ToString());
3277 this->EnterContributingSurface(surface, &occlusion, false);
3279 // Surface and replica are occluded different amounts.
3280 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
3281 occlusion.UnoccludedContributingSurfaceContentRect(
3282 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3283 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
3284 occlusion.UnoccludedContributingSurfaceContentRect(
3285 surface, true, gfx::Rect(0, 0, 100, 100), NULL));
3289 ALL_OCCLUSIONTRACKER_TEST(
3290 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
3292 template <class Types>
3293 class OcclusionTrackerTestSurfaceChildOfSurface
3294 : public OcclusionTrackerTest<Types> {
3295 protected:
3296 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
3297 : OcclusionTrackerTest<Types>(opaque_layers) {}
3298 void RunMyTest() {
3299 // This test verifies that the surface cliprect does not end up empty and
3300 // clip away the entire unoccluded rect.
3302 typename Types::ContentLayerType* parent = this->CreateRoot(
3303 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3304 typename Types::LayerType* surface =
3305 this->CreateDrawingSurface(parent,
3306 this->identity_matrix,
3307 gfx::PointF(),
3308 gfx::Size(100, 100),
3309 true);
3310 typename Types::LayerType* surface_child =
3311 this->CreateDrawingSurface(surface,
3312 this->identity_matrix,
3313 gfx::PointF(0.f, 10.f),
3314 gfx::Size(100, 50),
3315 true);
3316 typename Types::LayerType* topmost = this->CreateDrawingLayer(
3317 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3318 this->CalcDrawEtc(parent);
3320 TestOcclusionTrackerWithClip<typename Types::LayerType,
3321 typename Types::RenderSurfaceType> occlusion(
3322 gfx::Rect(-100, -100, 1000, 1000));
3324 // |topmost| occludes everything partially so we know occlusion is happening
3325 // at all.
3326 this->VisitLayer(topmost, &occlusion);
3328 EXPECT_EQ(gfx::Rect().ToString(),
3329 occlusion.occlusion_from_outside_target().ToString());
3330 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3331 occlusion.occlusion_from_inside_target().ToString());
3333 this->VisitLayer(surface_child, &occlusion);
3335 // surface_child increases the occlusion in the screen by a narrow sliver.
3336 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
3337 occlusion.occlusion_from_outside_target().ToString());
3338 // In its own surface, surface_child is at 0,0 as is its occlusion.
3339 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3340 occlusion.occlusion_from_inside_target().ToString());
3342 // The root layer always has a clip rect. So the parent of |surface| has a
3343 // clip rect. However, the owning layer for |surface| does not mask to
3344 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3345 // |surface_child| exercises different code paths as its parent does not
3346 // have a clip rect.
3348 this->EnterContributingSurface(surface_child, &occlusion, false);
3349 // The surface_child's parent does not have a clip rect as it owns a render
3350 // surface. Make sure the unoccluded rect does not get clipped away
3351 // inappropriately.
3352 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
3353 occlusion.UnoccludedContributingSurfaceContentRect(
3354 surface_child, false, gfx::Rect(0, 0, 100, 50), NULL));
3355 this->LeaveContributingSurface(surface_child, &occlusion);
3357 // When the surface_child's occlusion is transformed up to its parent, make
3358 // sure it is not clipped away inappropriately also.
3359 this->EnterLayer(surface, &occlusion, false);
3360 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3361 occlusion.occlusion_from_outside_target().ToString());
3362 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
3363 occlusion.occlusion_from_inside_target().ToString());
3364 this->LeaveLayer(surface, &occlusion);
3366 this->EnterContributingSurface(surface, &occlusion, false);
3367 // The surface's parent does have a clip rect as it is the root layer.
3368 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
3369 occlusion.UnoccludedContributingSurfaceContentRect(
3370 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3374 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
3376 template <class Types>
3377 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
3378 : public OcclusionTrackerTest<Types> {
3379 protected:
3380 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
3381 bool opaque_layers)
3382 : OcclusionTrackerTest<Types>(opaque_layers) {}
3383 void RunMyTest() {
3384 // This test verifies that the top-most surface is considered occluded
3385 // outside of its target's clip rect and outside the viewport rect.
3387 typename Types::ContentLayerType* parent = this->CreateRoot(
3388 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3389 typename Types::LayerType* surface =
3390 this->CreateDrawingSurface(parent,
3391 this->identity_matrix,
3392 gfx::PointF(),
3393 gfx::Size(100, 300),
3394 true);
3395 this->CalcDrawEtc(parent);
3397 // Make a viewport rect that is larger than the root layer.
3398 TestOcclusionTrackerWithClip<typename Types::LayerType,
3399 typename Types::RenderSurfaceType> occlusion(
3400 gfx::Rect(0, 0, 1000, 1000));
3402 this->VisitLayer(surface, &occlusion);
3404 // The root layer always has a clip rect. So the parent of |surface| has a
3405 // clip rect giving the surface itself a clip rect.
3406 this->EnterContributingSurface(surface, &occlusion, false);
3407 // Make sure the parent's clip rect clips the unoccluded region of the
3408 // child surface.
3409 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
3410 occlusion.UnoccludedContributingSurfaceContentRect(
3411 surface, false, gfx::Rect(0, 0, 100, 300), NULL));
3413 this->ResetLayerIterator();
3415 // Make a viewport rect that is smaller than the root layer.
3416 TestOcclusionTrackerWithClip<typename Types::LayerType,
3417 typename Types::RenderSurfaceType> occlusion(
3418 gfx::Rect(0, 0, 100, 100));
3420 this->VisitLayer(surface, &occlusion);
3422 // The root layer always has a clip rect. So the parent of |surface| has a
3423 // clip rect giving the surface itself a clip rect.
3424 this->EnterContributingSurface(surface, &occlusion, false);
3425 // Make sure the viewport rect clips the unoccluded region of the child
3426 // surface.
3427 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3428 occlusion.UnoccludedContributingSurfaceContentRect(
3429 surface, false, gfx::Rect(0, 0, 100, 300), NULL));
3434 ALL_OCCLUSIONTRACKER_TEST(
3435 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
3437 template <class Types>
3438 class OcclusionTrackerTestSurfaceChildOfClippingSurface
3439 : public OcclusionTrackerTest<Types> {
3440 protected:
3441 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers)
3442 : OcclusionTrackerTest<Types>(opaque_layers) {}
3443 void RunMyTest() {
3444 // This test verifies that the surface cliprect does not end up empty and
3445 // clip away the entire unoccluded rect.
3447 typename Types::ContentLayerType* parent = this->CreateRoot(
3448 this->identity_matrix, gfx::PointF(), gfx::Size(80, 200));
3449 parent->SetMasksToBounds(true);
3450 typename Types::LayerType* surface =
3451 this->CreateDrawingSurface(parent,
3452 this->identity_matrix,
3453 gfx::PointF(),
3454 gfx::Size(100, 100),
3455 true);
3456 typename Types::LayerType* surface_child =
3457 this->CreateDrawingSurface(surface,
3458 this->identity_matrix,
3459 gfx::PointF(),
3460 gfx::Size(100, 100),
3461 false);
3462 typename Types::LayerType* topmost = this->CreateDrawingLayer(
3463 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3464 this->CalcDrawEtc(parent);
3466 TestOcclusionTrackerWithClip<typename Types::LayerType,
3467 typename Types::RenderSurfaceType> occlusion(
3468 gfx::Rect(0, 0, 1000, 1000));
3470 // |topmost| occludes everything partially so we know occlusion is happening
3471 // at all.
3472 this->VisitLayer(topmost, &occlusion);
3474 EXPECT_EQ(gfx::Rect().ToString(),
3475 occlusion.occlusion_from_outside_target().ToString());
3476 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3477 occlusion.occlusion_from_inside_target().ToString());
3479 // surface_child is not opaque and does not occlude, so we have a non-empty
3480 // unoccluded area on surface.
3481 this->VisitLayer(surface_child, &occlusion);
3483 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3484 occlusion.occlusion_from_outside_target().ToString());
3485 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3486 occlusion.occlusion_from_inside_target().ToString());
3488 // The root layer always has a clip rect. So the parent of |surface| has a
3489 // clip rect. However, the owning layer for |surface| does not mask to
3490 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3491 // |surface_child| exercises different code paths as its parent does not
3492 // have a clip rect.
3494 this->EnterContributingSurface(surface_child, &occlusion, false);
3495 // The surface_child's parent does not have a clip rect as it owns a render
3496 // surface.
3497 EXPECT_EQ(
3498 gfx::Rect(0, 50, 80, 50).ToString(),
3499 occlusion.UnoccludedContributingSurfaceContentRect(
3500 surface_child, false, gfx::Rect(0, 0, 100, 100), NULL).ToString());
3501 this->LeaveContributingSurface(surface_child, &occlusion);
3503 this->VisitLayer(surface, &occlusion);
3504 this->EnterContributingSurface(surface, &occlusion, false);
3505 // The surface's parent does have a clip rect as it is the root layer.
3506 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3507 occlusion.UnoccludedContributingSurfaceContentRect(
3508 surface, false, gfx::Rect(0, 0, 100, 100), NULL).ToString());
3512 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
3514 template <class Types>
3515 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3516 : public OcclusionTrackerTest<Types> {
3517 protected:
3518 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3519 bool opaque_layers)
3520 : OcclusionTrackerTest<Types>(opaque_layers) {}
3521 void RunMyTest() {
3522 gfx::Transform scale_by_half;
3523 scale_by_half.Scale(0.5, 0.5);
3525 // Make a surface and its replica, each 50x50, that are completely
3526 // surrounded by opaque layers which are above them in the z-order. The
3527 // surface is scaled to test that the pixel moving is done in the target
3528 // space, where the background filter is applied, but the surface appears at
3529 // 50, 50 and the replica at 200, 50.
3530 typename Types::ContentLayerType* parent = this->CreateRoot(
3531 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3532 typename Types::LayerType* filtered_surface =
3533 this->CreateDrawingLayer(parent,
3534 scale_by_half,
3535 gfx::PointF(50.f, 50.f),
3536 gfx::Size(100, 100),
3537 false);
3538 this->CreateReplicaLayer(filtered_surface,
3539 this->identity_matrix,
3540 gfx::PointF(300.f, 0.f),
3541 gfx::Size());
3542 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3543 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
3544 typename Types::LayerType* occluding_layer2 =
3545 this->CreateDrawingLayer(parent,
3546 this->identity_matrix,
3547 gfx::PointF(0.f, 100.f),
3548 gfx::Size(300, 50),
3549 true);
3550 typename Types::LayerType* occluding_layer3 =
3551 this->CreateDrawingLayer(parent,
3552 this->identity_matrix,
3553 gfx::PointF(0.f, 50.f),
3554 gfx::Size(50, 50),
3555 true);
3556 typename Types::LayerType* occluding_layer4 =
3557 this->CreateDrawingLayer(parent,
3558 this->identity_matrix,
3559 gfx::PointF(100.f, 50.f),
3560 gfx::Size(100, 50),
3561 true);
3562 typename Types::LayerType* occluding_layer5 =
3563 this->CreateDrawingLayer(parent,
3564 this->identity_matrix,
3565 gfx::PointF(250.f, 50.f),
3566 gfx::Size(50, 50),
3567 true);
3569 // Filters make the layer own a surface.
3570 WebKit::WebFilterOperations filters;
3571 filters.append(WebKit::WebFilterOperation::createBlurFilter(10.f));
3572 filtered_surface->SetBackgroundFilters(filters);
3574 // Save the distance of influence for the blur effect.
3575 int outset_top, outset_right, outset_bottom, outset_left;
3576 filters.getOutsets(outset_top, outset_right, outset_bottom, outset_left);
3578 this->CalcDrawEtc(parent);
3580 TestOcclusionTrackerWithClip<typename Types::LayerType,
3581 typename Types::RenderSurfaceType> occlusion(
3582 gfx::Rect(0, 0, 1000, 1000));
3584 // These layers occlude pixels directly beside the filtered_surface. Because
3585 // filtered surface blends pixels in a radius, it will need to see some of
3586 // the pixels (up to radius far) underneath the occluding layers.
3587 this->VisitLayer(occluding_layer5, &occlusion);
3588 this->VisitLayer(occluding_layer4, &occlusion);
3589 this->VisitLayer(occluding_layer3, &occlusion);
3590 this->VisitLayer(occluding_layer2, &occlusion);
3591 this->VisitLayer(occluding_layer1, &occlusion);
3593 Region expected_occlusion;
3594 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
3595 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3596 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3597 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
3598 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));
3600 EXPECT_EQ(expected_occlusion.ToString(),
3601 occlusion.occlusion_from_inside_target().ToString());
3602 EXPECT_EQ(gfx::Rect().ToString(),
3603 occlusion.occlusion_from_outside_target().ToString());
3605 this->VisitLayer(filtered_surface, &occlusion);
3607 // The filtered layer/replica does not occlude.
3608 Region expected_occlusion_outside_surface;
3609 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
3610 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3611 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3612 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
3613 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));
3615 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3616 occlusion.occlusion_from_outside_target().ToString());
3617 EXPECT_EQ(gfx::Rect().ToString(),
3618 occlusion.occlusion_from_inside_target().ToString());
3620 // The surface has a background blur, so it needs pixels that are currently
3621 // considered occluded in order to be drawn. So the pixels it needs should
3622 // be removed some the occluded area so that when we get to the parent they
3623 // are drawn.
3624 this->VisitContributingSurface(filtered_surface, &occlusion);
3626 this->EnterLayer(parent, &occlusion, false);
3628 Region expected_blurred_occlusion;
3629 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
3630 expected_blurred_occlusion.Union(gfx::Rect(
3631 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
3632 expected_blurred_occlusion.Union(
3633 gfx::Rect(100 + outset_right,
3634 50 - outset_top,
3635 100 - outset_right - outset_left,
3636 50 + outset_top + outset_bottom));
3637 expected_blurred_occlusion.Union(
3638 gfx::Rect(250 + outset_right,
3639 50 - outset_top,
3640 50 - outset_right,
3641 50 + outset_top + outset_bottom));
3642 expected_blurred_occlusion.Union(
3643 gfx::Rect(0, 100 + outset_bottom, 300, 50 - outset_bottom));
3645 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3646 occlusion.occlusion_from_inside_target().ToString());
3647 EXPECT_EQ(gfx::Rect().ToString(),
3648 occlusion.occlusion_from_outside_target().ToString());
3650 gfx::Rect outset_rect;
3651 gfx::Rect test_rect;
3653 // Nothing in the blur outsets for the filtered_surface is occluded.
3654 outset_rect = gfx::Rect(50 - outset_left,
3655 50 - outset_top,
3656 50 + outset_left + outset_right,
3657 50 + outset_top + outset_bottom);
3658 test_rect = outset_rect;
3659 EXPECT_EQ(
3660 outset_rect.ToString(),
3661 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3663 // Stuff outside the blur outsets is still occluded though.
3664 test_rect = outset_rect;
3665 test_rect.Inset(0, 0, -1, 0);
3666 EXPECT_EQ(
3667 outset_rect.ToString(),
3668 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3669 test_rect = outset_rect;
3670 test_rect.Inset(0, 0, 0, -1);
3671 EXPECT_EQ(
3672 outset_rect.ToString(),
3673 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3674 test_rect = outset_rect;
3675 test_rect.Inset(-1, 0, 0, 0);
3676 EXPECT_EQ(
3677 outset_rect.ToString(),
3678 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3679 test_rect = outset_rect;
3680 test_rect.Inset(0, -1, 0, 0);
3681 EXPECT_EQ(
3682 outset_rect.ToString(),
3683 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3685 // Nothing in the blur outsets for the filtered_surface's replica is
3686 // occluded.
3687 outset_rect = gfx::Rect(200 - outset_left,
3688 50 - outset_top,
3689 50 + outset_left + outset_right,
3690 50 + outset_top + outset_bottom);
3691 test_rect = outset_rect;
3692 EXPECT_EQ(
3693 outset_rect.ToString(),
3694 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3696 // Stuff outside the blur outsets is still occluded though.
3697 test_rect = outset_rect;
3698 test_rect.Inset(0, 0, -1, 0);
3699 EXPECT_EQ(
3700 outset_rect.ToString(),
3701 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3702 test_rect = outset_rect;
3703 test_rect.Inset(0, 0, 0, -1);
3704 EXPECT_EQ(
3705 outset_rect.ToString(),
3706 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3707 test_rect = outset_rect;
3708 test_rect.Inset(-1, 0, 0, 0);
3709 EXPECT_EQ(
3710 outset_rect.ToString(),
3711 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3712 test_rect = outset_rect;
3713 test_rect.Inset(0, -1, 0, 0);
3714 EXPECT_EQ(
3715 outset_rect.ToString(),
3716 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3720 ALL_OCCLUSIONTRACKER_TEST(
3721 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
3723 template <class Types>
3724 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3725 : public OcclusionTrackerTest<Types> {
3726 protected:
3727 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3728 bool opaque_layers)
3729 : OcclusionTrackerTest<Types>(opaque_layers) {}
3730 void RunMyTest() {
3731 gfx::Transform scale_by_half;
3732 scale_by_half.Scale(0.5, 0.5);
3734 // Makes two surfaces that completely cover |parent|. The occlusion both
3735 // above and below the filters will be reduced by each of them.
3736 typename Types::ContentLayerType* root = this->CreateRoot(
3737 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
3738 typename Types::LayerType* parent = this->CreateSurface(
3739 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
3740 parent->SetMasksToBounds(true);
3741 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
3742 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3743 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
3744 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3745 typename Types::LayerType* occluding_layer_above =
3746 this->CreateDrawingLayer(parent,
3747 this->identity_matrix,
3748 gfx::PointF(100.f, 100.f),
3749 gfx::Size(50, 50),
3750 true);
3752 // Filters make the layers own surfaces.
3753 WebKit::WebFilterOperations filters;
3754 filters.append(WebKit::WebFilterOperation::createBlurFilter(1.f));
3755 filtered_surface1->SetBackgroundFilters(filters);
3756 filtered_surface2->SetBackgroundFilters(filters);
3758 // Save the distance of influence for the blur effect.
3759 int outset_top, outset_right, outset_bottom, outset_left;
3760 filters.getOutsets(outset_top, outset_right, outset_bottom, outset_left);
3762 this->CalcDrawEtc(root);
3764 TestOcclusionTrackerWithClip<typename Types::LayerType,
3765 typename Types::RenderSurfaceType> occlusion(
3766 gfx::Rect(0, 0, 1000, 1000));
3768 this->VisitLayer(occluding_layer_above, &occlusion);
3769 EXPECT_EQ(gfx::Rect().ToString(),
3770 occlusion.occlusion_from_outside_target().ToString());
3771 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3772 occlusion.occlusion_from_inside_target().ToString());
3774 this->VisitLayer(filtered_surface2, &occlusion);
3775 this->VisitContributingSurface(filtered_surface2, &occlusion);
3776 this->VisitLayer(filtered_surface1, &occlusion);
3777 this->VisitContributingSurface(filtered_surface1, &occlusion);
3779 // Test expectations in the target.
3780 gfx::Rect expected_occlusion =
3781 gfx::Rect(100 / 2 + outset_right * 2,
3782 100 / 2 + outset_bottom * 2,
3783 50 / 2 - (outset_left + outset_right) * 2,
3784 50 / 2 - (outset_top + outset_bottom) * 2);
3785 EXPECT_EQ(expected_occlusion.ToString(),
3786 occlusion.occlusion_from_inside_target().ToString());
3788 // Test expectations in the screen are the same as in the target, as the
3789 // render surface is 1:1 with the screen.
3790 EXPECT_EQ(expected_occlusion.ToString(),
3791 occlusion.occlusion_from_outside_target().ToString());
3795 ALL_OCCLUSIONTRACKER_TEST(
3796 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
3798 template <class Types>
3799 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
3800 : public OcclusionTrackerTest<Types> {
3801 protected:
3802 explicit
3803 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(
3804 bool opaque_layers)
3805 : OcclusionTrackerTest<Types>(opaque_layers) {}
3806 void RunMyTest() {
3807 // Make a surface and its replica, Each 50x50, that are completely
3808 // surrounded by opaque layers which are above them in the z-order.
3809 typename Types::ContentLayerType* parent = this->CreateRoot(
3810 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3811 // We stick the filtered surface inside a clipping surface so that we can
3812 // make sure the clip is honored when exposing pixels for
3813 // the background filter.
3814 typename Types::LayerType* clipping_surface =
3815 this->CreateDrawingSurface(parent,
3816 this->identity_matrix,
3817 gfx::PointF(),
3818 gfx::Size(300, 70),
3819 false);
3820 clipping_surface->SetMasksToBounds(true);
3821 typename Types::LayerType* filtered_surface =
3822 this->CreateDrawingLayer(clipping_surface,
3823 this->identity_matrix,
3824 gfx::PointF(50.f, 50.f),
3825 gfx::Size(50, 50),
3826 false);
3827 this->CreateReplicaLayer(filtered_surface,
3828 this->identity_matrix,
3829 gfx::PointF(150.f, 0.f),
3830 gfx::Size());
3831 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3832 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
3833 typename Types::LayerType* occluding_layer2 =
3834 this->CreateDrawingLayer(parent,
3835 this->identity_matrix,
3836 gfx::PointF(0.f, 100.f),
3837 gfx::Size(300, 50),
3838 true);
3839 typename Types::LayerType* occluding_layer3 =
3840 this->CreateDrawingLayer(parent,
3841 this->identity_matrix,
3842 gfx::PointF(0.f, 50.f),
3843 gfx::Size(50, 50),
3844 true);
3845 typename Types::LayerType* occluding_layer4 =
3846 this->CreateDrawingLayer(parent,
3847 this->identity_matrix,
3848 gfx::PointF(100.f, 50.f),
3849 gfx::Size(100, 50),
3850 true);
3851 typename Types::LayerType* occluding_layer5 =
3852 this->CreateDrawingLayer(parent,
3853 this->identity_matrix,
3854 gfx::PointF(250.f, 50.f),
3855 gfx::Size(50, 50),
3856 true);
3858 // Filters make the layer own a surface. This filter is large enough that it
3859 // goes outside the bottom of the clipping_surface.
3860 WebKit::WebFilterOperations filters;
3861 filters.append(WebKit::WebFilterOperation::createBlurFilter(12.f));
3862 filtered_surface->SetBackgroundFilters(filters);
3864 // Save the distance of influence for the blur effect.
3865 int outset_top, outset_right, outset_bottom, outset_left;
3866 filters.getOutsets(outset_top, outset_right, outset_bottom, outset_left);
3868 this->CalcDrawEtc(parent);
3870 TestOcclusionTrackerWithClip<typename Types::LayerType,
3871 typename Types::RenderSurfaceType> occlusion(
3872 gfx::Rect(0, 0, 1000, 1000));
3874 // These layers occlude pixels directly beside the filtered_surface. Because
3875 // filtered surface blends pixels in a radius, it will need to see some of
3876 // the pixels (up to radius far) underneath the occluding layers.
3877 this->VisitLayer(occluding_layer5, &occlusion);
3878 this->VisitLayer(occluding_layer4, &occlusion);
3879 this->VisitLayer(occluding_layer3, &occlusion);
3880 this->VisitLayer(occluding_layer2, &occlusion);
3881 this->VisitLayer(occluding_layer1, &occlusion);
3883 Region expected_occlusion;
3884 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
3885 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3886 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3887 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
3888 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));
3890 EXPECT_EQ(expected_occlusion.ToString(),
3891 occlusion.occlusion_from_inside_target().ToString());
3892 EXPECT_EQ(gfx::Rect().ToString(),
3893 occlusion.occlusion_from_outside_target().ToString());
3895 // Everything outside the surface/replica is occluded but the
3896 // surface/replica itself is not.
3897 this->VisitLayer(filtered_surface, &occlusion);
3899 // The filtered layer/replica does not occlude.
3900 Region expected_occlusion_outside_surface;
3901 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
3902 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3903 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3904 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
3905 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));
3907 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3908 occlusion.occlusion_from_outside_target().ToString());
3909 EXPECT_EQ(gfx::Rect().ToString(),
3910 occlusion.occlusion_from_inside_target().ToString());
3912 // The surface has a background blur, so it needs pixels that are currently
3913 // considered occluded in order to be drawn. So the pixels it needs should
3914 // be removed some the occluded area so that when we get to the parent they
3915 // are drawn.
3916 this->VisitContributingSurface(filtered_surface, &occlusion);
3918 this->VisitLayer(clipping_surface, &occlusion);
3919 this->EnterContributingSurface(clipping_surface, &occlusion, false);
3921 Region expected_blurred_occlusion;
3922 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
3923 expected_blurred_occlusion.Union(gfx::Rect(
3924 0, 50 - outset_top, 50 - outset_left, 20 + outset_top + outset_bottom));
3925 expected_blurred_occlusion.Union(
3926 gfx::Rect(100 + outset_right,
3927 50 - outset_top,
3928 100 - outset_right - outset_left,
3929 20 + outset_top + outset_bottom));
3930 expected_blurred_occlusion.Union(
3931 gfx::Rect(250 + outset_right,
3932 50 - outset_top,
3933 50 - outset_right,
3934 20 + outset_top + outset_bottom));
3935 expected_blurred_occlusion.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
3937 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3938 occlusion.occlusion_from_outside_target().ToString());
3939 EXPECT_EQ(gfx::Rect().ToString(),
3940 occlusion.occlusion_from_inside_target().ToString());
3942 gfx::Rect outset_rect;
3943 gfx::Rect clipped_outset_rect;
3944 gfx::Rect test_rect;
3946 // Nothing in the (clipped) blur outsets for the filtered_surface is
3947 // occluded.
3948 outset_rect = gfx::Rect(50 - outset_left,
3949 50 - outset_top,
3950 50 + outset_left + outset_right,
3951 50 + outset_top + outset_bottom);
3952 clipped_outset_rect = outset_rect;
3953 clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left,
3954 0 - outset_top,
3955 300 + outset_left + outset_right,
3956 70 + outset_top + outset_bottom));
3957 clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70));
3958 test_rect = outset_rect;
3959 EXPECT_RECT_EQ(
3960 clipped_outset_rect,
3961 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3963 // Stuff outside the (clipped) blur outsets is still occluded though.
3964 test_rect = outset_rect;
3965 test_rect.Inset(0, 0, -1, 0);
3966 EXPECT_RECT_EQ(
3967 clipped_outset_rect,
3968 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3969 test_rect = outset_rect;
3970 test_rect.Inset(0, 0, 0, -1);
3971 EXPECT_RECT_EQ(
3972 clipped_outset_rect,
3973 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3974 test_rect = outset_rect;
3975 test_rect.Inset(-1, 0, 0, 0);
3976 EXPECT_RECT_EQ(
3977 clipped_outset_rect,
3978 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3979 test_rect = outset_rect;
3980 test_rect.Inset(0, -1, 0, 0);
3981 EXPECT_RECT_EQ(
3982 clipped_outset_rect,
3983 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3985 // Nothing in the (clipped) blur outsets for the filtered_surface's replica
3986 // is occluded.
3987 outset_rect = gfx::Rect(200 - outset_left,
3988 50 - outset_top,
3989 50 + outset_left + outset_right,
3990 50 + outset_top + outset_bottom);
3991 clipped_outset_rect = outset_rect;
3992 clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left,
3993 0 - outset_top,
3994 300 + outset_left + outset_right,
3995 70 + outset_top + outset_bottom));
3996 clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70));
3997 test_rect = outset_rect;
3998 EXPECT_RECT_EQ(
3999 clipped_outset_rect,
4000 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4002 // Stuff outside the (clipped) blur outsets is still occluded though.
4003 test_rect = outset_rect;
4004 test_rect.Inset(0, 0, -1, 0);
4005 EXPECT_RECT_EQ(
4006 clipped_outset_rect,
4007 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4008 test_rect = outset_rect;
4009 test_rect.Inset(0, 0, 0, -1);
4010 EXPECT_RECT_EQ(
4011 clipped_outset_rect,
4012 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4013 test_rect = outset_rect;
4014 test_rect.Inset(-1, 0, 0, 0);
4015 EXPECT_RECT_EQ(
4016 clipped_outset_rect,
4017 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4018 test_rect = outset_rect;
4019 test_rect.Inset(0, -1, 0, 0);
4020 EXPECT_RECT_EQ(
4021 clipped_outset_rect,
4022 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4026 ALL_OCCLUSIONTRACKER_TEST(
4027 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
4029 template <class Types>
4030 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
4031 : public OcclusionTrackerTest<Types> {
4032 protected:
4033 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
4034 bool opaque_layers)
4035 : OcclusionTrackerTest<Types>(opaque_layers) {}
4036 void RunMyTest() {
4037 gfx::Transform scale_by_half;
4038 scale_by_half.Scale(0.5, 0.5);
4040 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
4041 // centered below each. The surface is scaled to test that the pixel moving
4042 // is done in the target space, where the background filter is applied, but
4043 // the surface appears at 50, 50 and the replica at 200, 50.
4044 typename Types::ContentLayerType* parent = this->CreateRoot(
4045 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4046 typename Types::LayerType* behind_surface_layer =
4047 this->CreateDrawingLayer(parent,
4048 this->identity_matrix,
4049 gfx::PointF(60.f, 60.f),
4050 gfx::Size(30, 30),
4051 true);
4052 typename Types::LayerType* behind_replica_layer =
4053 this->CreateDrawingLayer(parent,
4054 this->identity_matrix,
4055 gfx::PointF(210.f, 60.f),
4056 gfx::Size(30, 30),
4057 true);
4058 typename Types::LayerType* filtered_surface =
4059 this->CreateDrawingLayer(parent,
4060 scale_by_half,
4061 gfx::PointF(50.f, 50.f),
4062 gfx::Size(100, 100),
4063 false);
4064 this->CreateReplicaLayer(filtered_surface,
4065 this->identity_matrix,
4066 gfx::PointF(300.f, 0.f),
4067 gfx::Size());
4069 // Filters make the layer own a surface.
4070 WebKit::WebFilterOperations filters;
4071 filters.append(WebKit::WebFilterOperation::createBlurFilter(3.f));
4072 filtered_surface->SetBackgroundFilters(filters);
4074 this->CalcDrawEtc(parent);
4076 TestOcclusionTrackerWithClip<typename Types::LayerType,
4077 typename Types::RenderSurfaceType> occlusion(
4078 gfx::Rect(0, 0, 1000, 1000));
4080 // The surface has a background blur, so it blurs non-opaque pixels below
4081 // it.
4082 this->VisitLayer(filtered_surface, &occlusion);
4083 this->VisitContributingSurface(filtered_surface, &occlusion);
4085 this->VisitLayer(behind_replica_layer, &occlusion);
4086 this->VisitLayer(behind_surface_layer, &occlusion);
4088 // The layers behind the surface are not blurred, and their occlusion does
4089 // not change, until we leave the surface. So it should not be modified by
4090 // the filter here.
4091 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
4092 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
4094 Region expected_opaque_bounds =
4095 UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
4096 EXPECT_EQ(expected_opaque_bounds.ToString(),
4097 occlusion.occlusion_from_inside_target().ToString());
4099 EXPECT_EQ(gfx::Rect().ToString(),
4100 occlusion.occlusion_from_outside_target().ToString());
4104 ALL_OCCLUSIONTRACKER_TEST(
4105 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
4107 template <class Types>
4108 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
4109 : public OcclusionTrackerTest<Types> {
4110 protected:
4111 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
4112 bool opaque_layers)
4113 : OcclusionTrackerTest<Types>(opaque_layers) {}
4114 void RunMyTest() {
4115 gfx::Transform scale_by_half;
4116 scale_by_half.Scale(0.5, 0.5);
4118 // Make a surface and its replica, each 50x50, that are completely occluded
4119 // by opaque layers which are above them in the z-order. The surface is
4120 // scaled to test that the pixel moving is done in the target space, where
4121 // the background filter is applied, but the surface appears at 50, 50 and
4122 // the replica at 200, 50.
4123 typename Types::ContentLayerType* parent = this->CreateRoot(
4124 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4125 typename Types::LayerType* filtered_surface =
4126 this->CreateDrawingLayer(parent,
4127 scale_by_half,
4128 gfx::PointF(50.f, 50.f),
4129 gfx::Size(100, 100),
4130 false);
4131 this->CreateReplicaLayer(filtered_surface,
4132 this->identity_matrix,
4133 gfx::PointF(300.f, 0.f),
4134 gfx::Size());
4135 typename Types::LayerType* above_surface_layer =
4136 this->CreateDrawingLayer(parent,
4137 this->identity_matrix,
4138 gfx::PointF(50.f, 50.f),
4139 gfx::Size(50, 50),
4140 true);
4141 typename Types::LayerType* above_replica_layer =
4142 this->CreateDrawingLayer(parent,
4143 this->identity_matrix,
4144 gfx::PointF(200.f, 50.f),
4145 gfx::Size(50, 50),
4146 true);
4148 // Filters make the layer own a surface.
4149 WebKit::WebFilterOperations filters;
4150 filters.append(WebKit::WebFilterOperation::createBlurFilter(3.f));
4151 filtered_surface->SetBackgroundFilters(filters);
4153 this->CalcDrawEtc(parent);
4155 TestOcclusionTrackerWithClip<typename Types::LayerType,
4156 typename Types::RenderSurfaceType> occlusion(
4157 gfx::Rect(0, 0, 1000, 1000));
4159 this->VisitLayer(above_replica_layer, &occlusion);
4160 this->VisitLayer(above_surface_layer, &occlusion);
4162 this->VisitLayer(filtered_surface, &occlusion);
4164 // The layers above the filtered surface occlude from outside.
4165 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
4166 gfx::Rect occlusion_above_replica = gfx::Rect(150, 0, 50, 50);
4167 Region expected_opaque_region =
4168 UnionRegions(occlusion_above_surface, occlusion_above_replica);
4170 EXPECT_EQ(gfx::Rect().ToString(),
4171 occlusion.occlusion_from_inside_target().ToString());
4172 EXPECT_EQ(expected_opaque_region.ToString(),
4173 occlusion.occlusion_from_outside_target().ToString());
4176 // The surface has a background blur, so it blurs non-opaque pixels below
4177 // it.
4178 this->VisitContributingSurface(filtered_surface, &occlusion);
4180 // The filter is completely occluded, so it should not blur anything and
4181 // reduce any occlusion.
4182 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
4183 gfx::Rect occlusion_above_replica = gfx::Rect(200, 50, 50, 50);
4184 Region expected_opaque_region =
4185 UnionRegions(occlusion_above_surface, occlusion_above_replica);
4187 EXPECT_EQ(expected_opaque_region.ToString(),
4188 occlusion.occlusion_from_inside_target().ToString());
4189 EXPECT_EQ(gfx::Rect().ToString(),
4190 occlusion.occlusion_from_outside_target().ToString());
4195 ALL_OCCLUSIONTRACKER_TEST(
4196 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
4198 template <class Types>
4199 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
4200 : public OcclusionTrackerTest<Types> {
4201 protected:
4202 explicit
4203 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
4204 bool opaque_layers)
4205 : OcclusionTrackerTest<Types>(opaque_layers) {}
4206 void RunMyTest() {
4207 gfx::Transform scale_by_half;
4208 scale_by_half.Scale(0.5, 0.5);
4210 // Make a surface and its replica, each 50x50, that are partially occluded
4211 // by opaque layers which are above them in the z-order. The surface is
4212 // scaled to test that the pixel moving is done in the target space, where
4213 // the background filter is applied, but the surface appears at 50, 50 and
4214 // the replica at 200, 50.
4215 typename Types::ContentLayerType* parent = this->CreateRoot(
4216 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4217 typename Types::LayerType* filtered_surface =
4218 this->CreateDrawingLayer(parent,
4219 scale_by_half,
4220 gfx::PointF(50.f, 50.f),
4221 gfx::Size(100, 100),
4222 false);
4223 this->CreateReplicaLayer(filtered_surface,
4224 this->identity_matrix,
4225 gfx::PointF(300.f, 0.f),
4226 gfx::Size());
4227 typename Types::LayerType* above_surface_layer =
4228 this->CreateDrawingLayer(parent,
4229 this->identity_matrix,
4230 gfx::PointF(70.f, 50.f),
4231 gfx::Size(30, 50),
4232 true);
4233 typename Types::LayerType* above_replica_layer =
4234 this->CreateDrawingLayer(parent,
4235 this->identity_matrix,
4236 gfx::PointF(200.f, 50.f),
4237 gfx::Size(30, 50),
4238 true);
4239 typename Types::LayerType* beside_surface_layer =
4240 this->CreateDrawingLayer(parent,
4241 this->identity_matrix,
4242 gfx::PointF(90.f, 40.f),
4243 gfx::Size(10, 10),
4244 true);
4245 typename Types::LayerType* beside_replica_layer =
4246 this->CreateDrawingLayer(parent,
4247 this->identity_matrix,
4248 gfx::PointF(200.f, 40.f),
4249 gfx::Size(10, 10),
4250 true);
4252 // Filters make the layer own a surface.
4253 WebKit::WebFilterOperations filters;
4254 filters.append(WebKit::WebFilterOperation::createBlurFilter(3.f));
4255 filtered_surface->SetBackgroundFilters(filters);
4257 // Save the distance of influence for the blur effect.
4258 int outset_top, outset_right, outset_bottom, outset_left;
4259 filters.getOutsets(outset_top, outset_right, outset_bottom, outset_left);
4261 this->CalcDrawEtc(parent);
4263 TestOcclusionTrackerWithClip<typename Types::LayerType,
4264 typename Types::RenderSurfaceType> occlusion(
4265 gfx::Rect(0, 0, 1000, 1000));
4267 this->VisitLayer(beside_replica_layer, &occlusion);
4268 this->VisitLayer(beside_surface_layer, &occlusion);
4269 this->VisitLayer(above_replica_layer, &occlusion);
4270 this->VisitLayer(above_surface_layer, &occlusion);
4272 // The surface has a background blur, so it blurs non-opaque pixels below
4273 // it.
4274 this->VisitLayer(filtered_surface, &occlusion);
4275 this->VisitContributingSurface(filtered_surface, &occlusion);
4277 // The filter in the surface and replica are partially unoccluded. Only the
4278 // unoccluded parts should reduce occlusion. This means it will push back
4279 // the occlusion that touches the unoccluded part (occlusion_above___), but
4280 // it will not touch occlusion_beside____ since that is not beside the
4281 // unoccluded part of the surface, even though it is beside the occluded
4282 // part of the surface.
4283 gfx::Rect occlusion_above_surface =
4284 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
4285 gfx::Rect occlusion_above_replica =
4286 gfx::Rect(200, 50, 30 - outset_left, 50);
4287 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
4288 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
4290 Region expected_occlusion;
4291 expected_occlusion.Union(occlusion_above_surface);
4292 expected_occlusion.Union(occlusion_above_replica);
4293 expected_occlusion.Union(occlusion_beside_surface);
4294 expected_occlusion.Union(occlusion_beside_replica);
4296 ASSERT_EQ(expected_occlusion.ToString(),
4297 occlusion.occlusion_from_inside_target().ToString());
4298 EXPECT_EQ(gfx::Rect().ToString(),
4299 occlusion.occlusion_from_outside_target().ToString());
4301 Region::Iterator expected_rects(expected_occlusion);
4302 Region::Iterator target_surface_rects(
4303 occlusion.occlusion_from_inside_target());
4304 for (; expected_rects.has_rect();
4305 expected_rects.next(), target_surface_rects.next()) {
4306 ASSERT_TRUE(target_surface_rects.has_rect());
4307 EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
4312 ALL_OCCLUSIONTRACKER_TEST(
4313 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
4315 template <class Types>
4316 class OcclusionTrackerTestMinimumTrackingSize
4317 : public OcclusionTrackerTest<Types> {
4318 protected:
4319 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
4320 : OcclusionTrackerTest<Types>(opaque_layers) {}
4321 void RunMyTest() {
4322 gfx::Size tracking_size(100, 100);
4323 gfx::Size below_tracking_size(99, 99);
4325 typename Types::ContentLayerType* parent = this->CreateRoot(
4326 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4327 typename Types::LayerType* large = this->CreateDrawingLayer(
4328 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
4329 typename Types::LayerType* small =
4330 this->CreateDrawingLayer(parent,
4331 this->identity_matrix,
4332 gfx::PointF(),
4333 below_tracking_size,
4334 true);
4335 this->CalcDrawEtc(parent);
4337 TestOcclusionTrackerWithClip<typename Types::LayerType,
4338 typename Types::RenderSurfaceType> occlusion(
4339 gfx::Rect(0, 0, 1000, 1000));
4340 occlusion.set_minimum_tracking_size(tracking_size);
4342 // The small layer is not tracked because it is too small.
4343 this->VisitLayer(small, &occlusion);
4345 EXPECT_EQ(gfx::Rect().ToString(),
4346 occlusion.occlusion_from_outside_target().ToString());
4347 EXPECT_EQ(gfx::Rect().ToString(),
4348 occlusion.occlusion_from_inside_target().ToString());
4350 // The large layer is tracked as it is large enough.
4351 this->VisitLayer(large, &occlusion);
4353 EXPECT_EQ(gfx::Rect().ToString(),
4354 occlusion.occlusion_from_outside_target().ToString());
4355 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
4356 occlusion.occlusion_from_inside_target().ToString());
4360 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
4362 template <class Types>
4363 class OcclusionTrackerTestViewportClipIsExternalOcclusion
4364 : public OcclusionTrackerTest<Types> {
4365 protected:
4366 explicit OcclusionTrackerTestViewportClipIsExternalOcclusion(
4367 bool opaque_layers)
4368 : OcclusionTrackerTest<Types>(opaque_layers) {}
4369 void RunMyTest() {
4370 typename Types::ContentLayerType* parent = this->CreateRoot(
4371 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4372 typename Types::LayerType* small =
4373 this->CreateDrawingSurface(parent,
4374 this->identity_matrix,
4375 gfx::PointF(),
4376 gfx::Size(200, 200),
4377 false);
4378 typename Types::LayerType* large =
4379 this->CreateDrawingLayer(small,
4380 this->identity_matrix,
4381 gfx::PointF(),
4382 gfx::Size(400, 400),
4383 false);
4384 small->SetMasksToBounds(true);
4385 this->CalcDrawEtc(parent);
4387 TestOcclusionTrackerWithClip<typename Types::LayerType,
4388 typename Types::RenderSurfaceType> occlusion(
4389 gfx::Rect(0, 0, 100, 100));
4391 this->EnterLayer(large, &occlusion, false);
4393 bool has_occlusion_from_outside_target_surface = false;
4394 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4395 occlusion.UnoccludedLayerContentRect(
4396 large,
4397 gfx::Rect(0, 0, 400, 400),
4398 &has_occlusion_from_outside_target_surface));
4399 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4401 has_occlusion_from_outside_target_surface = false;
4402 EXPECT_FALSE(
4403 occlusion.OccludedLayer(large,
4404 gfx::Rect(0, 0, 400, 400),
4405 &has_occlusion_from_outside_target_surface));
4406 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4408 this->LeaveLayer(large, &occlusion);
4409 this->VisitLayer(small, &occlusion);
4411 has_occlusion_from_outside_target_surface = false;
4412 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4413 occlusion.UnoccludedLayerContentRect(
4414 small,
4415 gfx::Rect(0, 0, 200, 200),
4416 &has_occlusion_from_outside_target_surface));
4417 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4419 has_occlusion_from_outside_target_surface = false;
4420 EXPECT_FALSE(
4421 occlusion.OccludedLayer(small,
4422 gfx::Rect(0, 0, 200, 200),
4423 &has_occlusion_from_outside_target_surface));
4424 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4426 this->EnterContributingSurface(small, &occlusion, false);
4428 has_occlusion_from_outside_target_surface = false;
4429 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4430 occlusion.UnoccludedContributingSurfaceContentRect(
4431 small,
4432 false,
4433 gfx::Rect(0, 0, 200, 200),
4434 &has_occlusion_from_outside_target_surface));
4435 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4439 ALL_OCCLUSIONTRACKER_TEST(
4440 OcclusionTrackerTestViewportClipIsExternalOcclusion)
4442 template <class Types>
4443 class OcclusionTrackerTestLayerClipIsExternalOcclusion
4444 : public OcclusionTrackerTest<Types> {
4445 protected:
4446 explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers)
4447 : OcclusionTrackerTest<Types>(opaque_layers) {}
4448 void RunMyTest() {
4449 typename Types::ContentLayerType* parent = this->CreateRoot(
4450 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4451 typename Types::LayerType* smallest = this->CreateDrawingLayer(
4452 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4453 typename Types::LayerType* smaller =
4454 this->CreateDrawingSurface(smallest,
4455 this->identity_matrix,
4456 gfx::PointF(),
4457 gfx::Size(100, 100),
4458 false);
4459 typename Types::LayerType* small =
4460 this->CreateDrawingSurface(smaller,
4461 this->identity_matrix,
4462 gfx::PointF(),
4463 gfx::Size(200, 200),
4464 false);
4465 typename Types::LayerType* large =
4466 this->CreateDrawingLayer(small,
4467 this->identity_matrix,
4468 gfx::PointF(),
4469 gfx::Size(400, 400),
4470 false);
4471 smallest->SetMasksToBounds(true);
4472 smaller->SetMasksToBounds(true);
4473 small->SetMasksToBounds(true);
4474 this->CalcDrawEtc(parent);
4476 TestOcclusionTrackerWithClip<typename Types::LayerType,
4477 typename Types::RenderSurfaceType> occlusion(
4478 gfx::Rect(0, 0, 1000, 1000));
4480 this->EnterLayer(large, &occlusion, false);
4482 // Clipping from the smaller layer is from outside the target surface.
4483 bool has_occlusion_from_outside_target_surface = false;
4484 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4485 occlusion.UnoccludedLayerContentRect(
4486 large,
4487 gfx::Rect(0, 0, 400, 400),
4488 &has_occlusion_from_outside_target_surface));
4489 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4491 has_occlusion_from_outside_target_surface = false;
4492 EXPECT_FALSE(
4493 occlusion.OccludedLayer(large,
4494 gfx::Rect(0, 0, 400, 400),
4495 &has_occlusion_from_outside_target_surface));
4496 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4498 this->LeaveLayer(large, &occlusion);
4499 this->VisitLayer(small, &occlusion);
4501 // Clipping from the smaller layer is from outside the target surface.
4502 has_occlusion_from_outside_target_surface = false;
4503 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4504 occlusion.UnoccludedLayerContentRect(
4505 small,
4506 gfx::Rect(0, 0, 200, 200),
4507 &has_occlusion_from_outside_target_surface));
4508 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4510 has_occlusion_from_outside_target_surface = false;
4511 EXPECT_FALSE(
4512 occlusion.OccludedLayer(small,
4513 gfx::Rect(0, 0, 200, 200),
4514 &has_occlusion_from_outside_target_surface));
4515 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4517 this->EnterContributingSurface(small, &occlusion, false);
4519 // The |small| surface is clipped from outside its target by |smallest|.
4520 has_occlusion_from_outside_target_surface = false;
4521 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4522 occlusion.UnoccludedContributingSurfaceContentRect(
4523 small,
4524 false,
4525 gfx::Rect(0, 0, 200, 200),
4526 &has_occlusion_from_outside_target_surface));
4527 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4529 this->LeaveContributingSurface(small, &occlusion);
4530 this->VisitLayer(smaller, &occlusion);
4531 this->EnterContributingSurface(smaller, &occlusion, false);
4533 // The |smaller| surface is clipped from inside its target by |smallest|.
4534 has_occlusion_from_outside_target_surface = false;
4535 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4536 occlusion.UnoccludedContributingSurfaceContentRect(
4537 smaller,
4538 false,
4539 gfx::Rect(0, 0, 100, 100),
4540 &has_occlusion_from_outside_target_surface));
4541 EXPECT_FALSE(has_occlusion_from_outside_target_surface);
4545 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion)
4547 template <class Types>
4548 class OcclusionTrackerTestPreventOcclusionOnLayer
4549 : public OcclusionTrackerTest<Types> {
4550 protected:
4551 explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers)
4552 : OcclusionTrackerTest<Types>(opaque_layers) {}
4553 void RunMyTest() {
4554 typename Types::ContentLayerType* parent = this->CreateRoot(
4555 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4556 typename Types::LayerType* unprevented = this->CreateDrawingLayer(
4557 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4558 typename Types::LayerType* prevented = this->CreateDrawingLayer(
4559 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4560 typename Types::LayerType* occluding = this->CreateDrawingLayer(
4561 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
4562 this->CalcDrawEtc(parent);
4564 TestOcclusionTrackerWithClip<typename Types::LayerType,
4565 typename Types::RenderSurfaceType> occlusion(
4566 gfx::Rect(0, 0, 1000, 1000));
4567 bool external_occlusion = false;
4569 this->VisitLayer(occluding, &occlusion);
4570 this->EnterLayer(prevented, &occlusion, true);
4572 // This layer is not occluded because it is prevented.
4573 EXPECT_FALSE(occlusion.OccludedLayer(prevented,
4574 gfx::Rect(50, 50),
4575 &external_occlusion));
4576 EXPECT_FALSE(external_occlusion);
4578 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4579 occlusion.UnoccludedLayerContentRect(
4580 prevented,
4581 gfx::Rect(50, 50),
4582 &external_occlusion).ToString());
4583 EXPECT_FALSE(external_occlusion);
4585 this->LeaveLayer(prevented, &occlusion);
4586 this->EnterLayer(unprevented, &occlusion, false);
4588 // This layer is fully occluded.
4589 EXPECT_TRUE(occlusion.OccludedLayer(unprevented,
4590 gfx::Rect(50, 50),
4591 &external_occlusion));
4592 EXPECT_FALSE(external_occlusion);
4594 EXPECT_EQ(gfx::Rect().ToString(),
4595 occlusion.UnoccludedLayerContentRect(
4596 unprevented,
4597 gfx::Rect(50, 50),
4598 &external_occlusion).ToString());
4599 EXPECT_FALSE(external_occlusion);
4601 this->LeaveLayer(unprevented, &occlusion);
4605 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer)
4607 template <class Types>
4608 class OcclusionTrackerTestPreventOcclusionOnContributingSurface
4609 : public OcclusionTrackerTest<Types> {
4610 protected:
4611 explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface(
4612 bool opaque_layers)
4613 : OcclusionTrackerTest<Types>(opaque_layers) {}
4614 void RunMyTest() {
4615 typename Types::ContentLayerType* parent = this->CreateRoot(
4616 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4617 typename Types::LayerType* unprevented = this->CreateDrawingSurface(
4618 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4619 typename Types::LayerType* prevented = this->CreateDrawingSurface(
4620 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4621 typename Types::LayerType* occluding = this->CreateDrawingLayer(
4622 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
4623 this->CalcDrawEtc(parent);
4625 TestOcclusionTrackerWithClip<typename Types::LayerType,
4626 typename Types::RenderSurfaceType> occlusion(
4627 gfx::Rect(0, 0, 1000, 1000));
4628 bool external_occlusion = false;
4630 this->VisitLayer(occluding, &occlusion);
4631 this->EnterLayer(prevented, &occlusion, true);
4633 // This layer is not occluded because it is prevented.
4634 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4635 occlusion.UnoccludedLayerContentRect(
4636 prevented,
4637 gfx::Rect(50, 50),
4638 &external_occlusion).ToString());
4639 EXPECT_FALSE(external_occlusion);
4641 this->LeaveLayer(prevented, &occlusion);
4642 this->EnterContributingSurface(prevented, &occlusion, true);
4644 // This contributing surface is not occluded because it is prevented.
4645 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4646 occlusion.UnoccludedContributingSurfaceContentRect(
4647 prevented,
4648 false, // is_replica
4649 gfx::Rect(50, 50),
4650 &external_occlusion).ToString());
4651 EXPECT_FALSE(external_occlusion);
4653 this->LeaveContributingSurface(prevented, &occlusion);
4654 this->EnterLayer(unprevented, &occlusion, false);
4656 // This layer is fully occluded from outside its surface.
4657 EXPECT_EQ(gfx::Rect().ToString(),
4658 occlusion.UnoccludedLayerContentRect(
4659 unprevented,
4660 gfx::Rect(50, 50),
4661 &external_occlusion).ToString());
4662 EXPECT_TRUE(external_occlusion);
4664 this->LeaveLayer(unprevented, &occlusion);
4665 this->EnterContributingSurface(unprevented, &occlusion, false);
4667 // This contributing surface is fully occluded.
4668 EXPECT_EQ(gfx::Rect().ToString(),
4669 occlusion.UnoccludedContributingSurfaceContentRect(
4670 unprevented,
4671 false, // is_replica
4672 gfx::Rect(50, 50),
4673 &external_occlusion).ToString());
4674 EXPECT_FALSE(external_occlusion);
4676 this->LeaveContributingSurface(unprevented, &occlusion);
4680 ALL_OCCLUSIONTRACKER_TEST(
4681 OcclusionTrackerTestPreventOcclusionOnContributingSurface)
4683 template <class Types>
4684 class OcclusionTrackerTestPreventOcclusionByClipping
4685 : public OcclusionTrackerTest<Types> {
4686 protected:
4687 explicit OcclusionTrackerTestPreventOcclusionByClipping(bool opaque_layers)
4688 : OcclusionTrackerTest<Types>(opaque_layers) {}
4689 void RunMyTest() {
4690 typename Types::ContentLayerType* parent = this->CreateRoot(
4691 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4692 typename Types::LayerType* unprevented = this->CreateDrawingLayer(
4693 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4694 typename Types::LayerType* prevented = this->CreateDrawingLayer(
4695 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4696 this->CalcDrawEtc(parent);
4698 TestOcclusionTrackerWithClip<typename Types::LayerType,
4699 typename Types::RenderSurfaceType> occlusion(
4700 gfx::Rect(0, 0, 10, 10));
4701 bool external_occlusion = false;
4703 this->EnterLayer(prevented, &occlusion, true);
4705 // This layer is not occluded because it is prevented.
4706 EXPECT_FALSE(occlusion.OccludedLayer(prevented,
4707 gfx::Rect(50, 50),
4708 &external_occlusion));
4709 EXPECT_FALSE(external_occlusion);
4711 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4712 occlusion.UnoccludedLayerContentRect(
4713 prevented,
4714 gfx::Rect(50, 50),
4715 &external_occlusion).ToString());
4716 EXPECT_FALSE(external_occlusion);
4718 this->LeaveLayer(prevented, &occlusion);
4719 this->EnterLayer(unprevented, &occlusion, false);
4721 // This layer is clipped by the screen space clip rect.
4722 EXPECT_EQ(gfx::Rect(10, 10).ToString(),
4723 occlusion.UnoccludedLayerContentRect(
4724 unprevented,
4725 gfx::Rect(50, 50),
4726 &external_occlusion).ToString());
4727 EXPECT_TRUE(external_occlusion);
4729 this->LeaveLayer(unprevented, &occlusion);
4733 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionByClipping)
4735 template <class Types>
4736 class OcclusionTrackerTestScaledLayerIsClipped
4737 : public OcclusionTrackerTest<Types> {
4738 protected:
4739 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
4740 : OcclusionTrackerTest<Types>(opaque_layers) {}
4741 void RunMyTest() {
4742 gfx::Transform scale_transform;
4743 scale_transform.Scale(512.0, 512.0);
4745 typename Types::ContentLayerType* parent = this->CreateRoot(
4746 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4747 typename Types::LayerType* clip = this->CreateLayer(parent,
4748 this->identity_matrix,
4749 gfx::PointF(10.f, 10.f),
4750 gfx::Size(50, 50));
4751 clip->SetMasksToBounds(true);
4752 typename Types::LayerType* scale = this->CreateLayer(
4753 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
4754 typename Types::LayerType* scaled = this->CreateDrawingLayer(
4755 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
4756 this->CalcDrawEtc(parent);
4758 TestOcclusionTrackerWithClip<typename Types::LayerType,
4759 typename Types::RenderSurfaceType> occlusion(
4760 gfx::Rect(0, 0, 1000, 1000));
4762 this->VisitLayer(scaled, &occlusion);
4764 EXPECT_EQ(gfx::Rect().ToString(),
4765 occlusion.occlusion_from_outside_target().ToString());
4766 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
4767 occlusion.occlusion_from_inside_target().ToString());
4771 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
4773 template <class Types>
4774 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
4775 : public OcclusionTrackerTest<Types> {
4776 protected:
4777 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
4778 : OcclusionTrackerTest<Types>(opaque_layers) {}
4779 void RunMyTest() {
4780 gfx::Transform scale_transform;
4781 scale_transform.Scale(512.0, 512.0);
4783 typename Types::ContentLayerType* parent = this->CreateRoot(
4784 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4785 typename Types::LayerType* clip = this->CreateLayer(parent,
4786 this->identity_matrix,
4787 gfx::PointF(10.f, 10.f),
4788 gfx::Size(50, 50));
4789 clip->SetMasksToBounds(true);
4790 typename Types::LayerType* surface = this->CreateDrawingSurface(
4791 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
4792 typename Types::LayerType* scale = this->CreateLayer(
4793 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
4794 typename Types::LayerType* scaled = this->CreateDrawingLayer(
4795 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
4796 this->CalcDrawEtc(parent);
4798 TestOcclusionTrackerWithClip<typename Types::LayerType,
4799 typename Types::RenderSurfaceType> occlusion(
4800 gfx::Rect(0, 0, 1000, 1000));
4802 this->VisitLayer(scaled, &occlusion);
4803 this->VisitLayer(surface, &occlusion);
4804 this->VisitContributingSurface(surface, &occlusion);
4806 EXPECT_EQ(gfx::Rect().ToString(),
4807 occlusion.occlusion_from_outside_target().ToString());
4808 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
4809 occlusion.occlusion_from_inside_target().ToString());
4813 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
4815 } // namespace
4816 } // namespace cc