Move prefs::kLastPolicyStatisticsUpdate to the policy component.
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob469d65a4cb24d6772e3652525344d485f1271354
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/occlusion_tracker.h"
7 #include "cc/animation/layer_animation_controller.h"
8 #include "cc/base/math_util.h"
9 #include "cc/debug/overdraw_metrics.h"
10 #include "cc/layers/layer.h"
11 #include "cc/layers/layer_impl.h"
12 #include "cc/output/copy_output_request.h"
13 #include "cc/output/copy_output_result.h"
14 #include "cc/output/filter_operation.h"
15 #include "cc/output/filter_operations.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_impl_proxy.h"
18 #include "cc/test/fake_layer_tree_host.h"
19 #include "cc/test/fake_layer_tree_host_impl.h"
20 #include "cc/test/geometry_test_utils.h"
21 #include "cc/test/occlusion_tracker_test_common.h"
22 #include "cc/trees/layer_tree_host_common.h"
23 #include "cc/trees/single_thread_proxy.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/transform.h"
28 namespace cc {
29 namespace {
31 class TestContentLayer : public Layer {
32 public:
33 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {}
35 virtual bool DrawsContent() const OVERRIDE { return true; }
36 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
37 if (override_opaque_contents_rect_)
38 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
39 return Layer::VisibleContentOpaqueRegion();
41 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
42 override_opaque_contents_rect_ = true;
43 opaque_contents_rect_ = opaque_contents_rect;
46 private:
47 virtual ~TestContentLayer() {}
49 bool override_opaque_contents_rect_;
50 gfx::Rect opaque_contents_rect_;
53 class TestContentLayerImpl : public LayerImpl {
54 public:
55 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
56 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
57 SetDrawsContent(true);
60 virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
61 if (override_opaque_contents_rect_)
62 return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
63 return LayerImpl::VisibleContentOpaqueRegion();
65 void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
66 override_opaque_contents_rect_ = true;
67 opaque_contents_rect_ = opaque_contents_rect;
70 private:
71 bool override_opaque_contents_rect_;
72 gfx::Rect opaque_contents_rect_;
75 static inline bool LayerImplDrawTransformIsUnknown(const Layer* layer) {
76 return layer->draw_transform_is_animating();
78 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl* layer) {
79 return false;
82 template <typename LayerType, typename RenderSurfaceType>
83 class TestOcclusionTrackerWithClip
84 : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> {
85 public:
86 TestOcclusionTrackerWithClip(gfx::Rect viewport_rect,
87 bool record_metrics_for_frame)
88 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(
89 viewport_rect,
90 record_metrics_for_frame) {}
91 explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect)
92 : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewport_rect,
93 false) {}
95 bool OccludedLayer(const LayerType* layer, gfx::Rect content_rect) {
96 bool temp;
97 return OccludedLayer(layer, content_rect, &temp);
100 bool OccludedLayer(const LayerType* layer,
101 gfx::Rect content_rect,
102 bool* has_occlusion_from_outside_target_surface) const {
103 return this->Occluded(layer->render_target(),
104 content_rect,
105 layer->draw_transform(),
106 LayerImplDrawTransformIsUnknown(layer),
107 layer->is_clipped(),
108 layer->clip_rect(),
109 has_occlusion_from_outside_target_surface);
111 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
112 // layer. Simple wrapper around UnoccludedContentRect.
113 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
114 gfx::Rect content_rect) const {
115 bool temp;
116 return UnoccludedLayerContentRect(layer, content_rect, &temp);
119 gfx::Rect UnoccludedLayerContentRect(
120 const LayerType* layer,
121 gfx::Rect content_rect,
122 bool* has_occlusion_from_outside_target_surface) const {
123 return this->UnoccludedContentRect(
124 layer->render_target(),
125 content_rect,
126 layer->draw_transform(),
127 LayerImplDrawTransformIsUnknown(layer),
128 layer->is_clipped(),
129 layer->clip_rect(),
130 has_occlusion_from_outside_target_surface);
134 struct OcclusionTrackerTestMainThreadTypes {
135 typedef Layer LayerType;
136 typedef FakeLayerTreeHost HostType;
137 typedef RenderSurface RenderSurfaceType;
138 typedef TestContentLayer ContentLayerType;
139 typedef scoped_refptr<Layer> LayerPtrType;
140 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
141 typedef LayerIterator<Layer,
142 RenderSurfaceLayerList,
143 RenderSurface,
144 LayerIteratorActions::FrontToBack> TestLayerIterator;
145 typedef OcclusionTracker OcclusionTrackerType;
147 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
148 static ContentLayerPtrType CreateContentLayer(HostType* host) {
149 return make_scoped_refptr(new ContentLayerType());
152 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
153 LayerPtrType ref(*layer);
154 *layer = NULL;
155 return ref;
158 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
159 LayerPtrType ref(*layer);
160 *layer = NULL;
161 return ref;
164 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
167 struct OcclusionTrackerTestImplThreadTypes {
168 typedef LayerImpl LayerType;
169 typedef LayerTreeImpl HostType;
170 typedef RenderSurfaceImpl RenderSurfaceType;
171 typedef TestContentLayerImpl ContentLayerType;
172 typedef scoped_ptr<LayerImpl> LayerPtrType;
173 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
174 typedef LayerIterator<LayerImpl,
175 LayerImplList,
176 RenderSurfaceImpl,
177 LayerIteratorActions::FrontToBack> TestLayerIterator;
178 typedef OcclusionTrackerImpl OcclusionTrackerType;
180 static LayerPtrType CreateLayer(HostType* host) {
181 return LayerImpl::Create(host, next_layer_impl_id++);
183 static ContentLayerPtrType CreateContentLayer(HostType* host) {
184 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
186 static int next_layer_impl_id;
188 static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
189 return layer->Pass();
192 static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
193 return layer->PassAs<LayerType>();
196 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
199 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
201 template <typename Types> class OcclusionTrackerTest : public testing::Test {
202 protected:
203 explicit OcclusionTrackerTest(bool opaque_layers)
204 : opaque_layers_(opaque_layers), host_(FakeLayerTreeHost::Create()) {}
206 virtual void RunMyTest() = 0;
208 virtual void TearDown() {
209 Types::DestroyLayer(&root_);
210 render_surface_layer_list_.reset();
211 render_surface_layer_list_impl_.clear();
212 replica_layers_.clear();
213 mask_layers_.clear();
216 typename Types::HostType* GetHost();
218 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
219 gfx::PointF position,
220 gfx::Size bounds) {
221 typename Types::ContentLayerPtrType layer(
222 Types::CreateContentLayer(GetHost()));
223 typename Types::ContentLayerType* layer_ptr = layer.get();
224 SetProperties(layer_ptr, transform, position, bounds);
226 DCHECK(!root_.get());
227 root_ = Types::PassLayerPtr(&layer);
229 SetRootLayerOnMainThread(layer_ptr);
231 return layer_ptr;
234 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
235 const gfx::Transform& transform,
236 gfx::PointF position,
237 gfx::Size bounds) {
238 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
239 typename Types::LayerType* layer_ptr = layer.get();
240 SetProperties(layer_ptr, transform, position, bounds);
241 parent->AddChild(Types::PassLayerPtr(&layer));
242 return layer_ptr;
245 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
246 const gfx::Transform& transform,
247 gfx::PointF position,
248 gfx::Size bounds) {
249 typename Types::LayerType* layer =
250 CreateLayer(parent, transform, position, bounds);
251 layer->SetForceRenderSurface(true);
252 return layer;
255 typename Types::ContentLayerType* CreateDrawingLayer(
256 typename Types::LayerType* parent,
257 const gfx::Transform& transform,
258 gfx::PointF position,
259 gfx::Size bounds,
260 bool opaque) {
261 typename Types::ContentLayerPtrType layer(
262 Types::CreateContentLayer(GetHost()));
263 typename Types::ContentLayerType* layer_ptr = layer.get();
264 SetProperties(layer_ptr, transform, position, bounds);
266 if (opaque_layers_) {
267 layer_ptr->SetContentsOpaque(opaque);
268 } else {
269 layer_ptr->SetContentsOpaque(false);
270 if (opaque)
271 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
272 else
273 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
276 parent->AddChild(Types::PassLayerPtr(&layer));
277 return layer_ptr;
280 typename Types::LayerType* CreateReplicaLayer(
281 typename Types::LayerType* owning_layer,
282 const gfx::Transform& transform,
283 gfx::PointF position,
284 gfx::Size bounds) {
285 typename Types::ContentLayerPtrType layer(
286 Types::CreateContentLayer(GetHost()));
287 typename Types::ContentLayerType* layer_ptr = layer.get();
288 SetProperties(layer_ptr, transform, position, bounds);
289 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
290 return layer_ptr;
293 typename Types::LayerType* CreateMaskLayer(
294 typename Types::LayerType* owning_layer,
295 gfx::Size bounds) {
296 typename Types::ContentLayerPtrType layer(
297 Types::CreateContentLayer(GetHost()));
298 typename Types::ContentLayerType* layer_ptr = layer.get();
299 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
300 SetMask(owning_layer, Types::PassLayerPtr(&layer));
301 return layer_ptr;
304 typename Types::ContentLayerType* CreateDrawingSurface(
305 typename Types::LayerType* parent,
306 const gfx::Transform& transform,
307 gfx::PointF position,
308 gfx::Size bounds,
309 bool opaque) {
310 typename Types::ContentLayerType* layer =
311 CreateDrawingLayer(parent, transform, position, bounds, opaque);
312 layer->SetForceRenderSurface(true);
313 return layer;
317 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
319 void AddCopyRequest(Layer* layer) {
320 layer->RequestCopyOfOutput(
321 CopyOutputRequest::CreateBitmapRequest(base::Bind(
322 &OcclusionTrackerTest<Types>::CopyOutputCallback,
323 base::Unretained(this))));
326 void AddCopyRequest(LayerImpl* layer) {
327 ScopedPtrVector<CopyOutputRequest> requests;
328 requests.push_back(
329 CopyOutputRequest::CreateBitmapRequest(base::Bind(
330 &OcclusionTrackerTest<Types>::CopyOutputCallback,
331 base::Unretained(this))));
332 layer->PassCopyRequests(&requests);
335 void CalcDrawEtc(TestContentLayerImpl* root) {
336 DCHECK(root == root_.get());
337 DCHECK(!root->render_surface());
339 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
340 root, root->bounds(), &render_surface_layer_list_impl_);
341 inputs.can_adjust_raster_scales = true;
342 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
344 layer_iterator_ = layer_iterator_begin_ =
345 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
348 void CalcDrawEtc(TestContentLayer* root) {
349 DCHECK(root == root_.get());
350 DCHECK(!root->render_surface());
352 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
353 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
354 root, root->bounds(), render_surface_layer_list_.get());
355 inputs.can_adjust_raster_scales = true;
356 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
358 layer_iterator_ = layer_iterator_begin_ =
359 Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
362 void EnterLayer(typename Types::LayerType* layer,
363 typename Types::OcclusionTrackerType* occlusion,
364 bool prevent_occlusion) {
365 ASSERT_EQ(layer, *layer_iterator_);
366 ASSERT_TRUE(layer_iterator_.represents_itself());
367 occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
370 void LeaveLayer(typename Types::LayerType* layer,
371 typename Types::OcclusionTrackerType* occlusion) {
372 ASSERT_EQ(layer, *layer_iterator_);
373 ASSERT_TRUE(layer_iterator_.represents_itself());
374 occlusion->LeaveLayer(layer_iterator_);
375 ++layer_iterator_;
378 void VisitLayer(typename Types::LayerType* layer,
379 typename Types::OcclusionTrackerType* occlusion) {
380 EnterLayer(layer, occlusion, false);
381 LeaveLayer(layer, occlusion);
384 void EnterContributingSurface(
385 typename Types::LayerType* layer,
386 typename Types::OcclusionTrackerType* occlusion,
387 bool prevent_occlusion) {
388 ASSERT_EQ(layer, *layer_iterator_);
389 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
390 occlusion->EnterLayer(layer_iterator_, false);
391 occlusion->LeaveLayer(layer_iterator_);
392 ++layer_iterator_;
393 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
394 occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
397 void LeaveContributingSurface(
398 typename Types::LayerType* layer,
399 typename Types::OcclusionTrackerType* occlusion) {
400 ASSERT_EQ(layer, *layer_iterator_);
401 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
402 occlusion->LeaveLayer(layer_iterator_);
403 ++layer_iterator_;
406 void VisitContributingSurface(
407 typename Types::LayerType* layer,
408 typename Types::OcclusionTrackerType* occlusion) {
409 EnterContributingSurface(layer, occlusion, false);
410 LeaveContributingSurface(layer, occlusion);
413 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
415 const gfx::Transform identity_matrix;
417 private:
418 void SetRootLayerOnMainThread(Layer* root) {
419 host_->SetRootLayer(scoped_refptr<Layer>(root));
422 void SetRootLayerOnMainThread(LayerImpl* root) {}
424 void SetBaseProperties(typename Types::LayerType* layer,
425 const gfx::Transform& transform,
426 gfx::PointF position,
427 gfx::Size bounds) {
428 layer->SetTransform(transform);
429 layer->SetSublayerTransform(gfx::Transform());
430 layer->SetAnchorPoint(gfx::PointF());
431 layer->SetPosition(position);
432 layer->SetBounds(bounds);
435 void SetProperties(Layer* layer,
436 const gfx::Transform& transform,
437 gfx::PointF position,
438 gfx::Size bounds) {
439 SetBaseProperties(layer, transform, position, bounds);
442 void SetProperties(LayerImpl* layer,
443 const gfx::Transform& transform,
444 gfx::PointF position,
445 gfx::Size bounds) {
446 SetBaseProperties(layer, transform, position, bounds);
448 layer->SetContentBounds(layer->bounds());
451 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
452 owning_layer->SetReplicaLayer(layer.get());
453 replica_layers_.push_back(layer);
456 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
457 owning_layer->SetReplicaLayer(layer.Pass());
460 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
461 owning_layer->SetMaskLayer(layer.get());
462 mask_layers_.push_back(layer);
465 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
466 owning_layer->SetMaskLayer(layer.Pass());
469 bool opaque_layers_;
470 scoped_ptr<FakeLayerTreeHost> host_;
471 // These hold ownership of the layers for the duration of the test.
472 typename Types::LayerPtrType root_;
473 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
474 LayerImplList render_surface_layer_list_impl_;
475 typename Types::TestLayerIterator layer_iterator_begin_;
476 typename Types::TestLayerIterator layer_iterator_;
477 typename Types::LayerType* last_layer_visited_;
478 LayerList replica_layers_;
479 LayerList mask_layers_;
482 template <>
483 FakeLayerTreeHost*
484 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
485 return host_.get();
488 template <>
489 LayerTreeImpl*
490 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
491 return host_->host_impl()->active_tree();
494 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
495 class ClassName##MainThreadOpaqueLayers \
496 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
497 public: /* NOLINT(whitespace/indent) */ \
498 ClassName##MainThreadOpaqueLayers() \
499 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
500 }; \
501 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
502 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
503 class ClassName##MainThreadOpaquePaints \
504 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
505 public: /* NOLINT(whitespace/indent) */ \
506 ClassName##MainThreadOpaquePaints() \
507 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
508 }; \
509 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
511 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
512 class ClassName##ImplThreadOpaqueLayers \
513 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
514 public: /* NOLINT(whitespace/indent) */ \
515 ClassName##ImplThreadOpaqueLayers() \
516 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
517 }; \
518 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
519 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
520 class ClassName##ImplThreadOpaquePaints \
521 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
522 public: /* NOLINT(whitespace/indent) */ \
523 ClassName##ImplThreadOpaquePaints() \
524 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
525 }; \
526 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
528 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
529 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
530 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
531 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
532 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
534 #define MAIN_THREAD_TEST(ClassName) \
535 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
537 #define IMPL_THREAD_TEST(ClassName) \
538 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
540 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
541 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
542 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
544 template <class Types>
545 class OcclusionTrackerTestIdentityTransforms
546 : public OcclusionTrackerTest<Types> {
547 protected:
548 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
549 : OcclusionTrackerTest<Types>(opaque_layers) {}
551 void RunMyTest() {
552 typename Types::ContentLayerType* root = this->CreateRoot(
553 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
554 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
555 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
556 typename Types::ContentLayerType* layer =
557 this->CreateDrawingLayer(parent,
558 this->identity_matrix,
559 gfx::PointF(30.f, 30.f),
560 gfx::Size(500, 500),
561 true);
562 parent->SetMasksToBounds(true);
563 this->CalcDrawEtc(root);
565 TestOcclusionTrackerWithClip<typename Types::LayerType,
566 typename Types::RenderSurfaceType> occlusion(
567 gfx::Rect(0, 0, 1000, 1000), false);
569 this->VisitLayer(layer, &occlusion);
570 this->EnterLayer(parent, &occlusion, false);
572 EXPECT_EQ(gfx::Rect().ToString(),
573 occlusion.occlusion_from_outside_target().ToString());
574 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
575 occlusion.occlusion_from_inside_target().ToString());
577 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
578 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
579 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
580 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
581 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
583 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
584 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
585 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
586 occlusion.UnoccludedLayerContentRect(
587 parent, gfx::Rect(29, 30, 70, 70)));
588 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
589 occlusion.UnoccludedLayerContentRect(
590 parent, gfx::Rect(29, 29, 70, 70)));
591 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
592 occlusion.UnoccludedLayerContentRect(
593 parent, gfx::Rect(30, 29, 70, 70)));
594 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
595 occlusion.UnoccludedLayerContentRect(
596 parent, gfx::Rect(31, 29, 70, 70)));
597 EXPECT_RECT_EQ(gfx::Rect(),
598 occlusion.UnoccludedLayerContentRect(
599 parent, gfx::Rect(31, 30, 70, 70)));
600 EXPECT_RECT_EQ(gfx::Rect(),
601 occlusion.UnoccludedLayerContentRect(
602 parent, gfx::Rect(31, 31, 70, 70)));
603 EXPECT_RECT_EQ(gfx::Rect(),
604 occlusion.UnoccludedLayerContentRect(
605 parent, gfx::Rect(30, 31, 70, 70)));
606 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
607 occlusion.UnoccludedLayerContentRect(
608 parent, gfx::Rect(29, 31, 70, 70)));
612 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
614 template <class Types>
615 class OcclusionTrackerTestQuadsMismatchLayer
616 : public OcclusionTrackerTest<Types> {
617 protected:
618 explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
619 : OcclusionTrackerTest<Types>(opaque_layers) {}
620 void RunMyTest() {
621 gfx::Transform layer_transform;
622 layer_transform.Translate(10.0, 10.0);
624 typename Types::ContentLayerType* parent = this->CreateRoot(
625 this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
626 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
627 parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
628 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
629 layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
630 this->CalcDrawEtc(parent);
632 TestOcclusionTrackerWithClip<typename Types::LayerType,
633 typename Types::RenderSurfaceType> occlusion(
634 gfx::Rect(0, 0, 1000, 1000));
636 this->VisitLayer(layer2, &occlusion);
637 this->EnterLayer(layer1, &occlusion, false);
639 EXPECT_EQ(gfx::Rect().ToString(),
640 occlusion.occlusion_from_outside_target().ToString());
641 EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
642 occlusion.occlusion_from_inside_target().ToString());
644 // This checks cases where the quads don't match their "containing"
645 // layers, e.g. in terms of transforms or clip rect. This is typical for
646 // DelegatedRendererLayer.
648 gfx::Transform quad_transform;
649 quad_transform.Translate(30.0, 30.0);
650 gfx::Rect clip_rect_in_target(0, 0, 100, 100);
652 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent,
653 gfx::Rect(0, 0, 10, 10),
654 quad_transform,
655 false,
656 true,
657 clip_rect_in_target,
658 NULL).IsEmpty());
659 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
660 occlusion.UnoccludedContentRect(parent,
661 gfx::Rect(0, 0, 10, 10),
662 quad_transform,
663 true,
664 true,
665 clip_rect_in_target,
666 NULL));
667 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
668 occlusion.UnoccludedContentRect(parent,
669 gfx::Rect(40, 40, 10, 10),
670 quad_transform,
671 false,
672 true,
673 clip_rect_in_target,
674 NULL));
675 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
676 occlusion.UnoccludedContentRect(parent,
677 gfx::Rect(35, 30, 10, 10),
678 quad_transform,
679 false,
680 true,
681 clip_rect_in_target,
682 NULL));
683 EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5),
684 occlusion.UnoccludedContentRect(parent,
685 gfx::Rect(40, 40, 10, 10),
686 quad_transform,
687 false,
688 true,
689 gfx::Rect(0, 0, 75, 75),
690 NULL));
694 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
696 template <class Types>
697 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
698 protected:
699 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
700 : OcclusionTrackerTest<Types>(opaque_layers) {}
701 void RunMyTest() {
702 gfx::Transform layer_transform;
703 layer_transform.Translate(250.0, 250.0);
704 layer_transform.Rotate(90.0);
705 layer_transform.Translate(-250.0, -250.0);
707 typename Types::ContentLayerType* root = this->CreateRoot(
708 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
709 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
710 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
711 typename Types::ContentLayerType* layer =
712 this->CreateDrawingLayer(parent,
713 layer_transform,
714 gfx::PointF(30.f, 30.f),
715 gfx::Size(500, 500),
716 true);
717 parent->SetMasksToBounds(true);
718 this->CalcDrawEtc(root);
720 TestOcclusionTrackerWithClip<typename Types::LayerType,
721 typename Types::RenderSurfaceType> occlusion(
722 gfx::Rect(0, 0, 1000, 1000));
724 this->VisitLayer(layer, &occlusion);
725 this->EnterLayer(parent, &occlusion, false);
727 EXPECT_EQ(gfx::Rect().ToString(),
728 occlusion.occlusion_from_outside_target().ToString());
729 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
730 occlusion.occlusion_from_inside_target().ToString());
732 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
733 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
734 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
735 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
736 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70)));
738 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
739 parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
740 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
741 occlusion.UnoccludedLayerContentRect(
742 parent, gfx::Rect(29, 30, 70, 70)));
743 EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
744 occlusion.UnoccludedLayerContentRect(
745 parent, gfx::Rect(29, 29, 70, 70)));
746 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
747 occlusion.UnoccludedLayerContentRect(
748 parent, gfx::Rect(30, 29, 70, 70)));
749 EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
750 occlusion.UnoccludedLayerContentRect(
751 parent, gfx::Rect(31, 29, 70, 70)));
752 EXPECT_RECT_EQ(gfx::Rect(),
753 occlusion.UnoccludedLayerContentRect(
754 parent, gfx::Rect(31, 30, 70, 70)));
755 EXPECT_RECT_EQ(gfx::Rect(),
756 occlusion.UnoccludedLayerContentRect(
757 parent, gfx::Rect(31, 31, 70, 70)));
758 EXPECT_RECT_EQ(gfx::Rect(),
759 occlusion.UnoccludedLayerContentRect(
760 parent, gfx::Rect(30, 31, 70, 70)));
761 EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
762 occlusion.UnoccludedLayerContentRect(
763 parent, gfx::Rect(29, 31, 70, 70)));
767 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
769 template <class Types>
770 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
771 protected:
772 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
773 : OcclusionTrackerTest<Types>(opaque_layers) {}
774 void RunMyTest() {
775 gfx::Transform layer_transform;
776 layer_transform.Translate(20.0, 20.0);
778 typename Types::ContentLayerType* root = this->CreateRoot(
779 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
780 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
781 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
782 typename Types::ContentLayerType* layer =
783 this->CreateDrawingLayer(parent,
784 layer_transform,
785 gfx::PointF(30.f, 30.f),
786 gfx::Size(500, 500),
787 true);
788 parent->SetMasksToBounds(true);
789 this->CalcDrawEtc(root);
791 TestOcclusionTrackerWithClip<typename Types::LayerType,
792 typename Types::RenderSurfaceType> occlusion(
793 gfx::Rect(0, 0, 1000, 1000));
795 this->VisitLayer(layer, &occlusion);
796 this->EnterLayer(parent, &occlusion, false);
798 EXPECT_EQ(gfx::Rect().ToString(),
799 occlusion.occlusion_from_outside_target().ToString());
800 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
801 occlusion.occlusion_from_inside_target().ToString());
803 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
804 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
805 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
806 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 50, 50)));
807 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 50)));
809 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
810 parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
811 EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
812 occlusion.UnoccludedLayerContentRect(
813 parent, gfx::Rect(49, 50, 50, 50)));
814 EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
815 occlusion.UnoccludedLayerContentRect(
816 parent, gfx::Rect(49, 49, 50, 50)));
817 EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
818 occlusion.UnoccludedLayerContentRect(
819 parent, gfx::Rect(50, 49, 50, 50)));
820 EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
821 occlusion.UnoccludedLayerContentRect(
822 parent, gfx::Rect(51, 49, 50, 50)));
823 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
824 parent, gfx::Rect(51, 50, 50, 50)).IsEmpty());
825 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
826 parent, gfx::Rect(51, 51, 50, 50)).IsEmpty());
827 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
828 parent, gfx::Rect(50, 51, 50, 50)).IsEmpty());
829 EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
830 occlusion.UnoccludedLayerContentRect(
831 parent, gfx::Rect(49, 51, 50, 50)));
835 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
837 template <class Types>
838 class OcclusionTrackerTestChildInRotatedChild
839 : public OcclusionTrackerTest<Types> {
840 protected:
841 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
842 : OcclusionTrackerTest<Types>(opaque_layers) {}
843 void RunMyTest() {
844 gfx::Transform child_transform;
845 child_transform.Translate(250.0, 250.0);
846 child_transform.Rotate(90.0);
847 child_transform.Translate(-250.0, -250.0);
849 typename Types::ContentLayerType* parent = this->CreateRoot(
850 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
851 parent->SetMasksToBounds(true);
852 typename Types::LayerType* child = this->CreateSurface(
853 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
854 child->SetMasksToBounds(true);
855 typename Types::ContentLayerType* layer =
856 this->CreateDrawingLayer(child,
857 this->identity_matrix,
858 gfx::PointF(10.f, 10.f),
859 gfx::Size(500, 500),
860 true);
861 this->CalcDrawEtc(parent);
863 TestOcclusionTrackerWithClip<typename Types::LayerType,
864 typename Types::RenderSurfaceType> occlusion(
865 gfx::Rect(0, 0, 1000, 1000));
867 this->VisitLayer(layer, &occlusion);
868 this->EnterContributingSurface(child, &occlusion, false);
870 EXPECT_EQ(gfx::Rect().ToString(),
871 occlusion.occlusion_from_outside_target().ToString());
872 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
873 occlusion.occlusion_from_inside_target().ToString());
875 this->LeaveContributingSurface(child, &occlusion);
876 this->EnterLayer(parent, &occlusion, false);
878 EXPECT_EQ(gfx::Rect().ToString(),
879 occlusion.occlusion_from_outside_target().ToString());
880 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
881 occlusion.occlusion_from_inside_target().ToString());
883 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
884 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
885 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
886 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 70, 60)));
887 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 60)));
889 /* Justification for the above occlusion from |layer|:
891 +---------------------+
893 | 30 | rotate(90)
894 | 30 + ---------------------------------+
895 100 | | 10 | | ==>
896 | |10+---------------------------------+
897 | | | | | |
898 | | | | | |
899 | | | | | |
900 +----|--|-------------+ | |
901 | | | |
902 | | | |
903 | | | |500
904 | | | |
905 | | | |
906 | | | |
907 | | | |
908 +--|-------------------------------+ |
910 +---------------------------------+
913 +---------------------+
914 | |30 Visible region of |layer|: /////
916 | +---------------------------------+
917 100| | |10 |
918 | +---------------------------------+ |
919 | | |///////////////| 420 | |
920 | | |///////////////|60 | |
921 | | |///////////////| | |
922 +--|--|---------------+ | |
923 20|10| 70 | |
924 | | | |
925 | | | |
926 | | | |
927 | | | |
928 | | | |
929 | | |10|
930 | +------------------------------|--+
931 | 490 |
932 +---------------------------------+
939 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
941 template <class Types>
942 class OcclusionTrackerTestScaledRenderSurface
943 : public OcclusionTrackerTest<Types> {
944 protected:
945 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
946 : OcclusionTrackerTest<Types>(opaque_layers) {}
948 void RunMyTest() {
949 typename Types::ContentLayerType* parent = this->CreateRoot(
950 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
952 gfx::Transform layer1_matrix;
953 layer1_matrix.Scale(2.0, 2.0);
954 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
955 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
956 layer1->SetForceRenderSurface(true);
958 gfx::Transform layer2_matrix;
959 layer2_matrix.Translate(25.0, 25.0);
960 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
961 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
962 typename Types::ContentLayerType* occluder =
963 this->CreateDrawingLayer(parent,
964 this->identity_matrix,
965 gfx::PointF(100.f, 100.f),
966 gfx::Size(500, 500),
967 true);
968 this->CalcDrawEtc(parent);
970 TestOcclusionTrackerWithClip<typename Types::LayerType,
971 typename Types::RenderSurfaceType> occlusion(
972 gfx::Rect(0, 0, 1000, 1000));
974 this->VisitLayer(occluder, &occlusion);
975 this->EnterLayer(layer2, &occlusion, false);
977 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
978 occlusion.occlusion_from_outside_target().ToString());
979 EXPECT_EQ(gfx::Rect().ToString(),
980 occlusion.occlusion_from_inside_target().ToString());
982 EXPECT_RECT_EQ(
983 gfx::Rect(0, 0, 25, 25),
984 occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
985 EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
986 occlusion.UnoccludedLayerContentRect(
987 layer2, gfx::Rect(10, 25, 25, 25)));
988 EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
989 occlusion.UnoccludedLayerContentRect(
990 layer2, gfx::Rect(25, 10, 25, 25)));
991 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
992 layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
996 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
998 template <class Types>
999 class OcclusionTrackerTestVisitTargetTwoTimes
1000 : public OcclusionTrackerTest<Types> {
1001 protected:
1002 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
1003 : OcclusionTrackerTest<Types>(opaque_layers) {}
1004 void RunMyTest() {
1005 gfx::Transform child_transform;
1006 child_transform.Translate(250.0, 250.0);
1007 child_transform.Rotate(90.0);
1008 child_transform.Translate(-250.0, -250.0);
1010 typename Types::ContentLayerType* root = this->CreateRoot(
1011 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
1012 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1013 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1014 parent->SetMasksToBounds(true);
1015 typename Types::LayerType* child = this->CreateSurface(
1016 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1017 child->SetMasksToBounds(true);
1018 typename Types::ContentLayerType* layer =
1019 this->CreateDrawingLayer(child,
1020 this->identity_matrix,
1021 gfx::PointF(10.f, 10.f),
1022 gfx::Size(500, 500),
1023 true);
1024 // |child2| makes |parent|'s surface get considered by OcclusionTracker
1025 // first, instead of |child|'s. This exercises different code in
1026 // LeaveToRenderTarget, as the target surface has already been seen.
1027 typename Types::ContentLayerType* child2 =
1028 this->CreateDrawingLayer(parent,
1029 this->identity_matrix,
1030 gfx::PointF(30.f, 30.f),
1031 gfx::Size(60, 20),
1032 true);
1033 this->CalcDrawEtc(root);
1035 TestOcclusionTrackerWithClip<typename Types::LayerType,
1036 typename Types::RenderSurfaceType> occlusion(
1037 gfx::Rect(0, 0, 1000, 1000));
1039 this->VisitLayer(child2, &occlusion);
1041 EXPECT_EQ(gfx::Rect().ToString(),
1042 occlusion.occlusion_from_outside_target().ToString());
1043 EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1044 occlusion.occlusion_from_inside_target().ToString());
1046 this->VisitLayer(layer, &occlusion);
1048 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1049 occlusion.occlusion_from_outside_target().ToString());
1050 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1051 occlusion.occlusion_from_inside_target().ToString());
1053 this->EnterContributingSurface(child, &occlusion, false);
1055 EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1056 occlusion.occlusion_from_outside_target().ToString());
1057 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1058 occlusion.occlusion_from_inside_target().ToString());
1060 // Occlusion in |child2| should get merged with the |child| surface we are
1061 // leaving now.
1062 this->LeaveContributingSurface(child, &occlusion);
1063 this->EnterLayer(parent, &occlusion, false);
1065 EXPECT_EQ(gfx::Rect().ToString(),
1066 occlusion.occlusion_from_outside_target().ToString());
1067 EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1068 .ToString(),
1069 occlusion.occlusion_from_inside_target().ToString());
1071 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
1072 EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1073 occlusion.UnoccludedLayerContentRect(
1074 parent, gfx::Rect(30, 30, 70, 70)));
1076 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
1077 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
1078 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
1079 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
1080 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
1082 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1083 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1084 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1086 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1087 parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1088 EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1089 occlusion.UnoccludedLayerContentRect(
1090 parent, gfx::Rect(29, 30, 60, 10)));
1091 EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1092 occlusion.UnoccludedLayerContentRect(
1093 parent, gfx::Rect(30, 29, 60, 10)));
1094 EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1095 occlusion.UnoccludedLayerContentRect(
1096 parent, gfx::Rect(31, 30, 60, 10)));
1097 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1098 parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1100 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1101 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1102 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1103 occlusion.UnoccludedLayerContentRect(
1104 parent, gfx::Rect(29, 40, 70, 60)));
1105 // This rect is mostly occluded by |child2|.
1106 EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1107 occlusion.UnoccludedLayerContentRect(
1108 parent, gfx::Rect(30, 39, 70, 60)));
1109 // This rect extends past top/right ends of |child2|.
1110 EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1111 occlusion.UnoccludedLayerContentRect(
1112 parent, gfx::Rect(30, 29, 70, 70)));
1113 // This rect extends past left/right ends of |child2|.
1114 EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1115 occlusion.UnoccludedLayerContentRect(
1116 parent, gfx::Rect(20, 39, 80, 60)));
1117 EXPECT_RECT_EQ(gfx::Rect(),
1118 occlusion.UnoccludedLayerContentRect(
1119 parent, gfx::Rect(31, 40, 70, 60)));
1120 EXPECT_RECT_EQ(gfx::Rect(),
1121 occlusion.UnoccludedLayerContentRect(
1122 parent, gfx::Rect(30, 41, 70, 60)));
1124 /* Justification for the above occlusion from |layer|:
1126 +---------------------+
1128 | 30 | rotate(90)
1129 | 30 + ------------+--------------------+
1130 100 | | 10 | | | ==>
1131 | |10+----------|----------------------+
1132 | + ------------+ | | |
1133 | | | | | |
1134 | | | | | |
1135 +----|--|-------------+ | |
1136 | | | |
1137 | | | |
1138 | | | |500
1139 | | | |
1140 | | | |
1141 | | | |
1142 | | | |
1143 +--|-------------------------------+ |
1145 +---------------------------------+
1149 +---------------------+
1150 | |30 Visible region of |layer|: /////
1151 | 30 60 | |child2|: \\\\\
1152 | 30 +------------+--------------------+
1153 | |\\\\\\\\\\\\| |10 |
1154 | +--|\\\\\\\\\\\\|-----------------+ |
1155 | | +------------+//| 420 | |
1156 | | |///////////////|60 | |
1157 | | |///////////////| | |
1158 +--|--|---------------+ | |
1159 20|10| 70 | |
1160 | | | |
1161 | | | |
1162 | | | |
1163 | | | |
1164 | | | |
1165 | | |10|
1166 | +------------------------------|--+
1167 | 490 |
1168 +---------------------------------+
1174 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
1176 template <class Types>
1177 class OcclusionTrackerTestSurfaceRotatedOffAxis
1178 : public OcclusionTrackerTest<Types> {
1179 protected:
1180 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
1181 : OcclusionTrackerTest<Types>(opaque_layers) {}
1182 void RunMyTest() {
1183 gfx::Transform child_transform;
1184 child_transform.Translate(250.0, 250.0);
1185 child_transform.Rotate(95.0);
1186 child_transform.Translate(-250.0, -250.0);
1188 gfx::Transform layer_transform;
1189 layer_transform.Translate(10.0, 10.0);
1191 typename Types::ContentLayerType* root = this->CreateRoot(
1192 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1193 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1194 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1195 typename Types::LayerType* child = this->CreateLayer(
1196 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1197 child->SetMasksToBounds(true);
1198 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1199 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
1200 this->CalcDrawEtc(root);
1202 TestOcclusionTrackerWithClip<typename Types::LayerType,
1203 typename Types::RenderSurfaceType> occlusion(
1204 gfx::Rect(0, 0, 1000, 1000));
1206 gfx::Rect clipped_layer_in_child = MathUtil::MapClippedRect(
1207 layer_transform, layer->visible_content_rect());
1209 this->VisitLayer(layer, &occlusion);
1210 this->EnterContributingSurface(child, &occlusion, false);
1212 EXPECT_EQ(gfx::Rect().ToString(),
1213 occlusion.occlusion_from_outside_target().ToString());
1214 EXPECT_EQ(clipped_layer_in_child.ToString(),
1215 occlusion.occlusion_from_inside_target().ToString());
1217 this->LeaveContributingSurface(child, &occlusion);
1218 this->EnterLayer(parent, &occlusion, false);
1220 EXPECT_EQ(gfx::Rect().ToString(),
1221 occlusion.occlusion_from_outside_target().ToString());
1222 EXPECT_EQ(gfx::Rect().ToString(),
1223 occlusion.occlusion_from_inside_target().ToString());
1225 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
1226 EXPECT_RECT_EQ(
1227 gfx::Rect(75, 55, 1, 1),
1228 occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
1232 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
1234 template <class Types>
1235 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1236 : public OcclusionTrackerTest<Types> {
1237 protected:
1238 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
1239 : OcclusionTrackerTest<Types>(opaque_layers) {}
1240 void RunMyTest() {
1241 gfx::Transform child_transform;
1242 child_transform.Translate(250.0, 250.0);
1243 child_transform.Rotate(90.0);
1244 child_transform.Translate(-250.0, -250.0);
1246 typename Types::ContentLayerType* root = this->CreateRoot(
1247 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1248 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1249 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1250 parent->SetMasksToBounds(true);
1251 typename Types::ContentLayerType* child =
1252 this->CreateDrawingSurface(parent,
1253 child_transform,
1254 gfx::PointF(30.f, 30.f),
1255 gfx::Size(500, 500),
1256 false);
1257 child->SetMasksToBounds(true);
1258 typename Types::ContentLayerType* layer1 =
1259 this->CreateDrawingLayer(child,
1260 this->identity_matrix,
1261 gfx::PointF(10.f, 10.f),
1262 gfx::Size(500, 500),
1263 true);
1264 typename Types::ContentLayerType* layer2 =
1265 this->CreateDrawingLayer(child,
1266 this->identity_matrix,
1267 gfx::PointF(10.f, 450.f),
1268 gfx::Size(500, 60),
1269 true);
1270 this->CalcDrawEtc(root);
1272 TestOcclusionTrackerWithClip<typename Types::LayerType,
1273 typename Types::RenderSurfaceType> occlusion(
1274 gfx::Rect(0, 0, 1000, 1000));
1276 this->VisitLayer(layer2, &occlusion);
1277 this->VisitLayer(layer1, &occlusion);
1278 this->VisitLayer(child, &occlusion);
1279 this->EnterContributingSurface(child, &occlusion, false);
1281 EXPECT_EQ(gfx::Rect().ToString(),
1282 occlusion.occlusion_from_outside_target().ToString());
1283 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1284 occlusion.occlusion_from_inside_target().ToString());
1286 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
1287 EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
1288 // These rects are occluded except for the part outside the bounds of the
1289 // target surface.
1290 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 429, 60, 70)));
1291 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 60, 70)));
1292 EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 70)));
1294 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1295 child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1296 EXPECT_RECT_EQ(
1297 gfx::Rect(9, 430, 1, 70),
1298 occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
1299 // These rects are occluded except for the part outside the bounds of the
1300 // target surface.
1301 EXPECT_RECT_EQ(gfx::Rect(),
1302 occlusion.UnoccludedLayerContentRect(
1303 child, gfx::Rect(10, 429, 60, 70)));
1304 EXPECT_RECT_EQ(gfx::Rect(),
1305 occlusion.UnoccludedLayerContentRect(
1306 child, gfx::Rect(11, 430, 60, 70)));
1307 EXPECT_RECT_EQ(gfx::Rect(),
1308 occlusion.UnoccludedLayerContentRect(
1309 child, gfx::Rect(10, 431, 60, 70)));
1311 this->LeaveContributingSurface(child, &occlusion);
1312 this->EnterLayer(parent, &occlusion, false);
1314 EXPECT_EQ(gfx::Rect().ToString(),
1315 occlusion.occlusion_from_outside_target().ToString());
1316 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1317 occlusion.occlusion_from_inside_target().ToString());
1319 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1320 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1321 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1323 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1324 parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1325 EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1326 occlusion.UnoccludedLayerContentRect(
1327 parent, gfx::Rect(29, 40, 70, 60)));
1328 EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1329 occlusion.UnoccludedLayerContentRect(
1330 parent, gfx::Rect(30, 39, 70, 60)));
1331 EXPECT_RECT_EQ(gfx::Rect(),
1332 occlusion.UnoccludedLayerContentRect(
1333 parent, gfx::Rect(31, 40, 70, 60)));
1334 EXPECT_RECT_EQ(gfx::Rect(),
1335 occlusion.UnoccludedLayerContentRect(
1336 parent, gfx::Rect(30, 41, 70, 60)));
1338 /* Justification for the above occlusion from |layer1| and |layer2|:
1340 +---------------------+
1341 | |30 Visible region of |layer1|: /////
1342 | | Visible region of |layer2|: \\\\\
1343 | +---------------------------------+
1344 | | |10 |
1345 | +---------------+-----------------+ |
1346 | | |\\\\\\\\\\\\|//| 420 | |
1347 | | |\\\\\\\\\\\\|//|60 | |
1348 | | |\\\\\\\\\\\\|//| | |
1349 +--|--|------------|--+ | |
1350 20|10| 70 | | |
1351 | | | | |
1352 | | | | |
1353 | | | | |
1354 | | | | |
1355 | | | | |
1356 | | | |10|
1357 | +------------|-----------------|--+
1358 | | 490 |
1359 +---------------+-----------------+
1360 60 440
1365 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1367 template <class Types>
1368 class OcclusionTrackerTestOverlappingSurfaceSiblings
1369 : public OcclusionTrackerTest<Types> {
1370 protected:
1371 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
1372 : OcclusionTrackerTest<Types>(opaque_layers) {}
1373 void RunMyTest() {
1374 gfx::Transform child_transform;
1375 child_transform.Translate(250.0, 250.0);
1376 child_transform.Rotate(90.0);
1377 child_transform.Translate(-250.0, -250.0);
1379 typename Types::ContentLayerType* parent = this->CreateRoot(
1380 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1381 parent->SetMasksToBounds(true);
1382 typename Types::LayerType* child1 = this->CreateSurface(
1383 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
1384 typename Types::LayerType* child2 = this->CreateSurface(
1385 parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
1386 typename Types::ContentLayerType* layer1 =
1387 this->CreateDrawingLayer(child1,
1388 this->identity_matrix,
1389 gfx::PointF(-10.f, -10.f),
1390 gfx::Size(510, 510),
1391 true);
1392 typename Types::ContentLayerType* layer2 =
1393 this->CreateDrawingLayer(child2,
1394 this->identity_matrix,
1395 gfx::PointF(-10.f, -10.f),
1396 gfx::Size(510, 510),
1397 true);
1398 this->CalcDrawEtc(parent);
1400 TestOcclusionTrackerWithClip<typename Types::LayerType,
1401 typename Types::RenderSurfaceType> occlusion(
1402 gfx::Rect(0, 0, 1000, 1000));
1404 this->VisitLayer(layer2, &occlusion);
1405 this->EnterContributingSurface(child2, &occlusion, false);
1407 EXPECT_EQ(gfx::Rect().ToString(),
1408 occlusion.occlusion_from_outside_target().ToString());
1409 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1410 occlusion.occlusion_from_inside_target().ToString());
1412 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
1413 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
1414 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
1415 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
1416 EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));
1418 // There is nothing above child2's surface in the z-order.
1419 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1420 occlusion.UnoccludedContributingSurfaceContentRect(
1421 child2, false, gfx::Rect(-10, 420, 70, 80), NULL));
1423 this->LeaveContributingSurface(child2, &occlusion);
1424 this->VisitLayer(layer1, &occlusion);
1425 this->EnterContributingSurface(child1, &occlusion, false);
1427 EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1428 occlusion.occlusion_from_outside_target().ToString());
1429 EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1430 occlusion.occlusion_from_inside_target().ToString());
1432 // child2's contents will occlude child1 below it.
1433 EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1434 occlusion.UnoccludedContributingSurfaceContentRect(
1435 child1, false, gfx::Rect(-10, 430, 80, 70), NULL));
1437 this->LeaveContributingSurface(child1, &occlusion);
1438 this->EnterLayer(parent, &occlusion, false);
1440 EXPECT_EQ(gfx::Rect().ToString(),
1441 occlusion.occlusion_from_outside_target().ToString());
1442 EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1443 .ToString(),
1444 occlusion.occlusion_from_inside_target().ToString());
1446 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1448 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1449 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1450 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1452 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1453 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1454 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1456 /* Justification for the above occlusion:
1458 +---------------------+
1459 | 20 | layer1
1460 | 30+ ---------------------------------+
1461 100 | 30| | layer2 |
1462 |20+----------------------------------+ |
1463 | | | | | |
1464 | | | | | |
1465 | | | | | |
1466 +--|-|----------------+ | |
1467 | | | | 510
1468 | | | |
1469 | | | |
1470 | | | |
1471 | | | |
1472 | | | |
1473 | | | |
1474 | +--------------------------------|-+
1476 +----------------------------------+
1482 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1484 template <class Types>
1485 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1486 : public OcclusionTrackerTest<Types> {
1487 protected:
1488 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1489 bool opaque_layers)
1490 : OcclusionTrackerTest<Types>(opaque_layers) {}
1491 void RunMyTest() {
1492 gfx::Transform child1_transform;
1493 child1_transform.Translate(250.0, 250.0);
1494 child1_transform.Rotate(-90.0);
1495 child1_transform.Translate(-250.0, -250.0);
1497 gfx::Transform child2_transform;
1498 child2_transform.Translate(250.0, 250.0);
1499 child2_transform.Rotate(90.0);
1500 child2_transform.Translate(-250.0, -250.0);
1502 typename Types::ContentLayerType* parent = this->CreateRoot(
1503 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1504 parent->SetMasksToBounds(true);
1505 typename Types::LayerType* child1 = this->CreateSurface(
1506 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1507 typename Types::LayerType* child2 =
1508 this->CreateDrawingSurface(parent,
1509 child2_transform,
1510 gfx::PointF(20.f, 40.f),
1511 gfx::Size(10, 10),
1512 false);
1513 typename Types::ContentLayerType* layer1 =
1514 this->CreateDrawingLayer(child1,
1515 this->identity_matrix,
1516 gfx::PointF(-10.f, -20.f),
1517 gfx::Size(510, 510),
1518 true);
1519 typename Types::ContentLayerType* layer2 =
1520 this->CreateDrawingLayer(child2,
1521 this->identity_matrix,
1522 gfx::PointF(-10.f, -10.f),
1523 gfx::Size(510, 510),
1524 true);
1525 this->CalcDrawEtc(parent);
1527 TestOcclusionTrackerWithClip<typename Types::LayerType,
1528 typename Types::RenderSurfaceType> occlusion(
1529 gfx::Rect(0, 0, 1000, 1000));
1531 this->VisitLayer(layer2, &occlusion);
1532 this->EnterLayer(child2, &occlusion, false);
1534 EXPECT_EQ(gfx::Rect().ToString(),
1535 occlusion.occlusion_from_outside_target().ToString());
1536 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1537 occlusion.occlusion_from_inside_target().ToString());
1539 this->LeaveLayer(child2, &occlusion);
1540 this->EnterContributingSurface(child2, &occlusion, false);
1542 // There is nothing above child2's surface in the z-order.
1543 EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1544 occlusion.UnoccludedContributingSurfaceContentRect(
1545 child2, false, gfx::Rect(-10, 420, 70, 80), NULL));
1547 this->LeaveContributingSurface(child2, &occlusion);
1548 this->VisitLayer(layer1, &occlusion);
1549 this->EnterContributingSurface(child1, &occlusion, false);
1551 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1552 occlusion.occlusion_from_outside_target().ToString());
1553 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1554 occlusion.occlusion_from_inside_target().ToString());
1556 // child2's contents will occlude child1 below it.
1557 EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1558 occlusion.UnoccludedContributingSurfaceContentRect(
1559 child1, false, gfx::Rect(420, -20, 80, 90), NULL));
1560 EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1561 occlusion.UnoccludedContributingSurfaceContentRect(
1562 child1, false, gfx::Rect(420, -10, 80, 90), NULL));
1563 EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1564 occlusion.UnoccludedContributingSurfaceContentRect(
1565 child1, false, gfx::Rect(420, -20, 70, 90), NULL));
1567 this->LeaveContributingSurface(child1, &occlusion);
1568 this->EnterLayer(parent, &occlusion, false);
1570 EXPECT_EQ(gfx::Rect().ToString(),
1571 occlusion.occlusion_from_outside_target().ToString());
1572 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1573 occlusion.occlusion_from_inside_target().ToString());
1575 /* Justification for the above occlusion:
1577 +---------------------+
1578 |20 | layer1
1579 10+----------------------------------+
1580 100 || 30 | layer2 |
1581 |20+----------------------------------+
1582 || | | | |
1583 || | | | |
1584 || | | | |
1585 +|-|------------------+ | |
1586 | | | | 510
1587 | | 510 | |
1588 | | | |
1589 | | | |
1590 | | | |
1591 | | | |
1592 | | 520 | |
1593 +----------------------------------+ |
1595 +----------------------------------+
1601 ALL_OCCLUSIONTRACKER_TEST(
1602 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1604 template <class Types>
1605 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1606 protected:
1607 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1608 : OcclusionTrackerTest<Types>(opaque_layers) {}
1609 void RunMyTest() {
1610 gfx::Transform layer_transform;
1611 layer_transform.Translate(250.0, 250.0);
1612 layer_transform.Rotate(90.0);
1613 layer_transform.Translate(-250.0, -250.0);
1615 typename Types::ContentLayerType* parent = this->CreateRoot(
1616 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1617 parent->SetMasksToBounds(true);
1618 typename Types::ContentLayerType* blur_layer =
1619 this->CreateDrawingLayer(parent,
1620 layer_transform,
1621 gfx::PointF(30.f, 30.f),
1622 gfx::Size(500, 500),
1623 true);
1624 typename Types::ContentLayerType* opaque_layer =
1625 this->CreateDrawingLayer(parent,
1626 layer_transform,
1627 gfx::PointF(30.f, 30.f),
1628 gfx::Size(500, 500),
1629 true);
1630 typename Types::ContentLayerType* opacity_layer =
1631 this->CreateDrawingLayer(parent,
1632 layer_transform,
1633 gfx::PointF(30.f, 30.f),
1634 gfx::Size(500, 500),
1635 true);
1637 FilterOperations filters;
1638 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1639 blur_layer->SetFilters(filters);
1641 filters.Clear();
1642 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1643 opaque_layer->SetFilters(filters);
1645 filters.Clear();
1646 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1647 opacity_layer->SetFilters(filters);
1649 this->CalcDrawEtc(parent);
1651 TestOcclusionTrackerWithClip<typename Types::LayerType,
1652 typename Types::RenderSurfaceType> occlusion(
1653 gfx::Rect(0, 0, 1000, 1000));
1655 // Opacity layer won't contribute to occlusion.
1656 this->VisitLayer(opacity_layer, &occlusion);
1657 this->EnterContributingSurface(opacity_layer, &occlusion, false);
1659 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1660 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1662 // And has nothing to contribute to its parent surface.
1663 this->LeaveContributingSurface(opacity_layer, &occlusion);
1664 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1665 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1667 // Opaque layer will contribute to occlusion.
1668 this->VisitLayer(opaque_layer, &occlusion);
1669 this->EnterContributingSurface(opaque_layer, &occlusion, false);
1671 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1672 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1673 occlusion.occlusion_from_inside_target().ToString());
1675 // And it gets translated to the parent surface.
1676 this->LeaveContributingSurface(opaque_layer, &occlusion);
1677 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1678 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1679 occlusion.occlusion_from_inside_target().ToString());
1681 // The blur layer needs to throw away any occlusion from outside its
1682 // subtree.
1683 this->EnterLayer(blur_layer, &occlusion, false);
1684 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1685 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1687 // And it won't contribute to occlusion.
1688 this->LeaveLayer(blur_layer, &occlusion);
1689 this->EnterContributingSurface(blur_layer, &occlusion, false);
1690 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1691 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1693 // But the opaque layer's occlusion is preserved on the parent.
1694 this->LeaveContributingSurface(blur_layer, &occlusion);
1695 this->EnterLayer(parent, &occlusion, false);
1696 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1697 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1698 occlusion.occlusion_from_inside_target().ToString());
1702 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1704 template <class Types>
1705 class OcclusionTrackerTestReplicaDoesOcclude
1706 : public OcclusionTrackerTest<Types> {
1707 protected:
1708 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1709 : OcclusionTrackerTest<Types>(opaque_layers) {}
1710 void RunMyTest() {
1711 typename Types::ContentLayerType* parent = this->CreateRoot(
1712 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1713 typename Types::LayerType* surface =
1714 this->CreateDrawingSurface(parent,
1715 this->identity_matrix,
1716 gfx::PointF(0.f, 100.f),
1717 gfx::Size(50, 50),
1718 true);
1719 this->CreateReplicaLayer(
1720 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1721 this->CalcDrawEtc(parent);
1723 TestOcclusionTrackerWithClip<typename Types::LayerType,
1724 typename Types::RenderSurfaceType> occlusion(
1725 gfx::Rect(0, 0, 1000, 1000));
1727 this->VisitLayer(surface, &occlusion);
1729 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1730 occlusion.occlusion_from_inside_target().ToString());
1732 this->VisitContributingSurface(surface, &occlusion);
1733 this->EnterLayer(parent, &occlusion, false);
1735 // The surface and replica should both be occluding the parent.
1736 EXPECT_EQ(
1737 UnionRegions(gfx::Rect(0, 100, 50, 50),
1738 gfx::Rect(50, 150, 50, 50)).ToString(),
1739 occlusion.occlusion_from_inside_target().ToString());
1743 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1745 template <class Types>
1746 class OcclusionTrackerTestReplicaWithClipping
1747 : public OcclusionTrackerTest<Types> {
1748 protected:
1749 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1750 : OcclusionTrackerTest<Types>(opaque_layers) {}
1751 void RunMyTest() {
1752 typename Types::ContentLayerType* parent = this->CreateRoot(
1753 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1754 parent->SetMasksToBounds(true);
1755 typename Types::LayerType* surface =
1756 this->CreateDrawingSurface(parent,
1757 this->identity_matrix,
1758 gfx::PointF(0.f, 100.f),
1759 gfx::Size(50, 50),
1760 true);
1761 this->CreateReplicaLayer(
1762 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1763 this->CalcDrawEtc(parent);
1765 TestOcclusionTrackerWithClip<typename Types::LayerType,
1766 typename Types::RenderSurfaceType> occlusion(
1767 gfx::Rect(0, 0, 1000, 1000));
1769 this->VisitLayer(surface, &occlusion);
1771 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1772 occlusion.occlusion_from_inside_target().ToString());
1774 this->VisitContributingSurface(surface, &occlusion);
1775 this->EnterLayer(parent, &occlusion, false);
1777 // The surface and replica should both be occluding the parent.
1778 EXPECT_EQ(
1779 UnionRegions(gfx::Rect(0, 100, 50, 50),
1780 gfx::Rect(50, 150, 50, 20)).ToString(),
1781 occlusion.occlusion_from_inside_target().ToString());
1785 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1787 template <class Types>
1788 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1789 protected:
1790 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1791 : OcclusionTrackerTest<Types>(opaque_layers) {}
1792 void RunMyTest() {
1793 typename Types::ContentLayerType* parent = this->CreateRoot(
1794 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1795 typename Types::LayerType* surface =
1796 this->CreateDrawingSurface(parent,
1797 this->identity_matrix,
1798 gfx::PointF(0.f, 100.f),
1799 gfx::Size(50, 50),
1800 true);
1801 typename Types::LayerType* replica = this->CreateReplicaLayer(
1802 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1803 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1804 this->CalcDrawEtc(parent);
1806 TestOcclusionTrackerWithClip<typename Types::LayerType,
1807 typename Types::RenderSurfaceType> occlusion(
1808 gfx::Rect(0, 0, 1000, 1000));
1810 this->VisitLayer(surface, &occlusion);
1812 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1813 occlusion.occlusion_from_inside_target().ToString());
1815 this->VisitContributingSurface(surface, &occlusion);
1816 this->EnterLayer(parent, &occlusion, false);
1818 // The replica should not be occluding the parent, since it has a mask
1819 // applied to it.
1820 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1821 occlusion.occlusion_from_inside_target().ToString());
1825 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1827 template <class Types>
1828 class OcclusionTrackerTestLayerClipRectOutsideChild
1829 : public OcclusionTrackerTest<Types> {
1830 protected:
1831 explicit OcclusionTrackerTestLayerClipRectOutsideChild(bool opaque_layers)
1832 : OcclusionTrackerTest<Types>(opaque_layers) {}
1833 void RunMyTest() {
1834 typename Types::ContentLayerType* parent = this->CreateRoot(
1835 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1836 typename Types::ContentLayerType* clip =
1837 this->CreateDrawingLayer(parent,
1838 this->identity_matrix,
1839 gfx::PointF(200.f, 100.f),
1840 gfx::Size(100, 100),
1841 false);
1842 clip->SetMasksToBounds(true);
1843 typename Types::ContentLayerType* layer =
1844 this->CreateDrawingLayer(clip,
1845 this->identity_matrix,
1846 gfx::PointF(-200.f, -100.f),
1847 gfx::Size(200, 200),
1848 false);
1849 this->CalcDrawEtc(parent);
1851 TestOcclusionTrackerWithClip<typename Types::LayerType,
1852 typename Types::RenderSurfaceType> occlusion(
1853 gfx::Rect(0, 0, 1000, 1000));
1855 this->EnterLayer(layer, &occlusion, false);
1857 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1858 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1859 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1860 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1861 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1863 this->LeaveLayer(layer, &occlusion);
1864 this->EnterLayer(clip, &occlusion, false);
1866 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(-100, 0, 100, 100)));
1867 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, -100, 100, 100)));
1868 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100)));
1869 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100)));
1870 EXPECT_FALSE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100)));
1872 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
1873 occlusion.UnoccludedLayerContentRect(
1874 clip, gfx::Rect(-100, -100, 300, 300)));
1878 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild);
1880 template <class Types>
1881 class OcclusionTrackerTestViewportRectOutsideChild
1882 : public OcclusionTrackerTest<Types> {
1883 protected:
1884 explicit OcclusionTrackerTestViewportRectOutsideChild(bool opaque_layers)
1885 : OcclusionTrackerTest<Types>(opaque_layers) {}
1886 void RunMyTest() {
1887 typename Types::ContentLayerType* parent = this->CreateRoot(
1888 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1889 typename Types::ContentLayerType* layer =
1890 this->CreateDrawingSurface(parent,
1891 this->identity_matrix,
1892 gfx::PointF(),
1893 gfx::Size(200, 200),
1894 true);
1895 this->CalcDrawEtc(parent);
1897 TestOcclusionTrackerWithClip<typename Types::LayerType,
1898 typename Types::RenderSurfaceType> occlusion(
1899 gfx::Rect(200, 100, 100, 100));
1901 this->EnterLayer(layer, &occlusion, false);
1903 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1904 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1905 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1906 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1907 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
1909 this->LeaveLayer(layer, &occlusion);
1910 this->VisitContributingSurface(layer, &occlusion);
1911 this->EnterLayer(parent, &occlusion, false);
1913 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
1914 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1915 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
1916 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1917 EXPECT_FALSE(
1918 occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
1919 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
1920 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
1921 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
1922 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1924 EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100),
1925 occlusion.UnoccludedLayerContentRect(
1926 parent, gfx::Rect(0, 0, 300, 300)));
1930 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild);
1932 template <class Types>
1933 class OcclusionTrackerTestLayerClipRectOverChild
1934 : public OcclusionTrackerTest<Types> {
1935 protected:
1936 explicit OcclusionTrackerTestLayerClipRectOverChild(bool opaque_layers)
1937 : OcclusionTrackerTest<Types>(opaque_layers) {}
1938 void RunMyTest() {
1939 typename Types::ContentLayerType* parent = this->CreateRoot(
1940 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1941 typename Types::ContentLayerType* clip =
1942 this->CreateDrawingLayer(parent,
1943 this->identity_matrix,
1944 gfx::PointF(100.f, 100.f),
1945 gfx::Size(100, 100),
1946 false);
1947 clip->SetMasksToBounds(true);
1948 typename Types::ContentLayerType* layer =
1949 this->CreateDrawingSurface(clip,
1950 this->identity_matrix,
1951 gfx::PointF(-100.f, -100.f),
1952 gfx::Size(200, 200),
1953 true);
1954 this->CalcDrawEtc(parent);
1956 TestOcclusionTrackerWithClip<typename Types::LayerType,
1957 typename Types::RenderSurfaceType> occlusion(
1958 gfx::Rect(0, 0, 1000, 1000));
1960 this->EnterLayer(layer, &occlusion, false);
1962 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1963 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1964 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1965 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1967 this->LeaveLayer(layer, &occlusion);
1968 this->VisitContributingSurface(layer, &occlusion);
1970 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1971 occlusion.occlusion_from_inside_target().ToString());
1973 this->EnterLayer(clip, &occlusion, false);
1975 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100)));
1976 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100)));
1977 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100)));
1978 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 100, 100, 100)));
1979 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 100, 100, 100)));
1980 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 0, 100, 100)));
1981 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 200, 100, 100)));
1982 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 200, 100, 100)));
1983 EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 200, 100, 100)));
1985 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1986 clip, gfx::Rect(0, 0, 300, 300)).IsEmpty());
1990 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild);
1992 template <class Types>
1993 class OcclusionTrackerTestViewportRectOverChild
1994 : public OcclusionTrackerTest<Types> {
1995 protected:
1996 explicit OcclusionTrackerTestViewportRectOverChild(bool opaque_layers)
1997 : OcclusionTrackerTest<Types>(opaque_layers) {}
1998 void RunMyTest() {
1999 typename Types::ContentLayerType* parent = this->CreateRoot(
2000 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2001 typename Types::ContentLayerType* layer =
2002 this->CreateDrawingSurface(parent,
2003 this->identity_matrix,
2004 gfx::PointF(),
2005 gfx::Size(200, 200),
2006 true);
2007 this->CalcDrawEtc(parent);
2009 TestOcclusionTrackerWithClip<typename Types::LayerType,
2010 typename Types::RenderSurfaceType> occlusion(
2011 gfx::Rect(100, 100, 100, 100));
2013 this->EnterLayer(layer, &occlusion, false);
2015 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2016 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2017 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2018 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2020 this->LeaveLayer(layer, &occlusion);
2021 this->VisitContributingSurface(layer, &occlusion);
2022 this->EnterLayer(parent, &occlusion, false);
2024 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2025 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2026 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2027 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2028 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2029 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2030 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2031 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2032 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2034 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2035 parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2039 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild);
2041 template <class Types>
2042 class OcclusionTrackerTestLayerClipRectPartlyOverChild
2043 : public OcclusionTrackerTest<Types> {
2044 protected:
2045 explicit OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaque_layers)
2046 : OcclusionTrackerTest<Types>(opaque_layers) {}
2047 void RunMyTest() {
2048 typename Types::ContentLayerType* parent = this->CreateRoot(
2049 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2050 typename Types::ContentLayerType* clip =
2051 this->CreateDrawingLayer(parent,
2052 this->identity_matrix,
2053 gfx::PointF(50.f, 50.f),
2054 gfx::Size(200, 200),
2055 false);
2056 clip->SetMasksToBounds(true);
2057 typename Types::ContentLayerType* layer =
2058 this->CreateDrawingSurface(clip,
2059 this->identity_matrix,
2060 gfx::PointF(-50.f, -50.f),
2061 gfx::Size(200, 200),
2062 true);
2063 this->CalcDrawEtc(parent);
2065 TestOcclusionTrackerWithClip<typename Types::LayerType,
2066 typename Types::RenderSurfaceType> occlusion(
2067 gfx::Rect(0, 0, 1000, 1000));
2069 this->EnterLayer(layer, &occlusion, false);
2071 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2072 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2073 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2074 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2076 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 50)));
2077 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 50, 100)));
2078 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 50)));
2079 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 50, 100)));
2081 this->LeaveLayer(layer, &occlusion);
2082 this->VisitContributingSurface(layer, &occlusion);
2083 this->EnterLayer(clip, &occlusion, false);
2085 EXPECT_EQ(gfx::Rect(50, 50, 150, 150).ToString(),
2086 occlusion.occlusion_from_inside_target().ToString());
2090 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild);
2092 template <class Types>
2093 class OcclusionTrackerTestViewportRectPartlyOverChild
2094 : public OcclusionTrackerTest<Types> {
2095 protected:
2096 explicit OcclusionTrackerTestViewportRectPartlyOverChild(bool opaque_layers)
2097 : OcclusionTrackerTest<Types>(opaque_layers) {}
2098 void RunMyTest() {
2099 typename Types::ContentLayerType* parent = this->CreateRoot(
2100 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2101 typename Types::ContentLayerType* layer =
2102 this->CreateDrawingSurface(parent,
2103 this->identity_matrix,
2104 gfx::PointF(),
2105 gfx::Size(200, 200),
2106 true);
2107 this->CalcDrawEtc(parent);
2109 TestOcclusionTrackerWithClip<typename Types::LayerType,
2110 typename Types::RenderSurfaceType> occlusion(
2111 gfx::Rect(50, 50, 200, 200));
2113 this->EnterLayer(layer, &occlusion, false);
2115 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2116 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2117 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2118 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2120 this->LeaveLayer(layer, &occlusion);
2121 this->VisitContributingSurface(layer, &occlusion);
2122 this->EnterLayer(parent, &occlusion, false);
2124 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2125 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2126 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2127 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2128 EXPECT_FALSE(
2129 occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2130 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2131 EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2132 EXPECT_FALSE(
2133 occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2134 EXPECT_FALSE(
2135 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2137 EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200),
2138 occlusion.UnoccludedLayerContentRect(
2139 parent, gfx::Rect(0, 0, 300, 300)));
2140 EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50),
2141 occlusion.UnoccludedLayerContentRect(
2142 parent, gfx::Rect(0, 0, 300, 100)));
2143 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2144 occlusion.UnoccludedLayerContentRect(
2145 parent, gfx::Rect(0, 100, 300, 100)));
2146 EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
2147 occlusion.UnoccludedLayerContentRect(
2148 parent, gfx::Rect(200, 100, 100, 100)));
2149 EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50),
2150 occlusion.UnoccludedLayerContentRect(
2151 parent, gfx::Rect(100, 200, 100, 100)));
2155 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild);
2157 template <class Types>
2158 class OcclusionTrackerTestViewportRectOverNothing
2159 : public OcclusionTrackerTest<Types> {
2160 protected:
2161 explicit OcclusionTrackerTestViewportRectOverNothing(bool opaque_layers)
2162 : OcclusionTrackerTest<Types>(opaque_layers) {}
2163 void RunMyTest() {
2164 typename Types::ContentLayerType* parent = this->CreateRoot(
2165 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2166 typename Types::ContentLayerType* layer =
2167 this->CreateDrawingSurface(parent,
2168 this->identity_matrix,
2169 gfx::PointF(),
2170 gfx::Size(200, 200),
2171 true);
2172 this->CalcDrawEtc(parent);
2174 TestOcclusionTrackerWithClip<typename Types::LayerType,
2175 typename Types::RenderSurfaceType> occlusion(
2176 gfx::Rect(500, 500, 100, 100));
2178 this->EnterLayer(layer, &occlusion, false);
2180 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2181 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2182 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2183 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2185 this->LeaveLayer(layer, &occlusion);
2186 this->VisitContributingSurface(layer, &occlusion);
2187 this->EnterLayer(parent, &occlusion, false);
2189 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
2190 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2191 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
2192 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2193 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
2194 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
2195 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
2196 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
2197 EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2199 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2200 parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
2201 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2202 parent, gfx::Rect(0, 0, 300, 100)).IsEmpty());
2203 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2204 parent, gfx::Rect(0, 100, 300, 100)).IsEmpty());
2205 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2206 parent, gfx::Rect(200, 100, 100, 100)).IsEmpty());
2207 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2208 parent, gfx::Rect(100, 200, 100, 100)).IsEmpty());
2212 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing);
2214 template <class Types>
2215 class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
2216 : public OcclusionTrackerTest<Types> {
2217 protected:
2218 explicit OcclusionTrackerTestLayerClipRectForLayerOffOrigin(
2219 bool opaque_layers)
2220 : OcclusionTrackerTest<Types>(opaque_layers) {}
2221 void RunMyTest() {
2222 typename Types::ContentLayerType* parent = this->CreateRoot(
2223 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2224 typename Types::ContentLayerType* layer =
2225 this->CreateDrawingSurface(parent,
2226 this->identity_matrix,
2227 gfx::PointF(),
2228 gfx::Size(200, 200),
2229 true);
2230 this->CalcDrawEtc(parent);
2232 TestOcclusionTrackerWithClip<typename Types::LayerType,
2233 typename Types::RenderSurfaceType> occlusion(
2234 gfx::Rect(0, 0, 1000, 1000));
2235 this->EnterLayer(layer, &occlusion, false);
2237 // This layer is translated when drawn into its target. So if the clip rect
2238 // given from the target surface is not in that target space, then after
2239 // translating these query rects into the target, they will fall outside the
2240 // clip and be considered occluded.
2241 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2242 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2243 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2244 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2248 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin);
2250 template <class Types>
2251 class OcclusionTrackerTestOpaqueContentsRegionEmpty
2252 : public OcclusionTrackerTest<Types> {
2253 protected:
2254 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
2255 : OcclusionTrackerTest<Types>(opaque_layers) {}
2256 void RunMyTest() {
2257 typename Types::ContentLayerType* parent = this->CreateRoot(
2258 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2259 typename Types::ContentLayerType* layer =
2260 this->CreateDrawingSurface(parent,
2261 this->identity_matrix,
2262 gfx::PointF(),
2263 gfx::Size(200, 200),
2264 false);
2265 this->CalcDrawEtc(parent);
2267 TestOcclusionTrackerWithClip<typename Types::LayerType,
2268 typename Types::RenderSurfaceType> occlusion(
2269 gfx::Rect(0, 0, 1000, 1000));
2270 this->EnterLayer(layer, &occlusion, false);
2272 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2273 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
2274 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
2275 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
2277 // Occluded since its outside the surface bounds.
2278 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));
2280 this->LeaveLayer(layer, &occlusion);
2281 this->VisitContributingSurface(layer, &occlusion);
2282 this->EnterLayer(parent, &occlusion, false);
2284 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2288 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
2290 template <class Types>
2291 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
2292 : public OcclusionTrackerTest<Types> {
2293 protected:
2294 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
2295 : OcclusionTrackerTest<Types>(opaque_layers) {}
2296 void RunMyTest() {
2297 typename Types::ContentLayerType* parent = this->CreateRoot(
2298 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2299 typename Types::ContentLayerType* layer =
2300 this->CreateDrawingLayer(parent,
2301 this->identity_matrix,
2302 gfx::PointF(100.f, 100.f),
2303 gfx::Size(200, 200),
2304 false);
2305 this->CalcDrawEtc(parent);
2307 TestOcclusionTrackerWithClip<typename Types::LayerType,
2308 typename Types::RenderSurfaceType> occlusion(
2309 gfx::Rect(0, 0, 1000, 1000));
2310 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
2312 this->ResetLayerIterator();
2313 this->VisitLayer(layer, &occlusion);
2314 this->EnterLayer(parent, &occlusion, false);
2316 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
2317 occlusion.occlusion_from_inside_target().ToString());
2319 EXPECT_FALSE(
2320 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2321 EXPECT_TRUE(
2322 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2323 EXPECT_FALSE(
2324 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2327 TestOcclusionTrackerWithClip<typename Types::LayerType,
2328 typename Types::RenderSurfaceType> occlusion(
2329 gfx::Rect(0, 0, 1000, 1000));
2330 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
2332 this->ResetLayerIterator();
2333 this->VisitLayer(layer, &occlusion);
2334 this->EnterLayer(parent, &occlusion, false);
2336 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
2337 occlusion.occlusion_from_inside_target().ToString());
2339 EXPECT_FALSE(
2340 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2341 EXPECT_FALSE(
2342 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2343 EXPECT_TRUE(
2344 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2347 TestOcclusionTrackerWithClip<typename Types::LayerType,
2348 typename Types::RenderSurfaceType> occlusion(
2349 gfx::Rect(0, 0, 1000, 1000));
2350 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
2352 this->ResetLayerIterator();
2353 this->VisitLayer(layer, &occlusion);
2354 this->EnterLayer(parent, &occlusion, false);
2356 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
2357 occlusion.occlusion_from_inside_target().ToString());
2359 EXPECT_FALSE(
2360 occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
2361 EXPECT_FALSE(
2362 occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
2363 EXPECT_FALSE(
2364 occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
2369 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
2371 template <class Types>
2372 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
2373 protected:
2374 explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
2375 : OcclusionTrackerTest<Types>(opaque_layers) {}
2376 void RunMyTest() {
2377 gfx::Transform transform;
2378 transform.RotateAboutYAxis(30.0);
2380 typename Types::ContentLayerType* parent = this->CreateRoot(
2381 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2382 typename Types::LayerType* container = this->CreateLayer(
2383 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2384 typename Types::ContentLayerType* layer =
2385 this->CreateDrawingLayer(container,
2386 transform,
2387 gfx::PointF(100.f, 100.f),
2388 gfx::Size(200, 200),
2389 true);
2390 this->CalcDrawEtc(parent);
2392 TestOcclusionTrackerWithClip<typename Types::LayerType,
2393 typename Types::RenderSurfaceType> occlusion(
2394 gfx::Rect(0, 0, 1000, 1000));
2395 this->EnterLayer(layer, &occlusion, false);
2397 // The layer is rotated in 3d but without preserving 3d, so it only gets
2398 // resized.
2399 EXPECT_RECT_EQ(
2400 gfx::Rect(0, 0, 200, 200),
2401 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2405 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
2407 template <class Types>
2408 class OcclusionTrackerTestUnsorted3dLayers
2409 : public OcclusionTrackerTest<Types> {
2410 protected:
2411 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
2412 : OcclusionTrackerTest<Types>(opaque_layers) {}
2413 void RunMyTest() {
2414 // Currently, The main thread layer iterator does not iterate over 3d items
2415 // in sorted order, because layer sorting is not performed on the main
2416 // thread. Because of this, the occlusion tracker cannot assume that a 3d
2417 // layer occludes other layers that have not yet been iterated over. For
2418 // now, the expected behavior is that a 3d layer simply does not add any
2419 // occlusion to the occlusion tracker.
2421 gfx::Transform translation_to_front;
2422 translation_to_front.Translate3d(0.0, 0.0, -10.0);
2423 gfx::Transform translation_to_back;
2424 translation_to_front.Translate3d(0.0, 0.0, -100.0);
2426 typename Types::ContentLayerType* parent = this->CreateRoot(
2427 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2428 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
2429 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
2430 typename Types::ContentLayerType* child2 =
2431 this->CreateDrawingLayer(parent,
2432 translation_to_front,
2433 gfx::PointF(50.f, 50.f),
2434 gfx::Size(100, 100),
2435 true);
2436 parent->SetPreserves3d(true);
2438 this->CalcDrawEtc(parent);
2440 TestOcclusionTrackerWithClip<typename Types::LayerType,
2441 typename Types::RenderSurfaceType> occlusion(
2442 gfx::Rect(0, 0, 1000, 1000));
2443 this->VisitLayer(child2, &occlusion);
2444 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2445 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2447 this->VisitLayer(child1, &occlusion);
2448 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2449 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2453 // This test will have different layer ordering on the impl thread; the test
2454 // will only work on the main thread.
2455 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
2457 template <class Types>
2458 class OcclusionTrackerTestPerspectiveTransform
2459 : public OcclusionTrackerTest<Types> {
2460 protected:
2461 explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
2462 : OcclusionTrackerTest<Types>(opaque_layers) {}
2463 void RunMyTest() {
2464 gfx::Transform transform;
2465 transform.Translate(150.0, 150.0);
2466 transform.ApplyPerspectiveDepth(400.0);
2467 transform.RotateAboutXAxis(-30.0);
2468 transform.Translate(-150.0, -150.0);
2470 typename Types::ContentLayerType* parent = this->CreateRoot(
2471 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2472 typename Types::LayerType* container = this->CreateLayer(
2473 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2474 typename Types::ContentLayerType* layer =
2475 this->CreateDrawingLayer(container,
2476 transform,
2477 gfx::PointF(100.f, 100.f),
2478 gfx::Size(200, 200),
2479 true);
2480 container->SetPreserves3d(true);
2481 layer->SetPreserves3d(true);
2482 this->CalcDrawEtc(parent);
2484 TestOcclusionTrackerWithClip<typename Types::LayerType,
2485 typename Types::RenderSurfaceType> occlusion(
2486 gfx::Rect(0, 0, 1000, 1000));
2487 this->EnterLayer(layer, &occlusion, false);
2489 EXPECT_RECT_EQ(
2490 gfx::Rect(0, 0, 200, 200),
2491 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2495 // This test requires accumulating occlusion of 3d layers, which are skipped by
2496 // the occlusion tracker on the main thread. So this test should run on the impl
2497 // thread.
2498 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
2500 template <class Types>
2501 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2502 : public OcclusionTrackerTest<Types> {
2503 protected:
2504 explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2505 bool opaque_layers)
2506 : OcclusionTrackerTest<Types>(opaque_layers) {}
2507 void RunMyTest() {
2508 // This test is based on the platform/chromium/compositing/3d-corners.html
2509 // layout test.
2510 gfx::Transform transform;
2511 transform.Translate(250.0, 50.0);
2512 transform.ApplyPerspectiveDepth(10.0);
2513 transform.Translate(-250.0, -50.0);
2514 transform.Translate(250.0, 50.0);
2515 transform.RotateAboutXAxis(-167.0);
2516 transform.Translate(-250.0, -50.0);
2518 typename Types::ContentLayerType* parent = this->CreateRoot(
2519 this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
2520 typename Types::LayerType* container = this->CreateLayer(
2521 parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2522 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2523 container, transform, gfx::PointF(), gfx::Size(500, 500), true);
2524 container->SetPreserves3d(true);
2525 layer->SetPreserves3d(true);
2526 this->CalcDrawEtc(parent);
2528 TestOcclusionTrackerWithClip<typename Types::LayerType,
2529 typename Types::RenderSurfaceType> occlusion(
2530 gfx::Rect(0, 0, 1000, 1000));
2531 this->EnterLayer(layer, &occlusion, false);
2533 // The bottom 11 pixel rows of this layer remain visible inside the
2534 // container, after translation to the target surface. When translated back,
2535 // this will include many more pixels but must include at least the bottom
2536 // 11 rows.
2537 EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2538 layer, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
2542 // This test requires accumulating occlusion of 3d layers, which are skipped by
2543 // the occlusion tracker on the main thread. So this test should run on the impl
2544 // thread.
2545 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2547 template <class Types>
2548 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2549 : public OcclusionTrackerTest<Types> {
2550 protected:
2551 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2552 bool opaque_layers)
2553 : OcclusionTrackerTest<Types>(opaque_layers) {}
2554 void RunMyTest() {
2555 gfx::Transform transform;
2556 transform.Translate(50.0, 50.0);
2557 transform.ApplyPerspectiveDepth(100.0);
2558 transform.Translate3d(0.0, 0.0, 110.0);
2559 transform.Translate(-50.0, -50.0);
2561 typename Types::ContentLayerType* parent = this->CreateRoot(
2562 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2563 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2564 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2565 parent->SetPreserves3d(true);
2566 layer->SetPreserves3d(true);
2567 this->CalcDrawEtc(parent);
2569 TestOcclusionTrackerWithClip<typename Types::LayerType,
2570 typename Types::RenderSurfaceType> occlusion(
2571 gfx::Rect(0, 0, 1000, 1000));
2573 // The |layer| is entirely behind the camera and should not occlude.
2574 this->VisitLayer(layer, &occlusion);
2575 this->EnterLayer(parent, &occlusion, false);
2576 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2577 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2581 // This test requires accumulating occlusion of 3d layers, which are skipped by
2582 // the occlusion tracker on the main thread. So this test should run on the impl
2583 // thread.
2584 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2586 template <class Types>
2587 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2588 : public OcclusionTrackerTest<Types> {
2589 protected:
2590 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2591 bool opaque_layers)
2592 : OcclusionTrackerTest<Types>(opaque_layers) {}
2593 void RunMyTest() {
2594 gfx::Transform transform;
2595 transform.Translate(50.0, 50.0);
2596 transform.ApplyPerspectiveDepth(100.0);
2597 transform.Translate3d(0.0, 0.0, 99.0);
2598 transform.Translate(-50.0, -50.0);
2600 typename Types::ContentLayerType* parent = this->CreateRoot(
2601 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2602 parent->SetMasksToBounds(true);
2603 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2604 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2605 parent->SetPreserves3d(true);
2606 layer->SetPreserves3d(true);
2607 this->CalcDrawEtc(parent);
2609 TestOcclusionTrackerWithClip<typename Types::LayerType,
2610 typename Types::RenderSurfaceType> occlusion(
2611 gfx::Rect(0, 0, 1000, 1000));
2613 // This is very close to the camera, so pixels in its visible_content_rect()
2614 // will actually go outside of the layer's clip rect. Ensure that those
2615 // pixels don't occlude things outside the clip rect.
2616 this->VisitLayer(layer, &occlusion);
2617 this->EnterLayer(parent, &occlusion, false);
2618 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2619 occlusion.occlusion_from_inside_target().ToString());
2620 EXPECT_EQ(gfx::Rect().ToString(),
2621 occlusion.occlusion_from_outside_target().ToString());
2625 // This test requires accumulating occlusion of 3d layers, which are skipped by
2626 // the occlusion tracker on the main thread. So this test should run on the impl
2627 // thread.
2628 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2630 template <class Types>
2631 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2632 : public OcclusionTrackerTest<Types> {
2633 protected:
2634 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
2635 : OcclusionTrackerTest<Types>(opaque_layers) {}
2636 void RunMyTest() {
2637 // parent
2638 // +--layer
2639 // +--surface
2640 // | +--surface_child
2641 // | +--surface_child2
2642 // +--parent2
2643 // +--topmost
2645 typename Types::ContentLayerType* parent = this->CreateRoot(
2646 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2647 typename Types::ContentLayerType* layer =
2648 this->CreateDrawingLayer(parent,
2649 this->identity_matrix,
2650 gfx::PointF(),
2651 gfx::Size(300, 300),
2652 true);
2653 typename Types::ContentLayerType* surface =
2654 this->CreateDrawingSurface(parent,
2655 this->identity_matrix,
2656 gfx::PointF(),
2657 gfx::Size(300, 300),
2658 true);
2659 typename Types::ContentLayerType* surface_child =
2660 this->CreateDrawingLayer(surface,
2661 this->identity_matrix,
2662 gfx::PointF(),
2663 gfx::Size(200, 300),
2664 true);
2665 typename Types::ContentLayerType* surface_child2 =
2666 this->CreateDrawingLayer(surface,
2667 this->identity_matrix,
2668 gfx::PointF(),
2669 gfx::Size(100, 300),
2670 true);
2671 typename Types::ContentLayerType* parent2 =
2672 this->CreateDrawingLayer(parent,
2673 this->identity_matrix,
2674 gfx::PointF(),
2675 gfx::Size(300, 300),
2676 false);
2677 typename Types::ContentLayerType* topmost =
2678 this->CreateDrawingLayer(parent,
2679 this->identity_matrix,
2680 gfx::PointF(250.f, 0.f),
2681 gfx::Size(50, 300),
2682 true);
2684 AddOpacityTransitionToController(
2685 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2686 AddOpacityTransitionToController(
2687 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2688 this->CalcDrawEtc(parent);
2690 EXPECT_TRUE(layer->draw_opacity_is_animating());
2691 EXPECT_FALSE(surface->draw_opacity_is_animating());
2692 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2694 TestOcclusionTrackerWithClip<typename Types::LayerType,
2695 typename Types::RenderSurfaceType> occlusion(
2696 gfx::Rect(0, 0, 1000, 1000));
2698 this->VisitLayer(topmost, &occlusion);
2699 this->EnterLayer(parent2, &occlusion, false);
2700 // This occlusion will affect all surfaces.
2701 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2702 occlusion.occlusion_from_inside_target().ToString());
2703 EXPECT_EQ(gfx::Rect().ToString(),
2704 occlusion.occlusion_from_outside_target().ToString());
2705 EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2706 occlusion.UnoccludedLayerContentRect(
2707 parent2, gfx::Rect(0, 0, 300, 300)).ToString());
2708 this->LeaveLayer(parent2, &occlusion);
2710 this->VisitLayer(surface_child2, &occlusion);
2711 this->EnterLayer(surface_child, &occlusion, false);
2712 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2713 occlusion.occlusion_from_inside_target().ToString());
2714 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2715 occlusion.occlusion_from_outside_target().ToString());
2716 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2717 occlusion.UnoccludedLayerContentRect(
2718 surface_child, gfx::Rect(0, 0, 200, 300)));
2719 this->LeaveLayer(surface_child, &occlusion);
2720 this->EnterLayer(surface, &occlusion, false);
2721 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2722 occlusion.occlusion_from_inside_target().ToString());
2723 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2724 occlusion.occlusion_from_outside_target().ToString());
2725 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2726 occlusion.UnoccludedLayerContentRect(
2727 surface, gfx::Rect(0, 0, 300, 300)));
2728 this->LeaveLayer(surface, &occlusion);
2730 this->EnterContributingSurface(surface, &occlusion, false);
2731 // Occlusion within the surface is lost when leaving the animating surface.
2732 EXPECT_EQ(gfx::Rect().ToString(),
2733 occlusion.occlusion_from_inside_target().ToString());
2734 EXPECT_EQ(gfx::Rect().ToString(),
2735 occlusion.occlusion_from_outside_target().ToString());
2736 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2737 occlusion.UnoccludedContributingSurfaceContentRect(
2738 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
2739 this->LeaveContributingSurface(surface, &occlusion);
2741 // Occlusion from outside the animating surface still exists.
2742 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2743 occlusion.occlusion_from_inside_target().ToString());
2744 EXPECT_EQ(gfx::Rect().ToString(),
2745 occlusion.occlusion_from_outside_target().ToString());
2747 this->VisitLayer(layer, &occlusion);
2748 this->EnterLayer(parent, &occlusion, false);
2750 // Occlusion is not added for the animating |layer|.
2751 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2752 occlusion.UnoccludedLayerContentRect(
2753 parent, gfx::Rect(0, 0, 300, 300)));
2757 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2759 template <class Types>
2760 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2761 : public OcclusionTrackerTest<Types> {
2762 protected:
2763 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
2764 : OcclusionTrackerTest<Types>(opaque_layers) {}
2765 void RunMyTest() {
2766 typename Types::ContentLayerType* parent = this->CreateRoot(
2767 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2768 typename Types::ContentLayerType* layer =
2769 this->CreateDrawingLayer(parent,
2770 this->identity_matrix,
2771 gfx::PointF(),
2772 gfx::Size(300, 300),
2773 true);
2774 typename Types::ContentLayerType* surface =
2775 this->CreateDrawingSurface(parent,
2776 this->identity_matrix,
2777 gfx::PointF(),
2778 gfx::Size(300, 300),
2779 true);
2780 typename Types::ContentLayerType* surface_child =
2781 this->CreateDrawingLayer(surface,
2782 this->identity_matrix,
2783 gfx::PointF(),
2784 gfx::Size(200, 300),
2785 true);
2786 typename Types::ContentLayerType* surface_child2 =
2787 this->CreateDrawingLayer(surface,
2788 this->identity_matrix,
2789 gfx::PointF(),
2790 gfx::Size(100, 300),
2791 true);
2792 typename Types::ContentLayerType* parent2 =
2793 this->CreateDrawingLayer(parent,
2794 this->identity_matrix,
2795 gfx::PointF(),
2796 gfx::Size(300, 300),
2797 false);
2798 typename Types::ContentLayerType* topmost =
2799 this->CreateDrawingLayer(parent,
2800 this->identity_matrix,
2801 gfx::PointF(250.f, 0.f),
2802 gfx::Size(50, 300),
2803 true);
2805 AddOpacityTransitionToController(
2806 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2807 AddOpacityTransitionToController(
2808 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2809 this->CalcDrawEtc(parent);
2811 EXPECT_TRUE(layer->draw_opacity_is_animating());
2812 EXPECT_FALSE(surface->draw_opacity_is_animating());
2813 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2815 TestOcclusionTrackerWithClip<typename Types::LayerType,
2816 typename Types::RenderSurfaceType> occlusion(
2817 gfx::Rect(0, 0, 1000, 1000));
2819 this->VisitLayer(topmost, &occlusion);
2820 this->EnterLayer(parent2, &occlusion, false);
2821 // This occlusion will affect all surfaces.
2822 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2823 occlusion.occlusion_from_inside_target().ToString());
2824 EXPECT_EQ(gfx::Rect().ToString(),
2825 occlusion.occlusion_from_outside_target().ToString());
2826 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2827 occlusion.UnoccludedLayerContentRect(
2828 parent, gfx::Rect(0, 0, 300, 300)));
2829 this->LeaveLayer(parent2, &occlusion);
2831 this->VisitLayer(surface_child2, &occlusion);
2832 this->EnterLayer(surface_child, &occlusion, false);
2833 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2834 occlusion.occlusion_from_inside_target().ToString());
2835 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2836 occlusion.occlusion_from_outside_target().ToString());
2837 EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2838 occlusion.UnoccludedLayerContentRect(
2839 surface_child, gfx::Rect(0, 0, 200, 300)));
2840 this->LeaveLayer(surface_child, &occlusion);
2841 this->EnterLayer(surface, &occlusion, false);
2842 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2843 occlusion.occlusion_from_inside_target().ToString());
2844 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2845 occlusion.occlusion_from_outside_target().ToString());
2846 EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2847 occlusion.UnoccludedLayerContentRect(
2848 surface, gfx::Rect(0, 0, 300, 300)));
2849 this->LeaveLayer(surface, &occlusion);
2851 this->EnterContributingSurface(surface, &occlusion, false);
2852 // Occlusion within the surface is lost when leaving the animating surface.
2853 EXPECT_EQ(gfx::Rect().ToString(),
2854 occlusion.occlusion_from_inside_target().ToString());
2855 EXPECT_EQ(gfx::Rect().ToString(),
2856 occlusion.occlusion_from_outside_target().ToString());
2857 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2858 occlusion.UnoccludedContributingSurfaceContentRect(
2859 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
2860 this->LeaveContributingSurface(surface, &occlusion);
2862 // Occlusion from outside the animating surface still exists.
2863 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2864 occlusion.occlusion_from_inside_target().ToString());
2865 EXPECT_EQ(gfx::Rect().ToString(),
2866 occlusion.occlusion_from_outside_target().ToString());
2868 this->VisitLayer(layer, &occlusion);
2869 this->EnterLayer(parent, &occlusion, false);
2871 // Occlusion is not added for the animating |layer|.
2872 EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2873 occlusion.UnoccludedLayerContentRect(
2874 parent, gfx::Rect(0, 0, 300, 300)));
2878 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2880 template <class Types>
2881 class OcclusionTrackerTestAnimationTranslateOnMainThread
2882 : public OcclusionTrackerTest<Types> {
2883 protected:
2884 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2885 bool opaque_layers)
2886 : OcclusionTrackerTest<Types>(opaque_layers) {}
2887 void RunMyTest() {
2888 typename Types::ContentLayerType* parent = this->CreateRoot(
2889 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2890 typename Types::ContentLayerType* layer =
2891 this->CreateDrawingLayer(parent,
2892 this->identity_matrix,
2893 gfx::PointF(),
2894 gfx::Size(300, 300),
2895 true);
2896 typename Types::ContentLayerType* surface =
2897 this->CreateDrawingSurface(parent,
2898 this->identity_matrix,
2899 gfx::PointF(),
2900 gfx::Size(300, 300),
2901 true);
2902 typename Types::ContentLayerType* surface_child =
2903 this->CreateDrawingLayer(surface,
2904 this->identity_matrix,
2905 gfx::PointF(),
2906 gfx::Size(200, 300),
2907 true);
2908 typename Types::ContentLayerType* surface_child2 =
2909 this->CreateDrawingLayer(surface,
2910 this->identity_matrix,
2911 gfx::PointF(),
2912 gfx::Size(100, 300),
2913 true);
2914 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
2915 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
2917 AddAnimatedTransformToController(
2918 layer->layer_animation_controller(), 10.0, 30, 0);
2919 AddAnimatedTransformToController(
2920 surface->layer_animation_controller(), 10.0, 30, 0);
2921 AddAnimatedTransformToController(
2922 surface_child->layer_animation_controller(), 10.0, 30, 0);
2923 this->CalcDrawEtc(parent);
2925 EXPECT_TRUE(layer->draw_transform_is_animating());
2926 EXPECT_TRUE(layer->screen_space_transform_is_animating());
2927 EXPECT_TRUE(
2928 surface->render_surface()->target_surface_transforms_are_animating());
2929 EXPECT_TRUE(
2930 surface->render_surface()->screen_space_transforms_are_animating());
2931 // The surface owning layer doesn't animate against its own surface.
2932 EXPECT_FALSE(surface->draw_transform_is_animating());
2933 EXPECT_TRUE(surface->screen_space_transform_is_animating());
2934 EXPECT_TRUE(surface_child->draw_transform_is_animating());
2935 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
2937 TestOcclusionTrackerWithClip<typename Types::LayerType,
2938 typename Types::RenderSurfaceType> occlusion(
2939 gfx::Rect(0, 0, 1000, 1000));
2941 this->VisitLayer(surface2, &occlusion);
2942 this->EnterContributingSurface(surface2, &occlusion, false);
2944 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2945 occlusion.occlusion_from_inside_target().ToString());
2947 this->LeaveContributingSurface(surface2, &occlusion);
2948 this->EnterLayer(surface_child2, &occlusion, false);
2950 // surface_child2 is moving in screen space but not relative to its target,
2951 // so occlusion should happen in its target space only. It also means that
2952 // things occluding from outside the target (e.g. surface2) cannot occlude
2953 // this layer.
2954 EXPECT_EQ(gfx::Rect().ToString(),
2955 occlusion.occlusion_from_outside_target().ToString());
2957 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2958 occlusion.UnoccludedLayerContentRect(
2959 surface_child2, gfx::Rect(0, 0, 100, 300)));
2960 EXPECT_FALSE(
2961 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2963 this->LeaveLayer(surface_child2, &occlusion);
2964 this->EnterLayer(surface_child, &occlusion, false);
2965 EXPECT_FALSE(
2966 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300)));
2967 EXPECT_EQ(gfx::Rect().ToString(),
2968 occlusion.occlusion_from_outside_target().ToString());
2969 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2970 occlusion.occlusion_from_inside_target().ToString());
2971 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2972 occlusion.UnoccludedLayerContentRect(
2973 surface, gfx::Rect(0, 0, 300, 300)));
2975 // The surface_child is occluded by the surface_child2, but is moving
2976 // relative its target, so it can't be occluded.
2977 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2978 occlusion.UnoccludedLayerContentRect(
2979 surface_child, gfx::Rect(0, 0, 200, 300)));
2980 EXPECT_FALSE(
2981 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2983 this->LeaveLayer(surface_child, &occlusion);
2984 this->EnterLayer(surface, &occlusion, false);
2985 // The surface_child is moving in screen space but not relative to its
2986 // target, so occlusion should happen from within the target only.
2987 EXPECT_EQ(gfx::Rect().ToString(),
2988 occlusion.occlusion_from_outside_target().ToString());
2989 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2990 occlusion.occlusion_from_inside_target().ToString());
2991 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2992 occlusion.UnoccludedLayerContentRect(
2993 surface, gfx::Rect(0, 0, 300, 300)));
2995 this->LeaveLayer(surface, &occlusion);
2996 // The surface's owning layer is moving in screen space but not relative to
2997 // its target, so occlusion should happen within the target only.
2998 EXPECT_EQ(gfx::Rect().ToString(),
2999 occlusion.occlusion_from_outside_target().ToString());
3000 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
3001 occlusion.occlusion_from_inside_target().ToString());
3002 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3003 occlusion.UnoccludedLayerContentRect(
3004 surface, gfx::Rect(0, 0, 300, 300)));
3006 this->EnterContributingSurface(surface, &occlusion, false);
3007 // The contributing |surface| is animating so it can't be occluded.
3008 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
3009 occlusion.UnoccludedContributingSurfaceContentRect(
3010 surface, false, gfx::Rect(0, 0, 300, 300), NULL));
3011 this->LeaveContributingSurface(surface, &occlusion);
3013 this->EnterLayer(layer, &occlusion, false);
3014 // The |surface| is moving in the screen and in its target, so all occlusion
3015 // within the surface is lost when leaving it.
3016 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3017 occlusion.UnoccludedLayerContentRect(
3018 parent, gfx::Rect(0, 0, 300, 300)));
3019 this->LeaveLayer(layer, &occlusion);
3021 this->EnterLayer(parent, &occlusion, false);
3022 // The |layer| is animating in the screen and in its target, so no occlusion
3023 // is added.
3024 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
3025 occlusion.UnoccludedLayerContentRect(
3026 parent, gfx::Rect(0, 0, 300, 300)));
3030 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
3032 template <class Types>
3033 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
3034 : public OcclusionTrackerTest<Types> {
3035 protected:
3036 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
3037 bool opaque_layers)
3038 : OcclusionTrackerTest<Types>(opaque_layers) {}
3039 void RunMyTest() {
3040 gfx::Transform surface_transform;
3041 surface_transform.Translate(300.0, 300.0);
3042 surface_transform.Scale(2.0, 2.0);
3043 surface_transform.Translate(-150.0, -150.0);
3045 typename Types::ContentLayerType* parent = this->CreateRoot(
3046 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
3047 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
3048 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
3049 typename Types::ContentLayerType* surface2 =
3050 this->CreateDrawingSurface(parent,
3051 this->identity_matrix,
3052 gfx::PointF(50.f, 50.f),
3053 gfx::Size(300, 300),
3054 false);
3055 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3056 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
3057 this->CalcDrawEtc(parent);
3059 TestOcclusionTrackerWithClip<typename Types::LayerType,
3060 typename Types::RenderSurfaceType> occlusion(
3061 gfx::Rect(0, 0, 1000, 1000));
3063 this->VisitLayer(surface2, &occlusion);
3064 this->VisitContributingSurface(surface2, &occlusion);
3066 EXPECT_EQ(gfx::Rect().ToString(),
3067 occlusion.occlusion_from_outside_target().ToString());
3068 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
3069 occlusion.occlusion_from_inside_target().ToString());
3071 // Clear any stored occlusion.
3072 occlusion.set_occlusion_from_outside_target(Region());
3073 occlusion.set_occlusion_from_inside_target(Region());
3075 this->VisitLayer(surface, &occlusion);
3076 this->VisitContributingSurface(surface, &occlusion);
3078 EXPECT_EQ(gfx::Rect().ToString(),
3079 occlusion.occlusion_from_outside_target().ToString());
3080 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
3081 occlusion.occlusion_from_inside_target().ToString());
3085 MAIN_AND_IMPL_THREAD_TEST(
3086 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
3088 template <class Types>
3089 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
3090 : public OcclusionTrackerTest<Types> {
3091 protected:
3092 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
3093 bool opaque_layers)
3094 : OcclusionTrackerTest<Types>(opaque_layers) {}
3095 void RunMyTest() {
3096 typename Types::ContentLayerType* parent = this->CreateRoot(
3097 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
3098 parent->SetMasksToBounds(true);
3099 typename Types::ContentLayerType* surface =
3100 this->CreateDrawingSurface(parent,
3101 this->identity_matrix,
3102 gfx::PointF(),
3103 gfx::Size(500, 300),
3104 false);
3105 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
3106 this->CalcDrawEtc(parent);
3108 TestOcclusionTrackerWithClip<typename Types::LayerType,
3109 typename Types::RenderSurfaceType> occlusion(
3110 gfx::Rect(0, 0, 1000, 1000));
3112 this->VisitLayer(surface, &occlusion);
3113 this->VisitContributingSurface(surface, &occlusion);
3115 EXPECT_EQ(gfx::Rect().ToString(),
3116 occlusion.occlusion_from_outside_target().ToString());
3117 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
3118 occlusion.occlusion_from_inside_target().ToString());
3122 MAIN_AND_IMPL_THREAD_TEST(
3123 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
3125 template <class Types>
3126 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
3127 protected:
3128 explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
3129 : OcclusionTrackerTest<Types>(opaque_layers) {}
3130 void RunMyTest() {
3131 typename Types::ContentLayerType* parent = this->CreateRoot(
3132 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3133 typename Types::LayerType* surface =
3134 this->CreateDrawingSurface(parent,
3135 this->identity_matrix,
3136 gfx::PointF(),
3137 gfx::Size(100, 100),
3138 true);
3139 this->CreateReplicaLayer(surface,
3140 this->identity_matrix,
3141 gfx::PointF(0.f, 100.f),
3142 gfx::Size(100, 100));
3143 typename Types::LayerType* topmost =
3144 this->CreateDrawingLayer(parent,
3145 this->identity_matrix,
3146 gfx::PointF(0.f, 100.f),
3147 gfx::Size(100, 100),
3148 true);
3149 this->CalcDrawEtc(parent);
3151 TestOcclusionTrackerWithClip<typename Types::LayerType,
3152 typename Types::RenderSurfaceType> occlusion(
3153 gfx::Rect(0, 0, 1000, 1000));
3155 // |topmost| occludes the replica, but not the surface itself.
3156 this->VisitLayer(topmost, &occlusion);
3158 EXPECT_EQ(gfx::Rect().ToString(),
3159 occlusion.occlusion_from_outside_target().ToString());
3160 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3161 occlusion.occlusion_from_inside_target().ToString());
3163 this->VisitLayer(surface, &occlusion);
3165 EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
3166 occlusion.occlusion_from_outside_target().ToString());
3167 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3168 occlusion.occlusion_from_inside_target().ToString());
3170 this->EnterContributingSurface(surface, &occlusion, false);
3172 // Surface is not occluded so it shouldn't think it is.
3173 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3174 occlusion.UnoccludedContributingSurfaceContentRect(
3175 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3179 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
3181 template <class Types>
3182 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
3183 : public OcclusionTrackerTest<Types> {
3184 protected:
3185 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
3186 : OcclusionTrackerTest<Types>(opaque_layers) {}
3187 void RunMyTest() {
3188 typename Types::ContentLayerType* parent = this->CreateRoot(
3189 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3190 typename Types::LayerType* surface =
3191 this->CreateDrawingSurface(parent,
3192 this->identity_matrix,
3193 gfx::PointF(),
3194 gfx::Size(100, 100),
3195 true);
3196 this->CreateReplicaLayer(surface,
3197 this->identity_matrix,
3198 gfx::PointF(0.f, 100.f),
3199 gfx::Size(100, 100));
3200 typename Types::LayerType* topmost =
3201 this->CreateDrawingLayer(parent,
3202 this->identity_matrix,
3203 gfx::PointF(),
3204 gfx::Size(100, 110),
3205 true);
3206 this->CalcDrawEtc(parent);
3208 TestOcclusionTrackerWithClip<typename Types::LayerType,
3209 typename Types::RenderSurfaceType> occlusion(
3210 gfx::Rect(0, 0, 1000, 1000));
3212 // |topmost| occludes the surface, but not the entire surface's replica.
3213 this->VisitLayer(topmost, &occlusion);
3215 EXPECT_EQ(gfx::Rect().ToString(),
3216 occlusion.occlusion_from_outside_target().ToString());
3217 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3218 occlusion.occlusion_from_inside_target().ToString());
3220 this->VisitLayer(surface, &occlusion);
3222 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
3223 occlusion.occlusion_from_outside_target().ToString());
3224 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3225 occlusion.occlusion_from_inside_target().ToString());
3227 this->EnterContributingSurface(surface, &occlusion, false);
3229 // Surface is occluded, but only the top 10px of the replica.
3230 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3231 occlusion.UnoccludedContributingSurfaceContentRect(
3232 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3233 EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
3234 occlusion.UnoccludedContributingSurfaceContentRect(
3235 surface, true, gfx::Rect(0, 0, 100, 100), NULL));
3239 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
3241 template <class Types>
3242 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
3243 : public OcclusionTrackerTest<Types> {
3244 protected:
3245 explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
3246 bool opaque_layers)
3247 : OcclusionTrackerTest<Types>(opaque_layers) {}
3248 void RunMyTest() {
3249 typename Types::ContentLayerType* parent = this->CreateRoot(
3250 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3251 typename Types::LayerType* surface =
3252 this->CreateDrawingSurface(parent,
3253 this->identity_matrix,
3254 gfx::PointF(),
3255 gfx::Size(100, 100),
3256 true);
3257 this->CreateReplicaLayer(surface,
3258 this->identity_matrix,
3259 gfx::PointF(0.f, 100.f),
3260 gfx::Size(100, 100));
3261 typename Types::LayerType* over_surface = this->CreateDrawingLayer(
3262 parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
3263 typename Types::LayerType* over_replica =
3264 this->CreateDrawingLayer(parent,
3265 this->identity_matrix,
3266 gfx::PointF(0.f, 100.f),
3267 gfx::Size(50, 100),
3268 true);
3269 this->CalcDrawEtc(parent);
3271 TestOcclusionTrackerWithClip<typename Types::LayerType,
3272 typename Types::RenderSurfaceType> occlusion(
3273 gfx::Rect(0, 0, 1000, 1000));
3275 // These occlude the surface and replica differently, so we can test each
3276 // one.
3277 this->VisitLayer(over_replica, &occlusion);
3278 this->VisitLayer(over_surface, &occlusion);
3280 EXPECT_EQ(gfx::Rect().ToString(),
3281 occlusion.occlusion_from_outside_target().ToString());
3282 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3283 .ToString(),
3284 occlusion.occlusion_from_inside_target().ToString());
3286 this->VisitLayer(surface, &occlusion);
3288 EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
3289 .ToString(),
3290 occlusion.occlusion_from_outside_target().ToString());
3291 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
3292 occlusion.occlusion_from_inside_target().ToString());
3294 this->EnterContributingSurface(surface, &occlusion, false);
3296 // Surface and replica are occluded different amounts.
3297 EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
3298 occlusion.UnoccludedContributingSurfaceContentRect(
3299 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3300 EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
3301 occlusion.UnoccludedContributingSurfaceContentRect(
3302 surface, true, gfx::Rect(0, 0, 100, 100), NULL));
3306 ALL_OCCLUSIONTRACKER_TEST(
3307 OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
3309 template <class Types>
3310 class OcclusionTrackerTestSurfaceChildOfSurface
3311 : public OcclusionTrackerTest<Types> {
3312 protected:
3313 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
3314 : OcclusionTrackerTest<Types>(opaque_layers) {}
3315 void RunMyTest() {
3316 // This test verifies that the surface cliprect does not end up empty and
3317 // clip away the entire unoccluded rect.
3319 typename Types::ContentLayerType* parent = this->CreateRoot(
3320 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3321 typename Types::LayerType* surface =
3322 this->CreateDrawingSurface(parent,
3323 this->identity_matrix,
3324 gfx::PointF(),
3325 gfx::Size(100, 100),
3326 true);
3327 typename Types::LayerType* surface_child =
3328 this->CreateDrawingSurface(surface,
3329 this->identity_matrix,
3330 gfx::PointF(0.f, 10.f),
3331 gfx::Size(100, 50),
3332 true);
3333 typename Types::LayerType* topmost = this->CreateDrawingLayer(
3334 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3335 this->CalcDrawEtc(parent);
3337 TestOcclusionTrackerWithClip<typename Types::LayerType,
3338 typename Types::RenderSurfaceType> occlusion(
3339 gfx::Rect(-100, -100, 1000, 1000));
3341 // |topmost| occludes everything partially so we know occlusion is happening
3342 // at all.
3343 this->VisitLayer(topmost, &occlusion);
3345 EXPECT_EQ(gfx::Rect().ToString(),
3346 occlusion.occlusion_from_outside_target().ToString());
3347 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3348 occlusion.occlusion_from_inside_target().ToString());
3350 this->VisitLayer(surface_child, &occlusion);
3352 // surface_child increases the occlusion in the screen by a narrow sliver.
3353 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
3354 occlusion.occlusion_from_outside_target().ToString());
3355 // In its own surface, surface_child is at 0,0 as is its occlusion.
3356 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3357 occlusion.occlusion_from_inside_target().ToString());
3359 // The root layer always has a clip rect. So the parent of |surface| has a
3360 // clip rect. However, the owning layer for |surface| does not mask to
3361 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3362 // |surface_child| exercises different code paths as its parent does not
3363 // have a clip rect.
3365 this->EnterContributingSurface(surface_child, &occlusion, false);
3366 // The surface_child's parent does not have a clip rect as it owns a render
3367 // surface. Make sure the unoccluded rect does not get clipped away
3368 // inappropriately.
3369 EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
3370 occlusion.UnoccludedContributingSurfaceContentRect(
3371 surface_child, false, gfx::Rect(0, 0, 100, 50), NULL));
3372 this->LeaveContributingSurface(surface_child, &occlusion);
3374 // When the surface_child's occlusion is transformed up to its parent, make
3375 // sure it is not clipped away inappropriately also.
3376 this->EnterLayer(surface, &occlusion, false);
3377 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
3378 occlusion.occlusion_from_outside_target().ToString());
3379 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
3380 occlusion.occlusion_from_inside_target().ToString());
3381 this->LeaveLayer(surface, &occlusion);
3383 this->EnterContributingSurface(surface, &occlusion, false);
3384 // The surface's parent does have a clip rect as it is the root layer.
3385 EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
3386 occlusion.UnoccludedContributingSurfaceContentRect(
3387 surface, false, gfx::Rect(0, 0, 100, 100), NULL));
3391 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
3393 template <class Types>
3394 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
3395 : public OcclusionTrackerTest<Types> {
3396 protected:
3397 explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
3398 bool opaque_layers)
3399 : OcclusionTrackerTest<Types>(opaque_layers) {}
3400 void RunMyTest() {
3401 // This test verifies that the top-most surface is considered occluded
3402 // outside of its target's clip rect and outside the viewport rect.
3404 typename Types::ContentLayerType* parent = this->CreateRoot(
3405 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
3406 typename Types::LayerType* surface =
3407 this->CreateDrawingSurface(parent,
3408 this->identity_matrix,
3409 gfx::PointF(),
3410 gfx::Size(100, 300),
3411 true);
3412 this->CalcDrawEtc(parent);
3414 // Make a viewport rect that is larger than the root layer.
3415 TestOcclusionTrackerWithClip<typename Types::LayerType,
3416 typename Types::RenderSurfaceType> occlusion(
3417 gfx::Rect(0, 0, 1000, 1000));
3419 this->VisitLayer(surface, &occlusion);
3421 // The root layer always has a clip rect. So the parent of |surface| has a
3422 // clip rect giving the surface itself a clip rect.
3423 this->EnterContributingSurface(surface, &occlusion, false);
3424 // Make sure the parent's clip rect clips the unoccluded region of the
3425 // child surface.
3426 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
3427 occlusion.UnoccludedContributingSurfaceContentRect(
3428 surface, false, gfx::Rect(0, 0, 100, 300), NULL));
3430 this->ResetLayerIterator();
3432 // Make a viewport rect that is smaller than the root layer.
3433 TestOcclusionTrackerWithClip<typename Types::LayerType,
3434 typename Types::RenderSurfaceType> occlusion(
3435 gfx::Rect(0, 0, 100, 100));
3437 this->VisitLayer(surface, &occlusion);
3439 // The root layer always has a clip rect. So the parent of |surface| has a
3440 // clip rect giving the surface itself a clip rect.
3441 this->EnterContributingSurface(surface, &occlusion, false);
3442 // Make sure the viewport rect clips the unoccluded region of the child
3443 // surface.
3444 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3445 occlusion.UnoccludedContributingSurfaceContentRect(
3446 surface, false, gfx::Rect(0, 0, 100, 300), NULL));
3451 ALL_OCCLUSIONTRACKER_TEST(
3452 OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
3454 template <class Types>
3455 class OcclusionTrackerTestSurfaceChildOfClippingSurface
3456 : public OcclusionTrackerTest<Types> {
3457 protected:
3458 explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers)
3459 : OcclusionTrackerTest<Types>(opaque_layers) {}
3460 void RunMyTest() {
3461 // This test verifies that the surface cliprect does not end up empty and
3462 // clip away the entire unoccluded rect.
3464 typename Types::ContentLayerType* parent = this->CreateRoot(
3465 this->identity_matrix, gfx::PointF(), gfx::Size(80, 200));
3466 parent->SetMasksToBounds(true);
3467 typename Types::LayerType* surface =
3468 this->CreateDrawingSurface(parent,
3469 this->identity_matrix,
3470 gfx::PointF(),
3471 gfx::Size(100, 100),
3472 true);
3473 typename Types::LayerType* surface_child =
3474 this->CreateDrawingSurface(surface,
3475 this->identity_matrix,
3476 gfx::PointF(),
3477 gfx::Size(100, 100),
3478 false);
3479 typename Types::LayerType* topmost = this->CreateDrawingLayer(
3480 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3481 this->CalcDrawEtc(parent);
3483 TestOcclusionTrackerWithClip<typename Types::LayerType,
3484 typename Types::RenderSurfaceType> occlusion(
3485 gfx::Rect(0, 0, 1000, 1000));
3487 // |topmost| occludes everything partially so we know occlusion is happening
3488 // at all.
3489 this->VisitLayer(topmost, &occlusion);
3491 EXPECT_EQ(gfx::Rect().ToString(),
3492 occlusion.occlusion_from_outside_target().ToString());
3493 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3494 occlusion.occlusion_from_inside_target().ToString());
3496 // surface_child is not opaque and does not occlude, so we have a non-empty
3497 // unoccluded area on surface.
3498 this->VisitLayer(surface_child, &occlusion);
3500 EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3501 occlusion.occlusion_from_outside_target().ToString());
3502 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3503 occlusion.occlusion_from_inside_target().ToString());
3505 // The root layer always has a clip rect. So the parent of |surface| has a
3506 // clip rect. However, the owning layer for |surface| does not mask to
3507 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3508 // |surface_child| exercises different code paths as its parent does not
3509 // have a clip rect.
3511 this->EnterContributingSurface(surface_child, &occlusion, false);
3512 // The surface_child's parent does not have a clip rect as it owns a render
3513 // surface.
3514 EXPECT_EQ(
3515 gfx::Rect(0, 50, 80, 50).ToString(),
3516 occlusion.UnoccludedContributingSurfaceContentRect(
3517 surface_child, false, gfx::Rect(0, 0, 100, 100), NULL).ToString());
3518 this->LeaveContributingSurface(surface_child, &occlusion);
3520 this->VisitLayer(surface, &occlusion);
3521 this->EnterContributingSurface(surface, &occlusion, false);
3522 // The surface's parent does have a clip rect as it is the root layer.
3523 EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3524 occlusion.UnoccludedContributingSurfaceContentRect(
3525 surface, false, gfx::Rect(0, 0, 100, 100), NULL).ToString());
3529 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
3531 template <class Types>
3532 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3533 : public OcclusionTrackerTest<Types> {
3534 protected:
3535 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3536 bool opaque_layers)
3537 : OcclusionTrackerTest<Types>(opaque_layers) {}
3538 void RunMyTest() {
3539 gfx::Transform scale_by_half;
3540 scale_by_half.Scale(0.5, 0.5);
3542 // Make a surface and its replica, each 50x50, that are completely
3543 // surrounded by opaque layers which are above them in the z-order. The
3544 // surface is scaled to test that the pixel moving is done in the target
3545 // space, where the background filter is applied, but the surface appears at
3546 // 50, 50 and the replica at 200, 50.
3547 typename Types::ContentLayerType* parent = this->CreateRoot(
3548 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3549 typename Types::LayerType* filtered_surface =
3550 this->CreateDrawingLayer(parent,
3551 scale_by_half,
3552 gfx::PointF(50.f, 50.f),
3553 gfx::Size(100, 100),
3554 false);
3555 this->CreateReplicaLayer(filtered_surface,
3556 this->identity_matrix,
3557 gfx::PointF(300.f, 0.f),
3558 gfx::Size());
3559 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3560 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
3561 typename Types::LayerType* occluding_layer2 =
3562 this->CreateDrawingLayer(parent,
3563 this->identity_matrix,
3564 gfx::PointF(0.f, 100.f),
3565 gfx::Size(300, 50),
3566 true);
3567 typename Types::LayerType* occluding_layer3 =
3568 this->CreateDrawingLayer(parent,
3569 this->identity_matrix,
3570 gfx::PointF(0.f, 50.f),
3571 gfx::Size(50, 50),
3572 true);
3573 typename Types::LayerType* occluding_layer4 =
3574 this->CreateDrawingLayer(parent,
3575 this->identity_matrix,
3576 gfx::PointF(100.f, 50.f),
3577 gfx::Size(100, 50),
3578 true);
3579 typename Types::LayerType* occluding_layer5 =
3580 this->CreateDrawingLayer(parent,
3581 this->identity_matrix,
3582 gfx::PointF(250.f, 50.f),
3583 gfx::Size(50, 50),
3584 true);
3586 // Filters make the layer own a surface.
3587 FilterOperations filters;
3588 filters.Append(FilterOperation::CreateBlurFilter(10.f));
3589 filtered_surface->SetBackgroundFilters(filters);
3591 // Save the distance of influence for the blur effect.
3592 int outset_top, outset_right, outset_bottom, outset_left;
3593 filters.GetOutsets(
3594 &outset_top, &outset_right, &outset_bottom, &outset_left);
3596 this->CalcDrawEtc(parent);
3598 TestOcclusionTrackerWithClip<typename Types::LayerType,
3599 typename Types::RenderSurfaceType> occlusion(
3600 gfx::Rect(0, 0, 1000, 1000));
3602 // These layers occlude pixels directly beside the filtered_surface. Because
3603 // filtered surface blends pixels in a radius, it will need to see some of
3604 // the pixels (up to radius far) underneath the occluding layers.
3605 this->VisitLayer(occluding_layer5, &occlusion);
3606 this->VisitLayer(occluding_layer4, &occlusion);
3607 this->VisitLayer(occluding_layer3, &occlusion);
3608 this->VisitLayer(occluding_layer2, &occlusion);
3609 this->VisitLayer(occluding_layer1, &occlusion);
3611 Region expected_occlusion;
3612 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
3613 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3614 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3615 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
3616 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));
3618 EXPECT_EQ(expected_occlusion.ToString(),
3619 occlusion.occlusion_from_inside_target().ToString());
3620 EXPECT_EQ(gfx::Rect().ToString(),
3621 occlusion.occlusion_from_outside_target().ToString());
3623 this->VisitLayer(filtered_surface, &occlusion);
3625 // The filtered layer/replica does not occlude.
3626 Region expected_occlusion_outside_surface;
3627 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
3628 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3629 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3630 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
3631 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));
3633 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3634 occlusion.occlusion_from_outside_target().ToString());
3635 EXPECT_EQ(gfx::Rect().ToString(),
3636 occlusion.occlusion_from_inside_target().ToString());
3638 // The surface has a background blur, so it needs pixels that are currently
3639 // considered occluded in order to be drawn. So the pixels it needs should
3640 // be removed some the occluded area so that when we get to the parent they
3641 // are drawn.
3642 this->VisitContributingSurface(filtered_surface, &occlusion);
3644 this->EnterLayer(parent, &occlusion, false);
3646 Region expected_blurred_occlusion;
3647 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
3648 expected_blurred_occlusion.Union(gfx::Rect(
3649 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
3650 expected_blurred_occlusion.Union(
3651 gfx::Rect(100 + outset_right,
3652 50 - outset_top,
3653 100 - outset_right - outset_left,
3654 50 + outset_top + outset_bottom));
3655 expected_blurred_occlusion.Union(
3656 gfx::Rect(250 + outset_right,
3657 50 - outset_top,
3658 50 - outset_right,
3659 50 + outset_top + outset_bottom));
3660 expected_blurred_occlusion.Union(
3661 gfx::Rect(0, 100 + outset_bottom, 300, 50 - outset_bottom));
3663 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3664 occlusion.occlusion_from_inside_target().ToString());
3665 EXPECT_EQ(gfx::Rect().ToString(),
3666 occlusion.occlusion_from_outside_target().ToString());
3668 gfx::Rect outset_rect;
3669 gfx::Rect test_rect;
3671 // Nothing in the blur outsets for the filtered_surface is occluded.
3672 outset_rect = gfx::Rect(50 - outset_left,
3673 50 - outset_top,
3674 50 + outset_left + outset_right,
3675 50 + outset_top + outset_bottom);
3676 test_rect = outset_rect;
3677 EXPECT_EQ(
3678 outset_rect.ToString(),
3679 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3681 // Stuff outside the blur outsets is still occluded though.
3682 test_rect = outset_rect;
3683 test_rect.Inset(0, 0, -1, 0);
3684 EXPECT_EQ(
3685 outset_rect.ToString(),
3686 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3687 test_rect = outset_rect;
3688 test_rect.Inset(0, 0, 0, -1);
3689 EXPECT_EQ(
3690 outset_rect.ToString(),
3691 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3692 test_rect = outset_rect;
3693 test_rect.Inset(-1, 0, 0, 0);
3694 EXPECT_EQ(
3695 outset_rect.ToString(),
3696 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3697 test_rect = outset_rect;
3698 test_rect.Inset(0, -1, 0, 0);
3699 EXPECT_EQ(
3700 outset_rect.ToString(),
3701 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3703 // Nothing in the blur outsets for the filtered_surface's replica is
3704 // occluded.
3705 outset_rect = gfx::Rect(200 - outset_left,
3706 50 - outset_top,
3707 50 + outset_left + outset_right,
3708 50 + outset_top + outset_bottom);
3709 test_rect = outset_rect;
3710 EXPECT_EQ(
3711 outset_rect.ToString(),
3712 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3714 // Stuff outside the blur outsets is still occluded though.
3715 test_rect = outset_rect;
3716 test_rect.Inset(0, 0, -1, 0);
3717 EXPECT_EQ(
3718 outset_rect.ToString(),
3719 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3720 test_rect = outset_rect;
3721 test_rect.Inset(0, 0, 0, -1);
3722 EXPECT_EQ(
3723 outset_rect.ToString(),
3724 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3725 test_rect = outset_rect;
3726 test_rect.Inset(-1, 0, 0, 0);
3727 EXPECT_EQ(
3728 outset_rect.ToString(),
3729 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3730 test_rect = outset_rect;
3731 test_rect.Inset(0, -1, 0, 0);
3732 EXPECT_EQ(
3733 outset_rect.ToString(),
3734 occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3738 ALL_OCCLUSIONTRACKER_TEST(
3739 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
3741 template <class Types>
3742 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3743 : public OcclusionTrackerTest<Types> {
3744 protected:
3745 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3746 bool opaque_layers)
3747 : OcclusionTrackerTest<Types>(opaque_layers) {}
3748 void RunMyTest() {
3749 gfx::Transform scale_by_half;
3750 scale_by_half.Scale(0.5, 0.5);
3752 // Makes two surfaces that completely cover |parent|. The occlusion both
3753 // above and below the filters will be reduced by each of them.
3754 typename Types::ContentLayerType* root = this->CreateRoot(
3755 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
3756 typename Types::LayerType* parent = this->CreateSurface(
3757 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
3758 parent->SetMasksToBounds(true);
3759 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
3760 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3761 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
3762 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3763 typename Types::LayerType* occluding_layer_above =
3764 this->CreateDrawingLayer(parent,
3765 this->identity_matrix,
3766 gfx::PointF(100.f, 100.f),
3767 gfx::Size(50, 50),
3768 true);
3770 // Filters make the layers own surfaces.
3771 FilterOperations filters;
3772 filters.Append(FilterOperation::CreateBlurFilter(1.f));
3773 filtered_surface1->SetBackgroundFilters(filters);
3774 filtered_surface2->SetBackgroundFilters(filters);
3776 // Save the distance of influence for the blur effect.
3777 int outset_top, outset_right, outset_bottom, outset_left;
3778 filters.GetOutsets(
3779 &outset_top, &outset_right, &outset_bottom, &outset_left);
3781 this->CalcDrawEtc(root);
3783 TestOcclusionTrackerWithClip<typename Types::LayerType,
3784 typename Types::RenderSurfaceType> occlusion(
3785 gfx::Rect(0, 0, 1000, 1000));
3787 this->VisitLayer(occluding_layer_above, &occlusion);
3788 EXPECT_EQ(gfx::Rect().ToString(),
3789 occlusion.occlusion_from_outside_target().ToString());
3790 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3791 occlusion.occlusion_from_inside_target().ToString());
3793 this->VisitLayer(filtered_surface2, &occlusion);
3794 this->VisitContributingSurface(filtered_surface2, &occlusion);
3795 this->VisitLayer(filtered_surface1, &occlusion);
3796 this->VisitContributingSurface(filtered_surface1, &occlusion);
3798 // Test expectations in the target.
3799 gfx::Rect expected_occlusion =
3800 gfx::Rect(100 / 2 + outset_right * 2,
3801 100 / 2 + outset_bottom * 2,
3802 50 / 2 - (outset_left + outset_right) * 2,
3803 50 / 2 - (outset_top + outset_bottom) * 2);
3804 EXPECT_EQ(expected_occlusion.ToString(),
3805 occlusion.occlusion_from_inside_target().ToString());
3807 // Test expectations in the screen are the same as in the target, as the
3808 // render surface is 1:1 with the screen.
3809 EXPECT_EQ(expected_occlusion.ToString(),
3810 occlusion.occlusion_from_outside_target().ToString());
3814 ALL_OCCLUSIONTRACKER_TEST(
3815 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
3817 template <class Types>
3818 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
3819 : public OcclusionTrackerTest<Types> {
3820 protected:
3821 explicit
3822 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(
3823 bool opaque_layers)
3824 : OcclusionTrackerTest<Types>(opaque_layers) {}
3825 void RunMyTest() {
3826 // Make a surface and its replica, Each 50x50, that are completely
3827 // surrounded by opaque layers which are above them in the z-order.
3828 typename Types::ContentLayerType* parent = this->CreateRoot(
3829 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3830 // We stick the filtered surface inside a clipping surface so that we can
3831 // make sure the clip is honored when exposing pixels for
3832 // the background filter.
3833 typename Types::LayerType* clipping_surface =
3834 this->CreateDrawingSurface(parent,
3835 this->identity_matrix,
3836 gfx::PointF(),
3837 gfx::Size(300, 70),
3838 false);
3839 clipping_surface->SetMasksToBounds(true);
3840 typename Types::LayerType* filtered_surface =
3841 this->CreateDrawingLayer(clipping_surface,
3842 this->identity_matrix,
3843 gfx::PointF(50.f, 50.f),
3844 gfx::Size(50, 50),
3845 false);
3846 this->CreateReplicaLayer(filtered_surface,
3847 this->identity_matrix,
3848 gfx::PointF(150.f, 0.f),
3849 gfx::Size());
3850 typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3851 parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
3852 typename Types::LayerType* occluding_layer2 =
3853 this->CreateDrawingLayer(parent,
3854 this->identity_matrix,
3855 gfx::PointF(0.f, 100.f),
3856 gfx::Size(300, 50),
3857 true);
3858 typename Types::LayerType* occluding_layer3 =
3859 this->CreateDrawingLayer(parent,
3860 this->identity_matrix,
3861 gfx::PointF(0.f, 50.f),
3862 gfx::Size(50, 50),
3863 true);
3864 typename Types::LayerType* occluding_layer4 =
3865 this->CreateDrawingLayer(parent,
3866 this->identity_matrix,
3867 gfx::PointF(100.f, 50.f),
3868 gfx::Size(100, 50),
3869 true);
3870 typename Types::LayerType* occluding_layer5 =
3871 this->CreateDrawingLayer(parent,
3872 this->identity_matrix,
3873 gfx::PointF(250.f, 50.f),
3874 gfx::Size(50, 50),
3875 true);
3877 // Filters make the layer own a surface. This filter is large enough that it
3878 // goes outside the bottom of the clipping_surface.
3879 FilterOperations filters;
3880 filters.Append(FilterOperation::CreateBlurFilter(12.f));
3881 filtered_surface->SetBackgroundFilters(filters);
3883 // Save the distance of influence for the blur effect.
3884 int outset_top, outset_right, outset_bottom, outset_left;
3885 filters.GetOutsets(
3886 &outset_top, &outset_right, &outset_bottom, &outset_left);
3888 this->CalcDrawEtc(parent);
3890 TestOcclusionTrackerWithClip<typename Types::LayerType,
3891 typename Types::RenderSurfaceType> occlusion(
3892 gfx::Rect(0, 0, 1000, 1000));
3894 // These layers occlude pixels directly beside the filtered_surface. Because
3895 // filtered surface blends pixels in a radius, it will need to see some of
3896 // the pixels (up to radius far) underneath the occluding layers.
3897 this->VisitLayer(occluding_layer5, &occlusion);
3898 this->VisitLayer(occluding_layer4, &occlusion);
3899 this->VisitLayer(occluding_layer3, &occlusion);
3900 this->VisitLayer(occluding_layer2, &occlusion);
3901 this->VisitLayer(occluding_layer1, &occlusion);
3903 Region expected_occlusion;
3904 expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
3905 expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3906 expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3907 expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
3908 expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));
3910 EXPECT_EQ(expected_occlusion.ToString(),
3911 occlusion.occlusion_from_inside_target().ToString());
3912 EXPECT_EQ(gfx::Rect().ToString(),
3913 occlusion.occlusion_from_outside_target().ToString());
3915 // Everything outside the surface/replica is occluded but the
3916 // surface/replica itself is not.
3917 this->VisitLayer(filtered_surface, &occlusion);
3919 // The filtered layer/replica does not occlude.
3920 Region expected_occlusion_outside_surface;
3921 expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
3922 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3923 expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3924 expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
3925 expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));
3927 EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3928 occlusion.occlusion_from_outside_target().ToString());
3929 EXPECT_EQ(gfx::Rect().ToString(),
3930 occlusion.occlusion_from_inside_target().ToString());
3932 // The surface has a background blur, so it needs pixels that are currently
3933 // considered occluded in order to be drawn. So the pixels it needs should
3934 // be removed some the occluded area so that when we get to the parent they
3935 // are drawn.
3936 this->VisitContributingSurface(filtered_surface, &occlusion);
3938 this->VisitLayer(clipping_surface, &occlusion);
3939 this->EnterContributingSurface(clipping_surface, &occlusion, false);
3941 Region expected_blurred_occlusion;
3942 expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
3943 expected_blurred_occlusion.Union(gfx::Rect(
3944 0, 50 - outset_top, 50 - outset_left, 20 + outset_top + outset_bottom));
3945 expected_blurred_occlusion.Union(
3946 gfx::Rect(100 + outset_right,
3947 50 - outset_top,
3948 100 - outset_right - outset_left,
3949 20 + outset_top + outset_bottom));
3950 expected_blurred_occlusion.Union(
3951 gfx::Rect(250 + outset_right,
3952 50 - outset_top,
3953 50 - outset_right,
3954 20 + outset_top + outset_bottom));
3955 expected_blurred_occlusion.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));
3957 EXPECT_EQ(expected_blurred_occlusion.ToString(),
3958 occlusion.occlusion_from_outside_target().ToString());
3959 EXPECT_EQ(gfx::Rect().ToString(),
3960 occlusion.occlusion_from_inside_target().ToString());
3962 gfx::Rect outset_rect;
3963 gfx::Rect clipped_outset_rect;
3964 gfx::Rect test_rect;
3966 // Nothing in the (clipped) blur outsets for the filtered_surface is
3967 // occluded.
3968 outset_rect = gfx::Rect(50 - outset_left,
3969 50 - outset_top,
3970 50 + outset_left + outset_right,
3971 50 + outset_top + outset_bottom);
3972 clipped_outset_rect = outset_rect;
3973 clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left,
3974 0 - outset_top,
3975 300 + outset_left + outset_right,
3976 70 + outset_top + outset_bottom));
3977 clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70));
3978 test_rect = outset_rect;
3979 EXPECT_RECT_EQ(
3980 clipped_outset_rect,
3981 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3983 // Stuff outside the (clipped) blur outsets is still occluded though.
3984 test_rect = outset_rect;
3985 test_rect.Inset(0, 0, -1, 0);
3986 EXPECT_RECT_EQ(
3987 clipped_outset_rect,
3988 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3989 test_rect = outset_rect;
3990 test_rect.Inset(0, 0, 0, -1);
3991 EXPECT_RECT_EQ(
3992 clipped_outset_rect,
3993 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3994 test_rect = outset_rect;
3995 test_rect.Inset(-1, 0, 0, 0);
3996 EXPECT_RECT_EQ(
3997 clipped_outset_rect,
3998 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
3999 test_rect = outset_rect;
4000 test_rect.Inset(0, -1, 0, 0);
4001 EXPECT_RECT_EQ(
4002 clipped_outset_rect,
4003 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4005 // Nothing in the (clipped) blur outsets for the filtered_surface's replica
4006 // is occluded.
4007 outset_rect = gfx::Rect(200 - outset_left,
4008 50 - outset_top,
4009 50 + outset_left + outset_right,
4010 50 + outset_top + outset_bottom);
4011 clipped_outset_rect = outset_rect;
4012 clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left,
4013 0 - outset_top,
4014 300 + outset_left + outset_right,
4015 70 + outset_top + outset_bottom));
4016 clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70));
4017 test_rect = outset_rect;
4018 EXPECT_RECT_EQ(
4019 clipped_outset_rect,
4020 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4022 // Stuff outside the (clipped) blur outsets is still occluded though.
4023 test_rect = outset_rect;
4024 test_rect.Inset(0, 0, -1, 0);
4025 EXPECT_RECT_EQ(
4026 clipped_outset_rect,
4027 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4028 test_rect = outset_rect;
4029 test_rect.Inset(0, 0, 0, -1);
4030 EXPECT_RECT_EQ(
4031 clipped_outset_rect,
4032 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4033 test_rect = outset_rect;
4034 test_rect.Inset(-1, 0, 0, 0);
4035 EXPECT_RECT_EQ(
4036 clipped_outset_rect,
4037 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4038 test_rect = outset_rect;
4039 test_rect.Inset(0, -1, 0, 0);
4040 EXPECT_RECT_EQ(
4041 clipped_outset_rect,
4042 occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
4046 ALL_OCCLUSIONTRACKER_TEST(
4047 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);
4049 template <class Types>
4050 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
4051 : public OcclusionTrackerTest<Types> {
4052 protected:
4053 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
4054 bool opaque_layers)
4055 : OcclusionTrackerTest<Types>(opaque_layers) {}
4056 void RunMyTest() {
4057 gfx::Transform scale_by_half;
4058 scale_by_half.Scale(0.5, 0.5);
4060 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
4061 // centered below each. The surface is scaled to test that the pixel moving
4062 // is done in the target space, where the background filter is applied, but
4063 // the surface appears at 50, 50 and the replica at 200, 50.
4064 typename Types::ContentLayerType* parent = this->CreateRoot(
4065 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4066 typename Types::LayerType* behind_surface_layer =
4067 this->CreateDrawingLayer(parent,
4068 this->identity_matrix,
4069 gfx::PointF(60.f, 60.f),
4070 gfx::Size(30, 30),
4071 true);
4072 typename Types::LayerType* behind_replica_layer =
4073 this->CreateDrawingLayer(parent,
4074 this->identity_matrix,
4075 gfx::PointF(210.f, 60.f),
4076 gfx::Size(30, 30),
4077 true);
4078 typename Types::LayerType* filtered_surface =
4079 this->CreateDrawingLayer(parent,
4080 scale_by_half,
4081 gfx::PointF(50.f, 50.f),
4082 gfx::Size(100, 100),
4083 false);
4084 this->CreateReplicaLayer(filtered_surface,
4085 this->identity_matrix,
4086 gfx::PointF(300.f, 0.f),
4087 gfx::Size());
4089 // Filters make the layer own a surface.
4090 FilterOperations filters;
4091 filters.Append(FilterOperation::CreateBlurFilter(3.f));
4092 filtered_surface->SetBackgroundFilters(filters);
4094 this->CalcDrawEtc(parent);
4096 TestOcclusionTrackerWithClip<typename Types::LayerType,
4097 typename Types::RenderSurfaceType> occlusion(
4098 gfx::Rect(0, 0, 1000, 1000));
4100 // The surface has a background blur, so it blurs non-opaque pixels below
4101 // it.
4102 this->VisitLayer(filtered_surface, &occlusion);
4103 this->VisitContributingSurface(filtered_surface, &occlusion);
4105 this->VisitLayer(behind_replica_layer, &occlusion);
4106 this->VisitLayer(behind_surface_layer, &occlusion);
4108 // The layers behind the surface are not blurred, and their occlusion does
4109 // not change, until we leave the surface. So it should not be modified by
4110 // the filter here.
4111 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
4112 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
4114 Region expected_opaque_bounds =
4115 UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
4116 EXPECT_EQ(expected_opaque_bounds.ToString(),
4117 occlusion.occlusion_from_inside_target().ToString());
4119 EXPECT_EQ(gfx::Rect().ToString(),
4120 occlusion.occlusion_from_outside_target().ToString());
4124 ALL_OCCLUSIONTRACKER_TEST(
4125 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
4127 template <class Types>
4128 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
4129 : public OcclusionTrackerTest<Types> {
4130 protected:
4131 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
4132 bool opaque_layers)
4133 : OcclusionTrackerTest<Types>(opaque_layers) {}
4134 void RunMyTest() {
4135 gfx::Transform scale_by_half;
4136 scale_by_half.Scale(0.5, 0.5);
4138 // Make a surface and its replica, each 50x50, that are completely occluded
4139 // by opaque layers which are above them in the z-order. The surface is
4140 // scaled to test that the pixel moving is done in the target space, where
4141 // the background filter is applied, but the surface appears at 50, 50 and
4142 // the replica at 200, 50.
4143 typename Types::ContentLayerType* parent = this->CreateRoot(
4144 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4145 typename Types::LayerType* filtered_surface =
4146 this->CreateDrawingLayer(parent,
4147 scale_by_half,
4148 gfx::PointF(50.f, 50.f),
4149 gfx::Size(100, 100),
4150 false);
4151 this->CreateReplicaLayer(filtered_surface,
4152 this->identity_matrix,
4153 gfx::PointF(300.f, 0.f),
4154 gfx::Size());
4155 typename Types::LayerType* above_surface_layer =
4156 this->CreateDrawingLayer(parent,
4157 this->identity_matrix,
4158 gfx::PointF(50.f, 50.f),
4159 gfx::Size(50, 50),
4160 true);
4161 typename Types::LayerType* above_replica_layer =
4162 this->CreateDrawingLayer(parent,
4163 this->identity_matrix,
4164 gfx::PointF(200.f, 50.f),
4165 gfx::Size(50, 50),
4166 true);
4168 // Filters make the layer own a surface.
4169 FilterOperations filters;
4170 filters.Append(FilterOperation::CreateBlurFilter(3.f));
4171 filtered_surface->SetBackgroundFilters(filters);
4173 this->CalcDrawEtc(parent);
4175 TestOcclusionTrackerWithClip<typename Types::LayerType,
4176 typename Types::RenderSurfaceType> occlusion(
4177 gfx::Rect(0, 0, 1000, 1000));
4179 this->VisitLayer(above_replica_layer, &occlusion);
4180 this->VisitLayer(above_surface_layer, &occlusion);
4182 this->VisitLayer(filtered_surface, &occlusion);
4184 // The layers above the filtered surface occlude from outside.
4185 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
4186 gfx::Rect occlusion_above_replica = gfx::Rect(150, 0, 50, 50);
4187 Region expected_opaque_region =
4188 UnionRegions(occlusion_above_surface, occlusion_above_replica);
4190 EXPECT_EQ(gfx::Rect().ToString(),
4191 occlusion.occlusion_from_inside_target().ToString());
4192 EXPECT_EQ(expected_opaque_region.ToString(),
4193 occlusion.occlusion_from_outside_target().ToString());
4196 // The surface has a background blur, so it blurs non-opaque pixels below
4197 // it.
4198 this->VisitContributingSurface(filtered_surface, &occlusion);
4200 // The filter is completely occluded, so it should not blur anything and
4201 // reduce any occlusion.
4202 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
4203 gfx::Rect occlusion_above_replica = gfx::Rect(200, 50, 50, 50);
4204 Region expected_opaque_region =
4205 UnionRegions(occlusion_above_surface, occlusion_above_replica);
4207 EXPECT_EQ(expected_opaque_region.ToString(),
4208 occlusion.occlusion_from_inside_target().ToString());
4209 EXPECT_EQ(gfx::Rect().ToString(),
4210 occlusion.occlusion_from_outside_target().ToString());
4215 ALL_OCCLUSIONTRACKER_TEST(
4216 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
4218 template <class Types>
4219 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
4220 : public OcclusionTrackerTest<Types> {
4221 protected:
4222 explicit
4223 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
4224 bool opaque_layers)
4225 : OcclusionTrackerTest<Types>(opaque_layers) {}
4226 void RunMyTest() {
4227 gfx::Transform scale_by_half;
4228 scale_by_half.Scale(0.5, 0.5);
4230 // Make a surface and its replica, each 50x50, that are partially occluded
4231 // by opaque layers which are above them in the z-order. The surface is
4232 // scaled to test that the pixel moving is done in the target space, where
4233 // the background filter is applied, but the surface appears at 50, 50 and
4234 // the replica at 200, 50.
4235 typename Types::ContentLayerType* parent = this->CreateRoot(
4236 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
4237 typename Types::LayerType* filtered_surface =
4238 this->CreateDrawingLayer(parent,
4239 scale_by_half,
4240 gfx::PointF(50.f, 50.f),
4241 gfx::Size(100, 100),
4242 false);
4243 this->CreateReplicaLayer(filtered_surface,
4244 this->identity_matrix,
4245 gfx::PointF(300.f, 0.f),
4246 gfx::Size());
4247 typename Types::LayerType* above_surface_layer =
4248 this->CreateDrawingLayer(parent,
4249 this->identity_matrix,
4250 gfx::PointF(70.f, 50.f),
4251 gfx::Size(30, 50),
4252 true);
4253 typename Types::LayerType* above_replica_layer =
4254 this->CreateDrawingLayer(parent,
4255 this->identity_matrix,
4256 gfx::PointF(200.f, 50.f),
4257 gfx::Size(30, 50),
4258 true);
4259 typename Types::LayerType* beside_surface_layer =
4260 this->CreateDrawingLayer(parent,
4261 this->identity_matrix,
4262 gfx::PointF(90.f, 40.f),
4263 gfx::Size(10, 10),
4264 true);
4265 typename Types::LayerType* beside_replica_layer =
4266 this->CreateDrawingLayer(parent,
4267 this->identity_matrix,
4268 gfx::PointF(200.f, 40.f),
4269 gfx::Size(10, 10),
4270 true);
4272 // Filters make the layer own a surface.
4273 FilterOperations filters;
4274 filters.Append(FilterOperation::CreateBlurFilter(3.f));
4275 filtered_surface->SetBackgroundFilters(filters);
4277 // Save the distance of influence for the blur effect.
4278 int outset_top, outset_right, outset_bottom, outset_left;
4279 filters.GetOutsets(
4280 &outset_top, &outset_right, &outset_bottom, &outset_left);
4282 this->CalcDrawEtc(parent);
4284 TestOcclusionTrackerWithClip<typename Types::LayerType,
4285 typename Types::RenderSurfaceType> occlusion(
4286 gfx::Rect(0, 0, 1000, 1000));
4288 this->VisitLayer(beside_replica_layer, &occlusion);
4289 this->VisitLayer(beside_surface_layer, &occlusion);
4290 this->VisitLayer(above_replica_layer, &occlusion);
4291 this->VisitLayer(above_surface_layer, &occlusion);
4293 // The surface has a background blur, so it blurs non-opaque pixels below
4294 // it.
4295 this->VisitLayer(filtered_surface, &occlusion);
4296 this->VisitContributingSurface(filtered_surface, &occlusion);
4298 // The filter in the surface and replica are partially unoccluded. Only the
4299 // unoccluded parts should reduce occlusion. This means it will push back
4300 // the occlusion that touches the unoccluded part (occlusion_above___), but
4301 // it will not touch occlusion_beside____ since that is not beside the
4302 // unoccluded part of the surface, even though it is beside the occluded
4303 // part of the surface.
4304 gfx::Rect occlusion_above_surface =
4305 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
4306 gfx::Rect occlusion_above_replica =
4307 gfx::Rect(200, 50, 30 - outset_left, 50);
4308 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
4309 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
4311 Region expected_occlusion;
4312 expected_occlusion.Union(occlusion_above_surface);
4313 expected_occlusion.Union(occlusion_above_replica);
4314 expected_occlusion.Union(occlusion_beside_surface);
4315 expected_occlusion.Union(occlusion_beside_replica);
4317 ASSERT_EQ(expected_occlusion.ToString(),
4318 occlusion.occlusion_from_inside_target().ToString());
4319 EXPECT_EQ(gfx::Rect().ToString(),
4320 occlusion.occlusion_from_outside_target().ToString());
4322 Region::Iterator expected_rects(expected_occlusion);
4323 Region::Iterator target_surface_rects(
4324 occlusion.occlusion_from_inside_target());
4325 for (; expected_rects.has_rect();
4326 expected_rects.next(), target_surface_rects.next()) {
4327 ASSERT_TRUE(target_surface_rects.has_rect());
4328 EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
4333 ALL_OCCLUSIONTRACKER_TEST(
4334 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
4336 template <class Types>
4337 class OcclusionTrackerTestMinimumTrackingSize
4338 : public OcclusionTrackerTest<Types> {
4339 protected:
4340 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
4341 : OcclusionTrackerTest<Types>(opaque_layers) {}
4342 void RunMyTest() {
4343 gfx::Size tracking_size(100, 100);
4344 gfx::Size below_tracking_size(99, 99);
4346 typename Types::ContentLayerType* parent = this->CreateRoot(
4347 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4348 typename Types::LayerType* large = this->CreateDrawingLayer(
4349 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
4350 typename Types::LayerType* small =
4351 this->CreateDrawingLayer(parent,
4352 this->identity_matrix,
4353 gfx::PointF(),
4354 below_tracking_size,
4355 true);
4356 this->CalcDrawEtc(parent);
4358 TestOcclusionTrackerWithClip<typename Types::LayerType,
4359 typename Types::RenderSurfaceType> occlusion(
4360 gfx::Rect(0, 0, 1000, 1000));
4361 occlusion.set_minimum_tracking_size(tracking_size);
4363 // The small layer is not tracked because it is too small.
4364 this->VisitLayer(small, &occlusion);
4366 EXPECT_EQ(gfx::Rect().ToString(),
4367 occlusion.occlusion_from_outside_target().ToString());
4368 EXPECT_EQ(gfx::Rect().ToString(),
4369 occlusion.occlusion_from_inside_target().ToString());
4371 // The large layer is tracked as it is large enough.
4372 this->VisitLayer(large, &occlusion);
4374 EXPECT_EQ(gfx::Rect().ToString(),
4375 occlusion.occlusion_from_outside_target().ToString());
4376 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
4377 occlusion.occlusion_from_inside_target().ToString());
4381 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
4383 template <class Types>
4384 class OcclusionTrackerTestViewportClipIsExternalOcclusion
4385 : public OcclusionTrackerTest<Types> {
4386 protected:
4387 explicit OcclusionTrackerTestViewportClipIsExternalOcclusion(
4388 bool opaque_layers)
4389 : OcclusionTrackerTest<Types>(opaque_layers) {}
4390 void RunMyTest() {
4391 typename Types::ContentLayerType* parent = this->CreateRoot(
4392 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4393 typename Types::LayerType* small =
4394 this->CreateDrawingSurface(parent,
4395 this->identity_matrix,
4396 gfx::PointF(),
4397 gfx::Size(200, 200),
4398 false);
4399 typename Types::LayerType* large =
4400 this->CreateDrawingLayer(small,
4401 this->identity_matrix,
4402 gfx::PointF(),
4403 gfx::Size(400, 400),
4404 false);
4405 small->SetMasksToBounds(true);
4406 this->CalcDrawEtc(parent);
4408 TestOcclusionTrackerWithClip<typename Types::LayerType,
4409 typename Types::RenderSurfaceType> occlusion(
4410 gfx::Rect(0, 0, 100, 100));
4412 this->EnterLayer(large, &occlusion, false);
4414 bool has_occlusion_from_outside_target_surface = false;
4415 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4416 occlusion.UnoccludedLayerContentRect(
4417 large,
4418 gfx::Rect(0, 0, 400, 400),
4419 &has_occlusion_from_outside_target_surface));
4420 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4422 has_occlusion_from_outside_target_surface = false;
4423 EXPECT_FALSE(
4424 occlusion.OccludedLayer(large,
4425 gfx::Rect(0, 0, 400, 400),
4426 &has_occlusion_from_outside_target_surface));
4427 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4429 this->LeaveLayer(large, &occlusion);
4430 this->VisitLayer(small, &occlusion);
4432 has_occlusion_from_outside_target_surface = false;
4433 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4434 occlusion.UnoccludedLayerContentRect(
4435 small,
4436 gfx::Rect(0, 0, 200, 200),
4437 &has_occlusion_from_outside_target_surface));
4438 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4440 has_occlusion_from_outside_target_surface = false;
4441 EXPECT_FALSE(
4442 occlusion.OccludedLayer(small,
4443 gfx::Rect(0, 0, 200, 200),
4444 &has_occlusion_from_outside_target_surface));
4445 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4447 this->EnterContributingSurface(small, &occlusion, false);
4449 has_occlusion_from_outside_target_surface = false;
4450 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4451 occlusion.UnoccludedContributingSurfaceContentRect(
4452 small,
4453 false,
4454 gfx::Rect(0, 0, 200, 200),
4455 &has_occlusion_from_outside_target_surface));
4456 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4460 ALL_OCCLUSIONTRACKER_TEST(
4461 OcclusionTrackerTestViewportClipIsExternalOcclusion)
4463 template <class Types>
4464 class OcclusionTrackerTestLayerClipIsExternalOcclusion
4465 : public OcclusionTrackerTest<Types> {
4466 protected:
4467 explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers)
4468 : OcclusionTrackerTest<Types>(opaque_layers) {}
4469 void RunMyTest() {
4470 typename Types::ContentLayerType* parent = this->CreateRoot(
4471 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4472 typename Types::LayerType* smallest = this->CreateDrawingLayer(
4473 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4474 typename Types::LayerType* smaller =
4475 this->CreateDrawingSurface(smallest,
4476 this->identity_matrix,
4477 gfx::PointF(),
4478 gfx::Size(100, 100),
4479 false);
4480 typename Types::LayerType* small =
4481 this->CreateDrawingSurface(smaller,
4482 this->identity_matrix,
4483 gfx::PointF(),
4484 gfx::Size(200, 200),
4485 false);
4486 typename Types::LayerType* large =
4487 this->CreateDrawingLayer(small,
4488 this->identity_matrix,
4489 gfx::PointF(),
4490 gfx::Size(400, 400),
4491 false);
4492 smallest->SetMasksToBounds(true);
4493 smaller->SetMasksToBounds(true);
4494 small->SetMasksToBounds(true);
4495 this->CalcDrawEtc(parent);
4497 TestOcclusionTrackerWithClip<typename Types::LayerType,
4498 typename Types::RenderSurfaceType> occlusion(
4499 gfx::Rect(0, 0, 1000, 1000));
4501 this->EnterLayer(large, &occlusion, false);
4503 // Clipping from the smaller layer is from outside the target surface.
4504 bool has_occlusion_from_outside_target_surface = false;
4505 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4506 occlusion.UnoccludedLayerContentRect(
4507 large,
4508 gfx::Rect(0, 0, 400, 400),
4509 &has_occlusion_from_outside_target_surface));
4510 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4512 has_occlusion_from_outside_target_surface = false;
4513 EXPECT_FALSE(
4514 occlusion.OccludedLayer(large,
4515 gfx::Rect(0, 0, 400, 400),
4516 &has_occlusion_from_outside_target_surface));
4517 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4519 this->LeaveLayer(large, &occlusion);
4520 this->VisitLayer(small, &occlusion);
4522 // Clipping from the smaller layer is from outside the target surface.
4523 has_occlusion_from_outside_target_surface = false;
4524 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4525 occlusion.UnoccludedLayerContentRect(
4526 small,
4527 gfx::Rect(0, 0, 200, 200),
4528 &has_occlusion_from_outside_target_surface));
4529 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4531 has_occlusion_from_outside_target_surface = false;
4532 EXPECT_FALSE(
4533 occlusion.OccludedLayer(small,
4534 gfx::Rect(0, 0, 200, 200),
4535 &has_occlusion_from_outside_target_surface));
4536 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4538 this->EnterContributingSurface(small, &occlusion, false);
4540 // The |small| surface is clipped from outside its target by |smallest|.
4541 has_occlusion_from_outside_target_surface = false;
4542 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4543 occlusion.UnoccludedContributingSurfaceContentRect(
4544 small,
4545 false,
4546 gfx::Rect(0, 0, 200, 200),
4547 &has_occlusion_from_outside_target_surface));
4548 EXPECT_TRUE(has_occlusion_from_outside_target_surface);
4550 this->LeaveContributingSurface(small, &occlusion);
4551 this->VisitLayer(smaller, &occlusion);
4552 this->EnterContributingSurface(smaller, &occlusion, false);
4554 // The |smaller| surface is clipped from inside its target by |smallest|.
4555 has_occlusion_from_outside_target_surface = false;
4556 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
4557 occlusion.UnoccludedContributingSurfaceContentRect(
4558 smaller,
4559 false,
4560 gfx::Rect(0, 0, 100, 100),
4561 &has_occlusion_from_outside_target_surface));
4562 EXPECT_FALSE(has_occlusion_from_outside_target_surface);
4566 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion)
4568 template <class Types>
4569 class OcclusionTrackerTestPreventOcclusionOnLayer
4570 : public OcclusionTrackerTest<Types> {
4571 protected:
4572 explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers)
4573 : OcclusionTrackerTest<Types>(opaque_layers) {}
4574 void RunMyTest() {
4575 typename Types::ContentLayerType* parent = this->CreateRoot(
4576 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4577 typename Types::LayerType* unprevented = this->CreateDrawingLayer(
4578 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4579 typename Types::LayerType* prevented = this->CreateDrawingLayer(
4580 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4581 typename Types::LayerType* occluding = this->CreateDrawingLayer(
4582 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
4583 this->CalcDrawEtc(parent);
4585 TestOcclusionTrackerWithClip<typename Types::LayerType,
4586 typename Types::RenderSurfaceType> occlusion(
4587 gfx::Rect(0, 0, 1000, 1000));
4588 bool external_occlusion = false;
4590 this->VisitLayer(occluding, &occlusion);
4591 this->EnterLayer(prevented, &occlusion, true);
4593 // This layer is not occluded because it is prevented.
4594 EXPECT_FALSE(occlusion.OccludedLayer(prevented,
4595 gfx::Rect(50, 50),
4596 &external_occlusion));
4597 EXPECT_FALSE(external_occlusion);
4599 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4600 occlusion.UnoccludedLayerContentRect(
4601 prevented,
4602 gfx::Rect(50, 50),
4603 &external_occlusion).ToString());
4604 EXPECT_FALSE(external_occlusion);
4606 this->LeaveLayer(prevented, &occlusion);
4607 this->EnterLayer(unprevented, &occlusion, false);
4609 // This layer is fully occluded.
4610 EXPECT_TRUE(occlusion.OccludedLayer(unprevented,
4611 gfx::Rect(50, 50),
4612 &external_occlusion));
4613 EXPECT_FALSE(external_occlusion);
4615 EXPECT_EQ(gfx::Rect().ToString(),
4616 occlusion.UnoccludedLayerContentRect(
4617 unprevented,
4618 gfx::Rect(50, 50),
4619 &external_occlusion).ToString());
4620 EXPECT_FALSE(external_occlusion);
4622 this->LeaveLayer(unprevented, &occlusion);
4626 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer)
4628 template <class Types>
4629 class OcclusionTrackerTestPreventOcclusionOnContributingSurface
4630 : public OcclusionTrackerTest<Types> {
4631 protected:
4632 explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface(
4633 bool opaque_layers)
4634 : OcclusionTrackerTest<Types>(opaque_layers) {}
4635 void RunMyTest() {
4636 typename Types::ContentLayerType* parent = this->CreateRoot(
4637 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4638 typename Types::LayerType* unprevented = this->CreateDrawingSurface(
4639 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4640 typename Types::LayerType* prevented = this->CreateDrawingSurface(
4641 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4642 typename Types::LayerType* occluding = this->CreateDrawingLayer(
4643 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
4644 this->CalcDrawEtc(parent);
4646 TestOcclusionTrackerWithClip<typename Types::LayerType,
4647 typename Types::RenderSurfaceType> occlusion(
4648 gfx::Rect(0, 0, 1000, 1000));
4649 bool external_occlusion = false;
4651 this->VisitLayer(occluding, &occlusion);
4652 this->EnterLayer(prevented, &occlusion, true);
4654 // This layer is not occluded because it is prevented.
4655 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4656 occlusion.UnoccludedLayerContentRect(
4657 prevented,
4658 gfx::Rect(50, 50),
4659 &external_occlusion).ToString());
4660 EXPECT_FALSE(external_occlusion);
4662 this->LeaveLayer(prevented, &occlusion);
4663 this->EnterContributingSurface(prevented, &occlusion, true);
4665 // This contributing surface is not occluded because it is prevented.
4666 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4667 occlusion.UnoccludedContributingSurfaceContentRect(
4668 prevented,
4669 false, // is_replica
4670 gfx::Rect(50, 50),
4671 &external_occlusion).ToString());
4672 EXPECT_FALSE(external_occlusion);
4674 this->LeaveContributingSurface(prevented, &occlusion);
4675 this->EnterLayer(unprevented, &occlusion, false);
4677 // This layer is fully occluded from outside its surface.
4678 EXPECT_EQ(gfx::Rect().ToString(),
4679 occlusion.UnoccludedLayerContentRect(
4680 unprevented,
4681 gfx::Rect(50, 50),
4682 &external_occlusion).ToString());
4683 EXPECT_TRUE(external_occlusion);
4685 this->LeaveLayer(unprevented, &occlusion);
4686 this->EnterContributingSurface(unprevented, &occlusion, false);
4688 // This contributing surface is fully occluded.
4689 EXPECT_EQ(gfx::Rect().ToString(),
4690 occlusion.UnoccludedContributingSurfaceContentRect(
4691 unprevented,
4692 false, // is_replica
4693 gfx::Rect(50, 50),
4694 &external_occlusion).ToString());
4695 EXPECT_FALSE(external_occlusion);
4697 this->LeaveContributingSurface(unprevented, &occlusion);
4701 ALL_OCCLUSIONTRACKER_TEST(
4702 OcclusionTrackerTestPreventOcclusionOnContributingSurface)
4704 template <class Types>
4705 class OcclusionTrackerTestPreventOcclusionByClipping
4706 : public OcclusionTrackerTest<Types> {
4707 protected:
4708 explicit OcclusionTrackerTestPreventOcclusionByClipping(bool opaque_layers)
4709 : OcclusionTrackerTest<Types>(opaque_layers) {}
4710 void RunMyTest() {
4711 typename Types::ContentLayerType* parent = this->CreateRoot(
4712 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4713 typename Types::LayerType* unprevented = this->CreateDrawingLayer(
4714 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4715 typename Types::LayerType* prevented = this->CreateDrawingLayer(
4716 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
4717 this->CalcDrawEtc(parent);
4719 TestOcclusionTrackerWithClip<typename Types::LayerType,
4720 typename Types::RenderSurfaceType> occlusion(
4721 gfx::Rect(0, 0, 10, 10));
4722 bool external_occlusion = false;
4724 this->EnterLayer(prevented, &occlusion, true);
4726 // This layer is not occluded because it is prevented.
4727 EXPECT_FALSE(occlusion.OccludedLayer(prevented,
4728 gfx::Rect(50, 50),
4729 &external_occlusion));
4730 EXPECT_FALSE(external_occlusion);
4732 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
4733 occlusion.UnoccludedLayerContentRect(
4734 prevented,
4735 gfx::Rect(50, 50),
4736 &external_occlusion).ToString());
4737 EXPECT_FALSE(external_occlusion);
4739 this->LeaveLayer(prevented, &occlusion);
4740 this->EnterLayer(unprevented, &occlusion, false);
4742 // This layer is clipped by the screen space clip rect.
4743 EXPECT_EQ(gfx::Rect(10, 10).ToString(),
4744 occlusion.UnoccludedLayerContentRect(
4745 unprevented,
4746 gfx::Rect(50, 50),
4747 &external_occlusion).ToString());
4748 EXPECT_TRUE(external_occlusion);
4750 this->LeaveLayer(unprevented, &occlusion);
4754 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionByClipping)
4756 template <class Types>
4757 class OcclusionTrackerTestScaledLayerIsClipped
4758 : public OcclusionTrackerTest<Types> {
4759 protected:
4760 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
4761 : OcclusionTrackerTest<Types>(opaque_layers) {}
4762 void RunMyTest() {
4763 gfx::Transform scale_transform;
4764 scale_transform.Scale(512.0, 512.0);
4766 typename Types::ContentLayerType* parent = this->CreateRoot(
4767 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4768 typename Types::LayerType* clip = this->CreateLayer(parent,
4769 this->identity_matrix,
4770 gfx::PointF(10.f, 10.f),
4771 gfx::Size(50, 50));
4772 clip->SetMasksToBounds(true);
4773 typename Types::LayerType* scale = this->CreateLayer(
4774 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
4775 typename Types::LayerType* scaled = this->CreateDrawingLayer(
4776 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
4777 this->CalcDrawEtc(parent);
4779 TestOcclusionTrackerWithClip<typename Types::LayerType,
4780 typename Types::RenderSurfaceType> occlusion(
4781 gfx::Rect(0, 0, 1000, 1000));
4783 this->VisitLayer(scaled, &occlusion);
4785 EXPECT_EQ(gfx::Rect().ToString(),
4786 occlusion.occlusion_from_outside_target().ToString());
4787 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
4788 occlusion.occlusion_from_inside_target().ToString());
4792 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
4794 template <class Types>
4795 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
4796 : public OcclusionTrackerTest<Types> {
4797 protected:
4798 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
4799 : OcclusionTrackerTest<Types>(opaque_layers) {}
4800 void RunMyTest() {
4801 gfx::Transform scale_transform;
4802 scale_transform.Scale(512.0, 512.0);
4804 typename Types::ContentLayerType* parent = this->CreateRoot(
4805 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
4806 typename Types::LayerType* clip = this->CreateLayer(parent,
4807 this->identity_matrix,
4808 gfx::PointF(10.f, 10.f),
4809 gfx::Size(50, 50));
4810 clip->SetMasksToBounds(true);
4811 typename Types::LayerType* surface = this->CreateDrawingSurface(
4812 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
4813 typename Types::LayerType* scale = this->CreateLayer(
4814 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
4815 typename Types::LayerType* scaled = this->CreateDrawingLayer(
4816 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
4817 this->CalcDrawEtc(parent);
4819 TestOcclusionTrackerWithClip<typename Types::LayerType,
4820 typename Types::RenderSurfaceType> occlusion(
4821 gfx::Rect(0, 0, 1000, 1000));
4823 this->VisitLayer(scaled, &occlusion);
4824 this->VisitLayer(surface, &occlusion);
4825 this->VisitContributingSurface(surface, &occlusion);
4827 EXPECT_EQ(gfx::Rect().ToString(),
4828 occlusion.occlusion_from_outside_target().ToString());
4829 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
4830 occlusion.occlusion_from_inside_target().ToString());
4834 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
4836 template <class Types>
4837 class OcclusionTrackerTestCopyRequestDoesOcclude
4838 : public OcclusionTrackerTest<Types> {
4839 protected:
4840 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
4841 : OcclusionTrackerTest<Types>(opaque_layers) {}
4842 void RunMyTest() {
4843 typename Types::ContentLayerType* root = this->CreateRoot(
4844 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
4845 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
4846 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
4847 typename Types::LayerType* copy = this->CreateLayer(parent,
4848 this->identity_matrix,
4849 gfx::Point(100, 0),
4850 gfx::Size(200, 400));
4851 this->AddCopyRequest(copy);
4852 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
4853 copy,
4854 this->identity_matrix,
4855 gfx::PointF(),
4856 gfx::Size(200, 400),
4857 true);
4858 this->CalcDrawEtc(root);
4860 TestOcclusionTrackerWithClip<typename Types::LayerType,
4861 typename Types::RenderSurfaceType> occlusion(
4862 gfx::Rect(0, 0, 1000, 1000));
4864 this->VisitLayer(copy_child, &occlusion);
4865 EXPECT_EQ(gfx::Rect().ToString(),
4866 occlusion.occlusion_from_outside_target().ToString());
4867 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
4868 occlusion.occlusion_from_inside_target().ToString());
4870 // CopyRequests cause the layer to own a surface.
4871 this->VisitContributingSurface(copy, &occlusion);
4873 // The occlusion from the copy should be kept.
4874 EXPECT_EQ(gfx::Rect().ToString(),
4875 occlusion.occlusion_from_outside_target().ToString());
4876 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
4877 occlusion.occlusion_from_inside_target().ToString());
4881 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
4883 template <class Types>
4884 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
4885 : public OcclusionTrackerTest<Types> {
4886 protected:
4887 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
4888 bool opaque_layers)
4889 : OcclusionTrackerTest<Types>(opaque_layers) {}
4890 void RunMyTest() {
4891 typename Types::ContentLayerType* root = this->CreateRoot(
4892 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
4893 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
4894 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
4895 typename Types::LayerType* hide = this->CreateLayer(
4896 parent, this->identity_matrix, gfx::Point(), gfx::Size());
4897 typename Types::LayerType* copy = this->CreateLayer(
4898 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
4899 this->AddCopyRequest(copy);
4900 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
4901 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
4903 // The |copy| layer is hidden but since it is being copied, it will be
4904 // drawn.
4905 hide->SetHideLayerAndSubtree(true);
4907 this->CalcDrawEtc(root);
4909 TestOcclusionTrackerWithClip<typename Types::LayerType,
4910 typename Types::RenderSurfaceType> occlusion(
4911 gfx::Rect(0, 0, 1000, 1000));
4913 this->VisitLayer(copy_child, &occlusion);
4914 EXPECT_EQ(gfx::Rect().ToString(),
4915 occlusion.occlusion_from_outside_target().ToString());
4916 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
4917 occlusion.occlusion_from_inside_target().ToString());
4919 // CopyRequests cause the layer to own a surface.
4920 this->VisitContributingSurface(copy, &occlusion);
4922 // The occlusion from the copy should be dropped since it is hidden.
4923 EXPECT_EQ(gfx::Rect().ToString(),
4924 occlusion.occlusion_from_outside_target().ToString());
4925 EXPECT_EQ(gfx::Rect().ToString(),
4926 occlusion.occlusion_from_inside_target().ToString());
4930 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
4932 } // namespace
4933 } // namespace cc