Fix build break
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob9741d634036fe228d7455cbccff84b91b2071293
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 dummy_max_texture_size,
322 false,
323 &render_surface_layer_list_impl_,
324 false);
326 layer_iterator_ = layer_iterator_begin_ =
327 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
330 void CalcDrawEtc(TestContentLayer* root) {
331 DCHECK(root == root_.get());
332 int dummy_max_texture_size = 512;
334 DCHECK(!root->render_surface());
336 LayerTreeHostCommon::CalculateDrawProperties(root,
337 root->bounds(),
338 1.f,
339 1.f,
340 dummy_max_texture_size,
341 false,
342 &render_surface_layer_list_);
344 layer_iterator_ = layer_iterator_begin_ =
345 Types::TestLayerIterator::Begin(&render_surface_layer_list_);
348 void EnterLayer(typename Types::LayerType* layer,
349 typename Types::OcclusionTrackerType* occlusion) {
350 ASSERT_EQ(layer, *layer_iterator_);
351 ASSERT_TRUE(layer_iterator_.represents_itself());
352 occlusion->EnterLayer(layer_iterator_);
355 void LeaveLayer(typename Types::LayerType* layer,
356 typename Types::OcclusionTrackerType* occlusion) {
357 ASSERT_EQ(layer, *layer_iterator_);
358 ASSERT_TRUE(layer_iterator_.represents_itself());
359 occlusion->LeaveLayer(layer_iterator_);
360 ++layer_iterator_;
363 void VisitLayer(typename Types::LayerType* layer,
364 typename Types::OcclusionTrackerType* occlusion) {
365 EnterLayer(layer, occlusion);
366 LeaveLayer(layer, occlusion);
369 void EnterContributingSurface(
370 typename Types::LayerType* layer,
371 typename Types::OcclusionTrackerType* occlusion) {
372 ASSERT_EQ(layer, *layer_iterator_);
373 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
374 occlusion->EnterLayer(layer_iterator_);
375 occlusion->LeaveLayer(layer_iterator_);
376 ++layer_iterator_;
377 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
378 occlusion->EnterLayer(layer_iterator_);
381 void LeaveContributingSurface(
382 typename Types::LayerType* layer,
383 typename Types::OcclusionTrackerType* occlusion) {
384 ASSERT_EQ(layer, *layer_iterator_);
385 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
386 occlusion->LeaveLayer(layer_iterator_);
387 ++layer_iterator_;
390 void VisitContributingSurface(
391 typename Types::LayerType* layer,
392 typename Types::OcclusionTrackerType* occlusion) {
393 EnterContributingSurface(layer, occlusion);
394 LeaveContributingSurface(layer, occlusion);
397 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
399 const gfx::Transform identity_matrix;
401 private:
402 void SetBaseProperties(typename Types::LayerType* layer,
403 const gfx::Transform& transform,
404 gfx::PointF position,
405 gfx::Size bounds) {
406 layer->SetTransform(transform);
407 layer->SetSublayerTransform(gfx::Transform());
408 layer->SetAnchorPoint(gfx::PointF());
409 layer->SetPosition(position);
410 layer->SetBounds(bounds);
413 void SetProperties(Layer* layer,
414 const gfx::Transform& transform,
415 gfx::PointF position,
416 gfx::Size bounds) {
417 SetBaseProperties(layer, transform, position, bounds);
420 void SetProperties(LayerImpl* layer,
421 const gfx::Transform& transform,
422 gfx::PointF position,
423 gfx::Size bounds) {
424 SetBaseProperties(layer, transform, position, bounds);
426 layer->SetContentBounds(layer->bounds());
429 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
430 owning_layer->SetReplicaLayer(layer.get());
431 replica_layers_.push_back(layer);
434 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
435 owning_layer->SetReplicaLayer(layer.Pass());
438 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
439 owning_layer->SetMaskLayer(layer.get());
440 mask_layers_.push_back(layer);
443 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
444 owning_layer->SetMaskLayer(layer.Pass());
447 FakeImplProxy proxy_;
448 FakeLayerTreeHostImpl host_impl_;
449 bool opaque_layers_;
450 // These hold ownership of the layers for the duration of the test.
451 typename Types::LayerPtrType root_;
452 LayerList render_surface_layer_list_;
453 LayerImplList render_surface_layer_list_impl_;
454 typename Types::TestLayerIterator layer_iterator_begin_;
455 typename Types::TestLayerIterator layer_iterator_;
456 typename Types::LayerType* last_layer_visited_;
457 LayerList replica_layers_;
458 LayerList mask_layers_;
461 template <>
462 LayerTreeHost*
463 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
464 return NULL;
467 template <>
468 LayerTreeImpl*
469 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
470 return host_impl_.active_tree();
473 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
474 class ClassName##MainThreadOpaqueLayers \
475 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
476 public: /* NOLINT(whitespace/indent) */ \
477 ClassName##MainThreadOpaqueLayers() \
478 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
479 }; \
480 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
481 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
482 class ClassName##MainThreadOpaquePaints \
483 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
484 public: /* NOLINT(whitespace/indent) */ \
485 ClassName##MainThreadOpaquePaints() \
486 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
487 }; \
488 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
490 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
491 class ClassName##ImplThreadOpaqueLayers \
492 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
493 public: /* NOLINT(whitespace/indent) */ \
494 ClassName##ImplThreadOpaqueLayers() \
495 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
496 }; \
497 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
498 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
499 class ClassName##ImplThreadOpaquePaints \
500 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
501 public: /* NOLINT(whitespace/indent) */ \
502 ClassName##ImplThreadOpaquePaints() \
503 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
504 }; \
505 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
507 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
508 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
509 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
510 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
511 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
513 #define MAIN_THREAD_TEST(ClassName) \
514 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
516 #define IMPL_THREAD_TEST(ClassName) \
517 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
519 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
520 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
521 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
523 template <class Types>
524 class OcclusionTrackerTestIdentityTransforms
525 : public OcclusionTrackerTest<Types> {
526 protected:
527 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
528 : OcclusionTrackerTest<Types>(opaque_layers) {}
530 void RunMyTest() {
531 typename Types::ContentLayerType* root = this->CreateRoot(
532 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
533 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
534 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
535 typename Types::ContentLayerType* layer =
536 this->CreateDrawingLayer(parent,
537 this->identity_matrix,
538 gfx::PointF(30.f, 30.f),
539 gfx::Size(500, 500),
540 true);
541 parent->SetMasksToBounds(true);
542 this->CalcDrawEtc(root);
544 TestOcclusionTrackerWithClip<typename Types::LayerType,
545 typename Types::RenderSurfaceType> occlusion(
546 gfx::Rect(0, 0, 1000, 1000), false);
548 this->VisitLayer(layer, &occlusion);
549 this->EnterLayer(parent, &occlusion);
551 EXPECT_EQ(gfx::Rect().ToString(),
552 occlusion.occlusion_from_outside_target().ToString());
553 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
554 occlusion.occlusion_from_inside_target().ToString());
556 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
557 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
558 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
559 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
560 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
562 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
563 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
564 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
565 occlusion.UnoccludedLayerContentRect(
566 parent, gfx::Rect(29, 30, 70, 70)));
567 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
568 occlusion.UnoccludedLayerContentRect(
569 parent, gfx::Rect(29, 29, 70, 70)));
570 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
571 occlusion.UnoccludedLayerContentRect(
572 parent, gfx::Rect(30, 29, 70, 70)));
573 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
574 occlusion.UnoccludedLayerContentRect(
575 parent, gfx::Rect(31, 29, 70, 70)));
576 EXPECT_RECT_EQ(gfx::Rect(),
577 occlusion.UnoccludedLayerContentRect(
578 parent, gfx::Rect(31, 30, 70, 70)));
579 EXPECT_RECT_EQ(gfx::Rect(),
580 occlusion.UnoccludedLayerContentRect(
581 parent, gfx::Rect(31, 31, 70, 70)));
582 EXPECT_RECT_EQ(gfx::Rect(),
583 occlusion.UnoccludedLayerContentRect(
584 parent, gfx::Rect(30, 31, 70, 70)));
585 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
586 occlusion.UnoccludedLayerContentRect(
587 parent, gfx::Rect(29, 31, 70, 70)));
591 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
593 template <class Types>
594 class OcclusionTrackerTestQuadsMismatchLayer
595 : public OcclusionTrackerTest<Types> {
596 protected:
597 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
598 : OcclusionTrackerTest<Types>(opaque_layers) {}
599 void RunMyTest() {
600 gfx::Transform layer_transform;
601 layer_transform.Translate(10.0, 10.0);
603 typename Types::ContentLayerType* parent = this->CreateRoot(
604 this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
605 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
606 parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
607 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
608 layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
609 this->CalcDrawEtc(parent);
611 TestOcclusionTrackerWithClip<typename Types::LayerType,
612 typename Types::RenderSurfaceType> occlusion(
613 gfx::Rect(0, 0, 1000, 1000));
615 this->VisitLayer(layer2, &occlusion);
616 this->EnterLayer(layer1, &occlusion);
618 EXPECT_EQ(gfx::Rect().ToString(),
619 occlusion.occlusion_from_outside_target().ToString());
620 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
621 occlusion.occlusion_from_inside_target().ToString());
623 // This checks cases where the quads don't match their "containing"
624 // layers, e.g. in terms of transforms or clip rect. This is typical for
625 // DelegatedRendererLayer.
627 gfx::Transform quad_transform;
628 quad_transform.Translate(30.0, 30.0);
629 gfx::Rect clip_rect_in_target(0, 0, 100, 100);
631 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent,
632 gfx::Rect(0, 0, 10, 10),
633 quad_transform,
634 false,
635 true,
636 clip_rect_in_target,
637 NULL).IsEmpty());
638 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
639 occlusion.UnoccludedContentRect(parent,
640 gfx::Rect(0, 0, 10, 10),
641 quad_transform,
642 true,
643 true,
644 clip_rect_in_target,
645 NULL));
646 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
647 occlusion.UnoccludedContentRect(parent,
648 gfx::Rect(40, 40, 10, 10),
649 quad_transform,
650 false,
651 true,
652 clip_rect_in_target,
653 NULL));
654 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
655 occlusion.UnoccludedContentRect(parent,
656 gfx::Rect(35, 30, 10, 10),
657 quad_transform,
658 false,
659 true,
660 clip_rect_in_target,
661 NULL));
662 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5),
663 occlusion.UnoccludedContentRect(parent,
664 gfx::Rect(40, 40, 10, 10),
665 quad_transform,
666 false,
667 true,
668 gfx::Rect(0, 0, 75, 75),
669 NULL));
673 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
675 template <class Types>
676 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
677 protected:
678 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
679 : OcclusionTrackerTest<Types>(opaque_layers) {}
680 void RunMyTest() {
681 gfx::Transform layer_transform;
682 layer_transform.Translate(250.0, 250.0);
683 layer_transform.Rotate(90.0);
684 layer_transform.Translate(-250.0, -250.0);
686 typename Types::ContentLayerType* root = this->CreateRoot(
687 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
688 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
689 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
690 typename Types::ContentLayerType* layer =
691 this->CreateDrawingLayer(parent,
692 layer_transform,
693 gfx::PointF(30.f, 30.f),
694 gfx::Size(500, 500),
695 true);
696 parent->SetMasksToBounds(true);
697 this->CalcDrawEtc(root);
699 TestOcclusionTrackerWithClip<typename Types::LayerType,
700 typename Types::RenderSurfaceType> occlusion(
701 gfx::Rect(0, 0, 1000, 1000));
703 this->VisitLayer(layer, &occlusion);
704 this->EnterLayer(parent, &occlusion);
706 EXPECT_EQ(gfx::Rect().ToString(),
707 occlusion.occlusion_from_outside_target().ToString());
708 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
709 occlusion.occlusion_from_inside_target().ToString());
711 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
712 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
713 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
714 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
715 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
717 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
718 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
719 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
720 occlusion.UnoccludedLayerContentRect(
721 parent, gfx::Rect(29, 30, 70, 70)));
722 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
723 occlusion.UnoccludedLayerContentRect(
724 parent, gfx::Rect(29, 29, 70, 70)));
725 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
726 occlusion.UnoccludedLayerContentRect(
727 parent, gfx::Rect(30, 29, 70, 70)));
728 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
729 occlusion.UnoccludedLayerContentRect(
730 parent, gfx::Rect(31, 29, 70, 70)));
731 EXPECT_RECT_EQ(gfx::Rect(),
732 occlusion.UnoccludedLayerContentRect(
733 parent, gfx::Rect(31, 30, 70, 70)));
734 EXPECT_RECT_EQ(gfx::Rect(),
735 occlusion.UnoccludedLayerContentRect(
736 parent, gfx::Rect(31, 31, 70, 70)));
737 EXPECT_RECT_EQ(gfx::Rect(),
738 occlusion.UnoccludedLayerContentRect(
739 parent, gfx::Rect(30, 31, 70, 70)));
740 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
741 occlusion.UnoccludedLayerContentRect(
742 parent, gfx::Rect(29, 31, 70, 70)));
746 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
748 template <class Types>
749 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
750 protected:
751 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
752 : OcclusionTrackerTest<Types>(opaque_layers) {}
753 void RunMyTest() {
754 gfx::Transform layer_transform;
755 layer_transform.Translate(20.0, 20.0);
757 typename Types::ContentLayerType* root = this->CreateRoot(
758 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
759 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
760 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
761 typename Types::ContentLayerType* layer =
762 this->CreateDrawingLayer(parent,
763 layer_transform,
764 gfx::PointF(30.f, 30.f),
765 gfx::Size(500, 500),
766 true);
767 parent->SetMasksToBounds(true);
768 this->CalcDrawEtc(root);
770 TestOcclusionTrackerWithClip<typename Types::LayerType,
771 typename Types::RenderSurfaceType> occlusion(
772 gfx::Rect(0, 0, 1000, 1000));
774 this->VisitLayer(layer, &occlusion);
775 this->EnterLayer(parent, &occlusion);
777 EXPECT_EQ(gfx::Rect().ToString(),
778 occlusion.occlusion_from_outside_target().ToString());
779 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
780 occlusion.occlusion_from_inside_target().ToString());
782 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
783 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
784 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
785 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 50, 50)));
786 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 50)));
788 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
789 parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
790 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
791 occlusion.UnoccludedLayerContentRect(
792 parent, gfx::Rect(49, 50, 50, 50)));
793 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
794 occlusion.UnoccludedLayerContentRect(
795 parent, gfx::Rect(49, 49, 50, 50)));
796 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
797 occlusion.UnoccludedLayerContentRect(
798 parent, gfx::Rect(50, 49, 50, 50)));
799 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
800 occlusion.UnoccludedLayerContentRect(
801 parent, gfx::Rect(51, 49, 50, 50)));
802 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
803 parent, gfx::Rect(51, 50, 50, 50)).IsEmpty());
804 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
805 parent, gfx::Rect(51, 51, 50, 50)).IsEmpty());
806 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
807 parent, gfx::Rect(50, 51, 50, 50)).IsEmpty());
808 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
809 occlusion.UnoccludedLayerContentRect(
810 parent, gfx::Rect(49, 51, 50, 50)));
814 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
816 template <class Types>
817 class OcclusionTrackerTestChildInRotatedChild
818 : public OcclusionTrackerTest<Types> {
819 protected:
820 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
821 : OcclusionTrackerTest<Types>(opaque_layers) {}
822 void RunMyTest() {
823 gfx::Transform child_transform;
824 child_transform.Translate(250.0, 250.0);
825 child_transform.Rotate(90.0);
826 child_transform.Translate(-250.0, -250.0);
828 typename Types::ContentLayerType* parent = this->CreateRoot(
829 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
830 parent->SetMasksToBounds(true);
831 typename Types::LayerType* child = this->CreateLayer(
832 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
833 child->SetMasksToBounds(true);
834 typename Types::ContentLayerType* layer =
835 this->CreateDrawingLayer(child,
836 this->identity_matrix,
837 gfx::PointF(10.f, 10.f),
838 gfx::Size(500, 500),
839 true);
840 this->CalcDrawEtc(parent);
842 TestOcclusionTrackerWithClip<typename Types::LayerType,
843 typename Types::RenderSurfaceType> occlusion(
844 gfx::Rect(0, 0, 1000, 1000));
846 this->VisitLayer(layer, &occlusion);
847 this->EnterContributingSurface(child, &occlusion);
849 EXPECT_EQ(gfx::Rect().ToString(),
850 occlusion.occlusion_from_outside_target().ToString());
851 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
852 occlusion.occlusion_from_inside_target().ToString());
854 this->LeaveContributingSurface(child, &occlusion);
855 this->EnterLayer(parent, &occlusion);
857 EXPECT_EQ(gfx::Rect().ToString(),
858 occlusion.occlusion_from_outside_target().ToString());
859 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
860 occlusion.occlusion_from_inside_target().ToString());
862 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
863 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
864 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
865 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 70, 60)));
866 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 60)));
868 /* Justification for the above occlusion from |layer|:
870 +---------------------+
872 | 30 | rotate(90)
873 | 30 + ---------------------------------+
874 100 | | 10 | | ==>
875 | |10+---------------------------------+
876 | | | | | |
877 | | | | | |
878 | | | | | |
879 +----|--|-------------+ | |
880 | | | |
881 | | | |
882 | | | |500
883 | | | |
884 | | | |
885 | | | |
886 | | | |
887 +--|-------------------------------+ |
889 +---------------------------------+
892 +---------------------+
893 | |30 Visible region of |layer|: /////
895 | +---------------------------------+
896 100| | |10 |
897 | +---------------------------------+ |
898 | | |///////////////| 420 | |
899 | | |///////////////|60 | |
900 | | |///////////////| | |
901 +--|--|---------------+ | |
902 20|10| 70 | |
903 | | | |
904 | | | |
905 | | | |
906 | | | |
907 | | | |
908 | | |10|
909 | +------------------------------|--+
910 | 490 |
911 +---------------------------------+
918 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
920 template <class Types>
921 class OcclusionTrackerTestScaledRenderSurface
922 : public OcclusionTrackerTest<Types> {
923 protected:
924 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
925 : OcclusionTrackerTest<Types>(opaque_layers) {}
927 void RunMyTest() {
928 typename Types::ContentLayerType* parent = this->CreateRoot(
929 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
931 gfx::Transform layer1_matrix;
932 layer1_matrix.Scale(2.0, 2.0);
933 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
934 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
935 layer1->SetForceRenderSurface(true);
937 gfx::Transform layer2_matrix;
938 layer2_matrix.Translate(25.0, 25.0);
939 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
940 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
941 typename Types::ContentLayerType* occluder =
942 this->CreateDrawingLayer(parent,
943 this->identity_matrix,
944 gfx::PointF(100.f, 100.f),
945 gfx::Size(500, 500),
946 true);
947 this->CalcDrawEtc(parent);
949 TestOcclusionTrackerWithClip<typename Types::LayerType,
950 typename Types::RenderSurfaceType> occlusion(
951 gfx::Rect(0, 0, 1000, 1000));
953 this->VisitLayer(occluder, &occlusion);
954 this->EnterLayer(layer2, &occlusion);
956 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
957 occlusion.occlusion_from_outside_target().ToString());
958 EXPECT_EQ(gfx::Rect().ToString(),
959 occlusion.occlusion_from_inside_target().ToString());
961 EXPECT_RECT_EQ(
962 gfx::Rect(0, 0, 25, 25),
963 occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
964 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
965 occlusion.UnoccludedLayerContentRect(
966 layer2, gfx::Rect(10, 25, 25, 25)));
967 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
968 occlusion.UnoccludedLayerContentRect(
969 layer2, gfx::Rect(25, 10, 25, 25)));
970 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
971 layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
975 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
977 template <class Types>
978 class OcclusionTrackerTestVisitTargetTwoTimes
979 : public OcclusionTrackerTest<Types> {
980 protected:
981 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
982 : OcclusionTrackerTest<Types>(opaque_layers) {}
983 void RunMyTest() {
984 gfx::Transform child_transform;
985 child_transform.Translate(250.0, 250.0);
986 child_transform.Rotate(90.0);
987 child_transform.Translate(-250.0, -250.0);
989 typename Types::ContentLayerType* root = this->CreateRoot(
990 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
991 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
992 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
993 parent->SetMasksToBounds(true);
994 typename Types::LayerType* child = this->CreateLayer(
995 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
996 child->SetMasksToBounds(true);
997 typename Types::ContentLayerType* layer =
998 this->CreateDrawingLayer(child,
999 this->identity_matrix,
1000 gfx::PointF(10.f, 10.f),
1001 gfx::Size(500, 500),
1002 true);
1003 // |child2| makes |parent|'s surface get considered by OcclusionTracker
1004 // first, instead of |child|'s. This exercises different code in
1005 // LeaveToRenderTarget, as the target surface has already been seen.
1006 typename Types::ContentLayerType* child2 =
1007 this->CreateDrawingLayer(parent,
1008 this->identity_matrix,
1009 gfx::PointF(30.f, 30.f),
1010 gfx::Size(60, 20),
1011 true);
1012 this->CalcDrawEtc(root);
1014 TestOcclusionTrackerWithClip<typename Types::LayerType,
1015 typename Types::RenderSurfaceType> occlusion(
1016 gfx::Rect(0, 0, 1000, 1000));
1018 this->VisitLayer(child2, &occlusion);
1020 EXPECT_EQ(gfx::Rect().ToString(),
1021 occlusion.occlusion_from_outside_target().ToString());
1022 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1023 occlusion.occlusion_from_inside_target().ToString());
1025 this->VisitLayer(layer, &occlusion);
1027 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1028 occlusion.occlusion_from_outside_target().ToString());
1029 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1030 occlusion.occlusion_from_inside_target().ToString());
1032 this->EnterContributingSurface(child, &occlusion);
1034 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1035 occlusion.occlusion_from_outside_target().ToString());
1036 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1037 occlusion.occlusion_from_inside_target().ToString());
1039 // Occlusion in |child2| should get merged with the |child| surface we are
1040 // leaving now.
1041 this->LeaveContributingSurface(child, &occlusion);
1042 this->EnterLayer(parent, &occlusion);
1044 EXPECT_EQ(gfx::Rect().ToString(),
1045 occlusion.occlusion_from_outside_target().ToString());
1046 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1047 .ToString(),
1048 occlusion.occlusion_from_inside_target().ToString());
1050 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
1051 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1052 occlusion.UnoccludedLayerContentRect(
1053 parent, gfx::Rect(30, 30, 70, 70)));
1055 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
1056 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
1057 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
1058 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
1059 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
1061 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1062 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1063 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1065 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1066 parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1067 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1068 occlusion.UnoccludedLayerContentRect(
1069 parent, gfx::Rect(29, 30, 60, 10)));
1070 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1071 occlusion.UnoccludedLayerContentRect(
1072 parent, gfx::Rect(30, 29, 60, 10)));
1073 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1074 occlusion.UnoccludedLayerContentRect(
1075 parent, gfx::Rect(31, 30, 60, 10)));
1076 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1077 parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1079 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1080 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1081 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1082 occlusion.UnoccludedLayerContentRect(
1083 parent, gfx::Rect(29, 40, 70, 60)));
1084 // This rect is mostly occluded by |child2|.
1085 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1086 occlusion.UnoccludedLayerContentRect(
1087 parent, gfx::Rect(30, 39, 70, 60)));
1088 // This rect extends past top/right ends of |child2|.
1089 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1090 occlusion.UnoccludedLayerContentRect(
1091 parent, gfx::Rect(30, 29, 70, 70)));
1092 // This rect extends past left/right ends of |child2|.
1093 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1094 occlusion.UnoccludedLayerContentRect(
1095 parent, gfx::Rect(20, 39, 80, 60)));
1096 EXPECT_RECT_EQ(gfx::Rect(),
1097 occlusion.UnoccludedLayerContentRect(
1098 parent, gfx::Rect(31, 40, 70, 60)));
1099 EXPECT_RECT_EQ(gfx::Rect(),
1100 occlusion.UnoccludedLayerContentRect(
1101 parent, gfx::Rect(30, 41, 70, 60)));
1103 /* Justification for the above occlusion from |layer|:
1105 +---------------------+
1107 | 30 | rotate(90)
1108 | 30 + ------------+--------------------+
1109 100 | | 10 | | | ==>
1110 | |10+----------|----------------------+
1111 | + ------------+ | | |
1112 | | | | | |
1113 | | | | | |
1114 +----|--|-------------+ | |
1115 | | | |
1116 | | | |
1117 | | | |500
1118 | | | |
1119 | | | |
1120 | | | |
1121 | | | |
1122 +--|-------------------------------+ |
1124 +---------------------------------+
1128 +---------------------+
1129 | |30 Visible region of |layer|: /////
1130 | 30 60 | |child2|: \\\\\
1131 | 30 +------------+--------------------+
1132 | |\\\\\\\\\\\\| |10 |
1133 | +--|\\\\\\\\\\\\|-----------------+ |
1134 | | +------------+//| 420 | |
1135 | | |///////////////|60 | |
1136 | | |///////////////| | |
1137 +--|--|---------------+ | |
1138 20|10| 70 | |
1139 | | | |
1140 | | | |
1141 | | | |
1142 | | | |
1143 | | | |
1144 | | |10|
1145 | +------------------------------|--+
1146 | 490 |
1147 +---------------------------------+
1153 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
1155 template <class Types>
1156 class OcclusionTrackerTestSurfaceRotatedOffAxis
1157 : public OcclusionTrackerTest<Types> {
1158 protected:
1159 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
1160 : OcclusionTrackerTest<Types>(opaque_layers) {}
1161 void RunMyTest() {
1162 gfx::Transform child_transform;
1163 child_transform.Translate(250.0, 250.0);
1164 child_transform.Rotate(95.0);
1165 child_transform.Translate(-250.0, -250.0);
1167 gfx::Transform layer_transform;
1168 layer_transform.Translate(10.0, 10.0);
1170 typename Types::ContentLayerType* root = this->CreateRoot(
1171 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1172 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1173 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1174 typename Types::LayerType* child = this->CreateLayer(
1175 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1176 child->SetMasksToBounds(true);
1177 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1178 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
1179 this->CalcDrawEtc(root);
1181 TestOcclusionTrackerWithClip<typename Types::LayerType,
1182 typename Types::RenderSurfaceType> occlusion(
1183 gfx::Rect(0, 0, 1000, 1000));
1185 gfx::Rect clipped_layer_in_child = MathUtil::MapClippedRect(
1186 layer_transform, layer->visible_content_rect());
1188 this->VisitLayer(layer, &occlusion);
1189 this->EnterContributingSurface(child, &occlusion);
1191 EXPECT_EQ(gfx::Rect().ToString(),
1192 occlusion.occlusion_from_outside_target().ToString());
1193 EXPECT_EQ(clipped_layer_in_child.ToString(),
1194 occlusion.occlusion_from_inside_target().ToString());
1196 this->LeaveContributingSurface(child, &occlusion);
1197 this->EnterLayer(parent, &occlusion);
1199 EXPECT_EQ(gfx::Rect().ToString(),
1200 occlusion.occlusion_from_outside_target().ToString());
1201 EXPECT_EQ(gfx::Rect().ToString(),
1202 occlusion.occlusion_from_inside_target().ToString());
1204 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
1205 EXPECT_RECT_EQ(
1206 gfx::Rect(75, 55, 1, 1),
1207 occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
1211 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
1213 template <class Types>
1214 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1215 : public OcclusionTrackerTest<Types> {
1216 protected:
1217 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
1218 : OcclusionTrackerTest<Types>(opaque_layers) {}
1219 void RunMyTest() {
1220 gfx::Transform child_transform;
1221 child_transform.Translate(250.0, 250.0);
1222 child_transform.Rotate(90.0);
1223 child_transform.Translate(-250.0, -250.0);
1225 typename Types::ContentLayerType* root = this->CreateRoot(
1226 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1227 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1228 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1229 parent->SetMasksToBounds(true);
1230 typename Types::ContentLayerType* child =
1231 this->CreateDrawingLayer(parent,
1232 child_transform,
1233 gfx::PointF(30.f, 30.f),
1234 gfx::Size(500, 500),
1235 false);
1236 child->SetMasksToBounds(true);
1237 typename Types::ContentLayerType* layer1 =
1238 this->CreateDrawingLayer(child,
1239 this->identity_matrix,
1240 gfx::PointF(10.f, 10.f),
1241 gfx::Size(500, 500),
1242 true);
1243 typename Types::ContentLayerType* layer2 =
1244 this->CreateDrawingLayer(child,
1245 this->identity_matrix,
1246 gfx::PointF(10.f, 450.f),
1247 gfx::Size(500, 60),
1248 true);
1249 this->CalcDrawEtc(root);
1251 TestOcclusionTrackerWithClip<typename Types::LayerType,
1252 typename Types::RenderSurfaceType> occlusion(
1253 gfx::Rect(0, 0, 1000, 1000));
1255 this->VisitLayer(layer2, &occlusion);
1256 this->VisitLayer(layer1, &occlusion);
1257 this->VisitLayer(child, &occlusion);
1258 this->EnterContributingSurface(child, &occlusion);
1260 EXPECT_EQ(gfx::Rect().ToString(),
1261 occlusion.occlusion_from_outside_target().ToString());
1262 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1263 occlusion.occlusion_from_inside_target().ToString());
1265 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
1266 EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
1267 // These rects are occluded except for the part outside the bounds of the
1268 // target surface.
1269 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 429, 60, 70)));
1270 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 60, 70)));
1271 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 70)));
1273 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1274 child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1275 EXPECT_RECT_EQ(
1276 gfx::Rect(9, 430, 1, 70),
1277 occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
1278 // These rects are occluded except for the part outside the bounds of the
1279 // target surface.
1280 EXPECT_RECT_EQ(gfx::Rect(),
1281 occlusion.UnoccludedLayerContentRect(
1282 child, gfx::Rect(10, 429, 60, 70)));
1283 EXPECT_RECT_EQ(gfx::Rect(),
1284 occlusion.UnoccludedLayerContentRect(
1285 child, gfx::Rect(11, 430, 60, 70)));
1286 EXPECT_RECT_EQ(gfx::Rect(),
1287 occlusion.UnoccludedLayerContentRect(
1288 child, gfx::Rect(10, 431, 60, 70)));
1290 this->LeaveContributingSurface(child, &occlusion);
1291 this->EnterLayer(parent, &occlusion);
1293 EXPECT_EQ(gfx::Rect().ToString(),
1294 occlusion.occlusion_from_outside_target().ToString());
1295 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1296 occlusion.occlusion_from_inside_target().ToString());
1298 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1299 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1300 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1302 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1303 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1304 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1305 occlusion.UnoccludedLayerContentRect(
1306 parent, gfx::Rect(29, 40, 70, 60)));
1307 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1308 occlusion.UnoccludedLayerContentRect(
1309 parent, gfx::Rect(30, 39, 70, 60)));
1310 EXPECT_RECT_EQ(gfx::Rect(),
1311 occlusion.UnoccludedLayerContentRect(
1312 parent, gfx::Rect(31, 40, 70, 60)));
1313 EXPECT_RECT_EQ(gfx::Rect(),
1314 occlusion.UnoccludedLayerContentRect(
1315 parent, gfx::Rect(30, 41, 70, 60)));
1317 /* Justification for the above occlusion from |layer1| and |layer2|:
1319 +---------------------+
1320 | |30 Visible region of |layer1|: /////
1321 | | Visible region of |layer2|: \\\\\
1322 | +---------------------------------+
1323 | | |10 |
1324 | +---------------+-----------------+ |
1325 | | |\\\\\\\\\\\\|//| 420 | |
1326 | | |\\\\\\\\\\\\|//|60 | |
1327 | | |\\\\\\\\\\\\|//| | |
1328 +--|--|------------|--+ | |
1329 20|10| 70 | | |
1330 | | | | |
1331 | | | | |
1332 | | | | |
1333 | | | | |
1334 | | | | |
1335 | | | |10|
1336 | +------------|-----------------|--+
1337 | | 490 |
1338 +---------------+-----------------+
1339 60 440
1344 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1346 template <class Types>
1347 class OcclusionTrackerTestOverlappingSurfaceSiblings
1348 : public OcclusionTrackerTest<Types> {
1349 protected:
1350 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
1351 : OcclusionTrackerTest<Types>(opaque_layers) {}
1352 void RunMyTest() {
1353 gfx::Transform child_transform;
1354 child_transform.Translate(250.0, 250.0);
1355 child_transform.Rotate(90.0);
1356 child_transform.Translate(-250.0, -250.0);
1358 typename Types::ContentLayerType* parent = this->CreateRoot(
1359 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1360 parent->SetMasksToBounds(true);
1361 typename Types::LayerType* child1 = this->CreateSurface(
1362 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
1363 typename Types::LayerType* child2 = this->CreateSurface(
1364 parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
1365 typename Types::ContentLayerType* layer1 =
1366 this->CreateDrawingLayer(child1,
1367 this->identity_matrix,
1368 gfx::PointF(-10.f, -10.f),
1369 gfx::Size(510, 510),
1370 true);
1371 typename Types::ContentLayerType* layer2 =
1372 this->CreateDrawingLayer(child2,
1373 this->identity_matrix,
1374 gfx::PointF(-10.f, -10.f),
1375 gfx::Size(510, 510),
1376 true);
1377 this->CalcDrawEtc(parent);
1379 TestOcclusionTrackerWithClip<typename Types::LayerType,
1380 typename Types::RenderSurfaceType> occlusion(
1381 gfx::Rect(0, 0, 1000, 1000));
1383 this->VisitLayer(layer2, &occlusion);
1384 this->EnterContributingSurface(child2, &occlusion);
1386 EXPECT_EQ(gfx::Rect().ToString(),
1387 occlusion.occlusion_from_outside_target().ToString());
1388 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1389 occlusion.occlusion_from_inside_target().ToString());
1391 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1392 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1393 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1394 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1395 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1397 // There is nothing above child2's surface in the z-order.
1398 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1399 occlusion.UnoccludedContributingSurfaceContentRect(
1400 child2, false, gfx::Rect(-10, 420, 70, 80), NULL));
1402 this->LeaveContributingSurface(child2, &occlusion);
1403 this->VisitLayer(layer1, &occlusion);
1404 this->EnterContributingSurface(child1, &occlusion);
1406 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1407 occlusion.occlusion_from_outside_target().ToString());
1408 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1409 occlusion.occlusion_from_inside_target().ToString());
1411 // child2's contents will occlude child1 below it.
1412 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1413 occlusion.UnoccludedContributingSurfaceContentRect(
1414 child1, false, gfx::Rect(-10, 430, 80, 70), NULL));
1416 this->LeaveContributingSurface(child1, &occlusion);
1417 this->EnterLayer(parent, &occlusion);
1419 EXPECT_EQ(gfx::Rect().ToString(),
1420 occlusion.occlusion_from_outside_target().ToString());
1421 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1422 .ToString(),
1423 occlusion.occlusion_from_inside_target().ToString());
1425 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1427 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1428 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1429 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1431 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1432 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1433 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1435 /* Justification for the above occlusion:
1437 +---------------------+
1438 | 20 | layer1
1439 | 30+ ---------------------------------+
1440 100 | 30| | layer2 |
1441 |20+----------------------------------+ |
1442 | | | | | |
1443 | | | | | |
1444 | | | | | |
1445 +--|-|----------------+ | |
1446 | | | | 510
1447 | | | |
1448 | | | |
1449 | | | |
1450 | | | |
1451 | | | |
1452 | | | |
1453 | +--------------------------------|-+
1455 +----------------------------------+
1461 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1463 template <class Types>
1464 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1465 : public OcclusionTrackerTest<Types> {
1466 protected:
1467 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1468 bool opaque_layers)
1469 : OcclusionTrackerTest<Types>(opaque_layers) {}
1470 void RunMyTest() {
1471 gfx::Transform child1_transform;
1472 child1_transform.Translate(250.0, 250.0);
1473 child1_transform.Rotate(-90.0);
1474 child1_transform.Translate(-250.0, -250.0);
1476 gfx::Transform child2_transform;
1477 child2_transform.Translate(250.0, 250.0);
1478 child2_transform.Rotate(90.0);
1479 child2_transform.Translate(-250.0, -250.0);
1481 typename Types::ContentLayerType* parent = this->CreateRoot(
1482 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1483 parent->SetMasksToBounds(true);
1484 typename Types::LayerType* child1 = this->CreateSurface(
1485 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1486 typename Types::LayerType* child2 =
1487 this->CreateDrawingSurface(parent,
1488 child2_transform,
1489 gfx::PointF(20.f, 40.f),
1490 gfx::Size(10, 10),
1491 false);
1492 typename Types::ContentLayerType* layer1 =
1493 this->CreateDrawingLayer(child1,
1494 this->identity_matrix,
1495 gfx::PointF(-10.f, -20.f),
1496 gfx::Size(510, 510),
1497 true);
1498 typename Types::ContentLayerType* layer2 =
1499 this->CreateDrawingLayer(child2,
1500 this->identity_matrix,
1501 gfx::PointF(-10.f, -10.f),
1502 gfx::Size(510, 510),
1503 true);
1504 this->CalcDrawEtc(parent);
1506 TestOcclusionTrackerWithClip<typename Types::LayerType,
1507 typename Types::RenderSurfaceType> occlusion(
1508 gfx::Rect(0, 0, 1000, 1000));
1510 this->VisitLayer(layer2, &occlusion);
1511 this->EnterLayer(child2, &occlusion);
1513 EXPECT_EQ(gfx::Rect().ToString(),
1514 occlusion.occlusion_from_outside_target().ToString());
1515 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1516 occlusion.occlusion_from_inside_target().ToString());
1518 this->LeaveLayer(child2, &occlusion);
1519 this->EnterContributingSurface(child2, &occlusion);
1521 // There is nothing above child2's surface in the z-order.
1522 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1523 occlusion.UnoccludedContributingSurfaceContentRect(
1524 child2, false, gfx::Rect(-10, 420, 70, 80), NULL));
1526 this->LeaveContributingSurface(child2, &occlusion);
1527 this->VisitLayer(layer1, &occlusion);
1528 this->EnterContributingSurface(child1, &occlusion);
1530 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1531 occlusion.occlusion_from_outside_target().ToString());
1532 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1533 occlusion.occlusion_from_inside_target().ToString());
1535 // child2's contents will occlude child1 below it.
1536 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1537 occlusion.UnoccludedContributingSurfaceContentRect(
1538 child1, false, gfx::Rect(420, -20, 80, 90), NULL));
1539 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1540 occlusion.UnoccludedContributingSurfaceContentRect(
1541 child1, false, gfx::Rect(420, -10, 80, 90), NULL));
1542 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1543 occlusion.UnoccludedContributingSurfaceContentRect(
1544 child1, false, gfx::Rect(420, -20, 70, 90), NULL));
1546 this->LeaveContributingSurface(child1, &occlusion);
1547 this->EnterLayer(parent, &occlusion);
1549 EXPECT_EQ(gfx::Rect().ToString(),
1550 occlusion.occlusion_from_outside_target().ToString());
1551 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1552 occlusion.occlusion_from_inside_target().ToString());
1554 /* Justification for the above occlusion:
1556 +---------------------+
1557 |20 | layer1
1558 10+----------------------------------+
1559 100 || 30 | layer2 |
1560 |20+----------------------------------+
1561 || | | | |
1562 || | | | |
1563 || | | | |
1564 +|-|------------------+ | |
1565 | | | | 510
1566 | | 510 | |
1567 | | | |
1568 | | | |
1569 | | | |
1570 | | | |
1571 | | 520 | |
1572 +----------------------------------+ |
1574 +----------------------------------+
1580 ALL_OCCLUSIONTRACKER_TEST(
1581 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1583 template <class Types>
1584 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1585 protected:
1586 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1587 : OcclusionTrackerTest<Types>(opaque_layers) {}
1588 void RunMyTest() {
1589 gfx::Transform layer_transform;
1590 layer_transform.Translate(250.0, 250.0);
1591 layer_transform.Rotate(90.0);
1592 layer_transform.Translate(-250.0, -250.0);
1594 typename Types::ContentLayerType* parent = this->CreateRoot(
1595 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1596 parent->SetMasksToBounds(true);
1597 typename Types::ContentLayerType* blur_layer =
1598 this->CreateDrawingLayer(parent,
1599 layer_transform,
1600 gfx::PointF(30.f, 30.f),
1601 gfx::Size(500, 500),
1602 true);
1603 typename Types::ContentLayerType* opaque_layer =
1604 this->CreateDrawingLayer(parent,
1605 layer_transform,
1606 gfx::PointF(30.f, 30.f),
1607 gfx::Size(500, 500),
1608 true);
1609 typename Types::ContentLayerType* opacity_layer =
1610 this->CreateDrawingLayer(parent,
1611 layer_transform,
1612 gfx::PointF(30.f, 30.f),
1613 gfx::Size(500, 500),
1614 true);
1616 WebKit::WebFilterOperations filters;
1617 filters.append(WebKit::WebFilterOperation::createBlurFilter(10.f));
1618 blur_layer->SetFilters(filters);
1620 filters.clear();
1621 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5f));
1622 opaque_layer->SetFilters(filters);
1624 filters.clear();
1625 filters.append(WebKit::WebFilterOperation::createOpacityFilter(0.5f));
1626 opacity_layer->SetFilters(filters);
1628 this->CalcDrawEtc(parent);
1630 TestOcclusionTrackerWithClip<typename Types::LayerType,
1631 typename Types::RenderSurfaceType> occlusion(
1632 gfx::Rect(0, 0, 1000, 1000));
1634 // Opacity layer won't contribute to occlusion.
1635 this->VisitLayer(opacity_layer, &occlusion);
1636 this->EnterContributingSurface(opacity_layer, &occlusion);
1638 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1639 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1641 // And has nothing to contribute to its parent surface.
1642 this->LeaveContributingSurface(opacity_layer, &occlusion);
1643 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1644 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1646 // Opaque layer will contribute to occlusion.
1647 this->VisitLayer(opaque_layer, &occlusion);
1648 this->EnterContributingSurface(opaque_layer, &occlusion);
1650 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1651 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1652 occlusion.occlusion_from_inside_target().ToString());
1654 // And it gets translated to the parent surface.
1655 this->LeaveContributingSurface(opaque_layer, &occlusion);
1656 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1657 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1658 occlusion.occlusion_from_inside_target().ToString());
1660 // The blur layer needs to throw away any occlusion from outside its
1661 // subtree.
1662 this->EnterLayer(blur_layer, &occlusion);
1663 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1664 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1666 // And it won't contribute to occlusion.
1667 this->LeaveLayer(blur_layer, &occlusion);
1668 this->EnterContributingSurface(blur_layer, &occlusion);
1669 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1670 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1672 // But the opaque layer's occlusion is preserved on the parent.
1673 this->LeaveContributingSurface(blur_layer, &occlusion);
1674 this->EnterLayer(parent, &occlusion);
1675 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1676 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1677 occlusion.occlusion_from_inside_target().ToString());
1681 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1683 template <class Types>
1684 class OcclusionTrackerTestReplicaDoesOcclude
1685 : public OcclusionTrackerTest<Types> {
1686 protected:
1687 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1688 : OcclusionTrackerTest<Types>(opaque_layers) {}
1689 void RunMyTest() {
1690 typename Types::ContentLayerType* parent = this->CreateRoot(
1691 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1692 typename Types::LayerType* surface =
1693 this->CreateDrawingSurface(parent,
1694 this->identity_matrix,
1695 gfx::PointF(0.f, 100.f),
1696 gfx::Size(50, 50),
1697 true);
1698 this->CreateReplicaLayer(
1699 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1700 this->CalcDrawEtc(parent);
1702 TestOcclusionTrackerWithClip<typename Types::LayerType,
1703 typename Types::RenderSurfaceType> occlusion(
1704 gfx::Rect(0, 0, 1000, 1000));
1706 this->VisitLayer(surface, &occlusion);
1708 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1709 occlusion.occlusion_from_inside_target().ToString());
1711 this->VisitContributingSurface(surface, &occlusion);
1712 this->EnterLayer(parent, &occlusion);
1714 // The surface and replica should both be occluding the parent.
1715 EXPECT_EQ(
1716 UnionRegions(gfx::Rect(0, 100, 50, 50),
1717 gfx::Rect(50, 150, 50, 50)).ToString(),
1718 occlusion.occlusion_from_inside_target().ToString());
1722 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1724 template <class Types>
1725 class OcclusionTrackerTestReplicaWithClipping
1726 : public OcclusionTrackerTest<Types> {
1727 protected:
1728 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1729 : OcclusionTrackerTest<Types>(opaque_layers) {}
1730 void RunMyTest() {
1731 typename Types::ContentLayerType* parent = this->CreateRoot(
1732 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1733 parent->SetMasksToBounds(true);
1734 typename Types::LayerType* surface =
1735 this->CreateDrawingSurface(parent,
1736 this->identity_matrix,
1737 gfx::PointF(0.f, 100.f),
1738 gfx::Size(50, 50),
1739 true);
1740 this->CreateReplicaLayer(
1741 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1742 this->CalcDrawEtc(parent);
1744 TestOcclusionTrackerWithClip<typename Types::LayerType,
1745 typename Types::RenderSurfaceType> occlusion(
1746 gfx::Rect(0, 0, 1000, 1000));
1748 this->VisitLayer(surface, &occlusion);
1750 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1751 occlusion.occlusion_from_inside_target().ToString());
1753 this->VisitContributingSurface(surface, &occlusion);
1754 this->EnterLayer(parent, &occlusion);
1756 // The surface and replica should both be occluding the parent.
1757 EXPECT_EQ(
1758 UnionRegions(gfx::Rect(0, 100, 50, 50),
1759 gfx::Rect(50, 150, 50, 20)).ToString(),
1760 occlusion.occlusion_from_inside_target().ToString());
1764 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1766 template <class Types>
1767 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1768 protected:
1769 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1770 : OcclusionTrackerTest<Types>(opaque_layers) {}
1771 void RunMyTest() {
1772 typename Types::ContentLayerType* parent = this->CreateRoot(
1773 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1774 typename Types::LayerType* surface =
1775 this->CreateDrawingSurface(parent,
1776 this->identity_matrix,
1777 gfx::PointF(0.f, 100.f),
1778 gfx::Size(50, 50),
1779 true);
1780 typename Types::LayerType* replica = this->CreateReplicaLayer(
1781 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1782 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1783 this->CalcDrawEtc(parent);
1785 TestOcclusionTrackerWithClip<typename Types::LayerType,
1786 typename Types::RenderSurfaceType> occlusion(
1787 gfx::Rect(0, 0, 1000, 1000));
1789 this->VisitLayer(surface, &occlusion);
1791 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1792 occlusion.occlusion_from_inside_target().ToString());
1794 this->VisitContributingSurface(surface, &occlusion);
1795 this->EnterLayer(parent, &occlusion);
1797 // The replica should not be occluding the parent, since it has a mask
1798 // applied to it.
1799 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1800 occlusion.occlusion_from_inside_target().ToString());
1804 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1806 template <class Types>
1807 class OcclusionTrackerTestLayerClipRectOutsideChild
1808 : public OcclusionTrackerTest<Types> {
1809 protected:
1810 explicit OcclusionTrackerTestLayerClipRectOutsideChild(bool opaque_layers)
1811 : OcclusionTrackerTest<Types>(opaque_layers) {}
1812 void RunMyTest() {
1813 typename Types::ContentLayerType* parent = this->CreateRoot(
1814 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1815 typename Types::ContentLayerType* clip =
1816 this->CreateDrawingLayer(parent,
1817 this->identity_matrix,
1818 gfx::PointF(200.f, 100.f),
1819 gfx::Size(100, 100),
1820 false);
1821 clip->SetMasksToBounds(true);
1822 typename Types::ContentLayerType* layer =
1823 this->CreateDrawingLayer(clip,
1824 this->identity_matrix,
1825 gfx::PointF(-200.f, -100.f),
1826 gfx::Size(200, 200),
1827 false);
1828 this->CalcDrawEtc(parent);
1830 TestOcclusionTrackerWithClip<typename Types::LayerType,
1831 typename Types::RenderSurfaceType> occlusion(
1832 gfx::Rect(0, 0, 1000, 1000));
1834 this->EnterLayer(layer, &occlusion);
1836 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1837 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1838 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1839 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1840 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1842 this->LeaveLayer(layer, &occlusion);
1843 this->EnterLayer(clip, &occlusion);
1845 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(-100, 0, 100, 100)));
1846 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, -100, 100, 100)));
1847 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100)));
1848 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100)));
1849 EXPECT_FALSE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100)));
1851 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
1852 occlusion.UnoccludedLayerContentRect(
1853 clip, gfx::Rect(-100, -100, 300, 300)));
1857 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild);
1859 template <class Types>
1860 class OcclusionTrackerTestViewportRectOutsideChild
1861 : public OcclusionTrackerTest<Types> {
1862 protected:
1863 explicit OcclusionTrackerTestViewportRectOutsideChild(bool opaque_layers)
1864 : OcclusionTrackerTest<Types>(opaque_layers) {}
1865 void RunMyTest() {
1866 typename Types::ContentLayerType* parent = this->CreateRoot(
1867 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1868 typename Types::ContentLayerType* layer =
1869 this->CreateDrawingSurface(parent,
1870 this->identity_matrix,
1871 gfx::PointF(),
1872 gfx::Size(200, 200),
1873 true);
1874 this->CalcDrawEtc(parent);
1876 TestOcclusionTrackerWithClip<typename Types::LayerType,
1877 typename Types::RenderSurfaceType> occlusion(
1878 gfx::Rect(200, 100, 100, 100));
1880 this->EnterLayer(layer, &occlusion);
1882 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1883 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1884 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1885 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1886 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1888 this->LeaveLayer(layer, &occlusion);
1889 this->VisitContributingSurface(layer, &occlusion);
1890 this->EnterLayer(parent, &occlusion);
1892 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1893 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1894 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1895 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1896 EXPECT_FALSE(
1897 occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1898 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1899 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1900 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1901 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1903 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100),
1904 occlusion.UnoccludedLayerContentRect(
1905 parent, gfx::Rect(0, 0, 300, 300)));
1909 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild);
1911 template <class Types>
1912 class OcclusionTrackerTestLayerClipRectOverChild
1913 : public OcclusionTrackerTest<Types> {
1914 protected:
1915 explicit OcclusionTrackerTestLayerClipRectOverChild(bool opaque_layers)
1916 : OcclusionTrackerTest<Types>(opaque_layers) {}
1917 void RunMyTest() {
1918 typename Types::ContentLayerType* parent = this->CreateRoot(
1919 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1920 typename Types::ContentLayerType* clip =
1921 this->CreateDrawingLayer(parent,
1922 this->identity_matrix,
1923 gfx::PointF(100.f, 100.f),
1924 gfx::Size(100, 100),
1925 false);
1926 clip->SetMasksToBounds(true);
1927 typename Types::ContentLayerType* layer =
1928 this->CreateDrawingSurface(clip,
1929 this->identity_matrix,
1930 gfx::PointF(-100.f, -100.f),
1931 gfx::Size(200, 200),
1932 true);
1933 this->CalcDrawEtc(parent);
1935 TestOcclusionTrackerWithClip<typename Types::LayerType,
1936 typename Types::RenderSurfaceType> occlusion(
1937 gfx::Rect(0, 0, 1000, 1000));
1939 this->EnterLayer(layer, &occlusion);
1941 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1942 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1943 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1944 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1946 this->LeaveLayer(layer, &occlusion);
1947 this->VisitContributingSurface(layer, &occlusion);
1949 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1950 occlusion.occlusion_from_inside_target().ToString());
1952 this->EnterLayer(clip, &occlusion);
1954 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100)));
1955 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100)));
1956 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100)));
1957 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 100, 100, 100)));
1958 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 100, 100, 100)));
1959 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 0, 100, 100)));
1960 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 200, 100, 100)));
1961 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 200, 100, 100)));
1962 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 200, 100, 100)));
1964 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1965 clip, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1969 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild);
1971 template <class Types>
1972 class OcclusionTrackerTestViewportRectOverChild
1973 : public OcclusionTrackerTest<Types> {
1974 protected:
1975 explicit OcclusionTrackerTestViewportRectOverChild(bool opaque_layers)
1976 : OcclusionTrackerTest<Types>(opaque_layers) {}
1977 void RunMyTest() {
1978 typename Types::ContentLayerType* parent = this->CreateRoot(
1979 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1980 typename Types::ContentLayerType* layer =
1981 this->CreateDrawingSurface(parent,
1982 this->identity_matrix,
1983 gfx::PointF(),
1984 gfx::Size(200, 200),
1985 true);
1986 this->CalcDrawEtc(parent);
1988 TestOcclusionTrackerWithClip<typename Types::LayerType,
1989 typename Types::RenderSurfaceType> occlusion(
1990 gfx::Rect(100, 100, 100, 100));
1992 this->EnterLayer(layer, &occlusion);
1994 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1995 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1996 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1997 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1999 this->LeaveLayer(layer, &occlusion);
2000 this->VisitContributingSurface(layer, &occlusion);
2001 this->EnterLayer(parent, &occlusion);
2003 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2004 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2005 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2006 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2007 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2008 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2009 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2010 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2011 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2013 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2014 parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2018 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild);
2020 template <class Types>
2021 class OcclusionTrackerTestLayerClipRectPartlyOverChild
2022 : public OcclusionTrackerTest<Types> {
2023 protected:
2024 explicit OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaque_layers)
2025 : OcclusionTrackerTest<Types>(opaque_layers) {}
2026 void RunMyTest() {
2027 typename Types::ContentLayerType* parent = this->CreateRoot(
2028 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2029 typename Types::ContentLayerType* clip =
2030 this->CreateDrawingLayer(parent,
2031 this->identity_matrix,
2032 gfx::PointF(50.f, 50.f),
2033 gfx::Size(200, 200),
2034 false);
2035 clip->SetMasksToBounds(true);
2036 typename Types::ContentLayerType* layer =
2037 this->CreateDrawingSurface(clip,
2038 this->identity_matrix,
2039 gfx::PointF(-50.f, -50.f),
2040 gfx::Size(200, 200),
2041 true);
2042 this->CalcDrawEtc(parent);
2044 TestOcclusionTrackerWithClip<typename Types::LayerType,
2045 typename Types::RenderSurfaceType> occlusion(
2046 gfx::Rect(0, 0, 1000, 1000));
2048 this->EnterLayer(layer, &occlusion);
2050 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2051 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2052 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2053 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2055 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 50)));
2056 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 50, 100)));
2057 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 50)));
2058 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 50, 100)));
2060 this->LeaveLayer(layer, &occlusion);
2061 this->VisitContributingSurface(layer, &occlusion);
2062 this->EnterLayer(clip, &occlusion);
2064 EXPECT_EQ(gfx::Rect(50, 50, 150, 150).ToString(),
2065 occlusion.occlusion_from_inside_target().ToString());
2069 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild);
2071 template <class Types>
2072 class OcclusionTrackerTestViewportRectPartlyOverChild
2073 : public OcclusionTrackerTest<Types> {
2074 protected:
2075 explicit OcclusionTrackerTestViewportRectPartlyOverChild(bool opaque_layers)
2076 : OcclusionTrackerTest<Types>(opaque_layers) {}
2077 void RunMyTest() {
2078 typename Types::ContentLayerType* parent = this->CreateRoot(
2079 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2080 typename Types::ContentLayerType* layer =
2081 this->CreateDrawingSurface(parent,
2082 this->identity_matrix,
2083 gfx::PointF(),
2084 gfx::Size(200, 200),
2085 true);
2086 this->CalcDrawEtc(parent);
2088 TestOcclusionTrackerWithClip<typename Types::LayerType,
2089 typename Types::RenderSurfaceType> occlusion(
2090 gfx::Rect(50, 50, 200, 200));
2092 this->EnterLayer(layer, &occlusion);
2094 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2095 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2096 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2097 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2099 this->LeaveLayer(layer, &occlusion);
2100 this->VisitContributingSurface(layer, &occlusion);
2101 this->EnterLayer(parent, &occlusion);
2103 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2104 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2105 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2106 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2107 EXPECT_FALSE(
2108 occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2109 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2110 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2111 EXPECT_FALSE(
2112 occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2113 EXPECT_FALSE(
2114 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2116 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200),
2117 occlusion.UnoccludedLayerContentRect(
2118 parent, gfx::Rect(0, 0, 300, 300)));
2119 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50),
2120 occlusion.UnoccludedLayerContentRect(
2121 parent, gfx::Rect(0, 0, 300, 100)));
2122 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2123 occlusion.UnoccludedLayerContentRect(
2124 parent, gfx::Rect(0, 100, 300, 100)));
2125 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2126 occlusion.UnoccludedLayerContentRect(
2127 parent, gfx::Rect(200, 100, 100, 100)));
2128 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50),
2129 occlusion.UnoccludedLayerContentRect(
2130 parent, gfx::Rect(100, 200, 100, 100)));
2134 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild);
2136 template <class Types>
2137 class OcclusionTrackerTestViewportRectOverNothing
2138 : public OcclusionTrackerTest<Types> {
2139 protected:
2140 explicit OcclusionTrackerTestViewportRectOverNothing(bool opaque_layers)
2141 : OcclusionTrackerTest<Types>(opaque_layers) {}
2142 void RunMyTest() {
2143 typename Types::ContentLayerType* parent = this->CreateRoot(
2144 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2145 typename Types::ContentLayerType* layer =
2146 this->CreateDrawingSurface(parent,
2147 this->identity_matrix,
2148 gfx::PointF(),
2149 gfx::Size(200, 200),
2150 true);
2151 this->CalcDrawEtc(parent);
2153 TestOcclusionTrackerWithClip<typename Types::LayerType,
2154 typename Types::RenderSurfaceType> occlusion(
2155 gfx::Rect(500, 500, 100, 100));
2157 this->EnterLayer(layer, &occlusion);
2159 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2160 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2161 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2162 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2164 this->LeaveLayer(layer, &occlusion);
2165 this->VisitContributingSurface(layer, &occlusion);
2166 this->EnterLayer(parent, &occlusion);
2168 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2169 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2170 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2171 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2172 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2173 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2174 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2175 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2176 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2178 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2179 parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2180 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2181 parent, gfx::Rect(0, 0, 300, 100)).IsEmpty());
2182 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2183 parent, gfx::Rect(0, 100, 300, 100)).IsEmpty());
2184 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2185 parent, gfx::Rect(200, 100, 100, 100)).IsEmpty());
2186 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2187 parent, gfx::Rect(100, 200, 100, 100)).IsEmpty());
2191 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing);
2193 template <class Types>
2194 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
2195 : public OcclusionTrackerTest<Types> {
2196 protected:
2197 explicit OcclusionTrackerTestLayerClipRectForLayerOffOrigin(
2198 bool opaque_layers)
2199 : OcclusionTrackerTest<Types>(opaque_layers) {}
2200 void RunMyTest() {
2201 typename Types::ContentLayerType* parent = this->CreateRoot(
2202 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2203 typename Types::ContentLayerType* layer =
2204 this->CreateDrawingSurface(parent,
2205 this->identity_matrix,
2206 gfx::PointF(),
2207 gfx::Size(200, 200),
2208 true);
2209 this->CalcDrawEtc(parent);
2211 TestOcclusionTrackerWithClip<typename Types::LayerType,
2212 typename Types::RenderSurfaceType> occlusion(
2213 gfx::Rect(0, 0, 1000, 1000));
2214 this->EnterLayer(layer, &occlusion);
2216 // This layer is translated when drawn into its target. So if the clip rect
2217 // given from the target surface is not in that target space, then after
2218 // translating these query rects into the target, they will fall outside the
2219 // clip and be considered occluded.
2220 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2221 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2222 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2223 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2227 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin);
2229 template <class Types>
2230 class OcclusionTrackerTestOpaqueContentsRegionEmpty
2231 : public OcclusionTrackerTest<Types> {
2232 protected:
2233 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
2234 : OcclusionTrackerTest<Types>(opaque_layers) {}
2235 void RunMyTest() {
2236 typename Types::ContentLayerType* parent = this->CreateRoot(
2237 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2238 typename Types::ContentLayerType* layer =
2239 this->CreateDrawingSurface(parent,
2240 this->identity_matrix,
2241 gfx::PointF(),
2242 gfx::Size(200, 200),
2243 false);
2244 this->CalcDrawEtc(parent);
2246 TestOcclusionTrackerWithClip<typename Types::LayerType,
2247 typename Types::RenderSurfaceType> occlusion(
2248 gfx::Rect(0, 0, 1000, 1000));
2249 this->EnterLayer(layer, &occlusion);
2251 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2252 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2253 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2254 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2256 // Occluded since its outside the surface bounds.
2257 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
2259 this->LeaveLayer(layer, &occlusion);
2260 this->VisitContributingSurface(layer, &occlusion);
2261 this->EnterLayer(parent, &occlusion);
2263 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2267 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
2269 template <class Types>
2270 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
2271 : public OcclusionTrackerTest<Types> {
2272 protected:
2273 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
2274 : OcclusionTrackerTest<Types>(opaque_layers) {}
2275 void RunMyTest() {
2276 typename Types::ContentLayerType* parent = this->CreateRoot(
2277 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2278 typename Types::ContentLayerType* layer =
2279 this->CreateDrawingLayer(parent,
2280 this->identity_matrix,
2281 gfx::PointF(100.f, 100.f),
2282 gfx::Size(200, 200),
2283 false);
2284 this->CalcDrawEtc(parent);
2286 TestOcclusionTrackerWithClip<typename Types::LayerType,
2287 typename Types::RenderSurfaceType> occlusion(
2288 gfx::Rect(0, 0, 1000, 1000));
2289 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
2291 this->ResetLayerIterator();
2292 this->VisitLayer(layer, &occlusion);
2293 this->EnterLayer(parent, &occlusion);
2295 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
2296 occlusion.occlusion_from_inside_target().ToString());
2298 EXPECT_FALSE(
2299 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2300 EXPECT_TRUE(
2301 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2302 EXPECT_FALSE(
2303 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2306 TestOcclusionTrackerWithClip<typename Types::LayerType,
2307 typename Types::RenderSurfaceType> occlusion(
2308 gfx::Rect(0, 0, 1000, 1000));
2309 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
2311 this->ResetLayerIterator();
2312 this->VisitLayer(layer, &occlusion);
2313 this->EnterLayer(parent, &occlusion);
2315 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
2316 occlusion.occlusion_from_inside_target().ToString());
2318 EXPECT_FALSE(
2319 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2320 EXPECT_FALSE(
2321 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2322 EXPECT_TRUE(
2323 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2326 TestOcclusionTrackerWithClip<typename Types::LayerType,
2327 typename Types::RenderSurfaceType> occlusion(
2328 gfx::Rect(0, 0, 1000, 1000));
2329 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
2331 this->ResetLayerIterator();
2332 this->VisitLayer(layer, &occlusion);
2333 this->EnterLayer(parent, &occlusion);
2335 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
2336 occlusion.occlusion_from_inside_target().ToString());
2338 EXPECT_FALSE(
2339 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2340 EXPECT_FALSE(
2341 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2342 EXPECT_FALSE(
2343 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2348 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
2350 template <class Types>
2351 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
2352 protected:
2353 explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
2354 : OcclusionTrackerTest<Types>(opaque_layers) {}
2355 void RunMyTest() {
2356 gfx::Transform transform;
2357 transform.RotateAboutYAxis(30.0);
2359 typename Types::ContentLayerType* parent = this->CreateRoot(
2360 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2361 typename Types::LayerType* container = this->CreateLayer(
2362 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2363 typename Types::ContentLayerType* layer =
2364 this->CreateDrawingLayer(container,
2365 transform,
2366 gfx::PointF(100.f, 100.f),
2367 gfx::Size(200, 200),
2368 true);
2369 this->CalcDrawEtc(parent);
2371 TestOcclusionTrackerWithClip<typename Types::LayerType,
2372 typename Types::RenderSurfaceType> occlusion(
2373 gfx::Rect(0, 0, 1000, 1000));
2374 this->EnterLayer(layer, &occlusion);
2376 // The layer is rotated in 3d but without preserving 3d, so it only gets
2377 // resized.
2378 EXPECT_RECT_EQ(
2379 gfx::Rect(0, 0, 200, 200),
2380 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2384 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
2386 template <class Types>
2387 class OcclusionTrackerTestUnsorted3dLayers
2388 : public OcclusionTrackerTest<Types> {
2389 protected:
2390 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
2391 : OcclusionTrackerTest<Types>(opaque_layers) {}
2392 void RunMyTest() {
2393 // Currently, The main thread layer iterator does not iterate over 3d items
2394 // in sorted order, because layer sorting is not performed on the main
2395 // thread. Because of this, the occlusion tracker cannot assume that a 3d
2396 // layer occludes other layers that have not yet been iterated over. For
2397 // now, the expected behavior is that a 3d layer simply does not add any
2398 // occlusion to the occlusion tracker.
2400 gfx::Transform translation_to_front;
2401 translation_to_front.Translate3d(0.0, 0.0, -10.0);
2402 gfx::Transform translation_to_back;
2403 translation_to_front.Translate3d(0.0, 0.0, -100.0);
2405 typename Types::ContentLayerType* parent = this->CreateRoot(
2406 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2407 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
2408 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
2409 typename Types::ContentLayerType* child2 =
2410 this->CreateDrawingLayer(parent,
2411 translation_to_front,
2412 gfx::PointF(50.f, 50.f),
2413 gfx::Size(100, 100),
2414 true);
2415 parent->SetPreserves3d(true);
2417 this->CalcDrawEtc(parent);
2419 TestOcclusionTrackerWithClip<typename Types::LayerType,
2420 typename Types::RenderSurfaceType> occlusion(
2421 gfx::Rect(0, 0, 1000, 1000));
2422 this->VisitLayer(child2, &occlusion);
2423 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2424 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2426 this->VisitLayer(child1, &occlusion);
2427 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2428 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2432 // This test will have different layer ordering on the impl thread; the test
2433 // will only work on the main thread.
2434 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
2436 template <class Types>
2437 class OcclusionTrackerTestPerspectiveTransform
2438 : public OcclusionTrackerTest<Types> {
2439 protected:
2440 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
2441 : OcclusionTrackerTest<Types>(opaque_layers) {}
2442 void RunMyTest() {
2443 gfx::Transform transform;
2444 transform.Translate(150.0, 150.0);
2445 transform.ApplyPerspectiveDepth(400.0);
2446 transform.RotateAboutXAxis(-30.0);
2447 transform.Translate(-150.0, -150.0);
2449 typename Types::ContentLayerType* parent = this->CreateRoot(
2450 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2451 typename Types::LayerType* container = this->CreateLayer(
2452 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2453 typename Types::ContentLayerType* layer =
2454 this->CreateDrawingLayer(container,
2455 transform,
2456 gfx::PointF(100.f, 100.f),
2457 gfx::Size(200, 200),
2458 true);
2459 container->SetPreserves3d(true);
2460 layer->SetPreserves3d(true);
2461 this->CalcDrawEtc(parent);
2463 TestOcclusionTrackerWithClip<typename Types::LayerType,
2464 typename Types::RenderSurfaceType> occlusion(
2465 gfx::Rect(0, 0, 1000, 1000));
2466 this->EnterLayer(layer, &occlusion);
2468 EXPECT_RECT_EQ(
2469 gfx::Rect(0, 0, 200, 200),
2470 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2474 // This test requires accumulating occlusion of 3d layers, which are skipped by
2475 // the occlusion tracker on the main thread. So this test should run on the impl
2476 // thread.
2477 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
2479 template <class Types>
2480 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2481 : public OcclusionTrackerTest<Types> {
2482 protected:
2483 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2484 bool opaque_layers)
2485 : OcclusionTrackerTest<Types>(opaque_layers) {}
2486 void RunMyTest() {
2487 // This test is based on the platform/chromium/compositing/3d-corners.html
2488 // layout test.
2489 gfx::Transform transform;
2490 transform.Translate(250.0, 50.0);
2491 transform.ApplyPerspectiveDepth(10.0);
2492 transform.Translate(-250.0, -50.0);
2493 transform.Translate(250.0, 50.0);
2494 transform.RotateAboutXAxis(-167.0);
2495 transform.Translate(-250.0, -50.0);
2497 typename Types::ContentLayerType* parent = this->CreateRoot(
2498 this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
2499 typename Types::LayerType* container = this->CreateLayer(
2500 parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2501 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2502 container, transform, gfx::PointF(), gfx::Size(500, 500), true);
2503 container->SetPreserves3d(true);
2504 layer->SetPreserves3d(true);
2505 this->CalcDrawEtc(parent);
2507 TestOcclusionTrackerWithClip<typename Types::LayerType,
2508 typename Types::RenderSurfaceType> occlusion(
2509 gfx::Rect(0, 0, 1000, 1000));
2510 this->EnterLayer(layer, &occlusion);
2512 // The bottom 11 pixel rows of this layer remain visible inside the
2513 // container, after translation to the target surface. When translated back,
2514 // this will include many more pixels but must include at least the bottom
2515 // 11 rows.
2516 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2517 layer, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
2521 // This test requires accumulating occlusion of 3d layers, which are skipped by
2522 // the occlusion tracker on the main thread. So this test should run on the impl
2523 // thread.
2524 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2526 template <class Types>
2527 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2528 : public OcclusionTrackerTest<Types> {
2529 protected:
2530 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2531 bool opaque_layers)
2532 : OcclusionTrackerTest<Types>(opaque_layers) {}
2533 void RunMyTest() {
2534 gfx::Transform transform;
2535 transform.Translate(50.0, 50.0);
2536 transform.ApplyPerspectiveDepth(100.0);
2537 transform.Translate3d(0.0, 0.0, 110.0);
2538 transform.Translate(-50.0, -50.0);
2540 typename Types::ContentLayerType* parent = this->CreateRoot(
2541 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2542 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2543 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2544 parent->SetPreserves3d(true);
2545 layer->SetPreserves3d(true);
2546 this->CalcDrawEtc(parent);
2548 TestOcclusionTrackerWithClip<typename Types::LayerType,
2549 typename Types::RenderSurfaceType> occlusion(
2550 gfx::Rect(0, 0, 1000, 1000));
2552 // The |layer| is entirely behind the camera and should not occlude.
2553 this->VisitLayer(layer, &occlusion);
2554 this->EnterLayer(parent, &occlusion);
2555 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2556 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2560 // This test requires accumulating occlusion of 3d layers, which are skipped by
2561 // the occlusion tracker on the main thread. So this test should run on the impl
2562 // thread.
2563 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2565 template <class Types>
2566 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2567 : public OcclusionTrackerTest<Types> {
2568 protected:
2569 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2570 bool opaque_layers)
2571 : OcclusionTrackerTest<Types>(opaque_layers) {}
2572 void RunMyTest() {
2573 gfx::Transform transform;
2574 transform.Translate(50.0, 50.0);
2575 transform.ApplyPerspectiveDepth(100.0);
2576 transform.Translate3d(0.0, 0.0, 99.0);
2577 transform.Translate(-50.0, -50.0);
2579 typename Types::ContentLayerType* parent = this->CreateRoot(
2580 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2581 parent->SetMasksToBounds(true);
2582 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2583 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2584 parent->SetPreserves3d(true);
2585 layer->SetPreserves3d(true);
2586 this->CalcDrawEtc(parent);
2588 TestOcclusionTrackerWithClip<typename Types::LayerType,
2589 typename Types::RenderSurfaceType> occlusion(
2590 gfx::Rect(0, 0, 1000, 1000));
2592 // This is very close to the camera, so pixels in its visible_content_rect()
2593 // will actually go outside of the layer's clip rect. Ensure that those
2594 // pixels don't occlude things outside the clip rect.
2595 this->VisitLayer(layer, &occlusion);
2596 this->EnterLayer(parent, &occlusion);
2597 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2598 occlusion.occlusion_from_inside_target().ToString());
2599 EXPECT_EQ(gfx::Rect().ToString(),
2600 occlusion.occlusion_from_outside_target().ToString());
2604 // This test requires accumulating occlusion of 3d layers, which are skipped by
2605 // the occlusion tracker on the main thread. So this test should run on the impl
2606 // thread.
2607 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2609 template <class Types>
2610 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2611 : public OcclusionTrackerTest<Types> {
2612 protected:
2613 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
2614 : OcclusionTrackerTest<Types>(opaque_layers) {}
2615 void RunMyTest() {
2616 // parent
2617 // +--layer
2618 // +--surface
2619 // | +--surface_child
2620 // | +--surface_child2
2621 // +--parent2
2622 // +--topmost
2624 typename Types::ContentLayerType* parent = this->CreateRoot(
2625 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2626 typename Types::ContentLayerType* layer =
2627 this->CreateDrawingLayer(parent,
2628 this->identity_matrix,
2629 gfx::PointF(),
2630 gfx::Size(300, 300),
2631 true);
2632 typename Types::ContentLayerType* surface =
2633 this->CreateDrawingSurface(parent,
2634 this->identity_matrix,
2635 gfx::PointF(),
2636 gfx::Size(300, 300),
2637 true);
2638 typename Types::ContentLayerType* surface_child =
2639 this->CreateDrawingLayer(surface,
2640 this->identity_matrix,
2641 gfx::PointF(),
2642 gfx::Size(200, 300),
2643 true);
2644 typename Types::ContentLayerType* surface_child2 =
2645 this->CreateDrawingLayer(surface,
2646 this->identity_matrix,
2647 gfx::PointF(),
2648 gfx::Size(100, 300),
2649 true);
2650 typename Types::ContentLayerType* parent2 =
2651 this->CreateDrawingLayer(parent,
2652 this->identity_matrix,
2653 gfx::PointF(),
2654 gfx::Size(300, 300),
2655 false);
2656 typename Types::ContentLayerType* topmost =
2657 this->CreateDrawingLayer(parent,
2658 this->identity_matrix,
2659 gfx::PointF(250.f, 0.f),
2660 gfx::Size(50, 300),
2661 true);
2663 AddOpacityTransitionToController(
2664 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2665 AddOpacityTransitionToController(
2666 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2667 this->CalcDrawEtc(parent);
2669 EXPECT_TRUE(layer->draw_opacity_is_animating());
2670 EXPECT_FALSE(surface->draw_opacity_is_animating());
2671 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2673 TestOcclusionTrackerWithClip<typename Types::LayerType,
2674 typename Types::RenderSurfaceType> occlusion(
2675 gfx::Rect(0, 0, 1000, 1000));
2677 this->VisitLayer(topmost, &occlusion);
2678 this->EnterLayer(parent2, &occlusion);
2679 // This occlusion will affect all surfaces.
2680 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2681 occlusion.occlusion_from_inside_target().ToString());
2682 EXPECT_EQ(gfx::Rect().ToString(),
2683 occlusion.occlusion_from_outside_target().ToString());
2684 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2685 occlusion.UnoccludedLayerContentRect(
2686 parent2, gfx::Rect(0, 0, 300, 300)).ToString());
2687 this->LeaveLayer(parent2, &occlusion);
2689 this->VisitLayer(surface_child2, &occlusion);
2690 this->EnterLayer(surface_child, &occlusion);
2691 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2692 occlusion.occlusion_from_inside_target().ToString());
2693 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2694 occlusion.occlusion_from_outside_target().ToString());
2695 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2696 occlusion.UnoccludedLayerContentRect(
2697 surface_child, gfx::Rect(0, 0, 200, 300)));
2698 this->LeaveLayer(surface_child, &occlusion);
2699 this->EnterLayer(surface, &occlusion);
2700 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2701 occlusion.occlusion_from_inside_target().ToString());
2702 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2703 occlusion.occlusion_from_outside_target().ToString());
2704 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2705 occlusion.UnoccludedLayerContentRect(
2706 surface, gfx::Rect(0, 0, 300, 300)));
2707 this->LeaveLayer(surface, &occlusion);
2709 this->EnterContributingSurface(surface, &occlusion);
2710 // Occlusion within the surface is lost when leaving the animating surface.
2711 EXPECT_EQ(gfx::Rect().ToString(),
2712 occlusion.occlusion_from_inside_target().ToString());
2713 EXPECT_EQ(gfx::Rect().ToString(),
2714 occlusion.occlusion_from_outside_target().ToString());
2715 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2716 occlusion.UnoccludedContributingSurfaceContentRect(
2717 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
2718 this->LeaveContributingSurface(surface, &occlusion);
2720 // Occlusion from outside the animating surface still exists.
2721 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2722 occlusion.occlusion_from_inside_target().ToString());
2723 EXPECT_EQ(gfx::Rect().ToString(),
2724 occlusion.occlusion_from_outside_target().ToString());
2726 this->VisitLayer(layer, &occlusion);
2727 this->EnterLayer(parent, &occlusion);
2729 // Occlusion is not added for the animating |layer|.
2730 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2731 occlusion.UnoccludedLayerContentRect(
2732 parent, gfx::Rect(0, 0, 300, 300)));
2736 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2738 template <class Types>
2739 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2740 : public OcclusionTrackerTest<Types> {
2741 protected:
2742 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
2743 : OcclusionTrackerTest<Types>(opaque_layers) {}
2744 void RunMyTest() {
2745 typename Types::ContentLayerType* parent = this->CreateRoot(
2746 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2747 typename Types::ContentLayerType* layer =
2748 this->CreateDrawingLayer(parent,
2749 this->identity_matrix,
2750 gfx::PointF(),
2751 gfx::Size(300, 300),
2752 true);
2753 typename Types::ContentLayerType* surface =
2754 this->CreateDrawingSurface(parent,
2755 this->identity_matrix,
2756 gfx::PointF(),
2757 gfx::Size(300, 300),
2758 true);
2759 typename Types::ContentLayerType* surface_child =
2760 this->CreateDrawingLayer(surface,
2761 this->identity_matrix,
2762 gfx::PointF(),
2763 gfx::Size(200, 300),
2764 true);
2765 typename Types::ContentLayerType* surface_child2 =
2766 this->CreateDrawingLayer(surface,
2767 this->identity_matrix,
2768 gfx::PointF(),
2769 gfx::Size(100, 300),
2770 true);
2771 typename Types::ContentLayerType* parent2 =
2772 this->CreateDrawingLayer(parent,
2773 this->identity_matrix,
2774 gfx::PointF(),
2775 gfx::Size(300, 300),
2776 false);
2777 typename Types::ContentLayerType* topmost =
2778 this->CreateDrawingLayer(parent,
2779 this->identity_matrix,
2780 gfx::PointF(250.f, 0.f),
2781 gfx::Size(50, 300),
2782 true);
2784 AddOpacityTransitionToController(
2785 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2786 AddOpacityTransitionToController(
2787 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2788 this->CalcDrawEtc(parent);
2790 EXPECT_TRUE(layer->draw_opacity_is_animating());
2791 EXPECT_FALSE(surface->draw_opacity_is_animating());
2792 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2794 TestOcclusionTrackerWithClip<typename Types::LayerType,
2795 typename Types::RenderSurfaceType> occlusion(
2796 gfx::Rect(0, 0, 1000, 1000));
2798 this->VisitLayer(topmost, &occlusion);
2799 this->EnterLayer(parent2, &occlusion);
2800 // This occlusion will affect all surfaces.
2801 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2802 occlusion.occlusion_from_inside_target().ToString());
2803 EXPECT_EQ(gfx::Rect().ToString(),
2804 occlusion.occlusion_from_outside_target().ToString());
2805 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2806 occlusion.UnoccludedLayerContentRect(
2807 parent, gfx::Rect(0, 0, 300, 300)));
2808 this->LeaveLayer(parent2, &occlusion);
2810 this->VisitLayer(surface_child2, &occlusion);
2811 this->EnterLayer(surface_child, &occlusion);
2812 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2813 occlusion.occlusion_from_inside_target().ToString());
2814 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2815 occlusion.occlusion_from_outside_target().ToString());
2816 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2817 occlusion.UnoccludedLayerContentRect(
2818 surface_child, gfx::Rect(0, 0, 200, 300)));
2819 this->LeaveLayer(surface_child, &occlusion);
2820 this->EnterLayer(surface, &occlusion);
2821 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2822 occlusion.occlusion_from_inside_target().ToString());
2823 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2824 occlusion.occlusion_from_outside_target().ToString());
2825 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2826 occlusion.UnoccludedLayerContentRect(
2827 surface, gfx::Rect(0, 0, 300, 300)));
2828 this->LeaveLayer(surface, &occlusion);
2830 this->EnterContributingSurface(surface, &occlusion);
2831 // Occlusion within the surface is lost when leaving the animating surface.
2832 EXPECT_EQ(gfx::Rect().ToString(),
2833 occlusion.occlusion_from_inside_target().ToString());
2834 EXPECT_EQ(gfx::Rect().ToString(),
2835 occlusion.occlusion_from_outside_target().ToString());
2836 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2837 occlusion.UnoccludedContributingSurfaceContentRect(
2838 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
2839 this->LeaveContributingSurface(surface, &occlusion);
2841 // Occlusion from outside the animating surface still exists.
2842 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2843 occlusion.occlusion_from_inside_target().ToString());
2844 EXPECT_EQ(gfx::Rect().ToString(),
2845 occlusion.occlusion_from_outside_target().ToString());
2847 this->VisitLayer(layer, &occlusion);
2848 this->EnterLayer(parent, &occlusion);
2850 // Occlusion is not added for the animating |layer|.
2851 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2852 occlusion.UnoccludedLayerContentRect(
2853 parent, gfx::Rect(0, 0, 300, 300)));
2857 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2859 template <class Types>
2860 class OcclusionTrackerTestAnimationTranslateOnMainThread
2861 : public OcclusionTrackerTest<Types> {
2862 protected:
2863 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2864 bool opaque_layers)
2865 : OcclusionTrackerTest<Types>(opaque_layers) {}
2866 void RunMyTest() {
2867 typename Types::ContentLayerType* parent = this->CreateRoot(
2868 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2869 typename Types::ContentLayerType* layer =
2870 this->CreateDrawingLayer(parent,
2871 this->identity_matrix,
2872 gfx::PointF(),
2873 gfx::Size(300, 300),
2874 true);
2875 typename Types::ContentLayerType* surface =
2876 this->CreateDrawingSurface(parent,
2877 this->identity_matrix,
2878 gfx::PointF(),
2879 gfx::Size(300, 300),
2880 true);
2881 typename Types::ContentLayerType* surface_child =
2882 this->CreateDrawingLayer(surface,
2883 this->identity_matrix,
2884 gfx::PointF(),
2885 gfx::Size(200, 300),
2886 true);
2887 typename Types::ContentLayerType* surface_child2 =
2888 this->CreateDrawingLayer(surface,
2889 this->identity_matrix,
2890 gfx::PointF(),
2891 gfx::Size(100, 300),
2892 true);
2893 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
2894 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
2896 AddAnimatedTransformToController(
2897 layer->layer_animation_controller(), 10.0, 30, 0);
2898 AddAnimatedTransformToController(
2899 surface->layer_animation_controller(), 10.0, 30, 0);
2900 AddAnimatedTransformToController(
2901 surface_child->layer_animation_controller(), 10.0, 30, 0);
2902 this->CalcDrawEtc(parent);
2904 EXPECT_TRUE(layer->draw_transform_is_animating());
2905 EXPECT_TRUE(layer->screen_space_transform_is_animating());
2906 EXPECT_TRUE(
2907 surface->render_surface()->target_surface_transforms_are_animating());
2908 EXPECT_TRUE(
2909 surface->render_surface()->screen_space_transforms_are_animating());
2910 // The surface owning layer doesn't animate against its own surface.
2911 EXPECT_FALSE(surface->draw_transform_is_animating());
2912 EXPECT_TRUE(surface->screen_space_transform_is_animating());
2913 EXPECT_TRUE(surface_child->draw_transform_is_animating());
2914 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
2916 TestOcclusionTrackerWithClip<typename Types::LayerType,
2917 typename Types::RenderSurfaceType> occlusion(
2918 gfx::Rect(0, 0, 1000, 1000));
2920 this->VisitLayer(surface2, &occlusion);
2921 this->EnterContributingSurface(surface2, &occlusion);
2923 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2924 occlusion.occlusion_from_inside_target().ToString());
2926 this->LeaveContributingSurface(surface2, &occlusion);
2927 this->EnterLayer(surface_child2, &occlusion);
2929 // surface_child2 is moving in screen space but not relative to its target,
2930 // so occlusion should happen in its target space only. It also means that
2931 // things occluding from outside the target (e.g. surface2) cannot occlude
2932 // this layer.
2933 EXPECT_EQ(gfx::Rect().ToString(),
2934 occlusion.occlusion_from_outside_target().ToString());
2936 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2937 occlusion.UnoccludedLayerContentRect(
2938 surface_child2, gfx::Rect(0, 0, 100, 300)));
2939 EXPECT_FALSE(
2940 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2942 this->LeaveLayer(surface_child2, &occlusion);
2943 this->EnterLayer(surface_child, &occlusion);
2944 EXPECT_FALSE(
2945 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300)));
2946 EXPECT_EQ(gfx::Rect().ToString(),
2947 occlusion.occlusion_from_outside_target().ToString());
2948 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2949 occlusion.occlusion_from_inside_target().ToString());
2950 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2951 occlusion.UnoccludedLayerContentRect(
2952 surface, gfx::Rect(0, 0, 300, 300)));
2954 // The surface_child is occluded by the surface_child2, but is moving
2955 // relative its target, so it can't be occluded.
2956 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2957 occlusion.UnoccludedLayerContentRect(
2958 surface_child, gfx::Rect(0, 0, 200, 300)));
2959 EXPECT_FALSE(
2960 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2962 this->LeaveLayer(surface_child, &occlusion);
2963 this->EnterLayer(surface, &occlusion);
2964 // The surface_child is moving in screen space but not relative to its
2965 // target, so occlusion should happen from within the target only.
2966 EXPECT_EQ(gfx::Rect().ToString(),
2967 occlusion.occlusion_from_outside_target().ToString());
2968 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2969 occlusion.occlusion_from_inside_target().ToString());
2970 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2971 occlusion.UnoccludedLayerContentRect(
2972 surface, gfx::Rect(0, 0, 300, 300)));
2974 this->LeaveLayer(surface, &occlusion);
2975 // The surface's owning layer is moving in screen space but not relative to
2976 // its target, so occlusion should happen within the target only.
2977 EXPECT_EQ(gfx::Rect().ToString(),
2978 occlusion.occlusion_from_outside_target().ToString());
2979 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2980 occlusion.occlusion_from_inside_target().ToString());
2981 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2982 occlusion.UnoccludedLayerContentRect(
2983 surface, gfx::Rect(0, 0, 300, 300)));
2985 this->EnterContributingSurface(surface, &occlusion);
2986 // The contributing |surface| is animating so it can't be occluded.
2987 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2988 occlusion.UnoccludedContributingSurfaceContentRect(
2989 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
2990 this->LeaveContributingSurface(surface, &occlusion);
2992 this->EnterLayer(layer, &occlusion);
2993 // The |surface| is moving in the screen and in its target, so all occlusion
2994 // within the surface is lost when leaving it.
2995 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2996 occlusion.UnoccludedLayerContentRect(
2997 parent, gfx::Rect(0, 0, 300, 300)));
2998 this->LeaveLayer(layer, &occlusion);
3000 this->EnterLayer(parent, &occlusion);
3001 // The |layer| is animating in the screen and in its target, so no occlusion
3002 // is added.
3003 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3004 occlusion.UnoccludedLayerContentRect(
3005 parent, gfx::Rect(0, 0, 300, 300)));
3009 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
3011 template <class Types>
3012 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
3013 : public OcclusionTrackerTest<Types> {
3014 protected:
3015 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
3016 bool opaque_layers)
3017 : OcclusionTrackerTest<Types>(opaque_layers) {}
3018 void RunMyTest() {
3019 gfx::Transform surface_transform;
3020 surface_transform.Translate(300.0, 300.0);
3021 surface_transform.Scale(2.0, 2.0);
3022 surface_transform.Translate(-150.0, -150.0);
3024 typename Types::ContentLayerType* parent = this->CreateRoot(
3025 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
3026 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
3027 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
3028 typename Types::ContentLayerType* surface2 =
3029 this->CreateDrawingSurface(parent,
3030 this->identity_matrix,
3031 gfx::PointF(50.f, 50.f),
3032 gfx::Size(300, 300),
3033 false);
3034 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3035 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3036 this->CalcDrawEtc(parent);
3038 TestOcclusionTrackerWithClip<typename Types::LayerType,
3039 typename Types::RenderSurfaceType> occlusion(
3040 gfx::Rect(0, 0, 1000, 1000));
3042 this->VisitLayer(surface2, &occlusion);
3043 this->VisitContributingSurface(surface2, &occlusion);
3045 EXPECT_EQ(gfx::Rect().ToString(),
3046 occlusion.occlusion_from_outside_target().ToString());
3047 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
3048 occlusion.occlusion_from_inside_target().ToString());
3050 // Clear any stored occlusion.
3051 occlusion.set_occlusion_from_outside_target(Region());
3052 occlusion.set_occlusion_from_inside_target(Region());
3054 this->VisitLayer(surface, &occlusion);
3055 this->VisitContributingSurface(surface, &occlusion);
3057 EXPECT_EQ(gfx::Rect().ToString(),
3058 occlusion.occlusion_from_outside_target().ToString());
3059 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
3060 occlusion.occlusion_from_inside_target().ToString());
3064 MAIN_AND_IMPL_THREAD_TEST(
3065 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
3067 template <class Types>
3068 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
3069 : public OcclusionTrackerTest<Types> {
3070 protected:
3071 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
3072 bool opaque_layers)
3073 : OcclusionTrackerTest<Types>(opaque_layers) {}
3074 void RunMyTest() {
3075 typename Types::ContentLayerType* parent = this->CreateRoot(
3076 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
3077 parent->SetMasksToBounds(true);
3078 typename Types::ContentLayerType* surface =
3079 this->CreateDrawingSurface(parent,
3080 this->identity_matrix,
3081 gfx::PointF(),
3082 gfx::Size(500, 300),
3083 false);
3084 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
3085 this->CalcDrawEtc(parent);
3087 TestOcclusionTrackerWithClip<typename Types::LayerType,
3088 typename Types::RenderSurfaceType> occlusion(
3089 gfx::Rect(0, 0, 1000, 1000));
3091 this->VisitLayer(surface, &occlusion);
3092 this->VisitContributingSurface(surface, &occlusion);
3094 EXPECT_EQ(gfx::Rect().ToString(),
3095 occlusion.occlusion_from_outside_target().ToString());
3096 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
3097 occlusion.occlusion_from_inside_target().ToString());
3101 MAIN_AND_IMPL_THREAD_TEST(
3102 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
3104 template <class Types>
3105 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
3106 protected:
3107 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
3108 : OcclusionTrackerTest<Types>(opaque_layers) {}
3109 void RunMyTest() {
3110 typename Types::ContentLayerType* parent = this->CreateRoot(
3111 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3112 typename Types::LayerType* surface =
3113 this->CreateDrawingSurface(parent,
3114 this->identity_matrix,
3115 gfx::PointF(),
3116 gfx::Size(100, 100),
3117 true);
3118 this->CreateReplicaLayer(surface,
3119 this->identity_matrix,
3120 gfx::PointF(0.f, 100.f),
3121 gfx::Size(100, 100));
3122 typename Types::LayerType* topmost =
3123 this->CreateDrawingLayer(parent,
3124 this->identity_matrix,
3125 gfx::PointF(0.f, 100.f),
3126 gfx::Size(100, 100),
3127 true);
3128 this->CalcDrawEtc(parent);
3130 TestOcclusionTrackerWithClip<typename Types::LayerType,
3131 typename Types::RenderSurfaceType> occlusion(
3132 gfx::Rect(0, 0, 1000, 1000));
3134 // |topmost| occludes the replica, but not the surface itself.
3135 this->VisitLayer(topmost, &occlusion);
3137 EXPECT_EQ(gfx::Rect().ToString(),
3138 occlusion.occlusion_from_outside_target().ToString());
3139 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3140 occlusion.occlusion_from_inside_target().ToString());
3142 this->VisitLayer(surface, &occlusion);
3144 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3145 occlusion.occlusion_from_outside_target().ToString());
3146 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3147 occlusion.occlusion_from_inside_target().ToString());
3149 this->EnterContributingSurface(surface, &occlusion);
3151 // Surface is not occluded so it shouldn't think it is.
3152 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3153 occlusion.UnoccludedContributingSurfaceContentRect(
3154 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3158 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
3160 template <class Types>
3161 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
3162 : public OcclusionTrackerTest<Types> {
3163 protected:
3164 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
3165 : OcclusionTrackerTest<Types>(opaque_layers) {}
3166 void RunMyTest() {
3167 typename Types::ContentLayerType* parent = this->CreateRoot(
3168 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3169 typename Types::LayerType* surface =
3170 this->CreateDrawingSurface(parent,
3171 this->identity_matrix,
3172 gfx::PointF(),
3173 gfx::Size(100, 100),
3174 true);
3175 this->CreateReplicaLayer(surface,
3176 this->identity_matrix,
3177 gfx::PointF(0.f, 100.f),
3178 gfx::Size(100, 100));
3179 typename Types::LayerType* topmost =
3180 this->CreateDrawingLayer(parent,
3181 this->identity_matrix,
3182 gfx::PointF(),
3183 gfx::Size(100, 110),
3184 true);
3185 this->CalcDrawEtc(parent);
3187 TestOcclusionTrackerWithClip<typename Types::LayerType,
3188 typename Types::RenderSurfaceType> occlusion(
3189 gfx::Rect(0, 0, 1000, 1000));
3191 // |topmost| occludes the surface, but not the entire surface's replica.
3192 this->VisitLayer(topmost, &occlusion);
3194 EXPECT_EQ(gfx::Rect().ToString(),
3195 occlusion.occlusion_from_outside_target().ToString());
3196 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3197 occlusion.occlusion_from_inside_target().ToString());
3199 this->VisitLayer(surface, &occlusion);
3201 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3202 occlusion.occlusion_from_outside_target().ToString());
3203 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3204 occlusion.occlusion_from_inside_target().ToString());
3206 this->EnterContributingSurface(surface, &occlusion);
3208 // Surface is occluded, but only the top 10px of the replica.
3209 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3210 occlusion.UnoccludedContributingSurfaceContentRect(
3211 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3212 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
3213 occlusion.UnoccludedContributingSurfaceContentRect(
3214 surface, true, gfx::Rect(0, 0, 100, 100), NULL));
3218 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
3220 template <class Types>
3221 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
3222 : public OcclusionTrackerTest<Types> {
3223 protected:
3224 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
3225 bool opaque_layers)
3226 : OcclusionTrackerTest<Types>(opaque_layers) {}
3227 void RunMyTest() {
3228 typename Types::ContentLayerType* parent = this->CreateRoot(
3229 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3230 typename Types::LayerType* surface =
3231 this->CreateDrawingSurface(parent,
3232 this->identity_matrix,
3233 gfx::PointF(),
3234 gfx::Size(100, 100),
3235 true);
3236 this->CreateReplicaLayer(surface,
3237 this->identity_matrix,
3238 gfx::PointF(0.f, 100.f),
3239 gfx::Size(100, 100));
3240 typename Types::LayerType* over_surface = this->CreateDrawingLayer(
3241 parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
3242 typename Types::LayerType* over_replica =
3243 this->CreateDrawingLayer(parent,
3244 this->identity_matrix,
3245 gfx::PointF(0.f, 100.f),
3246 gfx::Size(50, 100),
3247 true);
3248 this->CalcDrawEtc(parent);
3250 TestOcclusionTrackerWithClip<typename Types::LayerType,
3251 typename Types::RenderSurfaceType> occlusion(
3252 gfx::Rect(0, 0, 1000, 1000));
3254 // These occlude the surface and replica differently, so we can test each
3255 // one.
3256 this->VisitLayer(over_replica, &occlusion);
3257 this->VisitLayer(over_surface, &occlusion);
3259 EXPECT_EQ(gfx::Rect().ToString(),
3260 occlusion.occlusion_from_outside_target().ToString());
3261 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3262 .ToString(),
3263 occlusion.occlusion_from_inside_target().ToString());
3265 this->VisitLayer(surface, &occlusion);
3267 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3268 .ToString(),
3269 occlusion.occlusion_from_outside_target().ToString());
3270 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3271 occlusion.occlusion_from_inside_target().ToString());
3273 this->EnterContributingSurface(surface, &occlusion);
3275 // Surface and replica are occluded different amounts.
3276 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
3277 occlusion.UnoccludedContributingSurfaceContentRect(
3278 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3279 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
3280 occlusion.UnoccludedContributingSurfaceContentRect(
3281 surface, true, gfx::Rect(0, 0, 100, 100), NULL));
3285 ALL_OCCLUSIONTRACKER_TEST(
3286 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
3288 template <class Types>
3289 class OcclusionTrackerTestSurfaceChildOfSurface
3290 : public OcclusionTrackerTest<Types> {
3291 protected:
3292 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
3293 : OcclusionTrackerTest<Types>(opaque_layers) {}
3294 void RunMyTest() {
3295 // This test verifies that the surface cliprect does not end up empty and
3296 // clip away the entire unoccluded rect.
3298 typename Types::ContentLayerType* parent = this->CreateRoot(
3299 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3300 typename Types::LayerType* surface =
3301 this->CreateDrawingSurface(parent,
3302 this->identity_matrix,
3303 gfx::PointF(),
3304 gfx::Size(100, 100),
3305 true);
3306 typename Types::LayerType* surface_child =
3307 this->CreateDrawingSurface(surface,
3308 this->identity_matrix,
3309 gfx::PointF(0.f, 10.f),
3310 gfx::Size(100, 50),
3311 true);
3312 typename Types::LayerType* topmost = this->CreateDrawingLayer(
3313 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3314 this->CalcDrawEtc(parent);
3316 TestOcclusionTrackerWithClip<typename Types::LayerType,
3317 typename Types::RenderSurfaceType> occlusion(
3318 gfx::Rect(-100, -100, 1000, 1000));
3320 // |topmost| occludes everything partially so we know occlusion is happening
3321 // at all.
3322 this->VisitLayer(topmost, &occlusion);
3324 EXPECT_EQ(gfx::Rect().ToString(),
3325 occlusion.occlusion_from_outside_target().ToString());
3326 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3327 occlusion.occlusion_from_inside_target().ToString());
3329 this->VisitLayer(surface_child, &occlusion);
3331 // surface_child increases the occlusion in the screen by a narrow sliver.
3332 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
3333 occlusion.occlusion_from_outside_target().ToString());
3334 // In its own surface, surface_child is at 0,0 as is its occlusion.
3335 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3336 occlusion.occlusion_from_inside_target().ToString());
3338 // The root layer always has a clip rect. So the parent of |surface| has a
3339 // clip rect. However, the owning layer for |surface| does not mask to
3340 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3341 // |surface_child| exercises different code paths as its parent does not
3342 // have a clip rect.
3344 this->EnterContributingSurface(surface_child, &occlusion);
3345 // The surface_child's parent does not have a clip rect as it owns a render
3346 // surface. Make sure the unoccluded rect does not get clipped away
3347 // inappropriately.
3348 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
3349 occlusion.UnoccludedContributingSurfaceContentRect(
3350 surface_child, false, gfx::Rect(0, 0, 100, 50), NULL));
3351 this->LeaveContributingSurface(surface_child, &occlusion);
3353 // When the surface_child's occlusion is transformed up to its parent, make
3354 // sure it is not clipped away inappropriately also.
3355 this->EnterLayer(surface, &occlusion);
3356 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3357 occlusion.occlusion_from_outside_target().ToString());
3358 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
3359 occlusion.occlusion_from_inside_target().ToString());
3360 this->LeaveLayer(surface, &occlusion);
3362 this->EnterContributingSurface(surface, &occlusion);
3363 // The surface's parent does have a clip rect as it is the root layer.
3364 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
3365 occlusion.UnoccludedContributingSurfaceContentRect(
3366 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3370 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
3372 template <class Types>
3373 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
3374 : public OcclusionTrackerTest<Types> {
3375 protected:
3376 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
3377 bool opaque_layers)
3378 : OcclusionTrackerTest<Types>(opaque_layers) {}
3379 void RunMyTest() {
3380 // This test verifies that the top-most surface is considered occluded
3381 // outside of its target's clip rect and outside the viewport rect.
3383 typename Types::ContentLayerType* parent = this->CreateRoot(
3384 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3385 typename Types::LayerType* surface =
3386 this->CreateDrawingSurface(parent,
3387 this->identity_matrix,
3388 gfx::PointF(),
3389 gfx::Size(100, 300),
3390 true);
3391 this->CalcDrawEtc(parent);
3393 // Make a viewport rect that is larger than the root layer.
3394 TestOcclusionTrackerWithClip<typename Types::LayerType,
3395 typename Types::RenderSurfaceType> occlusion(
3396 gfx::Rect(0, 0, 1000, 1000));
3398 this->VisitLayer(surface, &occlusion);
3400 // The root layer always has a clip rect. So the parent of |surface| has a
3401 // clip rect giving the surface itself a clip rect.
3402 this->EnterContributingSurface(surface, &occlusion);
3403 // Make sure the parent's clip rect clips the unoccluded region of the
3404 // child surface.
3405 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
3406 occlusion.UnoccludedContributingSurfaceContentRect(
3407 surface, false, gfx::Rect(0, 0, 100, 300), NULL));
3409 this->ResetLayerIterator();
3411 // Make a viewport rect that is smaller than the root layer.
3412 TestOcclusionTrackerWithClip<typename Types::LayerType,
3413 typename Types::RenderSurfaceType> occlusion(
3414 gfx::Rect(0, 0, 100, 100));
3416 this->VisitLayer(surface, &occlusion);
3418 // The root layer always has a clip rect. So the parent of |surface| has a
3419 // clip rect giving the surface itself a clip rect.
3420 this->EnterContributingSurface(surface, &occlusion);
3421 // Make sure the viewport rect clips the unoccluded region of the child
3422 // surface.
3423 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3424 occlusion.UnoccludedContributingSurfaceContentRect(
3425 surface, false, gfx::Rect(0, 0, 100, 300), NULL));
3430 ALL_OCCLUSIONTRACKER_TEST(
3431 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
3433 template <class Types>
3434 class OcclusionTrackerTestSurfaceChildOfClippingSurface
3435 : public OcclusionTrackerTest<Types> {
3436 protected:
3437 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers)
3438 : OcclusionTrackerTest<Types>(opaque_layers) {}
3439 void RunMyTest() {
3440 // This test verifies that the surface cliprect does not end up empty and
3441 // clip away the entire unoccluded rect.
3443 typename Types::ContentLayerType* parent = this->CreateRoot(
3444 this->identity_matrix, gfx::PointF(), gfx::Size(80, 200));
3445 parent->SetMasksToBounds(true);
3446 typename Types::LayerType* surface =
3447 this->CreateDrawingSurface(parent,
3448 this->identity_matrix,
3449 gfx::PointF(),
3450 gfx::Size(100, 100),
3451 true);
3452 typename Types::LayerType* surface_child =
3453 this->CreateDrawingSurface(surface,
3454 this->identity_matrix,
3455 gfx::PointF(),
3456 gfx::Size(100, 100),
3457 false);
3458 typename Types::LayerType* topmost = this->CreateDrawingLayer(
3459 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3460 this->CalcDrawEtc(parent);
3462 TestOcclusionTrackerWithClip<typename Types::LayerType,
3463 typename Types::RenderSurfaceType> occlusion(
3464 gfx::Rect(0, 0, 1000, 1000));
3466 // |topmost| occludes everything partially so we know occlusion is happening
3467 // at all.
3468 this->VisitLayer(topmost, &occlusion);
3470 EXPECT_EQ(gfx::Rect().ToString(),
3471 occlusion.occlusion_from_outside_target().ToString());
3472 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3473 occlusion.occlusion_from_inside_target().ToString());
3475 // surface_child is not opaque and does not occlude, so we have a non-empty
3476 // unoccluded area on surface.
3477 this->VisitLayer(surface_child, &occlusion);
3479 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3480 occlusion.occlusion_from_outside_target().ToString());
3481 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3482 occlusion.occlusion_from_inside_target().ToString());
3484 // The root layer always has a clip rect. So the parent of |surface| has a
3485 // clip rect. However, the owning layer for |surface| does not mask to
3486 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3487 // |surface_child| exercises different code paths as its parent does not
3488 // have a clip rect.
3490 this->EnterContributingSurface(surface_child, &occlusion);
3491 // The surface_child's parent does not have a clip rect as it owns a render
3492 // surface.
3493 EXPECT_EQ(
3494 gfx::Rect(0, 50, 80, 50).ToString(),
3495 occlusion.UnoccludedContributingSurfaceContentRect(
3496 surface_child, false, gfx::Rect(0, 0, 100, 100), NULL).ToString());
3497 this->LeaveContributingSurface(surface_child, &occlusion);
3499 this->VisitLayer(surface, &occlusion);
3500 this->EnterContributingSurface(surface, &occlusion);
3501 // The surface's parent does have a clip rect as it is the root layer.
3502 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3503 occlusion.UnoccludedContributingSurfaceContentRect(
3504 surface, false, gfx::Rect(0, 0, 100, 100), NULL).ToString());
3508 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
3510 template <class Types>
3511 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3512 : public OcclusionTrackerTest<Types> {
3513 protected:
3514 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3515 bool opaque_layers)
3516 : OcclusionTrackerTest<Types>(opaque_layers) {}
3517 void RunMyTest() {
3518 gfx::Transform scale_by_half;
3519 scale_by_half.Scale(0.5, 0.5);
3521 // Make a surface and its replica, each 50x50, that are completely
3522 // surrounded by opaque layers which are above them in the z-order. The
3523 // surface is scaled to test that the pixel moving is done in the target
3524 // space, where the background filter is applied, but the surface appears at
3525 // 50, 50 and the replica at 200, 50.
3526 typename Types::ContentLayerType* parent = this->CreateRoot(
3527 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3528 typename Types::LayerType* filtered_surface =
3529 this->CreateDrawingLayer(parent,
3530 scale_by_half,
3531 gfx::PointF(50.f, 50.f),
3532 gfx::Size(100, 100),
3533 false);
3534 this->CreateReplicaLayer(filtered_surface,
3535 this->identity_matrix,
3536 gfx::PointF(300.f, 0.f),
3537 gfx::Size());
3538 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3539 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
3540 typename Types::LayerType* occluding_layer2 =
3541 this->CreateDrawingLayer(parent,
3542 this->identity_matrix,
3543 gfx::PointF(0.f, 100.f),
3544 gfx::Size(300, 50),
3545 true);
3546 typename Types::LayerType* occluding_layer3 =
3547 this->CreateDrawingLayer(parent,
3548 this->identity_matrix,
3549 gfx::PointF(0.f, 50.f),
3550 gfx::Size(50, 50),
3551 true);
3552 typename Types::LayerType* occluding_layer4 =
3553 this->CreateDrawingLayer(parent,
3554 this->identity_matrix,
3555 gfx::PointF(100.f, 50.f),
3556 gfx::Size(100, 50),
3557 true);
3558 typename Types::LayerType* occluding_layer5 =
3559 this->CreateDrawingLayer(parent,
3560 this->identity_matrix,
3561 gfx::PointF(250.f, 50.f),
3562 gfx::Size(50, 50),
3563 true);
3565 // Filters make the layer own a surface.
3566 WebKit::WebFilterOperations filters;
3567 filters.append(WebKit::WebFilterOperation::createBlurFilter(10.f));
3568 filtered_surface->SetBackgroundFilters(filters);
3570 // Save the distance of influence for the blur effect.
3571 int outset_top, outset_right, outset_bottom, outset_left;
3572 filters.getOutsets(outset_top, outset_right, outset_bottom, outset_left);
3574 this->CalcDrawEtc(parent);
3576 TestOcclusionTrackerWithClip<typename Types::LayerType,
3577 typename Types::RenderSurfaceType> occlusion(
3578 gfx::Rect(0, 0, 1000, 1000));
3580 // These layers occlude pixels directly beside the filtered_surface. Because
3581 // filtered surface blends pixels in a radius, it will need to see some of
3582 // the pixels (up to radius far) underneath the occluding layers.
3583 this->VisitLayer(occluding_layer5, &occlusion);
3584 this->VisitLayer(occluding_layer4, &occlusion);
3585 this->VisitLayer(occluding_layer3, &occlusion);
3586 this->VisitLayer(occluding_layer2, &occlusion);
3587 this->VisitLayer(occluding_layer1, &occlusion);
3589 Region expected_occlusion;
3590 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
3591 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3592 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3593 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
3594 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));
3596 EXPECT_EQ(expected_occlusion.ToString(),
3597 occlusion.occlusion_from_inside_target().ToString());
3598 EXPECT_EQ(gfx::Rect().ToString(),
3599 occlusion.occlusion_from_outside_target().ToString());
3601 this->VisitLayer(filtered_surface, &occlusion);
3603 // The filtered layer/replica does not occlude.
3604 Region expected_occlusion_outside_surface;
3605 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
3606 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3607 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3608 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
3609 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));
3611 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3612 occlusion.occlusion_from_outside_target().ToString());
3613 EXPECT_EQ(gfx::Rect().ToString(),
3614 occlusion.occlusion_from_inside_target().ToString());
3616 // The surface has a background blur, so it needs pixels that are currently
3617 // considered occluded in order to be drawn. So the pixels it needs should
3618 // be removed some the occluded area so that when we get to the parent they
3619 // are drawn.
3620 this->VisitContributingSurface(filtered_surface, &occlusion);
3622 this->EnterLayer(parent, &occlusion);
3624 Region expected_blurred_occlusion;
3625 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
3626 expected_blurred_occlusion.Union(gfx::Rect(
3627 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
3628 expected_blurred_occlusion.Union(
3629 gfx::Rect(100 + outset_right,
3630 50 - outset_top,
3631 100 - outset_right - outset_left,
3632 50 + outset_top + outset_bottom));
3633 expected_blurred_occlusion.Union(
3634 gfx::Rect(250 + outset_right,
3635 50 - outset_top,
3636 50 - outset_right,
3637 50 + outset_top + outset_bottom));
3638 expected_blurred_occlusion.Union(
3639 gfx::Rect(0, 100 + outset_bottom, 300, 50 - outset_bottom));
3641 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3642 occlusion.occlusion_from_inside_target().ToString());
3643 EXPECT_EQ(gfx::Rect().ToString(),
3644 occlusion.occlusion_from_outside_target().ToString());
3646 gfx::Rect outset_rect;
3647 gfx::Rect test_rect;
3649 // Nothing in the blur outsets for the filtered_surface is occluded.
3650 outset_rect = gfx::Rect(50 - outset_left,
3651 50 - outset_top,
3652 50 + outset_left + outset_right,
3653 50 + outset_top + outset_bottom);
3654 test_rect = outset_rect;
3655 EXPECT_EQ(
3656 outset_rect.ToString(),
3657 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3659 // Stuff outside the blur outsets is still occluded though.
3660 test_rect = outset_rect;
3661 test_rect.Inset(0, 0, -1, 0);
3662 EXPECT_EQ(
3663 outset_rect.ToString(),
3664 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3665 test_rect = outset_rect;
3666 test_rect.Inset(0, 0, 0, -1);
3667 EXPECT_EQ(
3668 outset_rect.ToString(),
3669 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3670 test_rect = outset_rect;
3671 test_rect.Inset(-1, 0, 0, 0);
3672 EXPECT_EQ(
3673 outset_rect.ToString(),
3674 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3675 test_rect = outset_rect;
3676 test_rect.Inset(0, -1, 0, 0);
3677 EXPECT_EQ(
3678 outset_rect.ToString(),
3679 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3681 // Nothing in the blur outsets for the filtered_surface's replica is
3682 // occluded.
3683 outset_rect = gfx::Rect(200 - outset_left,
3684 50 - outset_top,
3685 50 + outset_left + outset_right,
3686 50 + outset_top + outset_bottom);
3687 test_rect = outset_rect;
3688 EXPECT_EQ(
3689 outset_rect.ToString(),
3690 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3692 // Stuff outside the blur outsets is still occluded though.
3693 test_rect = outset_rect;
3694 test_rect.Inset(0, 0, -1, 0);
3695 EXPECT_EQ(
3696 outset_rect.ToString(),
3697 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3698 test_rect = outset_rect;
3699 test_rect.Inset(0, 0, 0, -1);
3700 EXPECT_EQ(
3701 outset_rect.ToString(),
3702 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3703 test_rect = outset_rect;
3704 test_rect.Inset(-1, 0, 0, 0);
3705 EXPECT_EQ(
3706 outset_rect.ToString(),
3707 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3708 test_rect = outset_rect;
3709 test_rect.Inset(0, -1, 0, 0);
3710 EXPECT_EQ(
3711 outset_rect.ToString(),
3712 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3716 ALL_OCCLUSIONTRACKER_TEST(
3717 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
3719 template <class Types>
3720 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3721 : public OcclusionTrackerTest<Types> {
3722 protected:
3723 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3724 bool opaque_layers)
3725 : OcclusionTrackerTest<Types>(opaque_layers) {}
3726 void RunMyTest() {
3727 gfx::Transform scale_by_half;
3728 scale_by_half.Scale(0.5, 0.5);
3730 // Makes two surfaces that completely cover |parent|. The occlusion both
3731 // above and below the filters will be reduced by each of them.
3732 typename Types::ContentLayerType* root = this->CreateRoot(
3733 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
3734 typename Types::LayerType* parent = this->CreateSurface(
3735 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
3736 parent->SetMasksToBounds(true);
3737 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
3738 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3739 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
3740 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3741 typename Types::LayerType* occluding_layer_above =
3742 this->CreateDrawingLayer(parent,
3743 this->identity_matrix,
3744 gfx::PointF(100.f, 100.f),
3745 gfx::Size(50, 50),
3746 true);
3748 // Filters make the layers own surfaces.
3749 WebKit::WebFilterOperations filters;
3750 filters.append(WebKit::WebFilterOperation::createBlurFilter(1.f));
3751 filtered_surface1->SetBackgroundFilters(filters);
3752 filtered_surface2->SetBackgroundFilters(filters);
3754 // Save the distance of influence for the blur effect.
3755 int outset_top, outset_right, outset_bottom, outset_left;
3756 filters.getOutsets(outset_top, outset_right, outset_bottom, outset_left);
3758 this->CalcDrawEtc(root);
3760 TestOcclusionTrackerWithClip<typename Types::LayerType,
3761 typename Types::RenderSurfaceType> occlusion(
3762 gfx::Rect(0, 0, 1000, 1000));
3764 this->VisitLayer(occluding_layer_above, &occlusion);
3765 EXPECT_EQ(gfx::Rect().ToString(),
3766 occlusion.occlusion_from_outside_target().ToString());
3767 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3768 occlusion.occlusion_from_inside_target().ToString());
3770 this->VisitLayer(filtered_surface2, &occlusion);
3771 this->VisitContributingSurface(filtered_surface2, &occlusion);
3772 this->VisitLayer(filtered_surface1, &occlusion);
3773 this->VisitContributingSurface(filtered_surface1, &occlusion);
3775 // Test expectations in the target.
3776 gfx::Rect expected_occlusion =
3777 gfx::Rect(100 / 2 + outset_right * 2,
3778 100 / 2 + outset_bottom * 2,
3779 50 / 2 - (outset_left + outset_right) * 2,
3780 50 / 2 - (outset_top + outset_bottom) * 2);
3781 EXPECT_EQ(expected_occlusion.ToString(),
3782 occlusion.occlusion_from_inside_target().ToString());
3784 // Test expectations in the screen are the same as in the target, as the
3785 // render surface is 1:1 with the screen.
3786 EXPECT_EQ(expected_occlusion.ToString(),
3787 occlusion.occlusion_from_outside_target().ToString());
3791 ALL_OCCLUSIONTRACKER_TEST(
3792 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
3794 template <class Types>
3795 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
3796 : public OcclusionTrackerTest<Types> {
3797 protected:
3798 explicit
3799 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(
3800 bool opaque_layers)
3801 : OcclusionTrackerTest<Types>(opaque_layers) {}
3802 void RunMyTest() {
3803 // Make a surface and its replica, Each 50x50, that are completely
3804 // surrounded by opaque layers which are above them in the z-order.
3805 typename Types::ContentLayerType* parent = this->CreateRoot(
3806 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3807 // We stick the filtered surface inside a clipping surface so that we can
3808 // make sure the clip is honored when exposing pixels for
3809 // the background filter.
3810 typename Types::LayerType* clipping_surface =
3811 this->CreateDrawingSurface(parent,
3812 this->identity_matrix,
3813 gfx::PointF(),
3814 gfx::Size(300, 70),
3815 false);
3816 clipping_surface->SetMasksToBounds(true);
3817 typename Types::LayerType* filtered_surface =
3818 this->CreateDrawingLayer(clipping_surface,
3819 this->identity_matrix,
3820 gfx::PointF(50.f, 50.f),
3821 gfx::Size(50, 50),
3822 false);
3823 this->CreateReplicaLayer(filtered_surface,
3824 this->identity_matrix,
3825 gfx::PointF(150.f, 0.f),
3826 gfx::Size());
3827 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3828 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
3829 typename Types::LayerType* occluding_layer2 =
3830 this->CreateDrawingLayer(parent,
3831 this->identity_matrix,
3832 gfx::PointF(0.f, 100.f),
3833 gfx::Size(300, 50),
3834 true);
3835 typename Types::LayerType* occluding_layer3 =
3836 this->CreateDrawingLayer(parent,
3837 this->identity_matrix,
3838 gfx::PointF(0.f, 50.f),
3839 gfx::Size(50, 50),
3840 true);
3841 typename Types::LayerType* occluding_layer4 =
3842 this->CreateDrawingLayer(parent,
3843 this->identity_matrix,
3844 gfx::PointF(100.f, 50.f),
3845 gfx::Size(100, 50),
3846 true);
3847 typename Types::LayerType* occluding_layer5 =
3848 this->CreateDrawingLayer(parent,
3849 this->identity_matrix,
3850 gfx::PointF(250.f, 50.f),
3851 gfx::Size(50, 50),
3852 true);
3854 // Filters make the layer own a surface. This filter is large enough that it
3855 // goes outside the bottom of the clipping_surface.
3856 WebKit::WebFilterOperations filters;
3857 filters.append(WebKit::WebFilterOperation::createBlurFilter(12.f));
3858 filtered_surface->SetBackgroundFilters(filters);
3860 // Save the distance of influence for the blur effect.
3861 int outset_top, outset_right, outset_bottom, outset_left;
3862 filters.getOutsets(outset_top, outset_right, outset_bottom, outset_left);
3864 this->CalcDrawEtc(parent);
3866 TestOcclusionTrackerWithClip<typename Types::LayerType,
3867 typename Types::RenderSurfaceType> occlusion(
3868 gfx::Rect(0, 0, 1000, 1000));
3870 // These layers occlude pixels directly beside the filtered_surface. Because
3871 // filtered surface blends pixels in a radius, it will need to see some of
3872 // the pixels (up to radius far) underneath the occluding layers.
3873 this->VisitLayer(occluding_layer5, &occlusion);
3874 this->VisitLayer(occluding_layer4, &occlusion);
3875 this->VisitLayer(occluding_layer3, &occlusion);
3876 this->VisitLayer(occluding_layer2, &occlusion);
3877 this->VisitLayer(occluding_layer1, &occlusion);
3879 Region expected_occlusion;
3880 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
3881 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3882 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3883 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
3884 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));
3886 EXPECT_EQ(expected_occlusion.ToString(),
3887 occlusion.occlusion_from_inside_target().ToString());
3888 EXPECT_EQ(gfx::Rect().ToString(),
3889 occlusion.occlusion_from_outside_target().ToString());
3891 // Everything outside the surface/replica is occluded but the
3892 // surface/replica itself is not.
3893 this->VisitLayer(filtered_surface, &occlusion);
3895 // The filtered layer/replica does not occlude.
3896 Region expected_occlusion_outside_surface;
3897 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
3898 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3899 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3900 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
3901 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));
3903 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3904 occlusion.occlusion_from_outside_target().ToString());
3905 EXPECT_EQ(gfx::Rect().ToString(),
3906 occlusion.occlusion_from_inside_target().ToString());
3908 // The surface has a background blur, so it needs pixels that are currently
3909 // considered occluded in order to be drawn. So the pixels it needs should
3910 // be removed some the occluded area so that when we get to the parent they
3911 // are drawn.
3912 this->VisitContributingSurface(filtered_surface, &occlusion);
3914 this->VisitLayer(clipping_surface, &occlusion);
3915 this->EnterContributingSurface(clipping_surface, &occlusion);
3917 Region expected_blurred_occlusion;
3918 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
3919 expected_blurred_occlusion.Union(gfx::Rect(
3920 0, 50 - outset_top, 50 - outset_left, 20 + outset_top + outset_bottom));
3921 expected_blurred_occlusion.Union(
3922 gfx::Rect(100 + outset_right,
3923 50 - outset_top,
3924 100 - outset_right - outset_left,
3925 20 + outset_top + outset_bottom));
3926 expected_blurred_occlusion.Union(
3927 gfx::Rect(250 + outset_right,
3928 50 - outset_top,
3929 50 - outset_right,
3930 20 + outset_top + outset_bottom));
3931 expected_blurred_occlusion.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
3933 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3934 occlusion.occlusion_from_outside_target().ToString());
3935 EXPECT_EQ(gfx::Rect().ToString(),
3936 occlusion.occlusion_from_inside_target().ToString());
3938 gfx::Rect outset_rect;
3939 gfx::Rect clipped_outset_rect;
3940 gfx::Rect test_rect;
3942 // Nothing in the (clipped) blur outsets for the filtered_surface is
3943 // occluded.
3944 outset_rect = gfx::Rect(50 - outset_left,
3945 50 - outset_top,
3946 50 + outset_left + outset_right,
3947 50 + outset_top + outset_bottom);
3948 clipped_outset_rect = outset_rect;
3949 clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left,
3950 0 - outset_top,
3951 300 + outset_left + outset_right,
3952 70 + outset_top + outset_bottom));
3953 clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70));
3954 test_rect = outset_rect;
3955 EXPECT_RECT_EQ(
3956 clipped_outset_rect,
3957 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3959 // Stuff outside the (clipped) blur outsets is still occluded though.
3960 test_rect = outset_rect;
3961 test_rect.Inset(0, 0, -1, 0);
3962 EXPECT_RECT_EQ(
3963 clipped_outset_rect,
3964 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3965 test_rect = outset_rect;
3966 test_rect.Inset(0, 0, 0, -1);
3967 EXPECT_RECT_EQ(
3968 clipped_outset_rect,
3969 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3970 test_rect = outset_rect;
3971 test_rect.Inset(-1, 0, 0, 0);
3972 EXPECT_RECT_EQ(
3973 clipped_outset_rect,
3974 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3975 test_rect = outset_rect;
3976 test_rect.Inset(0, -1, 0, 0);
3977 EXPECT_RECT_EQ(
3978 clipped_outset_rect,
3979 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3981 // Nothing in the (clipped) blur outsets for the filtered_surface's replica
3982 // is occluded.
3983 outset_rect = gfx::Rect(200 - outset_left,
3984 50 - outset_top,
3985 50 + outset_left + outset_right,
3986 50 + outset_top + outset_bottom);
3987 clipped_outset_rect = outset_rect;
3988 clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left,
3989 0 - outset_top,
3990 300 + outset_left + outset_right,
3991 70 + outset_top + outset_bottom));
3992 clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70));
3993 test_rect = outset_rect;
3994 EXPECT_RECT_EQ(
3995 clipped_outset_rect,
3996 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3998 // Stuff outside the (clipped) blur outsets is still occluded though.
3999 test_rect = outset_rect;
4000 test_rect.Inset(0, 0, -1, 0);
4001 EXPECT_RECT_EQ(
4002 clipped_outset_rect,
4003 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4004 test_rect = outset_rect;
4005 test_rect.Inset(0, 0, 0, -1);
4006 EXPECT_RECT_EQ(
4007 clipped_outset_rect,
4008 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4009 test_rect = outset_rect;
4010 test_rect.Inset(-1, 0, 0, 0);
4011 EXPECT_RECT_EQ(
4012 clipped_outset_rect,
4013 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4014 test_rect = outset_rect;
4015 test_rect.Inset(0, -1, 0, 0);
4016 EXPECT_RECT_EQ(
4017 clipped_outset_rect,
4018 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4022 ALL_OCCLUSIONTRACKER_TEST(
4023 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
4025 template <class Types>
4026 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
4027 : public OcclusionTrackerTest<Types> {
4028 protected:
4029 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
4030 bool opaque_layers)
4031 : OcclusionTrackerTest<Types>(opaque_layers) {}
4032 void RunMyTest() {
4033 gfx::Transform scale_by_half;
4034 scale_by_half.Scale(0.5, 0.5);
4036 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
4037 // centered below each. The surface is scaled to test that the pixel moving
4038 // is done in the target space, where the background filter is applied, but
4039 // the surface appears at 50, 50 and the replica at 200, 50.
4040 typename Types::ContentLayerType* parent = this->CreateRoot(
4041 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4042 typename Types::LayerType* behind_surface_layer =
4043 this->CreateDrawingLayer(parent,
4044 this->identity_matrix,
4045 gfx::PointF(60.f, 60.f),
4046 gfx::Size(30, 30),
4047 true);
4048 typename Types::LayerType* behind_replica_layer =
4049 this->CreateDrawingLayer(parent,
4050 this->identity_matrix,
4051 gfx::PointF(210.f, 60.f),
4052 gfx::Size(30, 30),
4053 true);
4054 typename Types::LayerType* filtered_surface =
4055 this->CreateDrawingLayer(parent,
4056 scale_by_half,
4057 gfx::PointF(50.f, 50.f),
4058 gfx::Size(100, 100),
4059 false);
4060 this->CreateReplicaLayer(filtered_surface,
4061 this->identity_matrix,
4062 gfx::PointF(300.f, 0.f),
4063 gfx::Size());
4065 // Filters make the layer own a surface.
4066 WebKit::WebFilterOperations filters;
4067 filters.append(WebKit::WebFilterOperation::createBlurFilter(3.f));
4068 filtered_surface->SetBackgroundFilters(filters);
4070 this->CalcDrawEtc(parent);
4072 TestOcclusionTrackerWithClip<typename Types::LayerType,
4073 typename Types::RenderSurfaceType> occlusion(
4074 gfx::Rect(0, 0, 1000, 1000));
4076 // The surface has a background blur, so it blurs non-opaque pixels below
4077 // it.
4078 this->VisitLayer(filtered_surface, &occlusion);
4079 this->VisitContributingSurface(filtered_surface, &occlusion);
4081 this->VisitLayer(behind_replica_layer, &occlusion);
4082 this->VisitLayer(behind_surface_layer, &occlusion);
4084 // The layers behind the surface are not blurred, and their occlusion does
4085 // not change, until we leave the surface. So it should not be modified by
4086 // the filter here.
4087 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
4088 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
4090 Region expected_opaque_bounds =
4091 UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
4092 EXPECT_EQ(expected_opaque_bounds.ToString(),
4093 occlusion.occlusion_from_inside_target().ToString());
4095 EXPECT_EQ(gfx::Rect().ToString(),
4096 occlusion.occlusion_from_outside_target().ToString());
4100 ALL_OCCLUSIONTRACKER_TEST(
4101 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
4103 template <class Types>
4104 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
4105 : public OcclusionTrackerTest<Types> {
4106 protected:
4107 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
4108 bool opaque_layers)
4109 : OcclusionTrackerTest<Types>(opaque_layers) {}
4110 void RunMyTest() {
4111 gfx::Transform scale_by_half;
4112 scale_by_half.Scale(0.5, 0.5);
4114 // Make a surface and its replica, each 50x50, that are completely occluded
4115 // by opaque layers which are above them in the z-order. The surface is
4116 // scaled to test that the pixel moving is done in the target space, where
4117 // the background filter is applied, but the surface appears at 50, 50 and
4118 // the replica at 200, 50.
4119 typename Types::ContentLayerType* parent = this->CreateRoot(
4120 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4121 typename Types::LayerType* filtered_surface =
4122 this->CreateDrawingLayer(parent,
4123 scale_by_half,
4124 gfx::PointF(50.f, 50.f),
4125 gfx::Size(100, 100),
4126 false);
4127 this->CreateReplicaLayer(filtered_surface,
4128 this->identity_matrix,
4129 gfx::PointF(300.f, 0.f),
4130 gfx::Size());
4131 typename Types::LayerType* above_surface_layer =
4132 this->CreateDrawingLayer(parent,
4133 this->identity_matrix,
4134 gfx::PointF(50.f, 50.f),
4135 gfx::Size(50, 50),
4136 true);
4137 typename Types::LayerType* above_replica_layer =
4138 this->CreateDrawingLayer(parent,
4139 this->identity_matrix,
4140 gfx::PointF(200.f, 50.f),
4141 gfx::Size(50, 50),
4142 true);
4144 // Filters make the layer own a surface.
4145 WebKit::WebFilterOperations filters;
4146 filters.append(WebKit::WebFilterOperation::createBlurFilter(3.f));
4147 filtered_surface->SetBackgroundFilters(filters);
4149 this->CalcDrawEtc(parent);
4151 TestOcclusionTrackerWithClip<typename Types::LayerType,
4152 typename Types::RenderSurfaceType> occlusion(
4153 gfx::Rect(0, 0, 1000, 1000));
4155 this->VisitLayer(above_replica_layer, &occlusion);
4156 this->VisitLayer(above_surface_layer, &occlusion);
4158 this->VisitLayer(filtered_surface, &occlusion);
4160 // The layers above the filtered surface occlude from outside.
4161 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
4162 gfx::Rect occlusion_above_replica = gfx::Rect(150, 0, 50, 50);
4163 Region expected_opaque_region =
4164 UnionRegions(occlusion_above_surface, occlusion_above_replica);
4166 EXPECT_EQ(gfx::Rect().ToString(),
4167 occlusion.occlusion_from_inside_target().ToString());
4168 EXPECT_EQ(expected_opaque_region.ToString(),
4169 occlusion.occlusion_from_outside_target().ToString());
4172 // The surface has a background blur, so it blurs non-opaque pixels below
4173 // it.
4174 this->VisitContributingSurface(filtered_surface, &occlusion);
4176 // The filter is completely occluded, so it should not blur anything and
4177 // reduce any occlusion.
4178 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
4179 gfx::Rect occlusion_above_replica = gfx::Rect(200, 50, 50, 50);
4180 Region expected_opaque_region =
4181 UnionRegions(occlusion_above_surface, occlusion_above_replica);
4183 EXPECT_EQ(expected_opaque_region.ToString(),
4184 occlusion.occlusion_from_inside_target().ToString());
4185 EXPECT_EQ(gfx::Rect().ToString(),
4186 occlusion.occlusion_from_outside_target().ToString());
4191 ALL_OCCLUSIONTRACKER_TEST(
4192 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
4194 template <class Types>
4195 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
4196 : public OcclusionTrackerTest<Types> {
4197 protected:
4198 explicit
4199 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
4200 bool opaque_layers)
4201 : OcclusionTrackerTest<Types>(opaque_layers) {}
4202 void RunMyTest() {
4203 gfx::Transform scale_by_half;
4204 scale_by_half.Scale(0.5, 0.5);
4206 // Make a surface and its replica, each 50x50, that are partially occluded
4207 // by opaque layers which are above them in the z-order. The surface is
4208 // scaled to test that the pixel moving is done in the target space, where
4209 // the background filter is applied, but the surface appears at 50, 50 and
4210 // the replica at 200, 50.
4211 typename Types::ContentLayerType* parent = this->CreateRoot(
4212 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4213 typename Types::LayerType* filtered_surface =
4214 this->CreateDrawingLayer(parent,
4215 scale_by_half,
4216 gfx::PointF(50.f, 50.f),
4217 gfx::Size(100, 100),
4218 false);
4219 this->CreateReplicaLayer(filtered_surface,
4220 this->identity_matrix,
4221 gfx::PointF(300.f, 0.f),
4222 gfx::Size());
4223 typename Types::LayerType* above_surface_layer =
4224 this->CreateDrawingLayer(parent,
4225 this->identity_matrix,
4226 gfx::PointF(70.f, 50.f),
4227 gfx::Size(30, 50),
4228 true);
4229 typename Types::LayerType* above_replica_layer =
4230 this->CreateDrawingLayer(parent,
4231 this->identity_matrix,
4232 gfx::PointF(200.f, 50.f),
4233 gfx::Size(30, 50),
4234 true);
4235 typename Types::LayerType* beside_surface_layer =
4236 this->CreateDrawingLayer(parent,
4237 this->identity_matrix,
4238 gfx::PointF(90.f, 40.f),
4239 gfx::Size(10, 10),
4240 true);
4241 typename Types::LayerType* beside_replica_layer =
4242 this->CreateDrawingLayer(parent,
4243 this->identity_matrix,
4244 gfx::PointF(200.f, 40.f),
4245 gfx::Size(10, 10),
4246 true);
4248 // Filters make the layer own a surface.
4249 WebKit::WebFilterOperations filters;
4250 filters.append(WebKit::WebFilterOperation::createBlurFilter(3.f));
4251 filtered_surface->SetBackgroundFilters(filters);
4253 // Save the distance of influence for the blur effect.
4254 int outset_top, outset_right, outset_bottom, outset_left;
4255 filters.getOutsets(outset_top, outset_right, outset_bottom, outset_left);
4257 this->CalcDrawEtc(parent);
4259 TestOcclusionTrackerWithClip<typename Types::LayerType,
4260 typename Types::RenderSurfaceType> occlusion(
4261 gfx::Rect(0, 0, 1000, 1000));
4263 this->VisitLayer(beside_replica_layer, &occlusion);
4264 this->VisitLayer(beside_surface_layer, &occlusion);
4265 this->VisitLayer(above_replica_layer, &occlusion);
4266 this->VisitLayer(above_surface_layer, &occlusion);
4268 // The surface has a background blur, so it blurs non-opaque pixels below
4269 // it.
4270 this->VisitLayer(filtered_surface, &occlusion);
4271 this->VisitContributingSurface(filtered_surface, &occlusion);
4273 // The filter in the surface and replica are partially unoccluded. Only the
4274 // unoccluded parts should reduce occlusion. This means it will push back
4275 // the occlusion that touches the unoccluded part (occlusion_above___), but
4276 // it will not touch occlusion_beside____ since that is not beside the
4277 // unoccluded part of the surface, even though it is beside the occluded
4278 // part of the surface.
4279 gfx::Rect occlusion_above_surface =
4280 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
4281 gfx::Rect occlusion_above_replica =
4282 gfx::Rect(200, 50, 30 - outset_left, 50);
4283 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
4284 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
4286 Region expected_occlusion;
4287 expected_occlusion.Union(occlusion_above_surface);
4288 expected_occlusion.Union(occlusion_above_replica);
4289 expected_occlusion.Union(occlusion_beside_surface);
4290 expected_occlusion.Union(occlusion_beside_replica);
4292 ASSERT_EQ(expected_occlusion.ToString(),
4293 occlusion.occlusion_from_inside_target().ToString());
4294 EXPECT_EQ(gfx::Rect().ToString(),
4295 occlusion.occlusion_from_outside_target().ToString());
4297 Region::Iterator expected_rects(expected_occlusion);
4298 Region::Iterator target_surface_rects(
4299 occlusion.occlusion_from_inside_target());
4300 for (; expected_rects.has_rect();
4301 expected_rects.next(), target_surface_rects.next()) {
4302 ASSERT_TRUE(target_surface_rects.has_rect());
4303 EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
4308 ALL_OCCLUSIONTRACKER_TEST(
4309 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
4311 template <class Types>
4312 class OcclusionTrackerTestMinimumTrackingSize
4313 : public OcclusionTrackerTest<Types> {
4314 protected:
4315 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
4316 : OcclusionTrackerTest<Types>(opaque_layers) {}
4317 void RunMyTest() {
4318 gfx::Size tracking_size(100, 100);
4319 gfx::Size below_tracking_size(99, 99);
4321 typename Types::ContentLayerType* parent = this->CreateRoot(
4322 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4323 typename Types::LayerType* large = this->CreateDrawingLayer(
4324 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
4325 typename Types::LayerType* small =
4326 this->CreateDrawingLayer(parent,
4327 this->identity_matrix,
4328 gfx::PointF(),
4329 below_tracking_size,
4330 true);
4331 this->CalcDrawEtc(parent);
4333 TestOcclusionTrackerWithClip<typename Types::LayerType,
4334 typename Types::RenderSurfaceType> occlusion(
4335 gfx::Rect(0, 0, 1000, 1000));
4336 occlusion.set_minimum_tracking_size(tracking_size);
4338 // The small layer is not tracked because it is too small.
4339 this->VisitLayer(small, &occlusion);
4341 EXPECT_EQ(gfx::Rect().ToString(),
4342 occlusion.occlusion_from_outside_target().ToString());
4343 EXPECT_EQ(gfx::Rect().ToString(),
4344 occlusion.occlusion_from_inside_target().ToString());
4346 // The large layer is tracked as it is large enough.
4347 this->VisitLayer(large, &occlusion);
4349 EXPECT_EQ(gfx::Rect().ToString(),
4350 occlusion.occlusion_from_outside_target().ToString());
4351 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
4352 occlusion.occlusion_from_inside_target().ToString());
4356 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
4358 template <class Types>
4359 class OcclusionTrackerTestViewportClipIsExternalOcclusion
4360 : public OcclusionTrackerTest<Types> {
4361 protected:
4362 explicit OcclusionTrackerTestViewportClipIsExternalOcclusion(
4363 bool opaque_layers)
4364 : OcclusionTrackerTest<Types>(opaque_layers) {}
4365 void RunMyTest() {
4366 typename Types::ContentLayerType* parent = this->CreateRoot(
4367 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4368 typename Types::LayerType* small =
4369 this->CreateDrawingSurface(parent,
4370 this->identity_matrix,
4371 gfx::PointF(),
4372 gfx::Size(200, 200),
4373 false);
4374 typename Types::LayerType* large =
4375 this->CreateDrawingLayer(small,
4376 this->identity_matrix,
4377 gfx::PointF(),
4378 gfx::Size(400, 400),
4379 false);
4380 small->SetMasksToBounds(true);
4381 this->CalcDrawEtc(parent);
4383 TestOcclusionTrackerWithClip<typename Types::LayerType,
4384 typename Types::RenderSurfaceType> occlusion(
4385 gfx::Rect(0, 0, 100, 100));
4387 this->EnterLayer(large, &occlusion);
4389 bool has_occlusion_from_outside_target_surface = false;
4390 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4391 occlusion.UnoccludedLayerContentRect(
4392 large,
4393 gfx::Rect(0, 0, 400, 400),
4394 &has_occlusion_from_outside_target_surface));
4395 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4397 has_occlusion_from_outside_target_surface = false;
4398 EXPECT_FALSE(
4399 occlusion.OccludedLayer(large,
4400 gfx::Rect(0, 0, 400, 400),
4401 &has_occlusion_from_outside_target_surface));
4402 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4404 this->LeaveLayer(large, &occlusion);
4405 this->VisitLayer(small, &occlusion);
4407 has_occlusion_from_outside_target_surface = false;
4408 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4409 occlusion.UnoccludedLayerContentRect(
4410 small,
4411 gfx::Rect(0, 0, 200, 200),
4412 &has_occlusion_from_outside_target_surface));
4413 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4415 has_occlusion_from_outside_target_surface = false;
4416 EXPECT_FALSE(
4417 occlusion.OccludedLayer(small,
4418 gfx::Rect(0, 0, 200, 200),
4419 &has_occlusion_from_outside_target_surface));
4420 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4422 this->EnterContributingSurface(small, &occlusion);
4424 has_occlusion_from_outside_target_surface = false;
4425 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4426 occlusion.UnoccludedContributingSurfaceContentRect(
4427 small,
4428 false,
4429 gfx::Rect(0, 0, 200, 200),
4430 &has_occlusion_from_outside_target_surface));
4431 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4435 ALL_OCCLUSIONTRACKER_TEST(
4436 OcclusionTrackerTestViewportClipIsExternalOcclusion)
4438 template <class Types>
4439 class OcclusionTrackerTestLayerClipIsExternalOcclusion
4440 : public OcclusionTrackerTest<Types> {
4441 protected:
4442 explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers)
4443 : OcclusionTrackerTest<Types>(opaque_layers) {}
4444 void RunMyTest() {
4445 typename Types::ContentLayerType* parent = this->CreateRoot(
4446 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4447 typename Types::LayerType* smallest = this->CreateDrawingLayer(
4448 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4449 typename Types::LayerType* smaller =
4450 this->CreateDrawingSurface(smallest,
4451 this->identity_matrix,
4452 gfx::PointF(),
4453 gfx::Size(100, 100),
4454 false);
4455 typename Types::LayerType* small =
4456 this->CreateDrawingSurface(smaller,
4457 this->identity_matrix,
4458 gfx::PointF(),
4459 gfx::Size(200, 200),
4460 false);
4461 typename Types::LayerType* large =
4462 this->CreateDrawingLayer(small,
4463 this->identity_matrix,
4464 gfx::PointF(),
4465 gfx::Size(400, 400),
4466 false);
4467 smallest->SetMasksToBounds(true);
4468 smaller->SetMasksToBounds(true);
4469 small->SetMasksToBounds(true);
4470 this->CalcDrawEtc(parent);
4472 TestOcclusionTrackerWithClip<typename Types::LayerType,
4473 typename Types::RenderSurfaceType> occlusion(
4474 gfx::Rect(0, 0, 1000, 1000));
4476 this->EnterLayer(large, &occlusion);
4478 // Clipping from the smaller layer is from outside the target surface.
4479 bool has_occlusion_from_outside_target_surface = false;
4480 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4481 occlusion.UnoccludedLayerContentRect(
4482 large,
4483 gfx::Rect(0, 0, 400, 400),
4484 &has_occlusion_from_outside_target_surface));
4485 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4487 has_occlusion_from_outside_target_surface = false;
4488 EXPECT_FALSE(
4489 occlusion.OccludedLayer(large,
4490 gfx::Rect(0, 0, 400, 400),
4491 &has_occlusion_from_outside_target_surface));
4492 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4494 this->LeaveLayer(large, &occlusion);
4495 this->VisitLayer(small, &occlusion);
4497 // Clipping from the smaller layer is from outside the target surface.
4498 has_occlusion_from_outside_target_surface = false;
4499 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4500 occlusion.UnoccludedLayerContentRect(
4501 small,
4502 gfx::Rect(0, 0, 200, 200),
4503 &has_occlusion_from_outside_target_surface));
4504 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4506 has_occlusion_from_outside_target_surface = false;
4507 EXPECT_FALSE(
4508 occlusion.OccludedLayer(small,
4509 gfx::Rect(0, 0, 200, 200),
4510 &has_occlusion_from_outside_target_surface));
4511 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4513 this->EnterContributingSurface(small, &occlusion);
4515 // The |small| surface is clipped from outside its target by |smallest|.
4516 has_occlusion_from_outside_target_surface = false;
4517 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4518 occlusion.UnoccludedContributingSurfaceContentRect(
4519 small,
4520 false,
4521 gfx::Rect(0, 0, 200, 200),
4522 &has_occlusion_from_outside_target_surface));
4523 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4525 this->LeaveContributingSurface(small, &occlusion);
4526 this->VisitLayer(smaller, &occlusion);
4527 this->EnterContributingSurface(smaller, &occlusion);
4529 // The |smaller| surface is clipped from inside its target by |smallest|.
4530 has_occlusion_from_outside_target_surface = false;
4531 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4532 occlusion.UnoccludedContributingSurfaceContentRect(
4533 smaller,
4534 false,
4535 gfx::Rect(0, 0, 100, 100),
4536 &has_occlusion_from_outside_target_surface));
4537 EXPECT_FALSE(has_occlusion_from_outside_target_surface);
4541 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion)
4543 } // namespace
4544 } // namespace cc