Allow systematic prefix search in bookmarks.
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob75cd2438a7bdc4e39100ca6852e1fbf523919b83
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/occlusion_tracker.h"
7 #include "cc/animation/layer_animation_controller.h"
8 #include "cc/base/math_util.h"
9 #include "cc/layers/layer.h"
10 #include "cc/layers/layer_impl.h"
11 #include "cc/output/copy_output_request.h"
12 #include "cc/output/copy_output_result.h"
13 #include "cc/output/filter_operation.h"
14 #include "cc/output/filter_operations.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_impl_proxy.h"
17 #include "cc/test/fake_layer_tree_host.h"
18 #include "cc/test/fake_layer_tree_host_impl.h"
19 #include "cc/test/geometry_test_utils.h"
20 #include "cc/test/test_occlusion_tracker.h"
21 #include "cc/trees/layer_tree_host_common.h"
22 #include "cc/trees/single_thread_proxy.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/gfx/transform.h"
27 namespace cc {
28 namespace {
30 class TestContentLayer : public Layer {
31 public:
32 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
33 SetIsDrawable(true);
36 SimpleEnclosedRegion VisibleContentOpaqueRegion() const override {
37 if (override_opaque_contents_rect_) {
38 return SimpleEnclosedRegion(
39 gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()));
41 return Layer::VisibleContentOpaqueRegion();
43 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
44 override_opaque_contents_rect_ = true;
45 opaque_contents_rect_ = opaque_contents_rect;
48 private:
49 ~TestContentLayer() override {}
51 bool override_opaque_contents_rect_;
52 gfx::Rect opaque_contents_rect_;
55 class TestContentLayerImpl : public LayerImpl {
56 public:
57 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
58 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
59 SetDrawsContent(true);
62 SimpleEnclosedRegion VisibleContentOpaqueRegion() const override {
63 if (override_opaque_contents_rect_) {
64 return SimpleEnclosedRegion(
65 gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()));
67 return LayerImpl::VisibleContentOpaqueRegion();
69 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
70 override_opaque_contents_rect_ = true;
71 opaque_contents_rect_ = opaque_contents_rect;
74 private:
75 bool override_opaque_contents_rect_;
76 gfx::Rect opaque_contents_rect_;
79 template <typename LayerType>
80 class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> {
81 public:
82 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect)
83 : TestOcclusionTracker<LayerType>(viewport_rect) {}
85 bool OccludedLayer(const LayerType* layer,
86 const gfx::Rect& content_rect) const {
87 DCHECK(layer->visible_content_rect().Contains(content_rect));
88 return this->GetCurrentOcclusionForLayer(layer->draw_transform())
89 .IsOccluded(content_rect);
92 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
93 // layer. Simple wrapper around GetUnoccludedContentRect.
94 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
95 const gfx::Rect& content_rect) const {
96 DCHECK(layer->visible_content_rect().Contains(content_rect));
97 return this->GetCurrentOcclusionForLayer(layer->draw_transform())
98 .GetUnoccludedContentRect(content_rect);
101 gfx::Rect UnoccludedSurfaceContentRect(const LayerType* layer,
102 const gfx::Rect& content_rect) const {
103 typename LayerType::RenderSurfaceType* surface = layer->render_surface();
104 return this->UnoccludedContributingSurfaceContentRect(
105 content_rect, surface->draw_transform());
109 struct OcclusionTrackerTestMainThreadTypes {
110 typedef Layer LayerType;
111 typedef FakeLayerTreeHost HostType;
112 typedef RenderSurface RenderSurfaceType;
113 typedef TestContentLayer ContentLayerType;
114 typedef scoped_refptr<Layer> LayerPtrType;
115 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
116 typedef LayerIterator<Layer> TestLayerIterator;
117 typedef OcclusionTracker<Layer> OcclusionTrackerType;
119 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
120 static ContentLayerPtrType CreateContentLayer(HostType* host) {
121 return make_scoped_refptr(new ContentLayerType());
124 template <typename T>
125 static LayerPtrType PassLayerPtr(T* layer) {
126 LayerPtrType ref(*layer);
127 *layer = NULL;
128 return ref;
131 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
133 static void RecursiveUpdateNumChildren(LayerType* layerType) {}
136 struct OcclusionTrackerTestImplThreadTypes {
137 typedef LayerImpl LayerType;
138 typedef LayerTreeImpl HostType;
139 typedef RenderSurfaceImpl RenderSurfaceType;
140 typedef TestContentLayerImpl ContentLayerType;
141 typedef scoped_ptr<LayerImpl> LayerPtrType;
142 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
143 typedef LayerIterator<LayerImpl> TestLayerIterator;
144 typedef OcclusionTracker<LayerImpl> OcclusionTrackerType;
146 static LayerPtrType CreateLayer(HostType* host) {
147 return LayerImpl::Create(host, next_layer_impl_id++);
149 static ContentLayerPtrType CreateContentLayer(HostType* host) {
150 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
152 static int next_layer_impl_id;
154 template <typename T>
155 static LayerPtrType PassLayerPtr(T* layer) {
156 return layer->Pass();
159 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
161 static void RecursiveUpdateNumChildren(LayerType* layer) {
162 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer);
166 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
168 template <typename Types> class OcclusionTrackerTest : public testing::Test {
169 protected:
170 explicit OcclusionTrackerTest(bool opaque_layers)
171 : opaque_layers_(opaque_layers),
172 client_(FakeLayerTreeHostClient::DIRECT_3D),
173 host_(FakeLayerTreeHost::Create(&client_)) {}
175 virtual void RunMyTest() = 0;
177 virtual void TearDown() { DestroyLayers(); }
179 typename Types::HostType* GetHost();
181 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
182 const gfx::PointF& position,
183 const gfx::Size& bounds) {
184 typename Types::ContentLayerPtrType layer(
185 Types::CreateContentLayer(GetHost()));
186 typename Types::ContentLayerType* layer_ptr = layer.get();
187 SetProperties(layer_ptr, transform, position, bounds);
189 DCHECK(!root_.get());
190 root_ = Types::PassLayerPtr(&layer);
192 SetRootLayerOnMainThread(layer_ptr);
194 return layer_ptr;
197 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
198 const gfx::Transform& transform,
199 const gfx::PointF& position,
200 const gfx::Size& bounds) {
201 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
202 typename Types::LayerType* layer_ptr = layer.get();
203 SetProperties(layer_ptr, transform, position, bounds);
204 parent->AddChild(Types::PassLayerPtr(&layer));
205 return layer_ptr;
208 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
209 const gfx::Transform& transform,
210 const gfx::PointF& position,
211 const gfx::Size& bounds) {
212 typename Types::LayerType* layer =
213 CreateLayer(parent, transform, position, bounds);
214 layer->SetForceRenderSurface(true);
215 return layer;
218 typename Types::ContentLayerType* CreateDrawingLayer(
219 typename Types::LayerType* parent,
220 const gfx::Transform& transform,
221 const gfx::PointF& position,
222 const gfx::Size& bounds,
223 bool opaque) {
224 typename Types::ContentLayerPtrType layer(
225 Types::CreateContentLayer(GetHost()));
226 typename Types::ContentLayerType* layer_ptr = layer.get();
227 SetProperties(layer_ptr, transform, position, bounds);
229 if (opaque_layers_) {
230 layer_ptr->SetContentsOpaque(opaque);
231 } else {
232 layer_ptr->SetContentsOpaque(false);
233 if (opaque)
234 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
235 else
236 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
239 parent->AddChild(Types::PassLayerPtr(&layer));
240 return layer_ptr;
243 typename Types::LayerType* CreateReplicaLayer(
244 typename Types::LayerType* owning_layer,
245 const gfx::Transform& transform,
246 const gfx::PointF& position,
247 const gfx::Size& bounds) {
248 typename Types::ContentLayerPtrType layer(
249 Types::CreateContentLayer(GetHost()));
250 typename Types::ContentLayerType* layer_ptr = layer.get();
251 SetProperties(layer_ptr, transform, position, bounds);
252 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
253 return layer_ptr;
256 typename Types::LayerType* CreateMaskLayer(
257 typename Types::LayerType* owning_layer,
258 const gfx::Size& bounds) {
259 typename Types::ContentLayerPtrType layer(
260 Types::CreateContentLayer(GetHost()));
261 typename Types::ContentLayerType* layer_ptr = layer.get();
262 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
263 SetMask(owning_layer, Types::PassLayerPtr(&layer));
264 return layer_ptr;
267 typename Types::ContentLayerType* CreateDrawingSurface(
268 typename Types::LayerType* parent,
269 const gfx::Transform& transform,
270 const gfx::PointF& position,
271 const gfx::Size& bounds,
272 bool opaque) {
273 typename Types::ContentLayerType* layer =
274 CreateDrawingLayer(parent, transform, position, bounds, opaque);
275 layer->SetForceRenderSurface(true);
276 return layer;
279 void DestroyLayers() {
280 Types::DestroyLayer(&root_);
281 render_surface_layer_list_ = nullptr;
282 render_surface_layer_list_impl_.clear();
283 replica_layers_.clear();
284 mask_layers_.clear();
285 ResetLayerIterator();
288 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
290 void AddCopyRequest(Layer* layer) {
291 layer->RequestCopyOfOutput(
292 CopyOutputRequest::CreateBitmapRequest(base::Bind(
293 &OcclusionTrackerTest<Types>::CopyOutputCallback,
294 base::Unretained(this))));
297 void AddCopyRequest(LayerImpl* layer) {
298 ScopedPtrVector<CopyOutputRequest> requests;
299 requests.push_back(
300 CopyOutputRequest::CreateBitmapRequest(base::Bind(
301 &OcclusionTrackerTest<Types>::CopyOutputCallback,
302 base::Unretained(this))));
303 layer->PassCopyRequests(&requests);
306 void CalcDrawEtc(TestContentLayerImpl* root) {
307 DCHECK(root == root_.get());
308 DCHECK(!root->render_surface());
310 Types::RecursiveUpdateNumChildren(root);
311 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
312 root, root->bounds(), &render_surface_layer_list_impl_);
313 inputs.can_adjust_raster_scales = true;
314 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
316 layer_iterator_ = layer_iterator_begin_ =
317 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
320 void CalcDrawEtc(TestContentLayer* root) {
321 DCHECK(root == root_.get());
322 DCHECK(!root->render_surface());
324 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
325 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
326 root, root->bounds(), render_surface_layer_list_.get());
327 inputs.can_adjust_raster_scales = true;
328 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
330 layer_iterator_ = layer_iterator_begin_ =
331 Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
334 void EnterLayer(typename Types::LayerType* layer,
335 typename Types::OcclusionTrackerType* occlusion) {
336 ASSERT_EQ(*layer_iterator_, layer);
337 ASSERT_TRUE(layer_iterator_.represents_itself());
338 occlusion->EnterLayer(layer_iterator_);
341 void LeaveLayer(typename Types::LayerType* layer,
342 typename Types::OcclusionTrackerType* occlusion) {
343 ASSERT_EQ(*layer_iterator_, layer);
344 ASSERT_TRUE(layer_iterator_.represents_itself());
345 occlusion->LeaveLayer(layer_iterator_);
346 ++layer_iterator_;
349 void VisitLayer(typename Types::LayerType* layer,
350 typename Types::OcclusionTrackerType* occlusion) {
351 EnterLayer(layer, occlusion);
352 LeaveLayer(layer, occlusion);
355 void EnterContributingSurface(
356 typename Types::LayerType* layer,
357 typename Types::OcclusionTrackerType* occlusion) {
358 ASSERT_EQ(*layer_iterator_, layer);
359 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
360 occlusion->EnterLayer(layer_iterator_);
361 occlusion->LeaveLayer(layer_iterator_);
362 ++layer_iterator_;
363 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
364 occlusion->EnterLayer(layer_iterator_);
367 void LeaveContributingSurface(
368 typename Types::LayerType* layer,
369 typename Types::OcclusionTrackerType* occlusion) {
370 ASSERT_EQ(*layer_iterator_, layer);
371 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
372 occlusion->LeaveLayer(layer_iterator_);
373 ++layer_iterator_;
376 void VisitContributingSurface(
377 typename Types::LayerType* layer,
378 typename Types::OcclusionTrackerType* occlusion) {
379 EnterContributingSurface(layer, occlusion);
380 LeaveContributingSurface(layer, occlusion);
383 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
385 const gfx::Transform identity_matrix;
387 private:
388 void SetRootLayerOnMainThread(Layer* root) {
389 host_->SetRootLayer(scoped_refptr<Layer>(root));
392 void SetRootLayerOnMainThread(LayerImpl* root) {}
394 void SetBaseProperties(typename Types::LayerType* layer,
395 const gfx::Transform& transform,
396 const gfx::PointF& position,
397 const gfx::Size& bounds) {
398 layer->SetTransform(transform);
399 layer->SetPosition(position);
400 layer->SetBounds(bounds);
403 void SetProperties(Layer* layer,
404 const gfx::Transform& transform,
405 const gfx::PointF& position,
406 const gfx::Size& bounds) {
407 SetBaseProperties(layer, transform, position, bounds);
410 void SetProperties(LayerImpl* layer,
411 const gfx::Transform& transform,
412 const gfx::PointF& position,
413 const gfx::Size& bounds) {
414 SetBaseProperties(layer, transform, position, bounds);
416 layer->SetContentBounds(layer->bounds());
419 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
420 owning_layer->SetReplicaLayer(layer.get());
421 replica_layers_.push_back(layer);
424 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
425 owning_layer->SetReplicaLayer(layer.Pass());
428 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
429 owning_layer->SetMaskLayer(layer.get());
430 mask_layers_.push_back(layer);
433 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
434 owning_layer->SetMaskLayer(layer.Pass());
437 bool opaque_layers_;
438 FakeLayerTreeHostClient client_;
439 scoped_ptr<FakeLayerTreeHost> host_;
440 // These hold ownership of the layers for the duration of the test.
441 typename Types::LayerPtrType root_;
442 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
443 LayerImplList render_surface_layer_list_impl_;
444 typename Types::TestLayerIterator layer_iterator_begin_;
445 typename Types::TestLayerIterator layer_iterator_;
446 typename Types::LayerType* last_layer_visited_;
447 LayerList replica_layers_;
448 LayerList mask_layers_;
451 template <>
452 FakeLayerTreeHost*
453 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
454 return host_.get();
457 template <>
458 LayerTreeImpl*
459 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
460 return host_->host_impl()->active_tree();
463 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
464 class ClassName##MainThreadOpaqueLayers \
465 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
466 public: /* NOLINT(whitespace/indent) */ \
467 ClassName##MainThreadOpaqueLayers() \
468 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
469 }; \
470 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
471 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
472 class ClassName##MainThreadOpaquePaints \
473 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
474 public: /* NOLINT(whitespace/indent) */ \
475 ClassName##MainThreadOpaquePaints() \
476 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
477 }; \
478 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
480 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
481 class ClassName##ImplThreadOpaqueLayers \
482 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
483 public: /* NOLINT(whitespace/indent) */ \
484 ClassName##ImplThreadOpaqueLayers() \
485 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
486 }; \
487 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
488 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
489 class ClassName##ImplThreadOpaquePaints \
490 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
491 public: /* NOLINT(whitespace/indent) */ \
492 ClassName##ImplThreadOpaquePaints() \
493 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
494 }; \
495 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
497 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
498 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
499 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
500 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
501 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
503 #define MAIN_THREAD_TEST(ClassName) \
504 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
506 #define IMPL_THREAD_TEST(ClassName) \
507 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
509 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
510 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
511 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
513 template <class Types>
514 class OcclusionTrackerTestIdentityTransforms
515 : public OcclusionTrackerTest<Types> {
516 protected:
517 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
518 : OcclusionTrackerTest<Types>(opaque_layers) {}
520 void RunMyTest() {
521 typename Types::ContentLayerType* root = this->CreateRoot(
522 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
523 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
524 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
525 typename Types::ContentLayerType* layer =
526 this->CreateDrawingLayer(parent,
527 this->identity_matrix,
528 gfx::PointF(30.f, 30.f),
529 gfx::Size(500, 500),
530 true);
531 parent->SetMasksToBounds(true);
532 this->CalcDrawEtc(root);
534 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
535 gfx::Rect(0, 0, 1000, 1000));
537 this->VisitLayer(layer, &occlusion);
538 this->EnterLayer(parent, &occlusion);
540 EXPECT_EQ(gfx::Rect().ToString(),
541 occlusion.occlusion_from_outside_target().ToString());
542 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
543 occlusion.occlusion_from_inside_target().ToString());
547 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
549 template <class Types>
550 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
551 protected:
552 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
553 : OcclusionTrackerTest<Types>(opaque_layers) {}
554 void RunMyTest() {
555 gfx::Transform layer_transform;
556 layer_transform.Translate(250.0, 250.0);
557 layer_transform.Rotate(90.0);
558 layer_transform.Translate(-250.0, -250.0);
560 typename Types::ContentLayerType* root = this->CreateRoot(
561 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
562 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
563 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
564 typename Types::ContentLayerType* layer =
565 this->CreateDrawingLayer(parent,
566 layer_transform,
567 gfx::PointF(30.f, 30.f),
568 gfx::Size(500, 500),
569 true);
570 parent->SetMasksToBounds(true);
571 this->CalcDrawEtc(root);
573 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
574 gfx::Rect(0, 0, 1000, 1000));
576 this->VisitLayer(layer, &occlusion);
577 this->EnterLayer(parent, &occlusion);
579 EXPECT_EQ(gfx::Rect().ToString(),
580 occlusion.occlusion_from_outside_target().ToString());
581 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
582 occlusion.occlusion_from_inside_target().ToString());
586 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
588 template <class Types>
589 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
590 protected:
591 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
592 : OcclusionTrackerTest<Types>(opaque_layers) {}
593 void RunMyTest() {
594 gfx::Transform layer_transform;
595 layer_transform.Translate(20.0, 20.0);
597 typename Types::ContentLayerType* root = this->CreateRoot(
598 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
599 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
600 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
601 typename Types::ContentLayerType* layer =
602 this->CreateDrawingLayer(parent,
603 layer_transform,
604 gfx::PointF(30.f, 30.f),
605 gfx::Size(500, 500),
606 true);
607 parent->SetMasksToBounds(true);
608 this->CalcDrawEtc(root);
610 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
611 gfx::Rect(0, 0, 1000, 1000));
613 this->VisitLayer(layer, &occlusion);
614 this->EnterLayer(parent, &occlusion);
616 EXPECT_EQ(gfx::Rect().ToString(),
617 occlusion.occlusion_from_outside_target().ToString());
618 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
619 occlusion.occlusion_from_inside_target().ToString());
623 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
625 template <class Types>
626 class OcclusionTrackerTestChildInRotatedChild
627 : public OcclusionTrackerTest<Types> {
628 protected:
629 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
630 : OcclusionTrackerTest<Types>(opaque_layers) {}
631 void RunMyTest() {
632 gfx::Transform child_transform;
633 child_transform.Translate(250.0, 250.0);
634 child_transform.Rotate(90.0);
635 child_transform.Translate(-250.0, -250.0);
637 typename Types::ContentLayerType* parent = this->CreateRoot(
638 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
639 parent->SetMasksToBounds(true);
640 typename Types::LayerType* child = this->CreateSurface(
641 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
642 child->SetMasksToBounds(true);
643 typename Types::ContentLayerType* layer =
644 this->CreateDrawingLayer(child,
645 this->identity_matrix,
646 gfx::PointF(10.f, 10.f),
647 gfx::Size(500, 500),
648 true);
649 this->CalcDrawEtc(parent);
651 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
652 gfx::Rect(0, 0, 1000, 1000));
654 this->VisitLayer(layer, &occlusion);
655 this->EnterContributingSurface(child, &occlusion);
657 EXPECT_EQ(gfx::Rect().ToString(),
658 occlusion.occlusion_from_outside_target().ToString());
659 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
660 occlusion.occlusion_from_inside_target().ToString());
662 this->LeaveContributingSurface(child, &occlusion);
663 this->EnterLayer(parent, &occlusion);
665 EXPECT_EQ(gfx::Rect().ToString(),
666 occlusion.occlusion_from_outside_target().ToString());
667 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
668 occlusion.occlusion_from_inside_target().ToString());
670 /* Justification for the above occlusion from |layer|:
672 +---------------------+
674 | 30 | rotate(90)
675 | 30 + ---------------------------------+
676 100 | | 10 | | ==>
677 | |10+---------------------------------+
678 | | | | | |
679 | | | | | |
680 | | | | | |
681 +----|--|-------------+ | |
682 | | | |
683 | | | |
684 | | | |500
685 | | | |
686 | | | |
687 | | | |
688 | | | |
689 +--|-------------------------------+ |
691 +---------------------------------+
694 +---------------------+
695 | |30 Visible region of |layer|: /////
697 | +---------------------------------+
698 100| | |10 |
699 | +---------------------------------+ |
700 | | |///////////////| 420 | |
701 | | |///////////////|60 | |
702 | | |///////////////| | |
703 +--|--|---------------+ | |
704 20|10| 70 | |
705 | | | |
706 | | | |
707 | | | |
708 | | | |
709 | | | |
710 | | |10|
711 | +------------------------------|--+
712 | 490 |
713 +---------------------------------+
720 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
722 template <class Types>
723 class OcclusionTrackerTestScaledRenderSurface
724 : public OcclusionTrackerTest<Types> {
725 protected:
726 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
727 : OcclusionTrackerTest<Types>(opaque_layers) {}
729 void RunMyTest() {
730 typename Types::ContentLayerType* parent = this->CreateRoot(
731 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
733 gfx::Transform layer1_matrix;
734 layer1_matrix.Scale(2.0, 2.0);
735 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
736 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
737 layer1->SetForceRenderSurface(true);
739 gfx::Transform layer2_matrix;
740 layer2_matrix.Translate(25.0, 25.0);
741 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
742 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
743 typename Types::ContentLayerType* occluder =
744 this->CreateDrawingLayer(parent,
745 this->identity_matrix,
746 gfx::PointF(100.f, 100.f),
747 gfx::Size(500, 500),
748 true);
749 this->CalcDrawEtc(parent);
751 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
752 gfx::Rect(0, 0, 1000, 1000));
754 this->VisitLayer(occluder, &occlusion);
755 this->EnterLayer(layer2, &occlusion);
757 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
758 occlusion.occlusion_from_outside_target().ToString());
759 EXPECT_EQ(gfx::Rect().ToString(),
760 occlusion.occlusion_from_inside_target().ToString());
764 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
766 template <class Types>
767 class OcclusionTrackerTestVisitTargetTwoTimes
768 : public OcclusionTrackerTest<Types> {
769 protected:
770 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
771 : OcclusionTrackerTest<Types>(opaque_layers) {}
772 void RunMyTest() {
773 typename Types::ContentLayerType* root = this->CreateRoot(
774 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
775 typename Types::LayerType* surface = this->CreateSurface(
776 root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size());
777 typename Types::ContentLayerType* surface_child =
778 this->CreateDrawingLayer(surface,
779 this->identity_matrix,
780 gfx::PointF(10.f, 10.f),
781 gfx::Size(50, 50),
782 true);
783 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
784 // first, instead of |surface|'s. This exercises different code in
785 // LeaveToRenderTarget, as the target surface has already been seen when
786 // leaving |surface| later.
787 typename Types::ContentLayerType* top_layer =
788 this->CreateDrawingLayer(root,
789 this->identity_matrix,
790 gfx::PointF(40.f, 90.f),
791 gfx::Size(50, 20),
792 true);
793 this->CalcDrawEtc(root);
795 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
796 gfx::Rect(0, 0, 1000, 1000));
798 this->VisitLayer(top_layer, &occlusion);
800 EXPECT_EQ(gfx::Rect().ToString(),
801 occlusion.occlusion_from_outside_target().ToString());
802 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
803 occlusion.occlusion_from_inside_target().ToString());
805 this->VisitLayer(surface_child, &occlusion);
807 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
808 occlusion.occlusion_from_outside_target().ToString());
809 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
810 occlusion.occlusion_from_inside_target().ToString());
812 this->EnterContributingSurface(surface, &occlusion);
814 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
815 occlusion.occlusion_from_outside_target().ToString());
816 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
817 occlusion.occlusion_from_inside_target().ToString());
819 // Occlusion from |top_layer| already in the root target should get merged
820 // with the occlusion from the |surface| we are leaving now.
821 this->LeaveContributingSurface(surface, &occlusion);
822 this->EnterLayer(root, &occlusion);
824 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
825 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
826 occlusion.occlusion_from_inside_target().ToString());
830 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
832 template <class Types>
833 class OcclusionTrackerTestSurfaceRotatedOffAxis
834 : public OcclusionTrackerTest<Types> {
835 protected:
836 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
837 : OcclusionTrackerTest<Types>(opaque_layers) {}
838 void RunMyTest() {
839 gfx::Transform child_transform;
840 child_transform.Translate(250.0, 250.0);
841 child_transform.Rotate(95.0);
842 child_transform.Translate(-250.0, -250.0);
844 gfx::Transform layer_transform;
845 layer_transform.Translate(10.0, 10.0);
847 typename Types::ContentLayerType* root = this->CreateRoot(
848 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
849 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
850 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
851 typename Types::LayerType* child = this->CreateLayer(
852 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
853 child->SetMasksToBounds(true);
854 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
855 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
856 this->CalcDrawEtc(root);
858 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
859 gfx::Rect(0, 0, 1000, 1000));
861 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect(
862 layer_transform, layer->visible_content_rect());
864 this->VisitLayer(layer, &occlusion);
865 this->EnterContributingSurface(child, &occlusion);
867 EXPECT_EQ(gfx::Rect().ToString(),
868 occlusion.occlusion_from_outside_target().ToString());
869 EXPECT_EQ(clipped_layer_in_child.ToString(),
870 occlusion.occlusion_from_inside_target().ToString());
872 this->LeaveContributingSurface(child, &occlusion);
873 this->EnterLayer(parent, &occlusion);
875 EXPECT_EQ(gfx::Rect().ToString(),
876 occlusion.occlusion_from_outside_target().ToString());
877 EXPECT_EQ(gfx::Rect().ToString(),
878 occlusion.occlusion_from_inside_target().ToString());
882 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
884 template <class Types>
885 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
886 : public OcclusionTrackerTest<Types> {
887 protected:
888 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
889 : OcclusionTrackerTest<Types>(opaque_layers) {}
890 void RunMyTest() {
891 gfx::Transform child_transform;
892 child_transform.Translate(250.0, 250.0);
893 child_transform.Rotate(90.0);
894 child_transform.Translate(-250.0, -250.0);
896 typename Types::ContentLayerType* root = this->CreateRoot(
897 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
898 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
899 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
900 parent->SetMasksToBounds(true);
901 typename Types::ContentLayerType* child =
902 this->CreateDrawingSurface(parent,
903 child_transform,
904 gfx::PointF(30.f, 30.f),
905 gfx::Size(500, 500),
906 false);
907 child->SetMasksToBounds(true);
908 typename Types::ContentLayerType* layer1 =
909 this->CreateDrawingLayer(child,
910 this->identity_matrix,
911 gfx::PointF(10.f, 10.f),
912 gfx::Size(500, 500),
913 true);
914 typename Types::ContentLayerType* layer2 =
915 this->CreateDrawingLayer(child,
916 this->identity_matrix,
917 gfx::PointF(10.f, 450.f),
918 gfx::Size(500, 60),
919 true);
920 this->CalcDrawEtc(root);
922 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
923 gfx::Rect(0, 0, 1000, 1000));
925 this->VisitLayer(layer2, &occlusion);
926 this->VisitLayer(layer1, &occlusion);
927 this->VisitLayer(child, &occlusion);
928 this->EnterContributingSurface(child, &occlusion);
930 EXPECT_EQ(gfx::Rect().ToString(),
931 occlusion.occlusion_from_outside_target().ToString());
932 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
933 occlusion.occlusion_from_inside_target().ToString());
935 this->LeaveContributingSurface(child, &occlusion);
936 this->EnterLayer(parent, &occlusion);
938 EXPECT_EQ(gfx::Rect().ToString(),
939 occlusion.occlusion_from_outside_target().ToString());
940 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
941 occlusion.occlusion_from_inside_target().ToString());
943 /* Justification for the above occlusion from |layer1| and |layer2|:
945 +---------------------+
946 | |30 Visible region of |layer1|: /////
947 | | Visible region of |layer2|: \\\\\
948 | +---------------------------------+
949 | | |10 |
950 | +---------------+-----------------+ |
951 | | |\\\\\\\\\\\\|//| 420 | |
952 | | |\\\\\\\\\\\\|//|60 | |
953 | | |\\\\\\\\\\\\|//| | |
954 +--|--|------------|--+ | |
955 20|10| 70 | | |
956 | | | | |
957 | | | | |
958 | | | | |
959 | | | | |
960 | | | | |
961 | | | |10|
962 | +------------|-----------------|--+
963 | | 490 |
964 +---------------+-----------------+
965 60 440
970 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
972 template <class Types>
973 class OcclusionTrackerTestOverlappingSurfaceSiblings
974 : public OcclusionTrackerTest<Types> {
975 protected:
976 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
977 : OcclusionTrackerTest<Types>(opaque_layers) {}
978 void RunMyTest() {
979 typename Types::ContentLayerType* parent = this->CreateRoot(
980 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
981 parent->SetMasksToBounds(true);
982 typename Types::LayerType* child1 = this->CreateSurface(
983 parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size());
984 typename Types::LayerType* child2 = this->CreateSurface(
985 parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size());
986 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
987 child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true);
988 typename Types::ContentLayerType* layer2 =
989 this->CreateDrawingLayer(child2,
990 this->identity_matrix,
991 gfx::PointF(10.f, 0.f),
992 gfx::Size(40, 50),
993 true);
994 this->CalcDrawEtc(parent);
996 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
997 gfx::Rect(0, 0, 1000, 1000));
999 this->VisitLayer(layer2, &occlusion);
1000 this->EnterContributingSurface(child2, &occlusion);
1002 // layer2's occlusion.
1003 EXPECT_EQ(gfx::Rect().ToString(),
1004 occlusion.occlusion_from_outside_target().ToString());
1005 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
1006 occlusion.occlusion_from_inside_target().ToString());
1008 this->LeaveContributingSurface(child2, &occlusion);
1009 this->VisitLayer(layer1, &occlusion);
1010 this->EnterContributingSurface(child1, &occlusion);
1012 // layer2's occlusion in the target space of layer1.
1013 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
1014 occlusion.occlusion_from_outside_target().ToString());
1015 // layer1's occlusion.
1016 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
1017 occlusion.occlusion_from_inside_target().ToString());
1019 this->LeaveContributingSurface(child1, &occlusion);
1020 this->EnterLayer(parent, &occlusion);
1022 // The occlusion from from layer1 and layer2 is merged.
1023 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1024 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
1025 occlusion.occlusion_from_inside_target().ToString());
1029 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1031 template <class Types>
1032 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1033 : public OcclusionTrackerTest<Types> {
1034 protected:
1035 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1036 bool opaque_layers)
1037 : OcclusionTrackerTest<Types>(opaque_layers) {}
1038 void RunMyTest() {
1039 gfx::Transform child1_transform;
1040 child1_transform.Translate(250.0, 250.0);
1041 child1_transform.Rotate(-90.0);
1042 child1_transform.Translate(-250.0, -250.0);
1044 gfx::Transform child2_transform;
1045 child2_transform.Translate(250.0, 250.0);
1046 child2_transform.Rotate(90.0);
1047 child2_transform.Translate(-250.0, -250.0);
1049 typename Types::ContentLayerType* parent = this->CreateRoot(
1050 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1051 parent->SetMasksToBounds(true);
1052 typename Types::LayerType* child1 = this->CreateSurface(
1053 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1054 typename Types::LayerType* child2 =
1055 this->CreateDrawingSurface(parent,
1056 child2_transform,
1057 gfx::PointF(20.f, 40.f),
1058 gfx::Size(10, 10),
1059 false);
1060 typename Types::ContentLayerType* layer1 =
1061 this->CreateDrawingLayer(child1,
1062 this->identity_matrix,
1063 gfx::PointF(-10.f, -20.f),
1064 gfx::Size(510, 510),
1065 true);
1066 typename Types::ContentLayerType* layer2 =
1067 this->CreateDrawingLayer(child2,
1068 this->identity_matrix,
1069 gfx::PointF(-10.f, -10.f),
1070 gfx::Size(510, 510),
1071 true);
1072 this->CalcDrawEtc(parent);
1074 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1075 gfx::Rect(0, 0, 1000, 1000));
1077 this->VisitLayer(layer2, &occlusion);
1078 this->EnterLayer(child2, &occlusion);
1080 EXPECT_EQ(gfx::Rect().ToString(),
1081 occlusion.occlusion_from_outside_target().ToString());
1082 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1083 occlusion.occlusion_from_inside_target().ToString());
1085 this->LeaveLayer(child2, &occlusion);
1086 this->EnterContributingSurface(child2, &occlusion);
1088 EXPECT_EQ(gfx::Rect().ToString(),
1089 occlusion.occlusion_from_outside_target().ToString());
1090 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1091 occlusion.occlusion_from_inside_target().ToString());
1093 this->LeaveContributingSurface(child2, &occlusion);
1094 this->VisitLayer(layer1, &occlusion);
1095 this->EnterContributingSurface(child1, &occlusion);
1097 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1098 occlusion.occlusion_from_outside_target().ToString());
1099 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1100 occlusion.occlusion_from_inside_target().ToString());
1102 this->LeaveContributingSurface(child1, &occlusion);
1103 this->EnterLayer(parent, &occlusion);
1105 EXPECT_EQ(gfx::Rect().ToString(),
1106 occlusion.occlusion_from_outside_target().ToString());
1107 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1108 occlusion.occlusion_from_inside_target().ToString());
1110 /* Justification for the above occlusion:
1112 +---------------------+
1113 |20 | layer1
1114 10+----------------------------------+
1115 100 || 30 | layer2 |
1116 |20+----------------------------------+
1117 || | | | |
1118 || | | | |
1119 || | | | |
1120 +|-|------------------+ | |
1121 | | | | 510
1122 | | 510 | |
1123 | | | |
1124 | | | |
1125 | | | |
1126 | | | |
1127 | | 520 | |
1128 +----------------------------------+ |
1130 +----------------------------------+
1136 ALL_OCCLUSIONTRACKER_TEST(
1137 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1139 template <class Types>
1140 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1141 protected:
1142 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1143 : OcclusionTrackerTest<Types>(opaque_layers) {}
1144 void RunMyTest() {
1145 gfx::Transform layer_transform;
1146 layer_transform.Translate(250.0, 250.0);
1147 layer_transform.Rotate(90.0);
1148 layer_transform.Translate(-250.0, -250.0);
1150 typename Types::ContentLayerType* parent = this->CreateRoot(
1151 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1152 parent->SetMasksToBounds(true);
1153 typename Types::ContentLayerType* blur_layer =
1154 this->CreateDrawingLayer(parent,
1155 layer_transform,
1156 gfx::PointF(30.f, 30.f),
1157 gfx::Size(500, 500),
1158 true);
1159 typename Types::ContentLayerType* opaque_layer =
1160 this->CreateDrawingLayer(parent,
1161 layer_transform,
1162 gfx::PointF(30.f, 30.f),
1163 gfx::Size(500, 500),
1164 true);
1165 typename Types::ContentLayerType* opacity_layer =
1166 this->CreateDrawingLayer(parent,
1167 layer_transform,
1168 gfx::PointF(30.f, 30.f),
1169 gfx::Size(500, 500),
1170 true);
1172 FilterOperations filters;
1173 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1174 blur_layer->SetFilters(filters);
1176 filters.Clear();
1177 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1178 opaque_layer->SetFilters(filters);
1180 filters.Clear();
1181 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1182 opacity_layer->SetFilters(filters);
1184 this->CalcDrawEtc(parent);
1186 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1187 gfx::Rect(0, 0, 1000, 1000));
1189 // Opacity layer won't contribute to occlusion.
1190 this->VisitLayer(opacity_layer, &occlusion);
1191 this->EnterContributingSurface(opacity_layer, &occlusion);
1193 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1194 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1196 // And has nothing to contribute to its parent surface.
1197 this->LeaveContributingSurface(opacity_layer, &occlusion);
1198 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1199 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1201 // Opaque layer will contribute to occlusion.
1202 this->VisitLayer(opaque_layer, &occlusion);
1203 this->EnterContributingSurface(opaque_layer, &occlusion);
1205 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1206 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1207 occlusion.occlusion_from_inside_target().ToString());
1209 // And it gets translated to the parent surface.
1210 this->LeaveContributingSurface(opaque_layer, &occlusion);
1211 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1212 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1213 occlusion.occlusion_from_inside_target().ToString());
1215 // The blur layer needs to throw away any occlusion from outside its
1216 // subtree.
1217 this->EnterLayer(blur_layer, &occlusion);
1218 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1219 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1221 // And it won't contribute to occlusion.
1222 this->LeaveLayer(blur_layer, &occlusion);
1223 this->EnterContributingSurface(blur_layer, &occlusion);
1224 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1225 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1227 // But the opaque layer's occlusion is preserved on the parent.
1228 this->LeaveContributingSurface(blur_layer, &occlusion);
1229 this->EnterLayer(parent, &occlusion);
1230 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1231 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1232 occlusion.occlusion_from_inside_target().ToString());
1236 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1238 template <class Types>
1239 class OcclusionTrackerTestReplicaDoesOcclude
1240 : public OcclusionTrackerTest<Types> {
1241 protected:
1242 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1243 : OcclusionTrackerTest<Types>(opaque_layers) {}
1244 void RunMyTest() {
1245 typename Types::ContentLayerType* parent = this->CreateRoot(
1246 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1247 typename Types::LayerType* surface = this->CreateDrawingSurface(
1248 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
1249 this->CreateReplicaLayer(
1250 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
1251 this->CalcDrawEtc(parent);
1253 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1254 gfx::Rect(0, 0, 1000, 1000));
1256 this->VisitLayer(surface, &occlusion);
1258 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1259 occlusion.occlusion_from_inside_target().ToString());
1261 this->VisitContributingSurface(surface, &occlusion);
1262 this->EnterLayer(parent, &occlusion);
1264 // The surface and replica should both be occluding the parent.
1265 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1266 occlusion.occlusion_from_inside_target().ToString());
1270 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1272 template <class Types>
1273 class OcclusionTrackerTestReplicaWithClipping
1274 : public OcclusionTrackerTest<Types> {
1275 protected:
1276 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1277 : OcclusionTrackerTest<Types>(opaque_layers) {}
1278 void RunMyTest() {
1279 typename Types::ContentLayerType* parent = this->CreateRoot(
1280 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1281 parent->SetMasksToBounds(true);
1282 typename Types::LayerType* surface =
1283 this->CreateDrawingSurface(parent,
1284 this->identity_matrix,
1285 gfx::PointF(0.f, 100.f),
1286 gfx::Size(50, 50),
1287 true);
1288 this->CreateReplicaLayer(
1289 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
1290 this->CalcDrawEtc(parent);
1292 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1293 gfx::Rect(0, 0, 1000, 1000));
1295 this->VisitLayer(surface, &occlusion);
1297 // The surface layer's occlusion in its own space.
1298 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1299 occlusion.occlusion_from_inside_target().ToString());
1300 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1302 this->VisitContributingSurface(surface, &occlusion);
1303 this->EnterLayer(parent, &occlusion);
1305 // The surface and replica should both be occluding the parent, the
1306 // replica's occlusion is clipped by the parent.
1307 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1308 occlusion.occlusion_from_inside_target().ToString());
1309 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1313 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1315 template <class Types>
1316 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1317 protected:
1318 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1319 : OcclusionTrackerTest<Types>(opaque_layers) {}
1320 void RunMyTest() {
1321 typename Types::ContentLayerType* parent = this->CreateRoot(
1322 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1323 typename Types::LayerType* surface =
1324 this->CreateDrawingSurface(parent,
1325 this->identity_matrix,
1326 gfx::PointF(0.f, 100.f),
1327 gfx::Size(50, 50),
1328 true);
1329 typename Types::LayerType* replica = this->CreateReplicaLayer(
1330 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1331 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1332 this->CalcDrawEtc(parent);
1334 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1335 gfx::Rect(0, 0, 1000, 1000));
1337 this->VisitLayer(surface, &occlusion);
1339 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1340 occlusion.occlusion_from_inside_target().ToString());
1342 this->VisitContributingSurface(surface, &occlusion);
1343 this->EnterLayer(parent, &occlusion);
1345 // The replica should not be occluding the parent, since it has a mask
1346 // applied to it.
1347 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1348 occlusion.occlusion_from_inside_target().ToString());
1352 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1354 template <class Types>
1355 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1356 : public OcclusionTrackerTest<Types> {
1357 protected:
1358 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1359 : OcclusionTrackerTest<Types>(opaque_layers) {}
1360 void RunMyTest() {
1361 typename Types::ContentLayerType* parent = this->CreateRoot(
1362 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1363 typename Types::ContentLayerType* layer =
1364 this->CreateDrawingSurface(parent,
1365 this->identity_matrix,
1366 gfx::PointF(),
1367 gfx::Size(200, 200),
1368 false);
1369 this->CalcDrawEtc(parent);
1371 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1372 gfx::Rect(0, 0, 1000, 1000));
1373 this->EnterLayer(layer, &occlusion);
1375 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1376 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1378 this->LeaveLayer(layer, &occlusion);
1379 this->VisitContributingSurface(layer, &occlusion);
1380 this->EnterLayer(parent, &occlusion);
1382 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1383 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1387 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1389 template <class Types>
1390 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1391 : public OcclusionTrackerTest<Types> {
1392 protected:
1393 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1394 : OcclusionTrackerTest<Types>(opaque_layers) {}
1395 void RunMyTest() {
1396 typename Types::ContentLayerType* parent = this->CreateRoot(
1397 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1398 typename Types::ContentLayerType* layer =
1399 this->CreateDrawingLayer(parent,
1400 this->identity_matrix,
1401 gfx::PointF(100.f, 100.f),
1402 gfx::Size(200, 200),
1403 false);
1404 this->CalcDrawEtc(parent);
1406 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1407 gfx::Rect(0, 0, 1000, 1000));
1408 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1410 this->ResetLayerIterator();
1411 this->VisitLayer(layer, &occlusion);
1412 this->EnterLayer(parent, &occlusion);
1414 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1415 occlusion.occlusion_from_inside_target().ToString());
1418 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1419 gfx::Rect(0, 0, 1000, 1000));
1420 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1422 this->ResetLayerIterator();
1423 this->VisitLayer(layer, &occlusion);
1424 this->EnterLayer(parent, &occlusion);
1426 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1427 occlusion.occlusion_from_inside_target().ToString());
1430 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1431 gfx::Rect(0, 0, 1000, 1000));
1432 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1434 this->ResetLayerIterator();
1435 this->VisitLayer(layer, &occlusion);
1436 this->EnterLayer(parent, &occlusion);
1438 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1439 occlusion.occlusion_from_inside_target().ToString());
1444 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1446 template <class Types>
1447 class OcclusionTrackerTestUnsorted3dLayers
1448 : public OcclusionTrackerTest<Types> {
1449 protected:
1450 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
1451 : OcclusionTrackerTest<Types>(opaque_layers) {}
1452 void RunMyTest() {
1453 // Currently, The main thread layer iterator does not iterate over 3d items
1454 // in sorted order, because layer sorting is not performed on the main
1455 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1456 // layer occludes other layers that have not yet been iterated over. For
1457 // now, the expected behavior is that a 3d layer simply does not add any
1458 // occlusion to the occlusion tracker.
1460 gfx::Transform translation_to_front;
1461 translation_to_front.Translate3d(0.0, 0.0, -10.0);
1462 gfx::Transform translation_to_back;
1463 translation_to_front.Translate3d(0.0, 0.0, -100.0);
1465 typename Types::ContentLayerType* parent = this->CreateRoot(
1466 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1467 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
1468 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
1469 typename Types::ContentLayerType* child2 =
1470 this->CreateDrawingLayer(parent,
1471 translation_to_front,
1472 gfx::PointF(50.f, 50.f),
1473 gfx::Size(100, 100),
1474 true);
1475 parent->SetShouldFlattenTransform(false);
1476 parent->Set3dSortingContextId(1);
1477 child1->Set3dSortingContextId(1);
1478 child2->Set3dSortingContextId(1);
1480 this->CalcDrawEtc(parent);
1482 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1483 gfx::Rect(0, 0, 1000, 1000));
1484 this->VisitLayer(child2, &occlusion);
1485 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1486 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1488 this->VisitLayer(child1, &occlusion);
1489 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1490 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1494 // This test will have different layer ordering on the impl thread; the test
1495 // will only work on the main thread.
1496 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1498 template <class Types>
1499 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1500 : public OcclusionTrackerTest<Types> {
1501 protected:
1502 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1503 bool opaque_layers)
1504 : OcclusionTrackerTest<Types>(opaque_layers) {}
1505 void RunMyTest() {
1506 gfx::Transform transform;
1507 transform.Translate(50.0, 50.0);
1508 transform.ApplyPerspectiveDepth(100.0);
1509 transform.Translate3d(0.0, 0.0, 110.0);
1510 transform.Translate(-50.0, -50.0);
1512 typename Types::ContentLayerType* parent = this->CreateRoot(
1513 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1514 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1515 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
1516 parent->SetShouldFlattenTransform(false);
1517 parent->Set3dSortingContextId(1);
1518 layer->SetShouldFlattenTransform(false);
1519 layer->Set3dSortingContextId(1);
1520 this->CalcDrawEtc(parent);
1522 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1523 gfx::Rect(0, 0, 1000, 1000));
1525 // The |layer| is entirely behind the camera and should not occlude.
1526 this->VisitLayer(layer, &occlusion);
1527 this->EnterLayer(parent, &occlusion);
1528 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1529 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1533 // This test requires accumulating occlusion of 3d layers, which are skipped by
1534 // the occlusion tracker on the main thread. So this test should run on the impl
1535 // thread.
1536 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
1538 template <class Types>
1539 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
1540 : public OcclusionTrackerTest<Types> {
1541 protected:
1542 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
1543 bool opaque_layers)
1544 : OcclusionTrackerTest<Types>(opaque_layers) {}
1545 void RunMyTest() {
1546 gfx::Transform transform;
1547 transform.Translate(50.0, 50.0);
1548 transform.ApplyPerspectiveDepth(100.0);
1549 transform.Translate3d(0.0, 0.0, 99.0);
1550 transform.Translate(-50.0, -50.0);
1552 typename Types::ContentLayerType* parent = this->CreateRoot(
1553 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1554 parent->SetMasksToBounds(true);
1555 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1556 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
1557 parent->SetShouldFlattenTransform(false);
1558 parent->Set3dSortingContextId(1);
1559 layer->SetShouldFlattenTransform(false);
1560 layer->Set3dSortingContextId(1);
1561 this->CalcDrawEtc(parent);
1563 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1564 gfx::Rect(0, 0, 1000, 1000));
1566 // This is very close to the camera, so pixels in its visible_content_rect()
1567 // will actually go outside of the layer's clip rect. Ensure that those
1568 // pixels don't occlude things outside the clip rect.
1569 this->VisitLayer(layer, &occlusion);
1570 this->EnterLayer(parent, &occlusion);
1571 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
1572 occlusion.occlusion_from_inside_target().ToString());
1573 EXPECT_EQ(gfx::Rect().ToString(),
1574 occlusion.occlusion_from_outside_target().ToString());
1578 // This test requires accumulating occlusion of 3d layers, which are skipped by
1579 // the occlusion tracker on the main thread. So this test should run on the impl
1580 // thread.
1581 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
1583 template <class Types>
1584 class OcclusionTrackerTestAnimationOpacity1OnMainThread
1585 : public OcclusionTrackerTest<Types> {
1586 protected:
1587 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
1588 : OcclusionTrackerTest<Types>(opaque_layers) {}
1589 void RunMyTest() {
1590 // parent
1591 // +--layer
1592 // +--surface
1593 // | +--surface_child
1594 // | +--surface_child2
1595 // +--parent2
1596 // +--topmost
1598 typename Types::ContentLayerType* parent = this->CreateRoot(
1599 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1600 typename Types::ContentLayerType* layer =
1601 this->CreateDrawingLayer(parent,
1602 this->identity_matrix,
1603 gfx::PointF(),
1604 gfx::Size(300, 300),
1605 true);
1606 typename Types::ContentLayerType* surface =
1607 this->CreateDrawingSurface(parent,
1608 this->identity_matrix,
1609 gfx::PointF(),
1610 gfx::Size(300, 300),
1611 true);
1612 typename Types::ContentLayerType* surface_child =
1613 this->CreateDrawingLayer(surface,
1614 this->identity_matrix,
1615 gfx::PointF(),
1616 gfx::Size(200, 300),
1617 true);
1618 typename Types::ContentLayerType* surface_child2 =
1619 this->CreateDrawingLayer(surface,
1620 this->identity_matrix,
1621 gfx::PointF(),
1622 gfx::Size(100, 300),
1623 true);
1624 typename Types::ContentLayerType* parent2 =
1625 this->CreateDrawingLayer(parent,
1626 this->identity_matrix,
1627 gfx::PointF(),
1628 gfx::Size(300, 300),
1629 false);
1630 typename Types::ContentLayerType* topmost =
1631 this->CreateDrawingLayer(parent,
1632 this->identity_matrix,
1633 gfx::PointF(250.f, 0.f),
1634 gfx::Size(50, 300),
1635 true);
1637 AddOpacityTransitionToController(
1638 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
1639 AddOpacityTransitionToController(
1640 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
1641 this->CalcDrawEtc(parent);
1643 EXPECT_TRUE(layer->draw_opacity_is_animating());
1644 EXPECT_FALSE(surface->draw_opacity_is_animating());
1645 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
1647 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1648 gfx::Rect(0, 0, 1000, 1000));
1650 this->VisitLayer(topmost, &occlusion);
1651 this->EnterLayer(parent2, &occlusion);
1653 // This occlusion will affect all surfaces.
1654 EXPECT_EQ(gfx::Rect().ToString(),
1655 occlusion.occlusion_from_outside_target().ToString());
1656 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1657 occlusion.occlusion_from_inside_target().ToString());
1659 this->LeaveLayer(parent2, &occlusion);
1660 this->VisitLayer(surface_child2, &occlusion);
1661 this->EnterLayer(surface_child, &occlusion);
1662 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1663 occlusion.occlusion_from_outside_target().ToString());
1664 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1665 occlusion.occlusion_from_inside_target().ToString());
1667 this->LeaveLayer(surface_child, &occlusion);
1668 this->EnterLayer(surface, &occlusion);
1669 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1670 occlusion.occlusion_from_outside_target().ToString());
1671 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1672 occlusion.occlusion_from_inside_target().ToString());
1674 this->LeaveLayer(surface, &occlusion);
1675 this->EnterContributingSurface(surface, &occlusion);
1676 // Occlusion within the surface is lost when leaving the animating surface.
1677 EXPECT_EQ(gfx::Rect().ToString(),
1678 occlusion.occlusion_from_outside_target().ToString());
1679 EXPECT_EQ(gfx::Rect().ToString(),
1680 occlusion.occlusion_from_inside_target().ToString());
1682 this->LeaveContributingSurface(surface, &occlusion);
1683 // Occlusion from outside the animating surface still exists.
1684 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1685 occlusion.occlusion_from_inside_target().ToString());
1686 EXPECT_EQ(gfx::Rect().ToString(),
1687 occlusion.occlusion_from_outside_target().ToString());
1689 this->VisitLayer(layer, &occlusion);
1690 this->EnterLayer(parent, &occlusion);
1692 // Occlusion is not added for the animating |layer|.
1693 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1694 occlusion.occlusion_from_inside_target().ToString());
1695 EXPECT_EQ(gfx::Rect().ToString(),
1696 occlusion.occlusion_from_outside_target().ToString());
1700 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
1702 template <class Types>
1703 class OcclusionTrackerTestAnimationOpacity0OnMainThread
1704 : public OcclusionTrackerTest<Types> {
1705 protected:
1706 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
1707 : OcclusionTrackerTest<Types>(opaque_layers) {}
1708 void RunMyTest() {
1709 typename Types::ContentLayerType* parent = this->CreateRoot(
1710 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1711 typename Types::ContentLayerType* layer =
1712 this->CreateDrawingLayer(parent,
1713 this->identity_matrix,
1714 gfx::PointF(),
1715 gfx::Size(300, 300),
1716 true);
1717 typename Types::ContentLayerType* surface =
1718 this->CreateDrawingSurface(parent,
1719 this->identity_matrix,
1720 gfx::PointF(),
1721 gfx::Size(300, 300),
1722 true);
1723 typename Types::ContentLayerType* surface_child =
1724 this->CreateDrawingLayer(surface,
1725 this->identity_matrix,
1726 gfx::PointF(),
1727 gfx::Size(200, 300),
1728 true);
1729 typename Types::ContentLayerType* surface_child2 =
1730 this->CreateDrawingLayer(surface,
1731 this->identity_matrix,
1732 gfx::PointF(),
1733 gfx::Size(100, 300),
1734 true);
1735 typename Types::ContentLayerType* parent2 =
1736 this->CreateDrawingLayer(parent,
1737 this->identity_matrix,
1738 gfx::PointF(),
1739 gfx::Size(300, 300),
1740 false);
1741 typename Types::ContentLayerType* topmost =
1742 this->CreateDrawingLayer(parent,
1743 this->identity_matrix,
1744 gfx::PointF(250.f, 0.f),
1745 gfx::Size(50, 300),
1746 true);
1748 AddOpacityTransitionToController(
1749 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
1750 AddOpacityTransitionToController(
1751 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
1752 this->CalcDrawEtc(parent);
1754 EXPECT_TRUE(layer->draw_opacity_is_animating());
1755 EXPECT_FALSE(surface->draw_opacity_is_animating());
1756 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
1758 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1759 gfx::Rect(0, 0, 1000, 1000));
1761 this->VisitLayer(topmost, &occlusion);
1762 this->EnterLayer(parent2, &occlusion);
1763 // This occlusion will affect all surfaces.
1764 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1765 occlusion.occlusion_from_inside_target().ToString());
1766 EXPECT_EQ(gfx::Rect().ToString(),
1767 occlusion.occlusion_from_outside_target().ToString());
1769 this->LeaveLayer(parent2, &occlusion);
1770 this->VisitLayer(surface_child2, &occlusion);
1771 this->EnterLayer(surface_child, &occlusion);
1772 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1773 occlusion.occlusion_from_inside_target().ToString());
1774 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1775 occlusion.occlusion_from_outside_target().ToString());
1777 this->LeaveLayer(surface_child, &occlusion);
1778 this->EnterLayer(surface, &occlusion);
1779 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1780 occlusion.occlusion_from_inside_target().ToString());
1781 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1782 occlusion.occlusion_from_outside_target().ToString());
1784 this->LeaveLayer(surface, &occlusion);
1785 this->EnterContributingSurface(surface, &occlusion);
1786 // Occlusion within the surface is lost when leaving the animating surface.
1787 EXPECT_EQ(gfx::Rect().ToString(),
1788 occlusion.occlusion_from_inside_target().ToString());
1789 EXPECT_EQ(gfx::Rect().ToString(),
1790 occlusion.occlusion_from_outside_target().ToString());
1792 this->LeaveContributingSurface(surface, &occlusion);
1793 // Occlusion from outside the animating surface still exists.
1794 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1795 occlusion.occlusion_from_inside_target().ToString());
1796 EXPECT_EQ(gfx::Rect().ToString(),
1797 occlusion.occlusion_from_outside_target().ToString());
1799 this->VisitLayer(layer, &occlusion);
1800 this->EnterLayer(parent, &occlusion);
1802 // Occlusion is not added for the animating |layer|.
1803 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1804 occlusion.occlusion_from_inside_target().ToString());
1805 EXPECT_EQ(gfx::Rect().ToString(),
1806 occlusion.occlusion_from_outside_target().ToString());
1810 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
1812 template <class Types>
1813 class OcclusionTrackerTestAnimationTranslateOnMainThread
1814 : public OcclusionTrackerTest<Types> {
1815 protected:
1816 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
1817 bool opaque_layers)
1818 : OcclusionTrackerTest<Types>(opaque_layers) {}
1819 void RunMyTest() {
1820 typename Types::ContentLayerType* parent = this->CreateRoot(
1821 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1822 typename Types::ContentLayerType* layer =
1823 this->CreateDrawingLayer(parent,
1824 this->identity_matrix,
1825 gfx::PointF(),
1826 gfx::Size(300, 300),
1827 true);
1828 typename Types::ContentLayerType* surface =
1829 this->CreateDrawingSurface(parent,
1830 this->identity_matrix,
1831 gfx::PointF(),
1832 gfx::Size(300, 300),
1833 true);
1834 typename Types::ContentLayerType* surface_child =
1835 this->CreateDrawingLayer(surface,
1836 this->identity_matrix,
1837 gfx::PointF(),
1838 gfx::Size(200, 300),
1839 true);
1840 typename Types::ContentLayerType* surface_child2 =
1841 this->CreateDrawingLayer(surface,
1842 this->identity_matrix,
1843 gfx::PointF(),
1844 gfx::Size(100, 300),
1845 true);
1846 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
1847 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
1849 AddAnimatedTransformToController(
1850 layer->layer_animation_controller(), 10.0, 30, 0);
1851 AddAnimatedTransformToController(
1852 surface->layer_animation_controller(), 10.0, 30, 0);
1853 AddAnimatedTransformToController(
1854 surface_child->layer_animation_controller(), 10.0, 30, 0);
1855 this->CalcDrawEtc(parent);
1857 EXPECT_TRUE(layer->draw_transform_is_animating());
1858 EXPECT_TRUE(layer->screen_space_transform_is_animating());
1859 EXPECT_TRUE(
1860 surface->render_surface()->target_surface_transforms_are_animating());
1861 EXPECT_TRUE(
1862 surface->render_surface()->screen_space_transforms_are_animating());
1863 // The surface owning layer doesn't animate against its own surface.
1864 EXPECT_FALSE(surface->draw_transform_is_animating());
1865 EXPECT_TRUE(surface->screen_space_transform_is_animating());
1866 EXPECT_TRUE(surface_child->draw_transform_is_animating());
1867 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
1869 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1870 gfx::Rect(0, 0, 1000, 1000));
1872 this->VisitLayer(surface2, &occlusion);
1873 this->EnterContributingSurface(surface2, &occlusion);
1875 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1876 occlusion.occlusion_from_inside_target().ToString());
1878 this->LeaveContributingSurface(surface2, &occlusion);
1879 this->EnterLayer(surface_child2, &occlusion);
1880 // surface_child2 is moving in screen space but not relative to its target,
1881 // so occlusion should happen in its target space only. It also means that
1882 // things occluding from outside the target (e.g. surface2) cannot occlude
1883 // this layer.
1884 EXPECT_EQ(gfx::Rect().ToString(),
1885 occlusion.occlusion_from_outside_target().ToString());
1886 EXPECT_EQ(gfx::Rect().ToString(),
1887 occlusion.occlusion_from_inside_target().ToString());
1889 this->LeaveLayer(surface_child2, &occlusion);
1890 this->EnterLayer(surface_child, &occlusion);
1891 // surface_child2 added to the occlusion since it is not moving relative
1892 // to its target.
1893 EXPECT_EQ(gfx::Rect().ToString(),
1894 occlusion.occlusion_from_outside_target().ToString());
1895 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1896 occlusion.occlusion_from_inside_target().ToString());
1898 this->LeaveLayer(surface_child, &occlusion);
1899 // surface_child is moving relative to its target, so it does not add
1900 // occlusion.
1901 EXPECT_EQ(gfx::Rect().ToString(),
1902 occlusion.occlusion_from_outside_target().ToString());
1903 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1904 occlusion.occlusion_from_inside_target().ToString());
1906 this->EnterLayer(surface, &occlusion);
1907 EXPECT_EQ(gfx::Rect().ToString(),
1908 occlusion.occlusion_from_outside_target().ToString());
1909 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1910 occlusion.occlusion_from_inside_target().ToString());
1912 this->LeaveLayer(surface, &occlusion);
1913 // The surface's owning layer is moving in screen space but not relative to
1914 // its target, so it adds to the occlusion.
1915 EXPECT_EQ(gfx::Rect().ToString(),
1916 occlusion.occlusion_from_outside_target().ToString());
1917 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
1918 occlusion.occlusion_from_inside_target().ToString());
1920 this->EnterContributingSurface(surface, &occlusion);
1921 this->LeaveContributingSurface(surface, &occlusion);
1922 // The |surface| is moving in the screen and in its target, so all occlusion
1923 // within the surface is lost when leaving it. Only the |surface2| occlusion
1924 // is left.
1925 EXPECT_EQ(gfx::Rect().ToString(),
1926 occlusion.occlusion_from_outside_target().ToString());
1927 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1928 occlusion.occlusion_from_inside_target().ToString());
1930 this->VisitLayer(layer, &occlusion);
1931 // The |layer| is animating in the screen and in its target, so no occlusion
1932 // is added.
1933 EXPECT_EQ(gfx::Rect().ToString(),
1934 occlusion.occlusion_from_outside_target().ToString());
1935 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1936 occlusion.occlusion_from_inside_target().ToString());
1940 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
1942 template <class Types>
1943 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1944 : public OcclusionTrackerTest<Types> {
1945 protected:
1946 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1947 bool opaque_layers)
1948 : OcclusionTrackerTest<Types>(opaque_layers) {}
1949 void RunMyTest() {
1950 gfx::Transform surface_transform;
1951 surface_transform.Translate(300.0, 300.0);
1952 surface_transform.Scale(2.0, 2.0);
1953 surface_transform.Translate(-150.0, -150.0);
1955 typename Types::ContentLayerType* parent = this->CreateRoot(
1956 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
1957 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
1958 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
1959 typename Types::ContentLayerType* surface2 =
1960 this->CreateDrawingSurface(parent,
1961 this->identity_matrix,
1962 gfx::PointF(50.f, 50.f),
1963 gfx::Size(300, 300),
1964 false);
1965 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1966 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1967 this->CalcDrawEtc(parent);
1969 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1970 gfx::Rect(0, 0, 1000, 1000));
1972 this->VisitLayer(surface2, &occlusion);
1973 this->VisitContributingSurface(surface2, &occlusion);
1975 EXPECT_EQ(gfx::Rect().ToString(),
1976 occlusion.occlusion_from_outside_target().ToString());
1977 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1978 occlusion.occlusion_from_inside_target().ToString());
1980 // Clear any stored occlusion.
1981 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1982 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1984 this->VisitLayer(surface, &occlusion);
1985 this->VisitContributingSurface(surface, &occlusion);
1987 EXPECT_EQ(gfx::Rect().ToString(),
1988 occlusion.occlusion_from_outside_target().ToString());
1989 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1990 occlusion.occlusion_from_inside_target().ToString());
1994 MAIN_AND_IMPL_THREAD_TEST(
1995 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
1997 template <class Types>
1998 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1999 : public OcclusionTrackerTest<Types> {
2000 protected:
2001 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2002 bool opaque_layers)
2003 : OcclusionTrackerTest<Types>(opaque_layers) {}
2004 void RunMyTest() {
2005 typename Types::ContentLayerType* parent = this->CreateRoot(
2006 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2007 parent->SetMasksToBounds(true);
2008 typename Types::ContentLayerType* surface =
2009 this->CreateDrawingSurface(parent,
2010 this->identity_matrix,
2011 gfx::PointF(),
2012 gfx::Size(500, 300),
2013 false);
2014 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2015 this->CalcDrawEtc(parent);
2017 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2018 gfx::Rect(0, 0, 1000, 1000));
2020 this->VisitLayer(surface, &occlusion);
2021 this->VisitContributingSurface(surface, &occlusion);
2023 EXPECT_EQ(gfx::Rect().ToString(),
2024 occlusion.occlusion_from_outside_target().ToString());
2025 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2026 occlusion.occlusion_from_inside_target().ToString());
2030 MAIN_AND_IMPL_THREAD_TEST(
2031 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2033 template <class Types>
2034 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2035 : public OcclusionTrackerTest<Types> {
2036 protected:
2037 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
2038 : OcclusionTrackerTest<Types>(opaque_layers) {}
2039 void RunMyTest() {
2040 typename Types::ContentLayerType* parent = this->CreateRoot(
2041 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2042 typename Types::LayerType* surface =
2043 this->CreateDrawingSurface(parent,
2044 this->identity_matrix,
2045 gfx::PointF(),
2046 gfx::Size(100, 100),
2047 true);
2048 this->CreateReplicaLayer(surface,
2049 this->identity_matrix,
2050 gfx::PointF(0.f, 100.f),
2051 gfx::Size(100, 100));
2052 typename Types::LayerType* topmost =
2053 this->CreateDrawingLayer(parent,
2054 this->identity_matrix,
2055 gfx::PointF(),
2056 gfx::Size(100, 110),
2057 true);
2058 this->CalcDrawEtc(parent);
2060 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2061 gfx::Rect(0, 0, 1000, 1000));
2063 // |topmost| occludes the surface, but not the entire surface's replica.
2064 this->VisitLayer(topmost, &occlusion);
2066 EXPECT_EQ(gfx::Rect().ToString(),
2067 occlusion.occlusion_from_outside_target().ToString());
2068 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2069 occlusion.occlusion_from_inside_target().ToString());
2071 this->VisitLayer(surface, &occlusion);
2073 // Render target with replica ignores occlusion from outside.
2074 EXPECT_EQ(gfx::Rect().ToString(),
2075 occlusion.occlusion_from_outside_target().ToString());
2076 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2077 occlusion.occlusion_from_inside_target().ToString());
2079 this->EnterContributingSurface(surface, &occlusion);
2081 // Only occlusion from outside the surface occludes the surface/replica.
2082 EXPECT_EQ(gfx::Rect().ToString(),
2083 occlusion.occlusion_on_contributing_surface_from_outside_target()
2084 .ToString());
2085 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2086 occlusion.occlusion_on_contributing_surface_from_inside_target()
2087 .ToString());
2091 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2093 template <class Types>
2094 class OcclusionTrackerTestSurfaceChildOfSurface
2095 : public OcclusionTrackerTest<Types> {
2096 protected:
2097 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
2098 : OcclusionTrackerTest<Types>(opaque_layers) {}
2099 void RunMyTest() {
2100 // This test verifies that the surface cliprect does not end up empty and
2101 // clip away the entire unoccluded rect.
2103 typename Types::ContentLayerType* parent = this->CreateRoot(
2104 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2105 typename Types::LayerType* surface =
2106 this->CreateDrawingSurface(parent,
2107 this->identity_matrix,
2108 gfx::PointF(),
2109 gfx::Size(100, 100),
2110 false);
2111 typename Types::LayerType* surface_child =
2112 this->CreateDrawingSurface(surface,
2113 this->identity_matrix,
2114 gfx::PointF(0.f, 10.f),
2115 gfx::Size(100, 50),
2116 true);
2117 typename Types::LayerType* topmost = this->CreateDrawingLayer(
2118 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2119 this->CalcDrawEtc(parent);
2121 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2122 gfx::Rect(-100, -100, 1000, 1000));
2124 // |topmost| occludes everything partially so we know occlusion is happening
2125 // at all.
2126 this->VisitLayer(topmost, &occlusion);
2128 EXPECT_EQ(gfx::Rect().ToString(),
2129 occlusion.occlusion_from_outside_target().ToString());
2130 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2131 occlusion.occlusion_from_inside_target().ToString());
2133 this->VisitLayer(surface_child, &occlusion);
2135 // surface_child increases the occlusion in the screen by a narrow sliver.
2136 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2137 occlusion.occlusion_from_outside_target().ToString());
2138 // In its own surface, surface_child is at 0,0 as is its occlusion.
2139 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2140 occlusion.occlusion_from_inside_target().ToString());
2142 // The root layer always has a clip rect. So the parent of |surface| has a
2143 // clip rect. However, the owning layer for |surface| does not mask to
2144 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2145 // |surface_child| exercises different code paths as its parent does not
2146 // have a clip rect.
2148 this->EnterContributingSurface(surface_child, &occlusion);
2149 // The |surface_child| can't occlude its own surface, but occlusion from
2150 // |topmost| can.
2151 EXPECT_EQ(gfx::Rect().ToString(),
2152 occlusion.occlusion_on_contributing_surface_from_outside_target()
2153 .ToString());
2154 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2155 occlusion.occlusion_on_contributing_surface_from_inside_target()
2156 .ToString());
2157 this->LeaveContributingSurface(surface_child, &occlusion);
2159 // When the surface_child's occlusion is transformed up to its parent, make
2160 // sure it is not clipped away inappropriately.
2161 this->EnterLayer(surface, &occlusion);
2162 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2163 occlusion.occlusion_from_outside_target().ToString());
2164 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2165 occlusion.occlusion_from_inside_target().ToString());
2166 this->LeaveLayer(surface, &occlusion);
2168 this->EnterContributingSurface(surface, &occlusion);
2169 // The occlusion from inside |surface| can't affect the surface, but
2170 // |topmost| can.
2171 EXPECT_EQ(gfx::Rect().ToString(),
2172 occlusion.occlusion_on_contributing_surface_from_outside_target()
2173 .ToString());
2174 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2175 occlusion.occlusion_on_contributing_surface_from_inside_target()
2176 .ToString());
2178 this->LeaveContributingSurface(surface, &occlusion);
2179 this->EnterLayer(parent, &occlusion);
2180 // The occlusion in |surface| and without are merged into the parent.
2181 EXPECT_EQ(gfx::Rect().ToString(),
2182 occlusion.occlusion_from_outside_target().ToString());
2183 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
2184 occlusion.occlusion_from_inside_target().ToString());
2188 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2190 template <class Types>
2191 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2192 : public OcclusionTrackerTest<Types> {
2193 protected:
2194 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2195 bool opaque_layers)
2196 : OcclusionTrackerTest<Types>(opaque_layers) {}
2197 void RunMyTest() {
2198 gfx::Transform scale_by_half;
2199 scale_by_half.Scale(0.5, 0.5);
2201 FilterOperations filters;
2202 filters.Append(FilterOperation::CreateBlurFilter(10.f));
2204 // Save the distance of influence for the blur effect.
2205 int outset_top, outset_right, outset_bottom, outset_left;
2206 filters.GetOutsets(
2207 &outset_top, &outset_right, &outset_bottom, &outset_left);
2209 enum Direction {
2210 LEFT,
2211 RIGHT,
2212 TOP,
2213 BOTTOM,
2214 LAST_DIRECTION = BOTTOM,
2217 for (int i = 0; i <= LAST_DIRECTION; ++i) {
2218 SCOPED_TRACE(i);
2220 // Make a 50x50 filtered surface that is adjacent to occluding layers
2221 // which are above it in the z-order in various configurations. The
2222 // surface is scaled to test that the pixel moving is done in the target
2223 // space, where the background filter is applied.
2224 typename Types::ContentLayerType* parent = this->CreateRoot(
2225 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
2226 typename Types::LayerType* filtered_surface =
2227 this->CreateDrawingLayer(parent,
2228 scale_by_half,
2229 gfx::PointF(50.f, 50.f),
2230 gfx::Size(100, 100),
2231 false);
2232 filtered_surface->SetBackgroundFilters(filters);
2234 gfx::Rect occlusion_rect;
2235 switch (i) {
2236 case LEFT:
2237 occlusion_rect = gfx::Rect(0, 0, 50, 200);
2238 break;
2239 case RIGHT:
2240 occlusion_rect = gfx::Rect(100, 0, 50, 200);
2241 break;
2242 case TOP:
2243 occlusion_rect = gfx::Rect(0, 0, 200, 50);
2244 break;
2245 case BOTTOM:
2246 occlusion_rect = gfx::Rect(0, 100, 200, 50);
2247 break;
2250 typename Types::LayerType* occluding_layer =
2251 this->CreateDrawingLayer(parent,
2252 this->identity_matrix,
2253 occlusion_rect.origin(),
2254 occlusion_rect.size(),
2255 true);
2256 this->CalcDrawEtc(parent);
2258 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2259 gfx::Rect(0, 0, 200, 200));
2261 // This layer occludes pixels directly beside the filtered_surface.
2262 // Because filtered surface blends pixels in a radius, it will need to see
2263 // some of the pixels (up to radius far) underneath the occluding layers.
2264 this->VisitLayer(occluding_layer, &occlusion);
2266 EXPECT_EQ(occlusion_rect.ToString(),
2267 occlusion.occlusion_from_inside_target().ToString());
2268 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2270 this->VisitLayer(filtered_surface, &occlusion);
2272 // The occlusion is used fully inside the surface.
2273 gfx::Rect occlusion_inside_surface =
2274 occlusion_rect - gfx::Vector2d(50, 50);
2275 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2276 EXPECT_EQ(occlusion_inside_surface.ToString(),
2277 occlusion.occlusion_from_outside_target().ToString());
2279 // The surface has a background blur, so it needs pixels that are
2280 // currently considered occluded in order to be drawn. So the pixels it
2281 // needs should be removed some the occluded area so that when we get to
2282 // the parent they are drawn.
2283 this->VisitContributingSurface(filtered_surface, &occlusion);
2284 this->EnterLayer(parent, &occlusion);
2286 gfx::Rect expected_occlusion = occlusion_rect;
2287 switch (i) {
2288 case LEFT:
2289 expected_occlusion.Inset(0, 0, outset_right, 0);
2290 break;
2291 case RIGHT:
2292 expected_occlusion.Inset(outset_right, 0, 0, 0);
2293 break;
2294 case TOP:
2295 expected_occlusion.Inset(0, 0, 0, outset_right);
2296 break;
2297 case BOTTOM:
2298 expected_occlusion.Inset(0, outset_right, 0, 0);
2299 break;
2302 EXPECT_EQ(expected_occlusion.ToString(),
2303 occlusion.occlusion_from_inside_target().ToString());
2304 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2306 this->DestroyLayers();
2311 ALL_OCCLUSIONTRACKER_TEST(
2312 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2314 template <class Types>
2315 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
2316 : public OcclusionTrackerTest<Types> {
2317 protected:
2318 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
2319 bool opaque_layers)
2320 : OcclusionTrackerTest<Types>(opaque_layers) {}
2321 void RunMyTest() {
2322 gfx::Transform scale_by_half;
2323 scale_by_half.Scale(0.5, 0.5);
2325 // Makes two surfaces that completely cover |parent|. The occlusion both
2326 // above and below the filters will be reduced by each of them.
2327 typename Types::ContentLayerType* root = this->CreateRoot(
2328 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
2329 typename Types::LayerType* parent = this->CreateSurface(
2330 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
2331 parent->SetMasksToBounds(true);
2332 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
2333 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
2334 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
2335 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
2336 typename Types::LayerType* occluding_layer_above =
2337 this->CreateDrawingLayer(parent,
2338 this->identity_matrix,
2339 gfx::PointF(100.f, 100.f),
2340 gfx::Size(50, 50),
2341 true);
2343 // Filters make the layers own surfaces.
2344 FilterOperations filters;
2345 filters.Append(FilterOperation::CreateBlurFilter(1.f));
2346 filtered_surface1->SetBackgroundFilters(filters);
2347 filtered_surface2->SetBackgroundFilters(filters);
2349 // Save the distance of influence for the blur effect.
2350 int outset_top, outset_right, outset_bottom, outset_left;
2351 filters.GetOutsets(
2352 &outset_top, &outset_right, &outset_bottom, &outset_left);
2354 this->CalcDrawEtc(root);
2356 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2357 gfx::Rect(0, 0, 1000, 1000));
2359 this->VisitLayer(occluding_layer_above, &occlusion);
2360 EXPECT_EQ(gfx::Rect().ToString(),
2361 occlusion.occlusion_from_outside_target().ToString());
2362 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
2363 occlusion.occlusion_from_inside_target().ToString());
2365 this->VisitLayer(filtered_surface2, &occlusion);
2366 this->VisitContributingSurface(filtered_surface2, &occlusion);
2367 this->VisitLayer(filtered_surface1, &occlusion);
2368 this->VisitContributingSurface(filtered_surface1, &occlusion);
2370 // Test expectations in the target.
2371 gfx::Rect expected_occlusion =
2372 gfx::Rect(100 / 2 + outset_right * 2,
2373 100 / 2 + outset_bottom * 2,
2374 50 / 2 - (outset_left + outset_right) * 2,
2375 50 / 2 - (outset_top + outset_bottom) * 2);
2376 EXPECT_EQ(expected_occlusion.ToString(),
2377 occlusion.occlusion_from_inside_target().ToString());
2379 // Test expectations in the screen are the same as in the target, as the
2380 // render surface is 1:1 with the screen.
2381 EXPECT_EQ(expected_occlusion.ToString(),
2382 occlusion.occlusion_from_outside_target().ToString());
2386 ALL_OCCLUSIONTRACKER_TEST(
2387 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
2389 template <class Types>
2390 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
2391 : public OcclusionTrackerTest<Types> {
2392 protected:
2393 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
2394 bool opaque_layers)
2395 : OcclusionTrackerTest<Types>(opaque_layers) {}
2396 void RunMyTest() {
2397 gfx::Transform scale_by_half;
2398 scale_by_half.Scale(0.5, 0.5);
2400 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
2401 // centered below each. The surface is scaled to test that the pixel moving
2402 // is done in the target space, where the background filter is applied, but
2403 // the surface appears at 50, 50 and the replica at 200, 50.
2404 typename Types::ContentLayerType* parent = this->CreateRoot(
2405 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
2406 typename Types::LayerType* behind_surface_layer =
2407 this->CreateDrawingLayer(parent,
2408 this->identity_matrix,
2409 gfx::PointF(60.f, 60.f),
2410 gfx::Size(30, 30),
2411 true);
2412 typename Types::LayerType* behind_replica_layer =
2413 this->CreateDrawingLayer(parent,
2414 this->identity_matrix,
2415 gfx::PointF(210.f, 60.f),
2416 gfx::Size(30, 30),
2417 true);
2418 typename Types::LayerType* filtered_surface =
2419 this->CreateDrawingLayer(parent,
2420 scale_by_half,
2421 gfx::PointF(50.f, 50.f),
2422 gfx::Size(100, 100),
2423 false);
2424 this->CreateReplicaLayer(filtered_surface,
2425 this->identity_matrix,
2426 gfx::PointF(300.f, 0.f),
2427 gfx::Size());
2429 // Filters make the layer own a surface.
2430 FilterOperations filters;
2431 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2432 filtered_surface->SetBackgroundFilters(filters);
2434 this->CalcDrawEtc(parent);
2436 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2437 gfx::Rect(0, 0, 1000, 1000));
2439 // The surface has a background blur, so it blurs non-opaque pixels below
2440 // it.
2441 this->VisitLayer(filtered_surface, &occlusion);
2442 this->VisitContributingSurface(filtered_surface, &occlusion);
2444 this->VisitLayer(behind_replica_layer, &occlusion);
2446 // The layers behind the surface are not blurred, and their occlusion does
2447 // not change, until we leave the surface. So it should not be modified by
2448 // the filter here.
2449 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
2450 EXPECT_EQ(occlusion_behind_replica.ToString(),
2451 occlusion.occlusion_from_inside_target().ToString());
2452 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2454 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
2455 // without existing occlusion interfering.
2456 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2458 this->VisitLayer(behind_surface_layer, &occlusion);
2460 // The layers behind the surface are not blurred, and their occlusion does
2461 // not change, until we leave the surface. So it should not be modified by
2462 // the filter here.
2463 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
2464 EXPECT_EQ(occlusion_behind_surface.ToString(),
2465 occlusion.occlusion_from_inside_target().ToString());
2466 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2470 ALL_OCCLUSIONTRACKER_TEST(
2471 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
2473 template <class Types>
2474 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
2475 : public OcclusionTrackerTest<Types> {
2476 protected:
2477 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
2478 bool opaque_layers)
2479 : OcclusionTrackerTest<Types>(opaque_layers) {}
2480 void RunMyTest() {
2481 gfx::Transform scale_by_half;
2482 scale_by_half.Scale(0.5, 0.5);
2484 // Make a 50x50 filtered surface that is completely occluded by an opaque
2485 // layer which is above it in the z-order. The surface is
2486 // scaled to test that the pixel moving is done in the target space, where
2487 // the background filter is applied, but the surface appears at 50, 50.
2488 typename Types::ContentLayerType* parent = this->CreateRoot(
2489 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
2490 typename Types::LayerType* filtered_surface =
2491 this->CreateDrawingLayer(parent,
2492 scale_by_half,
2493 gfx::PointF(50.f, 50.f),
2494 gfx::Size(100, 100),
2495 false);
2496 typename Types::LayerType* occluding_layer =
2497 this->CreateDrawingLayer(parent,
2498 this->identity_matrix,
2499 gfx::PointF(50.f, 50.f),
2500 gfx::Size(50, 50),
2501 true);
2503 // Filters make the layer own a surface.
2504 FilterOperations filters;
2505 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2506 filtered_surface->SetBackgroundFilters(filters);
2508 this->CalcDrawEtc(parent);
2510 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2511 gfx::Rect(0, 0, 1000, 1000));
2513 this->VisitLayer(occluding_layer, &occlusion);
2515 this->VisitLayer(filtered_surface, &occlusion);
2517 // The layers above the filtered surface occlude from outside.
2518 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
2520 EXPECT_EQ(gfx::Rect().ToString(),
2521 occlusion.occlusion_from_inside_target().ToString());
2522 EXPECT_EQ(occlusion_above_surface.ToString(),
2523 occlusion.occlusion_from_outside_target().ToString());
2526 // The surface has a background blur, so it blurs non-opaque pixels below
2527 // it.
2528 this->VisitContributingSurface(filtered_surface, &occlusion);
2530 // The filter is completely occluded, so it should not blur anything and
2531 // reduce any occlusion.
2532 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
2534 EXPECT_EQ(occlusion_above_surface.ToString(),
2535 occlusion.occlusion_from_inside_target().ToString());
2536 EXPECT_EQ(gfx::Rect().ToString(),
2537 occlusion.occlusion_from_outside_target().ToString());
2542 ALL_OCCLUSIONTRACKER_TEST(
2543 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
2545 template <class Types>
2546 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
2547 : public OcclusionTrackerTest<Types> {
2548 protected:
2549 explicit
2550 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
2551 bool opaque_layers)
2552 : OcclusionTrackerTest<Types>(opaque_layers) {}
2553 void RunMyTest() {
2554 gfx::Transform scale_by_half;
2555 scale_by_half.Scale(0.5, 0.5);
2557 // Make a surface and its replica, each 50x50, that are partially occluded
2558 // by opaque layers which are above them in the z-order. The surface is
2559 // scaled to test that the pixel moving is done in the target space, where
2560 // the background filter is applied, but the surface appears at 50, 50 and
2561 // the replica at 200, 50.
2562 typename Types::ContentLayerType* parent = this->CreateRoot(
2563 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
2564 typename Types::LayerType* filtered_surface =
2565 this->CreateDrawingLayer(parent,
2566 scale_by_half,
2567 gfx::PointF(50.f, 50.f),
2568 gfx::Size(100, 100),
2569 false);
2570 this->CreateReplicaLayer(filtered_surface,
2571 this->identity_matrix,
2572 gfx::PointF(300.f, 0.f),
2573 gfx::Size());
2574 typename Types::LayerType* above_surface_layer =
2575 this->CreateDrawingLayer(parent,
2576 this->identity_matrix,
2577 gfx::PointF(70.f, 50.f),
2578 gfx::Size(30, 50),
2579 true);
2580 typename Types::LayerType* above_replica_layer =
2581 this->CreateDrawingLayer(parent,
2582 this->identity_matrix,
2583 gfx::PointF(200.f, 50.f),
2584 gfx::Size(30, 50),
2585 true);
2586 typename Types::LayerType* beside_surface_layer =
2587 this->CreateDrawingLayer(parent,
2588 this->identity_matrix,
2589 gfx::PointF(90.f, 40.f),
2590 gfx::Size(10, 10),
2591 true);
2592 typename Types::LayerType* beside_replica_layer =
2593 this->CreateDrawingLayer(parent,
2594 this->identity_matrix,
2595 gfx::PointF(200.f, 40.f),
2596 gfx::Size(10, 10),
2597 true);
2599 // Filters make the layer own a surface.
2600 FilterOperations filters;
2601 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2602 filtered_surface->SetBackgroundFilters(filters);
2604 // Save the distance of influence for the blur effect.
2605 int outset_top, outset_right, outset_bottom, outset_left;
2606 filters.GetOutsets(
2607 &outset_top, &outset_right, &outset_bottom, &outset_left);
2609 this->CalcDrawEtc(parent);
2611 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2612 gfx::Rect(0, 0, 1000, 1000));
2614 this->VisitLayer(beside_replica_layer, &occlusion);
2615 this->VisitLayer(beside_surface_layer, &occlusion);
2616 this->VisitLayer(above_replica_layer, &occlusion);
2617 this->VisitLayer(above_surface_layer, &occlusion);
2619 // The surface has a background blur, so it blurs non-opaque pixels below
2620 // it.
2621 this->VisitLayer(filtered_surface, &occlusion);
2622 this->VisitContributingSurface(filtered_surface, &occlusion);
2624 // The filter in the surface and replica are partially unoccluded. Only the
2625 // unoccluded parts should reduce occlusion. This means it will push back
2626 // the occlusion that touches the unoccluded part (occlusion_above___), but
2627 // it will not touch occlusion_beside____ since that is not beside the
2628 // unoccluded part of the surface, even though it is beside the occluded
2629 // part of the surface.
2630 gfx::Rect occlusion_above_surface =
2631 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
2632 gfx::Rect occlusion_above_replica =
2633 gfx::Rect(200, 50, 30 - outset_left, 50);
2634 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
2635 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
2637 SimpleEnclosedRegion expected_occlusion;
2638 expected_occlusion.Union(occlusion_beside_replica);
2639 expected_occlusion.Union(occlusion_beside_surface);
2640 expected_occlusion.Union(occlusion_above_replica);
2641 expected_occlusion.Union(occlusion_above_surface);
2643 EXPECT_EQ(expected_occlusion.ToString(),
2644 occlusion.occlusion_from_inside_target().ToString());
2645 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2647 const SimpleEnclosedRegion& actual_occlusion =
2648 occlusion.occlusion_from_inside_target();
2649 for (size_t i = 0; i < expected_occlusion.GetRegionComplexity(); ++i) {
2650 ASSERT_LT(i, actual_occlusion.GetRegionComplexity());
2651 EXPECT_EQ(expected_occlusion.GetRect(i), actual_occlusion.GetRect(i));
2656 ALL_OCCLUSIONTRACKER_TEST(
2657 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
2659 template <class Types>
2660 class OcclusionTrackerTestMinimumTrackingSize
2661 : public OcclusionTrackerTest<Types> {
2662 protected:
2663 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
2664 : OcclusionTrackerTest<Types>(opaque_layers) {}
2665 void RunMyTest() {
2666 gfx::Size tracking_size(100, 100);
2667 gfx::Size below_tracking_size(99, 99);
2669 typename Types::ContentLayerType* parent = this->CreateRoot(
2670 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2671 typename Types::LayerType* large = this->CreateDrawingLayer(
2672 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
2673 typename Types::LayerType* small =
2674 this->CreateDrawingLayer(parent,
2675 this->identity_matrix,
2676 gfx::PointF(),
2677 below_tracking_size,
2678 true);
2679 this->CalcDrawEtc(parent);
2681 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2682 gfx::Rect(0, 0, 1000, 1000));
2683 occlusion.set_minimum_tracking_size(tracking_size);
2685 // The small layer is not tracked because it is too small.
2686 this->VisitLayer(small, &occlusion);
2688 EXPECT_EQ(gfx::Rect().ToString(),
2689 occlusion.occlusion_from_outside_target().ToString());
2690 EXPECT_EQ(gfx::Rect().ToString(),
2691 occlusion.occlusion_from_inside_target().ToString());
2693 // The large layer is tracked as it is large enough.
2694 this->VisitLayer(large, &occlusion);
2696 EXPECT_EQ(gfx::Rect().ToString(),
2697 occlusion.occlusion_from_outside_target().ToString());
2698 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
2699 occlusion.occlusion_from_inside_target().ToString());
2703 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
2705 template <class Types>
2706 class OcclusionTrackerTestScaledLayerIsClipped
2707 : public OcclusionTrackerTest<Types> {
2708 protected:
2709 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
2710 : OcclusionTrackerTest<Types>(opaque_layers) {}
2711 void RunMyTest() {
2712 gfx::Transform scale_transform;
2713 scale_transform.Scale(512.0, 512.0);
2715 typename Types::ContentLayerType* parent = this->CreateRoot(
2716 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2717 typename Types::LayerType* clip = this->CreateLayer(parent,
2718 this->identity_matrix,
2719 gfx::PointF(10.f, 10.f),
2720 gfx::Size(50, 50));
2721 clip->SetMasksToBounds(true);
2722 typename Types::LayerType* scale = this->CreateLayer(
2723 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
2724 typename Types::LayerType* scaled = this->CreateDrawingLayer(
2725 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
2726 this->CalcDrawEtc(parent);
2728 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2729 gfx::Rect(0, 0, 1000, 1000));
2731 this->VisitLayer(scaled, &occlusion);
2733 EXPECT_EQ(gfx::Rect().ToString(),
2734 occlusion.occlusion_from_outside_target().ToString());
2735 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2736 occlusion.occlusion_from_inside_target().ToString());
2740 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
2742 template <class Types>
2743 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
2744 : public OcclusionTrackerTest<Types> {
2745 protected:
2746 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
2747 : OcclusionTrackerTest<Types>(opaque_layers) {}
2748 void RunMyTest() {
2749 gfx::Transform scale_transform;
2750 scale_transform.Scale(512.0, 512.0);
2752 typename Types::ContentLayerType* parent = this->CreateRoot(
2753 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2754 typename Types::LayerType* clip = this->CreateLayer(parent,
2755 this->identity_matrix,
2756 gfx::PointF(10.f, 10.f),
2757 gfx::Size(50, 50));
2758 clip->SetMasksToBounds(true);
2759 typename Types::LayerType* surface = this->CreateDrawingSurface(
2760 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
2761 typename Types::LayerType* scale = this->CreateLayer(
2762 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
2763 typename Types::LayerType* scaled = this->CreateDrawingLayer(
2764 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
2765 this->CalcDrawEtc(parent);
2767 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2768 gfx::Rect(0, 0, 1000, 1000));
2770 this->VisitLayer(scaled, &occlusion);
2771 this->VisitLayer(surface, &occlusion);
2772 this->VisitContributingSurface(surface, &occlusion);
2774 EXPECT_EQ(gfx::Rect().ToString(),
2775 occlusion.occlusion_from_outside_target().ToString());
2776 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2777 occlusion.occlusion_from_inside_target().ToString());
2781 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
2783 template <class Types>
2784 class OcclusionTrackerTestCopyRequestDoesOcclude
2785 : public OcclusionTrackerTest<Types> {
2786 protected:
2787 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
2788 : OcclusionTrackerTest<Types>(opaque_layers) {}
2789 void RunMyTest() {
2790 typename Types::ContentLayerType* root = this->CreateRoot(
2791 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2792 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
2793 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2794 typename Types::LayerType* copy = this->CreateLayer(parent,
2795 this->identity_matrix,
2796 gfx::Point(100, 0),
2797 gfx::Size(200, 400));
2798 this->AddCopyRequest(copy);
2799 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
2800 copy,
2801 this->identity_matrix,
2802 gfx::PointF(),
2803 gfx::Size(200, 400),
2804 true);
2805 this->CalcDrawEtc(root);
2807 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2808 gfx::Rect(0, 0, 1000, 1000));
2810 this->VisitLayer(copy_child, &occlusion);
2811 EXPECT_EQ(gfx::Rect().ToString(),
2812 occlusion.occlusion_from_outside_target().ToString());
2813 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2814 occlusion.occlusion_from_inside_target().ToString());
2816 // CopyRequests cause the layer to own a surface.
2817 this->VisitContributingSurface(copy, &occlusion);
2819 // The occlusion from the copy should be kept.
2820 EXPECT_EQ(gfx::Rect().ToString(),
2821 occlusion.occlusion_from_outside_target().ToString());
2822 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
2823 occlusion.occlusion_from_inside_target().ToString());
2827 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
2829 template <class Types>
2830 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2831 : public OcclusionTrackerTest<Types> {
2832 protected:
2833 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2834 bool opaque_layers)
2835 : OcclusionTrackerTest<Types>(opaque_layers) {}
2836 void RunMyTest() {
2837 typename Types::ContentLayerType* root = this->CreateRoot(
2838 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2839 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
2840 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2841 typename Types::LayerType* hide = this->CreateLayer(
2842 parent, this->identity_matrix, gfx::Point(), gfx::Size());
2843 typename Types::LayerType* copy = this->CreateLayer(
2844 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
2845 this->AddCopyRequest(copy);
2846 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
2847 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
2849 // The |copy| layer is hidden but since it is being copied, it will be
2850 // drawn.
2851 hide->SetHideLayerAndSubtree(true);
2853 this->CalcDrawEtc(root);
2855 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2856 gfx::Rect(0, 0, 1000, 1000));
2858 this->VisitLayer(copy_child, &occlusion);
2859 EXPECT_EQ(gfx::Rect().ToString(),
2860 occlusion.occlusion_from_outside_target().ToString());
2861 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2862 occlusion.occlusion_from_inside_target().ToString());
2864 // CopyRequests cause the layer to own a surface.
2865 this->VisitContributingSurface(copy, &occlusion);
2867 // The occlusion from the copy should be dropped since it is hidden.
2868 EXPECT_EQ(gfx::Rect().ToString(),
2869 occlusion.occlusion_from_outside_target().ToString());
2870 EXPECT_EQ(gfx::Rect().ToString(),
2871 occlusion.occlusion_from_inside_target().ToString());
2875 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
2877 template <class Types>
2878 class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest<Types> {
2879 protected:
2880 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers)
2881 : OcclusionTrackerTest<Types>(opaque_layers) {}
2882 void RunMyTest() {
2883 gfx::Transform translate;
2884 translate.Translate(10.0, 20.0);
2885 typename Types::ContentLayerType* root = this->CreateRoot(
2886 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2887 typename Types::LayerType* surface = this->CreateSurface(
2888 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2889 typename Types::LayerType* layer = this->CreateDrawingLayer(
2890 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2891 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
2892 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2893 this->CalcDrawEtc(root);
2895 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2896 gfx::Rect(0, 0, 200, 200));
2897 this->VisitLayer(outside_layer, &occlusion);
2898 this->EnterLayer(layer, &occlusion);
2900 // No occlusion, is not occluded.
2901 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2902 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2903 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100)));
2905 // Partial occlusion from outside, is not occluded.
2906 occlusion.set_occlusion_from_outside_target(
2907 SimpleEnclosedRegion(50, 50, 100, 100));
2908 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2909 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2910 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2911 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2912 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2913 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2914 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2915 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2916 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2918 // Full occlusion from outside, is occluded.
2919 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2920 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2921 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2922 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2924 // Partial occlusion from inside, is not occluded.
2925 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2926 occlusion.set_occlusion_from_inside_target(
2927 SimpleEnclosedRegion(50, 50, 100, 100));
2928 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2929 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2930 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2931 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2932 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2933 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2934 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2935 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2937 // Full occlusion from inside, is occluded.
2938 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2939 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2940 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2941 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2943 // Partial occlusion from both, is not occluded.
2944 occlusion.set_occlusion_from_outside_target(
2945 SimpleEnclosedRegion(50, 50, 100, 50));
2946 occlusion.set_occlusion_from_inside_target(
2947 SimpleEnclosedRegion(50, 100, 100, 50));
2948 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2949 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2950 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2951 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2952 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2953 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2954 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2955 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2957 // Full occlusion from both, is occluded.
2958 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2959 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2960 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2961 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2965 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer)
2967 template <class Types>
2968 class OcclusionTrackerTestUnoccludedLayerQuery
2969 : public OcclusionTrackerTest<Types> {
2970 protected:
2971 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers)
2972 : OcclusionTrackerTest<Types>(opaque_layers) {}
2973 void RunMyTest() {
2974 gfx::Transform translate;
2975 translate.Translate(10.0, 20.0);
2976 typename Types::ContentLayerType* root = this->CreateRoot(
2977 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2978 typename Types::LayerType* surface = this->CreateSurface(
2979 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2980 typename Types::LayerType* layer = this->CreateDrawingLayer(
2981 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2982 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
2983 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2984 this->CalcDrawEtc(root);
2986 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2987 gfx::Rect(0, 0, 200, 200));
2988 this->VisitLayer(outside_layer, &occlusion);
2989 this->EnterLayer(layer, &occlusion);
2991 // No occlusion, is not occluded.
2992 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2993 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2994 EXPECT_EQ(gfx::Rect(100, 100),
2995 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(100, 100)));
2997 // Partial occlusion from outside.
2998 occlusion.set_occlusion_from_outside_target(
2999 SimpleEnclosedRegion(50, 50, 100, 100));
3000 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3001 EXPECT_EQ(
3002 gfx::Rect(0, 0, 100, 100),
3003 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3004 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3005 occlusion.UnoccludedLayerContentRect(
3006 layer, gfx::Rect(90, 30, 100, 100)));
3007 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3008 occlusion.UnoccludedLayerContentRect(layer,
3009 gfx::Rect(40, 0, 100, 100)));
3010 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3011 occlusion.UnoccludedLayerContentRect(
3012 layer, gfx::Rect(40, 80, 100, 100)));
3013 EXPECT_EQ(
3014 gfx::Rect(0, 0, 80, 100),
3015 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3016 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3017 occlusion.UnoccludedLayerContentRect(
3018 layer, gfx::Rect(90, 80, 100, 100)));
3019 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3020 occlusion.UnoccludedLayerContentRect(layer,
3021 gfx::Rect(0, 80, 100, 100)));
3022 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3023 occlusion.UnoccludedLayerContentRect(layer,
3024 gfx::Rect(90, 0, 100, 100)));
3026 // Full occlusion from outside, is occluded.
3027 EXPECT_EQ(gfx::Rect(),
3028 occlusion.UnoccludedLayerContentRect(
3029 layer, gfx::Rect(40, 30, 100, 100)));
3030 EXPECT_EQ(
3031 gfx::Rect(),
3032 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3033 EXPECT_EQ(gfx::Rect(),
3034 occlusion.UnoccludedLayerContentRect(
3035 layer, gfx::Rect(130, 120, 10, 10)));
3036 EXPECT_EQ(
3037 gfx::Rect(),
3038 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3040 // Partial occlusion from inside, is not occluded.
3041 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3042 occlusion.set_occlusion_from_inside_target(
3043 SimpleEnclosedRegion(50, 50, 100, 100));
3044 EXPECT_EQ(
3045 gfx::Rect(0, 0, 100, 100),
3046 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3047 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3048 occlusion.UnoccludedLayerContentRect(
3049 layer, gfx::Rect(90, 30, 100, 100)));
3050 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3051 occlusion.UnoccludedLayerContentRect(layer,
3052 gfx::Rect(40, 0, 100, 100)));
3053 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3054 occlusion.UnoccludedLayerContentRect(
3055 layer, gfx::Rect(40, 80, 100, 100)));
3056 EXPECT_EQ(
3057 gfx::Rect(0, 0, 80, 100),
3058 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3059 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3060 occlusion.UnoccludedLayerContentRect(
3061 layer, gfx::Rect(90, 80, 100, 100)));
3062 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3063 occlusion.UnoccludedLayerContentRect(layer,
3064 gfx::Rect(0, 80, 100, 100)));
3065 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3066 occlusion.UnoccludedLayerContentRect(layer,
3067 gfx::Rect(90, 0, 100, 100)));
3069 // Full occlusion from inside, is occluded.
3070 EXPECT_EQ(gfx::Rect(),
3071 occlusion.UnoccludedLayerContentRect(
3072 layer, gfx::Rect(40, 30, 100, 100)));
3073 EXPECT_EQ(
3074 gfx::Rect(),
3075 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3076 EXPECT_EQ(gfx::Rect(),
3077 occlusion.UnoccludedLayerContentRect(
3078 layer, gfx::Rect(130, 120, 10, 10)));
3079 EXPECT_EQ(
3080 gfx::Rect(),
3081 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3083 // Partial occlusion from both, is not occluded.
3084 occlusion.set_occlusion_from_outside_target(
3085 SimpleEnclosedRegion(50, 50, 100, 50));
3086 occlusion.set_occlusion_from_inside_target(
3087 SimpleEnclosedRegion(50, 100, 100, 50));
3088 EXPECT_EQ(
3089 gfx::Rect(0, 0, 100, 100),
3090 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3091 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3092 // it's larger.
3093 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3094 occlusion.UnoccludedLayerContentRect(
3095 layer, gfx::Rect(90, 30, 100, 100)));
3096 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3097 occlusion.UnoccludedLayerContentRect(layer,
3098 gfx::Rect(40, 0, 100, 100)));
3099 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3100 occlusion.UnoccludedLayerContentRect(
3101 layer, gfx::Rect(40, 80, 100, 100)));
3102 EXPECT_EQ(
3103 gfx::Rect(0, 0, 80, 100),
3104 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3105 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3106 occlusion.UnoccludedLayerContentRect(
3107 layer, gfx::Rect(90, 80, 100, 100)));
3108 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3109 occlusion.UnoccludedLayerContentRect(layer,
3110 gfx::Rect(0, 80, 100, 100)));
3111 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3112 occlusion.UnoccludedLayerContentRect(layer,
3113 gfx::Rect(90, 0, 100, 100)));
3115 // Full occlusion from both, is occluded.
3116 EXPECT_EQ(gfx::Rect(),
3117 occlusion.UnoccludedLayerContentRect(
3118 layer, gfx::Rect(40, 30, 100, 100)));
3119 EXPECT_EQ(
3120 gfx::Rect(),
3121 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3122 EXPECT_EQ(gfx::Rect(),
3123 occlusion.UnoccludedLayerContentRect(
3124 layer, gfx::Rect(130, 120, 10, 10)));
3125 EXPECT_EQ(
3126 gfx::Rect(),
3127 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3131 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery)
3133 template <class Types>
3134 class OcclusionTrackerTestUnoccludedSurfaceQuery
3135 : public OcclusionTrackerTest<Types> {
3136 protected:
3137 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers)
3138 : OcclusionTrackerTest<Types>(opaque_layers) {}
3139 void RunMyTest() {
3140 gfx::Transform translate;
3141 translate.Translate(10.0, 20.0);
3142 typename Types::ContentLayerType* root = this->CreateRoot(
3143 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
3144 typename Types::LayerType* surface =
3145 this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200));
3146 typename Types::LayerType* layer =
3147 this->CreateDrawingLayer(surface,
3148 this->identity_matrix,
3149 gfx::Point(),
3150 gfx::Size(200, 200),
3151 false);
3152 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
3153 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
3154 this->CalcDrawEtc(root);
3156 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3157 gfx::Rect(0, 0, 200, 200));
3158 this->VisitLayer(outside_layer, &occlusion);
3159 this->VisitLayer(layer, &occlusion);
3160 this->EnterContributingSurface(surface, &occlusion);
3162 // No occlusion, is not occluded.
3163 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3164 SimpleEnclosedRegion());
3165 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3166 SimpleEnclosedRegion());
3167 EXPECT_EQ(
3168 gfx::Rect(100, 100),
3169 occlusion.UnoccludedSurfaceContentRect(surface, gfx::Rect(100, 100)));
3171 // Partial occlusion from outside.
3172 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3173 SimpleEnclosedRegion(50, 50, 100, 100));
3174 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3175 SimpleEnclosedRegion());
3176 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3177 occlusion.UnoccludedSurfaceContentRect(
3178 surface, gfx::Rect(0, 0, 100, 100)));
3179 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3180 occlusion.UnoccludedSurfaceContentRect(
3181 surface, gfx::Rect(90, 30, 100, 100)));
3182 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3183 occlusion.UnoccludedSurfaceContentRect(
3184 surface, gfx::Rect(40, 0, 100, 100)));
3185 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3186 occlusion.UnoccludedSurfaceContentRect(
3187 surface, gfx::Rect(40, 80, 100, 100)));
3188 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3189 occlusion.UnoccludedSurfaceContentRect(surface,
3190 gfx::Rect(0, 0, 80, 100)));
3191 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3192 occlusion.UnoccludedSurfaceContentRect(
3193 surface, gfx::Rect(90, 80, 100, 100)));
3194 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3195 occlusion.UnoccludedSurfaceContentRect(
3196 surface, gfx::Rect(0, 80, 100, 100)));
3197 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3198 occlusion.UnoccludedSurfaceContentRect(
3199 surface, gfx::Rect(90, 0, 100, 100)));
3201 // Full occlusion from outside, is occluded.
3202 EXPECT_EQ(gfx::Rect(),
3203 occlusion.UnoccludedSurfaceContentRect(
3204 surface, gfx::Rect(40, 30, 100, 100)));
3205 EXPECT_EQ(gfx::Rect(),
3206 occlusion.UnoccludedSurfaceContentRect(
3207 surface, gfx::Rect(40, 30, 10, 10)));
3208 EXPECT_EQ(gfx::Rect(),
3209 occlusion.UnoccludedSurfaceContentRect(
3210 surface, gfx::Rect(130, 120, 10, 10)));
3211 EXPECT_EQ(gfx::Rect(),
3212 occlusion.UnoccludedSurfaceContentRect(
3213 surface, gfx::Rect(80, 70, 50, 50)));
3215 // Partial occlusion from inside, is not occluded.
3216 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3217 SimpleEnclosedRegion());
3218 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3219 SimpleEnclosedRegion(50, 50, 100, 100));
3220 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3221 occlusion.UnoccludedSurfaceContentRect(
3222 surface, gfx::Rect(0, 0, 100, 100)));
3223 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3224 occlusion.UnoccludedSurfaceContentRect(
3225 surface, gfx::Rect(90, 30, 100, 100)));
3226 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3227 occlusion.UnoccludedSurfaceContentRect(
3228 surface, gfx::Rect(40, 0, 100, 100)));
3229 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3230 occlusion.UnoccludedSurfaceContentRect(
3231 surface, gfx::Rect(40, 80, 100, 100)));
3232 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3233 occlusion.UnoccludedSurfaceContentRect(surface,
3234 gfx::Rect(0, 0, 80, 100)));
3235 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3236 occlusion.UnoccludedSurfaceContentRect(
3237 surface, gfx::Rect(90, 80, 100, 100)));
3238 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3239 occlusion.UnoccludedSurfaceContentRect(
3240 surface, gfx::Rect(0, 80, 100, 100)));
3241 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3242 occlusion.UnoccludedSurfaceContentRect(
3243 surface, gfx::Rect(90, 0, 100, 100)));
3245 // Full occlusion from inside, is occluded.
3246 EXPECT_EQ(gfx::Rect(),
3247 occlusion.UnoccludedSurfaceContentRect(
3248 surface, gfx::Rect(40, 30, 100, 100)));
3249 EXPECT_EQ(gfx::Rect(),
3250 occlusion.UnoccludedSurfaceContentRect(
3251 surface, gfx::Rect(40, 30, 10, 10)));
3252 EXPECT_EQ(gfx::Rect(),
3253 occlusion.UnoccludedSurfaceContentRect(
3254 surface, gfx::Rect(130, 120, 10, 10)));
3255 EXPECT_EQ(gfx::Rect(),
3256 occlusion.UnoccludedSurfaceContentRect(
3257 surface, gfx::Rect(80, 70, 50, 50)));
3259 // Partial occlusion from both, is not occluded.
3260 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3261 SimpleEnclosedRegion(50, 50, 100, 50));
3262 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3263 SimpleEnclosedRegion(50, 100, 100, 50));
3264 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3265 occlusion.UnoccludedSurfaceContentRect(
3266 surface, gfx::Rect(0, 0, 100, 100)));
3267 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3268 // it's larger.
3269 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3270 occlusion.UnoccludedSurfaceContentRect(
3271 surface, gfx::Rect(90, 30, 100, 100)));
3272 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3273 occlusion.UnoccludedSurfaceContentRect(
3274 surface, gfx::Rect(40, 0, 100, 100)));
3275 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3276 occlusion.UnoccludedSurfaceContentRect(
3277 surface, gfx::Rect(40, 80, 100, 100)));
3278 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3279 occlusion.UnoccludedSurfaceContentRect(surface,
3280 gfx::Rect(0, 0, 80, 100)));
3281 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3282 occlusion.UnoccludedSurfaceContentRect(
3283 surface, gfx::Rect(90, 80, 100, 100)));
3284 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3285 occlusion.UnoccludedSurfaceContentRect(
3286 surface, gfx::Rect(0, 80, 100, 100)));
3287 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3288 occlusion.UnoccludedSurfaceContentRect(
3289 surface, gfx::Rect(90, 0, 100, 100)));
3291 // Full occlusion from both, is occluded.
3292 EXPECT_EQ(gfx::Rect(),
3293 occlusion.UnoccludedSurfaceContentRect(
3294 surface, gfx::Rect(40, 30, 100, 100)));
3295 EXPECT_EQ(gfx::Rect(),
3296 occlusion.UnoccludedSurfaceContentRect(
3297 surface, gfx::Rect(40, 30, 10, 10)));
3298 EXPECT_EQ(gfx::Rect(),
3299 occlusion.UnoccludedSurfaceContentRect(
3300 surface, gfx::Rect(130, 120, 10, 10)));
3301 EXPECT_EQ(gfx::Rect(),
3302 occlusion.UnoccludedSurfaceContentRect(
3303 surface, gfx::Rect(80, 70, 50, 50)));
3307 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery)
3309 } // namespace
3310 } // namespace cc