Update mojo sdk to rev cb6c5abfadfea0ca73dca466e2894554ac1ae144
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blobf3f218570eb52a71f989222dc88afc1ca3c53371
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->GetCurrentOcclusionForContributingSurface(
105 surface->draw_transform())
106 .GetUnoccludedContentRect(content_rect);
110 struct OcclusionTrackerTestMainThreadTypes {
111 typedef Layer LayerType;
112 typedef FakeLayerTreeHost HostType;
113 typedef RenderSurface RenderSurfaceType;
114 typedef TestContentLayer ContentLayerType;
115 typedef scoped_refptr<Layer> LayerPtrType;
116 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
117 typedef LayerIterator<Layer> TestLayerIterator;
118 typedef OcclusionTracker<Layer> OcclusionTrackerType;
120 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
121 static ContentLayerPtrType CreateContentLayer(HostType* host) {
122 return make_scoped_refptr(new ContentLayerType());
125 template <typename T>
126 static LayerPtrType PassLayerPtr(T* layer) {
127 LayerPtrType ref(*layer);
128 *layer = NULL;
129 return ref;
131 static void SetForceRenderSurface(LayerType* layer, bool force) {
132 layer->SetForceRenderSurface(force);
135 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
137 static void RecursiveUpdateNumChildren(LayerType* layerType) {}
140 struct OcclusionTrackerTestImplThreadTypes {
141 typedef LayerImpl LayerType;
142 typedef LayerTreeImpl HostType;
143 typedef RenderSurfaceImpl RenderSurfaceType;
144 typedef TestContentLayerImpl ContentLayerType;
145 typedef scoped_ptr<LayerImpl> LayerPtrType;
146 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
147 typedef LayerIterator<LayerImpl> TestLayerIterator;
148 typedef OcclusionTracker<LayerImpl> OcclusionTrackerType;
150 static LayerPtrType CreateLayer(HostType* host) {
151 return LayerImpl::Create(host, next_layer_impl_id++);
153 static ContentLayerPtrType CreateContentLayer(HostType* host) {
154 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
156 static int next_layer_impl_id;
158 template <typename T>
159 static LayerPtrType PassLayerPtr(T* layer) {
160 return layer->Pass();
163 static void SetForceRenderSurface(LayerType* layer, bool force) {
164 layer->SetHasRenderSurface(force);
166 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
168 static void RecursiveUpdateNumChildren(LayerType* layer) {
169 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer);
173 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
175 template <typename Types> class OcclusionTrackerTest : public testing::Test {
176 protected:
177 explicit OcclusionTrackerTest(bool opaque_layers)
178 : opaque_layers_(opaque_layers),
179 client_(FakeLayerTreeHostClient::DIRECT_3D),
180 host_(FakeLayerTreeHost::Create(&client_)) {}
182 virtual void RunMyTest() = 0;
184 void TearDown() override { DestroyLayers(); }
186 typename Types::HostType* GetHost();
188 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
189 const gfx::PointF& position,
190 const gfx::Size& bounds) {
191 typename Types::ContentLayerPtrType layer(
192 Types::CreateContentLayer(GetHost()));
193 typename Types::ContentLayerType* layer_ptr = layer.get();
194 SetProperties(layer_ptr, transform, position, bounds);
196 DCHECK(!root_.get());
197 root_ = Types::PassLayerPtr(&layer);
199 Types::SetForceRenderSurface(layer_ptr, true);
200 SetRootLayerOnMainThread(layer_ptr);
202 return layer_ptr;
205 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
206 const gfx::Transform& transform,
207 const gfx::PointF& position,
208 const gfx::Size& bounds) {
209 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
210 typename Types::LayerType* layer_ptr = layer.get();
211 SetProperties(layer_ptr, transform, position, bounds);
212 parent->AddChild(Types::PassLayerPtr(&layer));
213 return layer_ptr;
216 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
217 const gfx::Transform& transform,
218 const gfx::PointF& position,
219 const gfx::Size& bounds) {
220 typename Types::LayerType* layer =
221 CreateLayer(parent, transform, position, bounds);
222 Types::SetForceRenderSurface(layer, true);
223 return layer;
226 typename Types::ContentLayerType* CreateDrawingLayer(
227 typename Types::LayerType* parent,
228 const gfx::Transform& transform,
229 const gfx::PointF& position,
230 const gfx::Size& bounds,
231 bool opaque) {
232 typename Types::ContentLayerPtrType layer(
233 Types::CreateContentLayer(GetHost()));
234 typename Types::ContentLayerType* layer_ptr = layer.get();
235 SetProperties(layer_ptr, transform, position, bounds);
237 if (opaque_layers_) {
238 layer_ptr->SetContentsOpaque(opaque);
239 } else {
240 layer_ptr->SetContentsOpaque(false);
241 if (opaque)
242 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
243 else
244 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
247 parent->AddChild(Types::PassLayerPtr(&layer));
248 return layer_ptr;
251 typename Types::LayerType* CreateReplicaLayer(
252 typename Types::LayerType* owning_layer,
253 const gfx::Transform& transform,
254 const gfx::PointF& position,
255 const gfx::Size& bounds) {
256 typename Types::ContentLayerPtrType layer(
257 Types::CreateContentLayer(GetHost()));
258 typename Types::ContentLayerType* layer_ptr = layer.get();
259 SetProperties(layer_ptr, transform, position, bounds);
260 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
261 return layer_ptr;
264 typename Types::LayerType* CreateMaskLayer(
265 typename Types::LayerType* owning_layer,
266 const gfx::Size& bounds) {
267 typename Types::ContentLayerPtrType layer(
268 Types::CreateContentLayer(GetHost()));
269 typename Types::ContentLayerType* layer_ptr = layer.get();
270 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
271 SetMask(owning_layer, Types::PassLayerPtr(&layer));
272 return layer_ptr;
275 typename Types::ContentLayerType* CreateDrawingSurface(
276 typename Types::LayerType* parent,
277 const gfx::Transform& transform,
278 const gfx::PointF& position,
279 const gfx::Size& bounds,
280 bool opaque) {
281 typename Types::ContentLayerType* layer =
282 CreateDrawingLayer(parent, transform, position, bounds, opaque);
283 Types::SetForceRenderSurface(layer, true);
284 return layer;
287 void DestroyLayers() {
288 Types::DestroyLayer(&root_);
289 render_surface_layer_list_ = nullptr;
290 render_surface_layer_list_impl_.clear();
291 replica_layers_.clear();
292 mask_layers_.clear();
293 ResetLayerIterator();
296 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
298 void AddCopyRequest(Layer* layer) {
299 layer->RequestCopyOfOutput(
300 CopyOutputRequest::CreateBitmapRequest(base::Bind(
301 &OcclusionTrackerTest<Types>::CopyOutputCallback,
302 base::Unretained(this))));
305 void AddCopyRequest(LayerImpl* layer) {
306 ScopedPtrVector<CopyOutputRequest> requests;
307 requests.push_back(
308 CopyOutputRequest::CreateBitmapRequest(base::Bind(
309 &OcclusionTrackerTest<Types>::CopyOutputCallback,
310 base::Unretained(this))));
311 layer->SetHasRenderSurface(true);
312 layer->PassCopyRequests(&requests);
315 void CalcDrawEtc(TestContentLayerImpl* root) {
316 DCHECK(root == root_.get());
318 Types::RecursiveUpdateNumChildren(root);
319 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
320 root, root->bounds(), &render_surface_layer_list_impl_);
321 inputs.can_adjust_raster_scales = true;
322 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
324 layer_iterator_ = layer_iterator_begin_ =
325 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
328 void CalcDrawEtc(TestContentLayer* root) {
329 DCHECK(root == root_.get());
330 DCHECK(!root->render_surface());
332 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
333 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
334 root, root->bounds(), render_surface_layer_list_.get());
335 inputs.can_adjust_raster_scales = true;
336 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
338 layer_iterator_ = layer_iterator_begin_ =
339 Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
342 void EnterLayer(typename Types::LayerType* layer,
343 typename Types::OcclusionTrackerType* occlusion) {
344 ASSERT_EQ(*layer_iterator_, layer);
345 ASSERT_TRUE(layer_iterator_.represents_itself());
346 occlusion->EnterLayer(layer_iterator_);
349 void LeaveLayer(typename Types::LayerType* layer,
350 typename Types::OcclusionTrackerType* occlusion) {
351 ASSERT_EQ(*layer_iterator_, layer);
352 ASSERT_TRUE(layer_iterator_.represents_itself());
353 occlusion->LeaveLayer(layer_iterator_);
354 ++layer_iterator_;
357 void VisitLayer(typename Types::LayerType* layer,
358 typename Types::OcclusionTrackerType* occlusion) {
359 EnterLayer(layer, occlusion);
360 LeaveLayer(layer, occlusion);
363 void EnterContributingSurface(
364 typename Types::LayerType* layer,
365 typename Types::OcclusionTrackerType* occlusion) {
366 ASSERT_EQ(*layer_iterator_, layer);
367 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
368 occlusion->EnterLayer(layer_iterator_);
369 occlusion->LeaveLayer(layer_iterator_);
370 ++layer_iterator_;
371 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
372 occlusion->EnterLayer(layer_iterator_);
375 void LeaveContributingSurface(
376 typename Types::LayerType* layer,
377 typename Types::OcclusionTrackerType* occlusion) {
378 ASSERT_EQ(*layer_iterator_, layer);
379 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
380 occlusion->LeaveLayer(layer_iterator_);
381 ++layer_iterator_;
384 void VisitContributingSurface(
385 typename Types::LayerType* layer,
386 typename Types::OcclusionTrackerType* occlusion) {
387 EnterContributingSurface(layer, occlusion);
388 LeaveContributingSurface(layer, occlusion);
391 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
393 const gfx::Transform identity_matrix;
395 private:
396 void SetRootLayerOnMainThread(Layer* root) {
397 host_->SetRootLayer(scoped_refptr<Layer>(root));
400 void SetRootLayerOnMainThread(LayerImpl* root) {}
402 void SetBaseProperties(typename Types::LayerType* layer,
403 const gfx::Transform& transform,
404 const gfx::PointF& position,
405 const gfx::Size& bounds) {
406 layer->SetTransform(transform);
407 layer->SetPosition(position);
408 layer->SetBounds(bounds);
411 void SetProperties(Layer* layer,
412 const gfx::Transform& transform,
413 const gfx::PointF& position,
414 const gfx::Size& bounds) {
415 SetBaseProperties(layer, transform, position, bounds);
418 void SetProperties(LayerImpl* layer,
419 const gfx::Transform& transform,
420 const gfx::PointF& position,
421 const gfx::Size& bounds) {
422 SetBaseProperties(layer, transform, position, bounds);
424 layer->SetContentBounds(layer->bounds());
427 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
428 owning_layer->SetReplicaLayer(layer.get());
429 replica_layers_.push_back(layer);
432 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
433 owning_layer->SetReplicaLayer(layer.Pass());
436 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
437 owning_layer->SetMaskLayer(layer.get());
438 mask_layers_.push_back(layer);
441 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
442 owning_layer->SetMaskLayer(layer.Pass());
445 bool opaque_layers_;
446 FakeLayerTreeHostClient client_;
447 scoped_ptr<FakeLayerTreeHost> host_;
448 // These hold ownership of the layers for the duration of the test.
449 typename Types::LayerPtrType root_;
450 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
451 LayerImplList render_surface_layer_list_impl_;
452 typename Types::TestLayerIterator layer_iterator_begin_;
453 typename Types::TestLayerIterator layer_iterator_;
454 typename Types::LayerType* last_layer_visited_;
455 LayerList replica_layers_;
456 LayerList mask_layers_;
459 template <>
460 FakeLayerTreeHost*
461 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
462 return host_.get();
465 template <>
466 LayerTreeImpl*
467 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
468 return host_->host_impl()->active_tree();
471 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
472 class ClassName##MainThreadOpaqueLayers \
473 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
474 public: /* NOLINT(whitespace/indent) */ \
475 ClassName##MainThreadOpaqueLayers() \
476 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
477 }; \
478 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
479 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
480 class ClassName##MainThreadOpaquePaints \
481 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
482 public: /* NOLINT(whitespace/indent) */ \
483 ClassName##MainThreadOpaquePaints() \
484 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
485 }; \
486 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
488 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
489 class ClassName##ImplThreadOpaqueLayers \
490 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
491 public: /* NOLINT(whitespace/indent) */ \
492 ClassName##ImplThreadOpaqueLayers() \
493 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
494 }; \
495 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
496 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
497 class ClassName##ImplThreadOpaquePaints \
498 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
499 public: /* NOLINT(whitespace/indent) */ \
500 ClassName##ImplThreadOpaquePaints() \
501 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
502 }; \
503 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
505 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
506 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
507 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
508 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
509 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
511 #define MAIN_THREAD_TEST(ClassName) \
512 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
514 #define IMPL_THREAD_TEST(ClassName) \
515 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
517 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
518 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
519 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
521 template <class Types>
522 class OcclusionTrackerTestIdentityTransforms
523 : public OcclusionTrackerTest<Types> {
524 protected:
525 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
526 : OcclusionTrackerTest<Types>(opaque_layers) {}
528 void RunMyTest() override {
529 typename Types::ContentLayerType* root = this->CreateRoot(
530 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
531 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
532 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
533 typename Types::ContentLayerType* layer =
534 this->CreateDrawingLayer(parent,
535 this->identity_matrix,
536 gfx::PointF(30.f, 30.f),
537 gfx::Size(500, 500),
538 true);
539 parent->SetMasksToBounds(true);
540 this->CalcDrawEtc(root);
542 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
543 gfx::Rect(0, 0, 1000, 1000));
545 this->VisitLayer(layer, &occlusion);
546 this->EnterLayer(parent, &occlusion);
548 EXPECT_EQ(gfx::Rect().ToString(),
549 occlusion.occlusion_from_outside_target().ToString());
550 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
551 occlusion.occlusion_from_inside_target().ToString());
555 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
557 template <class Types>
558 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
559 protected:
560 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
561 : OcclusionTrackerTest<Types>(opaque_layers) {}
562 void RunMyTest() override {
563 gfx::Transform layer_transform;
564 layer_transform.Translate(250.0, 250.0);
565 layer_transform.Rotate(90.0);
566 layer_transform.Translate(-250.0, -250.0);
568 typename Types::ContentLayerType* root = this->CreateRoot(
569 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
570 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
571 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
572 typename Types::ContentLayerType* layer =
573 this->CreateDrawingLayer(parent,
574 layer_transform,
575 gfx::PointF(30.f, 30.f),
576 gfx::Size(500, 500),
577 true);
578 parent->SetMasksToBounds(true);
579 this->CalcDrawEtc(root);
581 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
582 gfx::Rect(0, 0, 1000, 1000));
584 this->VisitLayer(layer, &occlusion);
585 this->EnterLayer(parent, &occlusion);
587 EXPECT_EQ(gfx::Rect().ToString(),
588 occlusion.occlusion_from_outside_target().ToString());
589 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
590 occlusion.occlusion_from_inside_target().ToString());
594 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
596 template <class Types>
597 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
598 protected:
599 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
600 : OcclusionTrackerTest<Types>(opaque_layers) {}
601 void RunMyTest() override {
602 gfx::Transform layer_transform;
603 layer_transform.Translate(20.0, 20.0);
605 typename Types::ContentLayerType* root = this->CreateRoot(
606 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
607 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
608 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
609 typename Types::ContentLayerType* layer =
610 this->CreateDrawingLayer(parent,
611 layer_transform,
612 gfx::PointF(30.f, 30.f),
613 gfx::Size(500, 500),
614 true);
615 parent->SetMasksToBounds(true);
616 this->CalcDrawEtc(root);
618 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
619 gfx::Rect(0, 0, 1000, 1000));
621 this->VisitLayer(layer, &occlusion);
622 this->EnterLayer(parent, &occlusion);
624 EXPECT_EQ(gfx::Rect().ToString(),
625 occlusion.occlusion_from_outside_target().ToString());
626 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
627 occlusion.occlusion_from_inside_target().ToString());
631 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
633 template <class Types>
634 class OcclusionTrackerTestChildInRotatedChild
635 : public OcclusionTrackerTest<Types> {
636 protected:
637 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
638 : OcclusionTrackerTest<Types>(opaque_layers) {}
639 void RunMyTest() override {
640 gfx::Transform child_transform;
641 child_transform.Translate(250.0, 250.0);
642 child_transform.Rotate(90.0);
643 child_transform.Translate(-250.0, -250.0);
645 typename Types::ContentLayerType* parent = this->CreateRoot(
646 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
647 parent->SetMasksToBounds(true);
648 typename Types::LayerType* child = this->CreateSurface(
649 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
650 child->SetMasksToBounds(true);
651 typename Types::ContentLayerType* layer =
652 this->CreateDrawingLayer(child,
653 this->identity_matrix,
654 gfx::PointF(10.f, 10.f),
655 gfx::Size(500, 500),
656 true);
657 this->CalcDrawEtc(parent);
659 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
660 gfx::Rect(0, 0, 1000, 1000));
662 this->VisitLayer(layer, &occlusion);
663 this->EnterContributingSurface(child, &occlusion);
665 EXPECT_EQ(gfx::Rect().ToString(),
666 occlusion.occlusion_from_outside_target().ToString());
667 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
668 occlusion.occlusion_from_inside_target().ToString());
670 this->LeaveContributingSurface(child, &occlusion);
671 this->EnterLayer(parent, &occlusion);
673 EXPECT_EQ(gfx::Rect().ToString(),
674 occlusion.occlusion_from_outside_target().ToString());
675 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
676 occlusion.occlusion_from_inside_target().ToString());
678 /* Justification for the above occlusion from |layer|:
680 +---------------------+
682 | 30 | rotate(90)
683 | 30 + ---------------------------------+
684 100 | | 10 | | ==>
685 | |10+---------------------------------+
686 | | | | | |
687 | | | | | |
688 | | | | | |
689 +----|--|-------------+ | |
690 | | | |
691 | | | |
692 | | | |500
693 | | | |
694 | | | |
695 | | | |
696 | | | |
697 +--|-------------------------------+ |
699 +---------------------------------+
702 +---------------------+
703 | |30 Visible region of |layer|: /////
705 | +---------------------------------+
706 100| | |10 |
707 | +---------------------------------+ |
708 | | |///////////////| 420 | |
709 | | |///////////////|60 | |
710 | | |///////////////| | |
711 +--|--|---------------+ | |
712 20|10| 70 | |
713 | | | |
714 | | | |
715 | | | |
716 | | | |
717 | | | |
718 | | |10|
719 | +------------------------------|--+
720 | 490 |
721 +---------------------------------+
728 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
730 template <class Types>
731 class OcclusionTrackerTestScaledRenderSurface
732 : public OcclusionTrackerTest<Types> {
733 protected:
734 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
735 : OcclusionTrackerTest<Types>(opaque_layers) {}
737 void RunMyTest() override {
738 typename Types::ContentLayerType* parent = this->CreateRoot(
739 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
741 gfx::Transform layer1_matrix;
742 layer1_matrix.Scale(2.0, 2.0);
743 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
744 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
745 Types::SetForceRenderSurface(layer1, true);
747 gfx::Transform layer2_matrix;
748 layer2_matrix.Translate(25.0, 25.0);
749 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
750 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
751 typename Types::ContentLayerType* occluder =
752 this->CreateDrawingLayer(parent,
753 this->identity_matrix,
754 gfx::PointF(100.f, 100.f),
755 gfx::Size(500, 500),
756 true);
757 this->CalcDrawEtc(parent);
759 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
760 gfx::Rect(0, 0, 1000, 1000));
762 this->VisitLayer(occluder, &occlusion);
763 this->EnterLayer(layer2, &occlusion);
765 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
766 occlusion.occlusion_from_outside_target().ToString());
767 EXPECT_EQ(gfx::Rect().ToString(),
768 occlusion.occlusion_from_inside_target().ToString());
772 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
774 template <class Types>
775 class OcclusionTrackerTestVisitTargetTwoTimes
776 : public OcclusionTrackerTest<Types> {
777 protected:
778 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
779 : OcclusionTrackerTest<Types>(opaque_layers) {}
780 void RunMyTest() override {
781 typename Types::ContentLayerType* root = this->CreateRoot(
782 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
783 typename Types::LayerType* surface = this->CreateSurface(
784 root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size());
785 typename Types::ContentLayerType* surface_child =
786 this->CreateDrawingLayer(surface,
787 this->identity_matrix,
788 gfx::PointF(10.f, 10.f),
789 gfx::Size(50, 50),
790 true);
791 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
792 // first, instead of |surface|'s. This exercises different code in
793 // LeaveToRenderTarget, as the target surface has already been seen when
794 // leaving |surface| later.
795 typename Types::ContentLayerType* top_layer =
796 this->CreateDrawingLayer(root,
797 this->identity_matrix,
798 gfx::PointF(40.f, 90.f),
799 gfx::Size(50, 20),
800 true);
801 this->CalcDrawEtc(root);
803 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
804 gfx::Rect(0, 0, 1000, 1000));
806 this->VisitLayer(top_layer, &occlusion);
808 EXPECT_EQ(gfx::Rect().ToString(),
809 occlusion.occlusion_from_outside_target().ToString());
810 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
811 occlusion.occlusion_from_inside_target().ToString());
813 this->VisitLayer(surface_child, &occlusion);
815 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
816 occlusion.occlusion_from_outside_target().ToString());
817 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
818 occlusion.occlusion_from_inside_target().ToString());
820 this->EnterContributingSurface(surface, &occlusion);
822 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
823 occlusion.occlusion_from_outside_target().ToString());
824 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
825 occlusion.occlusion_from_inside_target().ToString());
827 // Occlusion from |top_layer| already in the root target should get merged
828 // with the occlusion from the |surface| we are leaving now.
829 this->LeaveContributingSurface(surface, &occlusion);
830 this->EnterLayer(root, &occlusion);
832 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
833 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
834 occlusion.occlusion_from_inside_target().ToString());
838 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
840 template <class Types>
841 class OcclusionTrackerTestSurfaceRotatedOffAxis
842 : public OcclusionTrackerTest<Types> {
843 protected:
844 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
845 : OcclusionTrackerTest<Types>(opaque_layers) {}
846 void RunMyTest() override {
847 gfx::Transform child_transform;
848 child_transform.Translate(250.0, 250.0);
849 child_transform.Rotate(95.0);
850 child_transform.Translate(-250.0, -250.0);
852 gfx::Transform layer_transform;
853 layer_transform.Translate(10.0, 10.0);
855 typename Types::ContentLayerType* root = this->CreateRoot(
856 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
857 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
858 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
859 typename Types::LayerType* child = this->CreateSurface(
860 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
861 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
862 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
863 this->CalcDrawEtc(root);
865 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
866 gfx::Rect(0, 0, 1000, 1000));
868 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect(
869 layer_transform, layer->visible_content_rect());
871 this->VisitLayer(layer, &occlusion);
872 this->EnterContributingSurface(child, &occlusion);
874 EXPECT_EQ(gfx::Rect().ToString(),
875 occlusion.occlusion_from_outside_target().ToString());
876 EXPECT_EQ(clipped_layer_in_child.ToString(),
877 occlusion.occlusion_from_inside_target().ToString());
879 this->LeaveContributingSurface(child, &occlusion);
880 this->EnterLayer(parent, &occlusion);
882 EXPECT_EQ(gfx::Rect().ToString(),
883 occlusion.occlusion_from_outside_target().ToString());
884 EXPECT_EQ(gfx::Rect().ToString(),
885 occlusion.occlusion_from_inside_target().ToString());
889 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
891 template <class Types>
892 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
893 : public OcclusionTrackerTest<Types> {
894 protected:
895 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
896 : OcclusionTrackerTest<Types>(opaque_layers) {}
897 void RunMyTest() override {
898 gfx::Transform child_transform;
899 child_transform.Translate(250.0, 250.0);
900 child_transform.Rotate(90.0);
901 child_transform.Translate(-250.0, -250.0);
903 typename Types::ContentLayerType* root = this->CreateRoot(
904 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
905 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
906 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
907 parent->SetMasksToBounds(true);
908 typename Types::ContentLayerType* child =
909 this->CreateDrawingSurface(parent,
910 child_transform,
911 gfx::PointF(30.f, 30.f),
912 gfx::Size(500, 500),
913 false);
914 child->SetMasksToBounds(true);
915 typename Types::ContentLayerType* layer1 =
916 this->CreateDrawingLayer(child,
917 this->identity_matrix,
918 gfx::PointF(10.f, 10.f),
919 gfx::Size(500, 500),
920 true);
921 typename Types::ContentLayerType* layer2 =
922 this->CreateDrawingLayer(child,
923 this->identity_matrix,
924 gfx::PointF(10.f, 450.f),
925 gfx::Size(500, 60),
926 true);
927 this->CalcDrawEtc(root);
929 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
930 gfx::Rect(0, 0, 1000, 1000));
932 this->VisitLayer(layer2, &occlusion);
933 this->VisitLayer(layer1, &occlusion);
934 this->VisitLayer(child, &occlusion);
935 this->EnterContributingSurface(child, &occlusion);
937 EXPECT_EQ(gfx::Rect().ToString(),
938 occlusion.occlusion_from_outside_target().ToString());
939 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
940 occlusion.occlusion_from_inside_target().ToString());
942 this->LeaveContributingSurface(child, &occlusion);
943 this->EnterLayer(parent, &occlusion);
945 EXPECT_EQ(gfx::Rect().ToString(),
946 occlusion.occlusion_from_outside_target().ToString());
947 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
948 occlusion.occlusion_from_inside_target().ToString());
950 /* Justification for the above occlusion from |layer1| and |layer2|:
952 +---------------------+
953 | |30 Visible region of |layer1|: /////
954 | | Visible region of |layer2|: \\\\\
955 | +---------------------------------+
956 | | |10 |
957 | +---------------+-----------------+ |
958 | | |\\\\\\\\\\\\|//| 420 | |
959 | | |\\\\\\\\\\\\|//|60 | |
960 | | |\\\\\\\\\\\\|//| | |
961 +--|--|------------|--+ | |
962 20|10| 70 | | |
963 | | | | |
964 | | | | |
965 | | | | |
966 | | | | |
967 | | | | |
968 | | | |10|
969 | +------------|-----------------|--+
970 | | 490 |
971 +---------------+-----------------+
972 60 440
977 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
979 template <class Types>
980 class OcclusionTrackerTestOverlappingSurfaceSiblings
981 : public OcclusionTrackerTest<Types> {
982 protected:
983 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
984 : OcclusionTrackerTest<Types>(opaque_layers) {}
985 void RunMyTest() override {
986 typename Types::ContentLayerType* parent = this->CreateRoot(
987 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
988 parent->SetMasksToBounds(true);
989 typename Types::LayerType* child1 = this->CreateSurface(
990 parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size());
991 typename Types::LayerType* child2 = this->CreateSurface(
992 parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size());
993 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
994 child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true);
995 typename Types::ContentLayerType* layer2 =
996 this->CreateDrawingLayer(child2,
997 this->identity_matrix,
998 gfx::PointF(10.f, 0.f),
999 gfx::Size(40, 50),
1000 true);
1001 this->CalcDrawEtc(parent);
1003 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1004 gfx::Rect(0, 0, 1000, 1000));
1006 this->VisitLayer(layer2, &occlusion);
1007 this->EnterContributingSurface(child2, &occlusion);
1009 // layer2's occlusion.
1010 EXPECT_EQ(gfx::Rect().ToString(),
1011 occlusion.occlusion_from_outside_target().ToString());
1012 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
1013 occlusion.occlusion_from_inside_target().ToString());
1015 this->LeaveContributingSurface(child2, &occlusion);
1016 this->VisitLayer(layer1, &occlusion);
1017 this->EnterContributingSurface(child1, &occlusion);
1019 // layer2's occlusion in the target space of layer1.
1020 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
1021 occlusion.occlusion_from_outside_target().ToString());
1022 // layer1's occlusion.
1023 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
1024 occlusion.occlusion_from_inside_target().ToString());
1026 this->LeaveContributingSurface(child1, &occlusion);
1027 this->EnterLayer(parent, &occlusion);
1029 // The occlusion from from layer1 and layer2 is merged.
1030 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1031 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
1032 occlusion.occlusion_from_inside_target().ToString());
1036 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1038 template <class Types>
1039 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1040 : public OcclusionTrackerTest<Types> {
1041 protected:
1042 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1043 bool opaque_layers)
1044 : OcclusionTrackerTest<Types>(opaque_layers) {}
1045 void RunMyTest() override {
1046 gfx::Transform child1_transform;
1047 child1_transform.Translate(250.0, 250.0);
1048 child1_transform.Rotate(-90.0);
1049 child1_transform.Translate(-250.0, -250.0);
1051 gfx::Transform child2_transform;
1052 child2_transform.Translate(250.0, 250.0);
1053 child2_transform.Rotate(90.0);
1054 child2_transform.Translate(-250.0, -250.0);
1056 typename Types::ContentLayerType* parent = this->CreateRoot(
1057 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1058 parent->SetMasksToBounds(true);
1059 typename Types::LayerType* child1 = this->CreateSurface(
1060 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1061 typename Types::LayerType* child2 =
1062 this->CreateDrawingSurface(parent,
1063 child2_transform,
1064 gfx::PointF(20.f, 40.f),
1065 gfx::Size(10, 10),
1066 false);
1067 typename Types::ContentLayerType* layer1 =
1068 this->CreateDrawingLayer(child1,
1069 this->identity_matrix,
1070 gfx::PointF(-10.f, -20.f),
1071 gfx::Size(510, 510),
1072 true);
1073 typename Types::ContentLayerType* layer2 =
1074 this->CreateDrawingLayer(child2,
1075 this->identity_matrix,
1076 gfx::PointF(-10.f, -10.f),
1077 gfx::Size(510, 510),
1078 true);
1079 this->CalcDrawEtc(parent);
1081 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1082 gfx::Rect(0, 0, 1000, 1000));
1084 this->VisitLayer(layer2, &occlusion);
1085 this->EnterLayer(child2, &occlusion);
1087 EXPECT_EQ(gfx::Rect().ToString(),
1088 occlusion.occlusion_from_outside_target().ToString());
1089 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1090 occlusion.occlusion_from_inside_target().ToString());
1092 this->LeaveLayer(child2, &occlusion);
1093 this->EnterContributingSurface(child2, &occlusion);
1095 EXPECT_EQ(gfx::Rect().ToString(),
1096 occlusion.occlusion_from_outside_target().ToString());
1097 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1098 occlusion.occlusion_from_inside_target().ToString());
1100 this->LeaveContributingSurface(child2, &occlusion);
1101 this->VisitLayer(layer1, &occlusion);
1102 this->EnterContributingSurface(child1, &occlusion);
1104 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1105 occlusion.occlusion_from_outside_target().ToString());
1106 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1107 occlusion.occlusion_from_inside_target().ToString());
1109 this->LeaveContributingSurface(child1, &occlusion);
1110 this->EnterLayer(parent, &occlusion);
1112 EXPECT_EQ(gfx::Rect().ToString(),
1113 occlusion.occlusion_from_outside_target().ToString());
1114 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1115 occlusion.occlusion_from_inside_target().ToString());
1117 /* Justification for the above occlusion:
1119 +---------------------+
1120 |20 | layer1
1121 10+----------------------------------+
1122 100 || 30 | layer2 |
1123 |20+----------------------------------+
1124 || | | | |
1125 || | | | |
1126 || | | | |
1127 +|-|------------------+ | |
1128 | | | | 510
1129 | | 510 | |
1130 | | | |
1131 | | | |
1132 | | | |
1133 | | | |
1134 | | 520 | |
1135 +----------------------------------+ |
1137 +----------------------------------+
1143 ALL_OCCLUSIONTRACKER_TEST(
1144 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1146 template <class Types>
1147 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1148 protected:
1149 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1150 : OcclusionTrackerTest<Types>(opaque_layers) {}
1151 void RunMyTest() override {
1152 gfx::Transform layer_transform;
1153 layer_transform.Translate(250.0, 250.0);
1154 layer_transform.Rotate(90.0);
1155 layer_transform.Translate(-250.0, -250.0);
1157 typename Types::ContentLayerType* parent = this->CreateRoot(
1158 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1159 parent->SetMasksToBounds(true);
1160 typename Types::ContentLayerType* blur_layer =
1161 this->CreateDrawingLayer(parent,
1162 layer_transform,
1163 gfx::PointF(30.f, 30.f),
1164 gfx::Size(500, 500),
1165 true);
1166 typename Types::ContentLayerType* opaque_layer =
1167 this->CreateDrawingLayer(parent,
1168 layer_transform,
1169 gfx::PointF(30.f, 30.f),
1170 gfx::Size(500, 500),
1171 true);
1172 typename Types::ContentLayerType* opacity_layer =
1173 this->CreateDrawingLayer(parent,
1174 layer_transform,
1175 gfx::PointF(30.f, 30.f),
1176 gfx::Size(500, 500),
1177 true);
1179 Types::SetForceRenderSurface(blur_layer, true);
1180 FilterOperations filters;
1181 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1182 blur_layer->SetFilters(filters);
1184 Types::SetForceRenderSurface(opaque_layer, true);
1185 filters.Clear();
1186 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1187 opaque_layer->SetFilters(filters);
1189 Types::SetForceRenderSurface(opacity_layer, true);
1190 filters.Clear();
1191 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1192 opacity_layer->SetFilters(filters);
1194 this->CalcDrawEtc(parent);
1196 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1197 gfx::Rect(0, 0, 1000, 1000));
1199 // Opacity layer won't contribute to occlusion.
1200 this->VisitLayer(opacity_layer, &occlusion);
1201 this->EnterContributingSurface(opacity_layer, &occlusion);
1203 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1204 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1206 // And has nothing to contribute to its parent surface.
1207 this->LeaveContributingSurface(opacity_layer, &occlusion);
1208 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1209 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1211 // Opaque layer will contribute to occlusion.
1212 this->VisitLayer(opaque_layer, &occlusion);
1213 this->EnterContributingSurface(opaque_layer, &occlusion);
1215 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1216 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1217 occlusion.occlusion_from_inside_target().ToString());
1219 // And it gets translated to the parent surface.
1220 this->LeaveContributingSurface(opaque_layer, &occlusion);
1221 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1222 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1223 occlusion.occlusion_from_inside_target().ToString());
1225 // The blur layer needs to throw away any occlusion from outside its
1226 // subtree.
1227 this->EnterLayer(blur_layer, &occlusion);
1228 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1229 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1231 // And it won't contribute to occlusion.
1232 this->LeaveLayer(blur_layer, &occlusion);
1233 this->EnterContributingSurface(blur_layer, &occlusion);
1234 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1235 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1237 // But the opaque layer's occlusion is preserved on the parent.
1238 this->LeaveContributingSurface(blur_layer, &occlusion);
1239 this->EnterLayer(parent, &occlusion);
1240 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1241 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1242 occlusion.occlusion_from_inside_target().ToString());
1246 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1248 template <class Types>
1249 class OcclusionTrackerTestReplicaDoesOcclude
1250 : public OcclusionTrackerTest<Types> {
1251 protected:
1252 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1253 : OcclusionTrackerTest<Types>(opaque_layers) {}
1254 void RunMyTest() override {
1255 typename Types::ContentLayerType* parent = this->CreateRoot(
1256 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1257 typename Types::LayerType* surface = this->CreateDrawingSurface(
1258 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
1259 this->CreateReplicaLayer(
1260 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
1261 this->CalcDrawEtc(parent);
1263 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1264 gfx::Rect(0, 0, 1000, 1000));
1266 this->VisitLayer(surface, &occlusion);
1268 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1269 occlusion.occlusion_from_inside_target().ToString());
1271 this->VisitContributingSurface(surface, &occlusion);
1272 this->EnterLayer(parent, &occlusion);
1274 // The surface and replica should both be occluding the parent.
1275 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1276 occlusion.occlusion_from_inside_target().ToString());
1280 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1282 template <class Types>
1283 class OcclusionTrackerTestReplicaWithClipping
1284 : public OcclusionTrackerTest<Types> {
1285 protected:
1286 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1287 : OcclusionTrackerTest<Types>(opaque_layers) {}
1288 void RunMyTest() override {
1289 typename Types::ContentLayerType* parent = this->CreateRoot(
1290 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1291 parent->SetMasksToBounds(true);
1292 typename Types::LayerType* surface =
1293 this->CreateDrawingSurface(parent,
1294 this->identity_matrix,
1295 gfx::PointF(0.f, 100.f),
1296 gfx::Size(50, 50),
1297 true);
1298 this->CreateReplicaLayer(
1299 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
1300 this->CalcDrawEtc(parent);
1302 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1303 gfx::Rect(0, 0, 1000, 1000));
1305 this->VisitLayer(surface, &occlusion);
1307 // The surface layer's occlusion in its own space.
1308 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1309 occlusion.occlusion_from_inside_target().ToString());
1310 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1312 this->VisitContributingSurface(surface, &occlusion);
1313 this->EnterLayer(parent, &occlusion);
1315 // The surface and replica should both be occluding the parent, the
1316 // replica's occlusion is clipped by the parent.
1317 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1318 occlusion.occlusion_from_inside_target().ToString());
1319 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1323 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1325 template <class Types>
1326 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1327 protected:
1328 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1329 : OcclusionTrackerTest<Types>(opaque_layers) {}
1330 void RunMyTest() override {
1331 typename Types::ContentLayerType* parent = this->CreateRoot(
1332 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1333 typename Types::LayerType* surface =
1334 this->CreateDrawingSurface(parent,
1335 this->identity_matrix,
1336 gfx::PointF(0.f, 100.f),
1337 gfx::Size(50, 50),
1338 true);
1339 typename Types::LayerType* replica = this->CreateReplicaLayer(
1340 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1341 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1342 this->CalcDrawEtc(parent);
1344 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1345 gfx::Rect(0, 0, 1000, 1000));
1347 this->VisitLayer(surface, &occlusion);
1349 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1350 occlusion.occlusion_from_inside_target().ToString());
1352 this->VisitContributingSurface(surface, &occlusion);
1353 this->EnterLayer(parent, &occlusion);
1355 // The replica should not be occluding the parent, since it has a mask
1356 // applied to it.
1357 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1358 occlusion.occlusion_from_inside_target().ToString());
1362 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1364 template <class Types>
1365 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1366 : public OcclusionTrackerTest<Types> {
1367 protected:
1368 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1369 : OcclusionTrackerTest<Types>(opaque_layers) {}
1370 void RunMyTest() override {
1371 typename Types::ContentLayerType* parent = this->CreateRoot(
1372 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1373 typename Types::ContentLayerType* layer =
1374 this->CreateDrawingSurface(parent,
1375 this->identity_matrix,
1376 gfx::PointF(),
1377 gfx::Size(200, 200),
1378 false);
1379 this->CalcDrawEtc(parent);
1381 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1382 gfx::Rect(0, 0, 1000, 1000));
1383 this->EnterLayer(layer, &occlusion);
1385 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1386 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1388 this->LeaveLayer(layer, &occlusion);
1389 this->VisitContributingSurface(layer, &occlusion);
1390 this->EnterLayer(parent, &occlusion);
1392 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1393 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1397 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1399 template <class Types>
1400 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1401 : public OcclusionTrackerTest<Types> {
1402 protected:
1403 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1404 : OcclusionTrackerTest<Types>(opaque_layers) {}
1405 void RunMyTest() override {
1406 typename Types::ContentLayerType* parent = this->CreateRoot(
1407 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1408 typename Types::ContentLayerType* layer =
1409 this->CreateDrawingLayer(parent,
1410 this->identity_matrix,
1411 gfx::PointF(100.f, 100.f),
1412 gfx::Size(200, 200),
1413 false);
1414 this->CalcDrawEtc(parent);
1416 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1417 gfx::Rect(0, 0, 1000, 1000));
1418 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1420 this->ResetLayerIterator();
1421 this->VisitLayer(layer, &occlusion);
1422 this->EnterLayer(parent, &occlusion);
1424 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1425 occlusion.occlusion_from_inside_target().ToString());
1428 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1429 gfx::Rect(0, 0, 1000, 1000));
1430 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1432 this->ResetLayerIterator();
1433 this->VisitLayer(layer, &occlusion);
1434 this->EnterLayer(parent, &occlusion);
1436 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1437 occlusion.occlusion_from_inside_target().ToString());
1440 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1441 gfx::Rect(0, 0, 1000, 1000));
1442 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1444 this->ResetLayerIterator();
1445 this->VisitLayer(layer, &occlusion);
1446 this->EnterLayer(parent, &occlusion);
1448 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1449 occlusion.occlusion_from_inside_target().ToString());
1454 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1456 template <class Types>
1457 class OcclusionTrackerTestUnsorted3dLayers
1458 : public OcclusionTrackerTest<Types> {
1459 protected:
1460 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
1461 : OcclusionTrackerTest<Types>(opaque_layers) {}
1462 void RunMyTest() override {
1463 // Currently, The main thread layer iterator does not iterate over 3d items
1464 // in sorted order, because layer sorting is not performed on the main
1465 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1466 // layer occludes other layers that have not yet been iterated over. For
1467 // now, the expected behavior is that a 3d layer simply does not add any
1468 // occlusion to the occlusion tracker.
1470 gfx::Transform translation_to_front;
1471 translation_to_front.Translate3d(0.0, 0.0, -10.0);
1472 gfx::Transform translation_to_back;
1473 translation_to_front.Translate3d(0.0, 0.0, -100.0);
1475 typename Types::ContentLayerType* parent = this->CreateRoot(
1476 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1477 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
1478 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
1479 typename Types::ContentLayerType* child2 =
1480 this->CreateDrawingLayer(parent,
1481 translation_to_front,
1482 gfx::PointF(50.f, 50.f),
1483 gfx::Size(100, 100),
1484 true);
1485 parent->SetShouldFlattenTransform(false);
1486 parent->Set3dSortingContextId(1);
1487 child1->Set3dSortingContextId(1);
1488 child2->Set3dSortingContextId(1);
1490 this->CalcDrawEtc(parent);
1492 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1493 gfx::Rect(0, 0, 1000, 1000));
1494 this->VisitLayer(child2, &occlusion);
1495 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1496 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1498 this->VisitLayer(child1, &occlusion);
1499 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1500 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1504 // This test will have different layer ordering on the impl thread; the test
1505 // will only work on the main thread.
1506 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1508 template <class Types>
1509 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1510 : public OcclusionTrackerTest<Types> {
1511 protected:
1512 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1513 bool opaque_layers)
1514 : OcclusionTrackerTest<Types>(opaque_layers) {}
1515 void RunMyTest() override {
1516 gfx::Transform transform;
1517 transform.Translate(50.0, 50.0);
1518 transform.ApplyPerspectiveDepth(100.0);
1519 transform.Translate3d(0.0, 0.0, 110.0);
1520 transform.Translate(-50.0, -50.0);
1522 typename Types::ContentLayerType* parent = this->CreateRoot(
1523 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1524 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1525 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
1526 parent->SetShouldFlattenTransform(false);
1527 parent->Set3dSortingContextId(1);
1528 layer->SetShouldFlattenTransform(false);
1529 layer->Set3dSortingContextId(1);
1530 this->CalcDrawEtc(parent);
1532 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1533 gfx::Rect(0, 0, 1000, 1000));
1535 // The |layer| is entirely behind the camera and should not occlude.
1536 this->VisitLayer(layer, &occlusion);
1537 this->EnterLayer(parent, &occlusion);
1538 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1539 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1543 template <class Types>
1544 class OcclusionTrackerTestAnimationOpacity1OnMainThread
1545 : public OcclusionTrackerTest<Types> {
1546 protected:
1547 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
1548 : OcclusionTrackerTest<Types>(opaque_layers) {}
1549 void RunMyTest() override {
1550 // parent
1551 // +--layer
1552 // +--surface
1553 // | +--surface_child
1554 // | +--surface_child2
1555 // +--parent2
1556 // +--topmost
1558 typename Types::ContentLayerType* parent = this->CreateRoot(
1559 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1560 typename Types::ContentLayerType* layer =
1561 this->CreateDrawingLayer(parent,
1562 this->identity_matrix,
1563 gfx::PointF(),
1564 gfx::Size(300, 300),
1565 true);
1566 typename Types::ContentLayerType* surface =
1567 this->CreateDrawingSurface(parent,
1568 this->identity_matrix,
1569 gfx::PointF(),
1570 gfx::Size(300, 300),
1571 true);
1572 typename Types::ContentLayerType* surface_child =
1573 this->CreateDrawingLayer(surface,
1574 this->identity_matrix,
1575 gfx::PointF(),
1576 gfx::Size(200, 300),
1577 true);
1578 typename Types::ContentLayerType* surface_child2 =
1579 this->CreateDrawingLayer(surface,
1580 this->identity_matrix,
1581 gfx::PointF(),
1582 gfx::Size(100, 300),
1583 true);
1584 typename Types::ContentLayerType* parent2 =
1585 this->CreateDrawingLayer(parent,
1586 this->identity_matrix,
1587 gfx::PointF(),
1588 gfx::Size(300, 300),
1589 false);
1590 typename Types::ContentLayerType* topmost =
1591 this->CreateDrawingLayer(parent,
1592 this->identity_matrix,
1593 gfx::PointF(250.f, 0.f),
1594 gfx::Size(50, 300),
1595 true);
1597 AddOpacityTransitionToController(
1598 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
1599 AddOpacityTransitionToController(
1600 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
1601 this->CalcDrawEtc(parent);
1603 EXPECT_TRUE(layer->draw_opacity_is_animating());
1604 EXPECT_FALSE(surface->draw_opacity_is_animating());
1605 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
1607 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1608 gfx::Rect(0, 0, 1000, 1000));
1610 this->VisitLayer(topmost, &occlusion);
1611 this->EnterLayer(parent2, &occlusion);
1613 // This occlusion will affect all surfaces.
1614 EXPECT_EQ(gfx::Rect().ToString(),
1615 occlusion.occlusion_from_outside_target().ToString());
1616 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1617 occlusion.occlusion_from_inside_target().ToString());
1619 this->LeaveLayer(parent2, &occlusion);
1620 this->VisitLayer(surface_child2, &occlusion);
1621 this->EnterLayer(surface_child, &occlusion);
1622 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1623 occlusion.occlusion_from_outside_target().ToString());
1624 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1625 occlusion.occlusion_from_inside_target().ToString());
1627 this->LeaveLayer(surface_child, &occlusion);
1628 this->EnterLayer(surface, &occlusion);
1629 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1630 occlusion.occlusion_from_outside_target().ToString());
1631 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1632 occlusion.occlusion_from_inside_target().ToString());
1634 this->LeaveLayer(surface, &occlusion);
1635 this->EnterContributingSurface(surface, &occlusion);
1636 // Occlusion within the surface is lost when leaving the animating surface.
1637 EXPECT_EQ(gfx::Rect().ToString(),
1638 occlusion.occlusion_from_outside_target().ToString());
1639 EXPECT_EQ(gfx::Rect().ToString(),
1640 occlusion.occlusion_from_inside_target().ToString());
1642 this->LeaveContributingSurface(surface, &occlusion);
1643 // Occlusion from outside the animating surface still exists.
1644 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1645 occlusion.occlusion_from_inside_target().ToString());
1646 EXPECT_EQ(gfx::Rect().ToString(),
1647 occlusion.occlusion_from_outside_target().ToString());
1649 this->VisitLayer(layer, &occlusion);
1650 this->EnterLayer(parent, &occlusion);
1652 // Occlusion is not added for the animating |layer|.
1653 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1654 occlusion.occlusion_from_inside_target().ToString());
1655 EXPECT_EQ(gfx::Rect().ToString(),
1656 occlusion.occlusion_from_outside_target().ToString());
1660 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
1662 template <class Types>
1663 class OcclusionTrackerTestAnimationOpacity0OnMainThread
1664 : public OcclusionTrackerTest<Types> {
1665 protected:
1666 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
1667 : OcclusionTrackerTest<Types>(opaque_layers) {}
1668 void RunMyTest() override {
1669 typename Types::ContentLayerType* parent = this->CreateRoot(
1670 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1671 typename Types::ContentLayerType* layer =
1672 this->CreateDrawingLayer(parent,
1673 this->identity_matrix,
1674 gfx::PointF(),
1675 gfx::Size(300, 300),
1676 true);
1677 typename Types::ContentLayerType* surface =
1678 this->CreateDrawingSurface(parent,
1679 this->identity_matrix,
1680 gfx::PointF(),
1681 gfx::Size(300, 300),
1682 true);
1683 typename Types::ContentLayerType* surface_child =
1684 this->CreateDrawingLayer(surface,
1685 this->identity_matrix,
1686 gfx::PointF(),
1687 gfx::Size(200, 300),
1688 true);
1689 typename Types::ContentLayerType* surface_child2 =
1690 this->CreateDrawingLayer(surface,
1691 this->identity_matrix,
1692 gfx::PointF(),
1693 gfx::Size(100, 300),
1694 true);
1695 typename Types::ContentLayerType* parent2 =
1696 this->CreateDrawingLayer(parent,
1697 this->identity_matrix,
1698 gfx::PointF(),
1699 gfx::Size(300, 300),
1700 false);
1701 typename Types::ContentLayerType* topmost =
1702 this->CreateDrawingLayer(parent,
1703 this->identity_matrix,
1704 gfx::PointF(250.f, 0.f),
1705 gfx::Size(50, 300),
1706 true);
1708 AddOpacityTransitionToController(
1709 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
1710 AddOpacityTransitionToController(
1711 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
1712 this->CalcDrawEtc(parent);
1714 EXPECT_TRUE(layer->draw_opacity_is_animating());
1715 EXPECT_FALSE(surface->draw_opacity_is_animating());
1716 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
1718 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1719 gfx::Rect(0, 0, 1000, 1000));
1721 this->VisitLayer(topmost, &occlusion);
1722 this->EnterLayer(parent2, &occlusion);
1723 // This occlusion will affect all surfaces.
1724 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1725 occlusion.occlusion_from_inside_target().ToString());
1726 EXPECT_EQ(gfx::Rect().ToString(),
1727 occlusion.occlusion_from_outside_target().ToString());
1729 this->LeaveLayer(parent2, &occlusion);
1730 this->VisitLayer(surface_child2, &occlusion);
1731 this->EnterLayer(surface_child, &occlusion);
1732 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1733 occlusion.occlusion_from_inside_target().ToString());
1734 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1735 occlusion.occlusion_from_outside_target().ToString());
1737 this->LeaveLayer(surface_child, &occlusion);
1738 this->EnterLayer(surface, &occlusion);
1739 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1740 occlusion.occlusion_from_inside_target().ToString());
1741 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1742 occlusion.occlusion_from_outside_target().ToString());
1744 this->LeaveLayer(surface, &occlusion);
1745 this->EnterContributingSurface(surface, &occlusion);
1746 // Occlusion within the surface is lost when leaving the animating surface.
1747 EXPECT_EQ(gfx::Rect().ToString(),
1748 occlusion.occlusion_from_inside_target().ToString());
1749 EXPECT_EQ(gfx::Rect().ToString(),
1750 occlusion.occlusion_from_outside_target().ToString());
1752 this->LeaveContributingSurface(surface, &occlusion);
1753 // Occlusion from outside the animating surface still exists.
1754 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1755 occlusion.occlusion_from_inside_target().ToString());
1756 EXPECT_EQ(gfx::Rect().ToString(),
1757 occlusion.occlusion_from_outside_target().ToString());
1759 this->VisitLayer(layer, &occlusion);
1760 this->EnterLayer(parent, &occlusion);
1762 // Occlusion is not added for the animating |layer|.
1763 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1764 occlusion.occlusion_from_inside_target().ToString());
1765 EXPECT_EQ(gfx::Rect().ToString(),
1766 occlusion.occlusion_from_outside_target().ToString());
1770 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
1772 template <class Types>
1773 class OcclusionTrackerTestAnimationTranslateOnMainThread
1774 : public OcclusionTrackerTest<Types> {
1775 protected:
1776 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
1777 bool opaque_layers)
1778 : OcclusionTrackerTest<Types>(opaque_layers) {}
1779 void RunMyTest() override {
1780 typename Types::ContentLayerType* parent = this->CreateRoot(
1781 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1782 typename Types::ContentLayerType* layer =
1783 this->CreateDrawingLayer(parent,
1784 this->identity_matrix,
1785 gfx::PointF(),
1786 gfx::Size(300, 300),
1787 true);
1788 typename Types::ContentLayerType* surface =
1789 this->CreateDrawingSurface(parent,
1790 this->identity_matrix,
1791 gfx::PointF(),
1792 gfx::Size(300, 300),
1793 true);
1794 typename Types::ContentLayerType* surface_child =
1795 this->CreateDrawingLayer(surface,
1796 this->identity_matrix,
1797 gfx::PointF(),
1798 gfx::Size(200, 300),
1799 true);
1800 typename Types::ContentLayerType* surface_child2 =
1801 this->CreateDrawingLayer(surface,
1802 this->identity_matrix,
1803 gfx::PointF(),
1804 gfx::Size(100, 300),
1805 true);
1806 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
1807 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
1809 AddAnimatedTransformToController(
1810 layer->layer_animation_controller(), 10.0, 30, 0);
1811 AddAnimatedTransformToController(
1812 surface->layer_animation_controller(), 10.0, 30, 0);
1813 AddAnimatedTransformToController(
1814 surface_child->layer_animation_controller(), 10.0, 30, 0);
1815 this->CalcDrawEtc(parent);
1817 EXPECT_TRUE(layer->draw_transform_is_animating());
1818 EXPECT_TRUE(layer->screen_space_transform_is_animating());
1819 EXPECT_TRUE(
1820 surface->render_surface()->target_surface_transforms_are_animating());
1821 EXPECT_TRUE(
1822 surface->render_surface()->screen_space_transforms_are_animating());
1823 // The surface owning layer doesn't animate against its own surface.
1824 EXPECT_FALSE(surface->draw_transform_is_animating());
1825 EXPECT_TRUE(surface->screen_space_transform_is_animating());
1826 EXPECT_TRUE(surface_child->draw_transform_is_animating());
1827 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
1829 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1830 gfx::Rect(0, 0, 1000, 1000));
1832 this->VisitLayer(surface2, &occlusion);
1833 this->EnterContributingSurface(surface2, &occlusion);
1835 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1836 occlusion.occlusion_from_inside_target().ToString());
1838 this->LeaveContributingSurface(surface2, &occlusion);
1839 this->EnterLayer(surface_child2, &occlusion);
1840 // surface_child2 is moving in screen space but not relative to its target,
1841 // so occlusion should happen in its target space only. It also means that
1842 // things occluding from outside the target (e.g. surface2) cannot occlude
1843 // this layer.
1844 EXPECT_EQ(gfx::Rect().ToString(),
1845 occlusion.occlusion_from_outside_target().ToString());
1846 EXPECT_EQ(gfx::Rect().ToString(),
1847 occlusion.occlusion_from_inside_target().ToString());
1849 this->LeaveLayer(surface_child2, &occlusion);
1850 this->EnterLayer(surface_child, &occlusion);
1851 // surface_child2 added to the occlusion since it is not moving relative
1852 // to its target.
1853 EXPECT_EQ(gfx::Rect().ToString(),
1854 occlusion.occlusion_from_outside_target().ToString());
1855 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1856 occlusion.occlusion_from_inside_target().ToString());
1858 this->LeaveLayer(surface_child, &occlusion);
1859 // surface_child is moving relative to its target, so it does not add
1860 // occlusion.
1861 EXPECT_EQ(gfx::Rect().ToString(),
1862 occlusion.occlusion_from_outside_target().ToString());
1863 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1864 occlusion.occlusion_from_inside_target().ToString());
1866 this->EnterLayer(surface, &occlusion);
1867 EXPECT_EQ(gfx::Rect().ToString(),
1868 occlusion.occlusion_from_outside_target().ToString());
1869 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1870 occlusion.occlusion_from_inside_target().ToString());
1872 this->LeaveLayer(surface, &occlusion);
1873 // The surface's owning layer is moving in screen space but not relative to
1874 // its target, so it adds to the occlusion.
1875 EXPECT_EQ(gfx::Rect().ToString(),
1876 occlusion.occlusion_from_outside_target().ToString());
1877 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
1878 occlusion.occlusion_from_inside_target().ToString());
1880 this->EnterContributingSurface(surface, &occlusion);
1881 this->LeaveContributingSurface(surface, &occlusion);
1882 // The |surface| is moving in the screen and in its target, so all occlusion
1883 // within the surface is lost when leaving it. Only the |surface2| occlusion
1884 // is left.
1885 EXPECT_EQ(gfx::Rect().ToString(),
1886 occlusion.occlusion_from_outside_target().ToString());
1887 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1888 occlusion.occlusion_from_inside_target().ToString());
1890 this->VisitLayer(layer, &occlusion);
1891 // The |layer| is animating in the screen and in its target, so no occlusion
1892 // is added.
1893 EXPECT_EQ(gfx::Rect().ToString(),
1894 occlusion.occlusion_from_outside_target().ToString());
1895 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1896 occlusion.occlusion_from_inside_target().ToString());
1900 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
1902 template <class Types>
1903 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1904 : public OcclusionTrackerTest<Types> {
1905 protected:
1906 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1907 bool opaque_layers)
1908 : OcclusionTrackerTest<Types>(opaque_layers) {}
1909 void RunMyTest() override {
1910 gfx::Transform surface_transform;
1911 surface_transform.Translate(300.0, 300.0);
1912 surface_transform.Scale(2.0, 2.0);
1913 surface_transform.Translate(-150.0, -150.0);
1915 typename Types::ContentLayerType* parent = this->CreateRoot(
1916 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
1917 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
1918 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
1919 typename Types::ContentLayerType* surface2 =
1920 this->CreateDrawingSurface(parent,
1921 this->identity_matrix,
1922 gfx::PointF(50.f, 50.f),
1923 gfx::Size(300, 300),
1924 false);
1925 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1926 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1927 this->CalcDrawEtc(parent);
1929 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1930 gfx::Rect(0, 0, 1000, 1000));
1932 this->VisitLayer(surface2, &occlusion);
1933 this->VisitContributingSurface(surface2, &occlusion);
1935 EXPECT_EQ(gfx::Rect().ToString(),
1936 occlusion.occlusion_from_outside_target().ToString());
1937 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1938 occlusion.occlusion_from_inside_target().ToString());
1940 // Clear any stored occlusion.
1941 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1942 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1944 this->VisitLayer(surface, &occlusion);
1945 this->VisitContributingSurface(surface, &occlusion);
1947 EXPECT_EQ(gfx::Rect().ToString(),
1948 occlusion.occlusion_from_outside_target().ToString());
1949 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1950 occlusion.occlusion_from_inside_target().ToString());
1954 MAIN_AND_IMPL_THREAD_TEST(
1955 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
1957 template <class Types>
1958 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1959 : public OcclusionTrackerTest<Types> {
1960 protected:
1961 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
1962 bool opaque_layers)
1963 : OcclusionTrackerTest<Types>(opaque_layers) {}
1964 void RunMyTest() override {
1965 typename Types::ContentLayerType* parent = this->CreateRoot(
1966 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1967 parent->SetMasksToBounds(true);
1968 typename Types::ContentLayerType* surface =
1969 this->CreateDrawingSurface(parent,
1970 this->identity_matrix,
1971 gfx::PointF(),
1972 gfx::Size(500, 300),
1973 false);
1974 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
1975 this->CalcDrawEtc(parent);
1977 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1978 gfx::Rect(0, 0, 1000, 1000));
1980 this->VisitLayer(surface, &occlusion);
1981 this->VisitContributingSurface(surface, &occlusion);
1983 EXPECT_EQ(gfx::Rect().ToString(),
1984 occlusion.occlusion_from_outside_target().ToString());
1985 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
1986 occlusion.occlusion_from_inside_target().ToString());
1990 MAIN_AND_IMPL_THREAD_TEST(
1991 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
1993 template <class Types>
1994 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
1995 : public OcclusionTrackerTest<Types> {
1996 protected:
1997 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
1998 : OcclusionTrackerTest<Types>(opaque_layers) {}
1999 void RunMyTest() override {
2000 typename Types::ContentLayerType* parent = this->CreateRoot(
2001 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2002 typename Types::LayerType* surface =
2003 this->CreateDrawingSurface(parent,
2004 this->identity_matrix,
2005 gfx::PointF(),
2006 gfx::Size(100, 100),
2007 true);
2008 this->CreateReplicaLayer(surface,
2009 this->identity_matrix,
2010 gfx::PointF(0.f, 100.f),
2011 gfx::Size(100, 100));
2012 typename Types::LayerType* topmost =
2013 this->CreateDrawingLayer(parent,
2014 this->identity_matrix,
2015 gfx::PointF(),
2016 gfx::Size(100, 110),
2017 true);
2018 this->CalcDrawEtc(parent);
2020 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2021 gfx::Rect(0, 0, 1000, 1000));
2023 // |topmost| occludes the surface, but not the entire surface's replica.
2024 this->VisitLayer(topmost, &occlusion);
2026 EXPECT_EQ(gfx::Rect().ToString(),
2027 occlusion.occlusion_from_outside_target().ToString());
2028 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2029 occlusion.occlusion_from_inside_target().ToString());
2031 this->VisitLayer(surface, &occlusion);
2033 // Render target with replica ignores occlusion from outside.
2034 EXPECT_EQ(gfx::Rect().ToString(),
2035 occlusion.occlusion_from_outside_target().ToString());
2036 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2037 occlusion.occlusion_from_inside_target().ToString());
2039 this->EnterContributingSurface(surface, &occlusion);
2041 // Only occlusion from outside the surface occludes the surface/replica.
2042 EXPECT_EQ(gfx::Rect().ToString(),
2043 occlusion.occlusion_on_contributing_surface_from_outside_target()
2044 .ToString());
2045 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2046 occlusion.occlusion_on_contributing_surface_from_inside_target()
2047 .ToString());
2051 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2053 template <class Types>
2054 class OcclusionTrackerTestSurfaceChildOfSurface
2055 : public OcclusionTrackerTest<Types> {
2056 protected:
2057 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
2058 : OcclusionTrackerTest<Types>(opaque_layers) {}
2059 void RunMyTest() override {
2060 // This test verifies that the surface cliprect does not end up empty and
2061 // clip away the entire unoccluded rect.
2063 typename Types::ContentLayerType* parent = this->CreateRoot(
2064 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2065 typename Types::LayerType* surface =
2066 this->CreateDrawingSurface(parent,
2067 this->identity_matrix,
2068 gfx::PointF(),
2069 gfx::Size(100, 100),
2070 false);
2071 typename Types::LayerType* surface_child =
2072 this->CreateDrawingSurface(surface,
2073 this->identity_matrix,
2074 gfx::PointF(0.f, 10.f),
2075 gfx::Size(100, 50),
2076 true);
2077 typename Types::LayerType* topmost = this->CreateDrawingLayer(
2078 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2079 this->CalcDrawEtc(parent);
2081 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2082 gfx::Rect(-100, -100, 1000, 1000));
2084 // |topmost| occludes everything partially so we know occlusion is happening
2085 // at all.
2086 this->VisitLayer(topmost, &occlusion);
2088 EXPECT_EQ(gfx::Rect().ToString(),
2089 occlusion.occlusion_from_outside_target().ToString());
2090 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2091 occlusion.occlusion_from_inside_target().ToString());
2093 this->VisitLayer(surface_child, &occlusion);
2095 // surface_child increases the occlusion in the screen by a narrow sliver.
2096 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2097 occlusion.occlusion_from_outside_target().ToString());
2098 // In its own surface, surface_child is at 0,0 as is its occlusion.
2099 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2100 occlusion.occlusion_from_inside_target().ToString());
2102 // The root layer always has a clip rect. So the parent of |surface| has a
2103 // clip rect. However, the owning layer for |surface| does not mask to
2104 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2105 // |surface_child| exercises different code paths as its parent does not
2106 // have a clip rect.
2108 this->EnterContributingSurface(surface_child, &occlusion);
2109 // The |surface_child| can't occlude its own surface, but occlusion from
2110 // |topmost| can.
2111 EXPECT_EQ(gfx::Rect().ToString(),
2112 occlusion.occlusion_on_contributing_surface_from_outside_target()
2113 .ToString());
2114 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2115 occlusion.occlusion_on_contributing_surface_from_inside_target()
2116 .ToString());
2117 this->LeaveContributingSurface(surface_child, &occlusion);
2119 // When the surface_child's occlusion is transformed up to its parent, make
2120 // sure it is not clipped away inappropriately.
2121 this->EnterLayer(surface, &occlusion);
2122 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2123 occlusion.occlusion_from_outside_target().ToString());
2124 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2125 occlusion.occlusion_from_inside_target().ToString());
2126 this->LeaveLayer(surface, &occlusion);
2128 this->EnterContributingSurface(surface, &occlusion);
2129 // The occlusion from inside |surface| can't affect the surface, but
2130 // |topmost| can.
2131 EXPECT_EQ(gfx::Rect().ToString(),
2132 occlusion.occlusion_on_contributing_surface_from_outside_target()
2133 .ToString());
2134 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2135 occlusion.occlusion_on_contributing_surface_from_inside_target()
2136 .ToString());
2138 this->LeaveContributingSurface(surface, &occlusion);
2139 this->EnterLayer(parent, &occlusion);
2140 // The occlusion in |surface| and without are merged into the parent.
2141 EXPECT_EQ(gfx::Rect().ToString(),
2142 occlusion.occlusion_from_outside_target().ToString());
2143 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
2144 occlusion.occlusion_from_inside_target().ToString());
2148 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2150 template <class Types>
2151 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2152 : public OcclusionTrackerTest<Types> {
2153 protected:
2154 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2155 bool opaque_layers)
2156 : OcclusionTrackerTest<Types>(opaque_layers) {}
2157 void RunMyTest() override {
2158 gfx::Transform scale_by_half;
2159 scale_by_half.Scale(0.5, 0.5);
2161 FilterOperations filters;
2162 filters.Append(FilterOperation::CreateBlurFilter(10.f));
2164 // Save the distance of influence for the blur effect.
2165 int outset_top, outset_right, outset_bottom, outset_left;
2166 filters.GetOutsets(
2167 &outset_top, &outset_right, &outset_bottom, &outset_left);
2169 enum Direction {
2170 LEFT,
2171 RIGHT,
2172 TOP,
2173 BOTTOM,
2174 LAST_DIRECTION = BOTTOM,
2177 for (int i = 0; i <= LAST_DIRECTION; ++i) {
2178 SCOPED_TRACE(i);
2180 // Make a 50x50 filtered surface that is adjacent to occluding layers
2181 // which are above it in the z-order in various configurations. The
2182 // surface is scaled to test that the pixel moving is done in the target
2183 // space, where the background filter is applied.
2184 typename Types::ContentLayerType* parent = this->CreateRoot(
2185 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
2186 typename Types::LayerType* filtered_surface =
2187 this->CreateDrawingLayer(parent,
2188 scale_by_half,
2189 gfx::PointF(50.f, 50.f),
2190 gfx::Size(100, 100),
2191 false);
2192 Types::SetForceRenderSurface(filtered_surface, true);
2193 filtered_surface->SetBackgroundFilters(filters);
2194 gfx::Rect occlusion_rect;
2195 switch (i) {
2196 case LEFT:
2197 occlusion_rect = gfx::Rect(0, 0, 50, 200);
2198 break;
2199 case RIGHT:
2200 occlusion_rect = gfx::Rect(100, 0, 50, 200);
2201 break;
2202 case TOP:
2203 occlusion_rect = gfx::Rect(0, 0, 200, 50);
2204 break;
2205 case BOTTOM:
2206 occlusion_rect = gfx::Rect(0, 100, 200, 50);
2207 break;
2210 typename Types::LayerType* occluding_layer =
2211 this->CreateDrawingLayer(parent,
2212 this->identity_matrix,
2213 occlusion_rect.origin(),
2214 occlusion_rect.size(),
2215 true);
2216 this->CalcDrawEtc(parent);
2218 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2219 gfx::Rect(0, 0, 200, 200));
2221 // This layer occludes pixels directly beside the filtered_surface.
2222 // Because filtered surface blends pixels in a radius, it will need to see
2223 // some of the pixels (up to radius far) underneath the occluding layers.
2224 this->VisitLayer(occluding_layer, &occlusion);
2226 EXPECT_EQ(occlusion_rect.ToString(),
2227 occlusion.occlusion_from_inside_target().ToString());
2228 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2230 this->VisitLayer(filtered_surface, &occlusion);
2232 // The occlusion is used fully inside the surface.
2233 gfx::Rect occlusion_inside_surface =
2234 occlusion_rect - gfx::Vector2d(50, 50);
2235 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2236 EXPECT_EQ(occlusion_inside_surface.ToString(),
2237 occlusion.occlusion_from_outside_target().ToString());
2239 // The surface has a background blur, so it needs pixels that are
2240 // currently considered occluded in order to be drawn. So the pixels it
2241 // needs should be removed some the occluded area so that when we get to
2242 // the parent they are drawn.
2243 this->VisitContributingSurface(filtered_surface, &occlusion);
2244 this->EnterLayer(parent, &occlusion);
2246 gfx::Rect expected_occlusion = occlusion_rect;
2247 switch (i) {
2248 case LEFT:
2249 expected_occlusion.Inset(0, 0, outset_right, 0);
2250 break;
2251 case RIGHT:
2252 expected_occlusion.Inset(outset_right, 0, 0, 0);
2253 break;
2254 case TOP:
2255 expected_occlusion.Inset(0, 0, 0, outset_right);
2256 break;
2257 case BOTTOM:
2258 expected_occlusion.Inset(0, outset_right, 0, 0);
2259 break;
2262 EXPECT_EQ(expected_occlusion.ToString(),
2263 occlusion.occlusion_from_inside_target().ToString());
2264 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2266 this->DestroyLayers();
2271 ALL_OCCLUSIONTRACKER_TEST(
2272 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2274 template <class Types>
2275 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
2276 : public OcclusionTrackerTest<Types> {
2277 protected:
2278 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
2279 bool opaque_layers)
2280 : OcclusionTrackerTest<Types>(opaque_layers) {}
2281 void RunMyTest() override {
2282 gfx::Transform scale_by_half;
2283 scale_by_half.Scale(0.5, 0.5);
2285 // Makes two surfaces that completely cover |parent|. The occlusion both
2286 // above and below the filters will be reduced by each of them.
2287 typename Types::ContentLayerType* root = this->CreateRoot(
2288 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
2289 typename Types::LayerType* parent = this->CreateSurface(
2290 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
2291 parent->SetMasksToBounds(true);
2292 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
2293 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
2294 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
2295 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
2296 typename Types::LayerType* occluding_layer_above =
2297 this->CreateDrawingLayer(parent,
2298 this->identity_matrix,
2299 gfx::PointF(100.f, 100.f),
2300 gfx::Size(50, 50),
2301 true);
2303 // Filters make the layers own surfaces.
2304 Types::SetForceRenderSurface(filtered_surface1, true);
2305 Types::SetForceRenderSurface(filtered_surface2, true);
2306 FilterOperations filters;
2307 filters.Append(FilterOperation::CreateBlurFilter(1.f));
2308 filtered_surface1->SetBackgroundFilters(filters);
2309 filtered_surface2->SetBackgroundFilters(filters);
2311 // Save the distance of influence for the blur effect.
2312 int outset_top, outset_right, outset_bottom, outset_left;
2313 filters.GetOutsets(
2314 &outset_top, &outset_right, &outset_bottom, &outset_left);
2316 this->CalcDrawEtc(root);
2318 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2319 gfx::Rect(0, 0, 1000, 1000));
2321 this->VisitLayer(occluding_layer_above, &occlusion);
2322 EXPECT_EQ(gfx::Rect().ToString(),
2323 occlusion.occlusion_from_outside_target().ToString());
2324 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
2325 occlusion.occlusion_from_inside_target().ToString());
2327 this->VisitLayer(filtered_surface2, &occlusion);
2328 this->VisitContributingSurface(filtered_surface2, &occlusion);
2329 this->VisitLayer(filtered_surface1, &occlusion);
2330 this->VisitContributingSurface(filtered_surface1, &occlusion);
2332 // Test expectations in the target.
2333 gfx::Rect expected_occlusion =
2334 gfx::Rect(100 / 2 + outset_right * 2,
2335 100 / 2 + outset_bottom * 2,
2336 50 / 2 - (outset_left + outset_right) * 2,
2337 50 / 2 - (outset_top + outset_bottom) * 2);
2338 EXPECT_EQ(expected_occlusion.ToString(),
2339 occlusion.occlusion_from_inside_target().ToString());
2341 // Test expectations in the screen are the same as in the target, as the
2342 // render surface is 1:1 with the screen.
2343 EXPECT_EQ(expected_occlusion.ToString(),
2344 occlusion.occlusion_from_outside_target().ToString());
2348 ALL_OCCLUSIONTRACKER_TEST(
2349 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
2351 template <class Types>
2352 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
2353 : public OcclusionTrackerTest<Types> {
2354 protected:
2355 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
2356 bool opaque_layers)
2357 : OcclusionTrackerTest<Types>(opaque_layers) {}
2358 void RunMyTest() override {
2359 gfx::Transform scale_by_half;
2360 scale_by_half.Scale(0.5, 0.5);
2362 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
2363 // centered below each. The surface is scaled to test that the pixel moving
2364 // is done in the target space, where the background filter is applied, but
2365 // the surface appears at 50, 50 and the replica at 200, 50.
2366 typename Types::ContentLayerType* parent = this->CreateRoot(
2367 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
2368 typename Types::LayerType* behind_surface_layer =
2369 this->CreateDrawingLayer(parent,
2370 this->identity_matrix,
2371 gfx::PointF(60.f, 60.f),
2372 gfx::Size(30, 30),
2373 true);
2374 typename Types::LayerType* behind_replica_layer =
2375 this->CreateDrawingLayer(parent,
2376 this->identity_matrix,
2377 gfx::PointF(210.f, 60.f),
2378 gfx::Size(30, 30),
2379 true);
2380 typename Types::LayerType* filtered_surface =
2381 this->CreateDrawingLayer(parent,
2382 scale_by_half,
2383 gfx::PointF(50.f, 50.f),
2384 gfx::Size(100, 100),
2385 false);
2386 this->CreateReplicaLayer(filtered_surface,
2387 this->identity_matrix,
2388 gfx::PointF(300.f, 0.f),
2389 gfx::Size());
2391 // Filters make the layer own a surface.
2392 Types::SetForceRenderSurface(filtered_surface, true);
2393 FilterOperations filters;
2394 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2395 filtered_surface->SetBackgroundFilters(filters);
2397 this->CalcDrawEtc(parent);
2399 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2400 gfx::Rect(0, 0, 1000, 1000));
2402 // The surface has a background blur, so it blurs non-opaque pixels below
2403 // it.
2404 this->VisitLayer(filtered_surface, &occlusion);
2405 this->VisitContributingSurface(filtered_surface, &occlusion);
2407 this->VisitLayer(behind_replica_layer, &occlusion);
2409 // The layers behind the surface are not blurred, and their occlusion does
2410 // not change, until we leave the surface. So it should not be modified by
2411 // the filter here.
2412 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
2413 EXPECT_EQ(occlusion_behind_replica.ToString(),
2414 occlusion.occlusion_from_inside_target().ToString());
2415 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2417 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
2418 // without existing occlusion interfering.
2419 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2421 this->VisitLayer(behind_surface_layer, &occlusion);
2423 // The layers behind the surface are not blurred, and their occlusion does
2424 // not change, until we leave the surface. So it should not be modified by
2425 // the filter here.
2426 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
2427 EXPECT_EQ(occlusion_behind_surface.ToString(),
2428 occlusion.occlusion_from_inside_target().ToString());
2429 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2433 ALL_OCCLUSIONTRACKER_TEST(
2434 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
2436 template <class Types>
2437 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
2438 : public OcclusionTrackerTest<Types> {
2439 protected:
2440 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
2441 bool opaque_layers)
2442 : OcclusionTrackerTest<Types>(opaque_layers) {}
2443 void RunMyTest() override {
2444 gfx::Transform scale_by_half;
2445 scale_by_half.Scale(0.5, 0.5);
2447 // Make a 50x50 filtered surface that is completely occluded by an opaque
2448 // layer which is above it in the z-order. The surface is
2449 // scaled to test that the pixel moving is done in the target space, where
2450 // the background filter is applied, but the surface appears at 50, 50.
2451 typename Types::ContentLayerType* parent = this->CreateRoot(
2452 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
2453 typename Types::LayerType* filtered_surface =
2454 this->CreateDrawingLayer(parent,
2455 scale_by_half,
2456 gfx::PointF(50.f, 50.f),
2457 gfx::Size(100, 100),
2458 false);
2459 typename Types::LayerType* occluding_layer =
2460 this->CreateDrawingLayer(parent,
2461 this->identity_matrix,
2462 gfx::PointF(50.f, 50.f),
2463 gfx::Size(50, 50),
2464 true);
2466 // Filters make the layer own a surface.
2467 Types::SetForceRenderSurface(filtered_surface, true);
2468 FilterOperations filters;
2469 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2470 filtered_surface->SetBackgroundFilters(filters);
2472 this->CalcDrawEtc(parent);
2474 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2475 gfx::Rect(0, 0, 1000, 1000));
2477 this->VisitLayer(occluding_layer, &occlusion);
2479 this->VisitLayer(filtered_surface, &occlusion);
2481 // The layers above the filtered surface occlude from outside.
2482 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
2484 EXPECT_EQ(gfx::Rect().ToString(),
2485 occlusion.occlusion_from_inside_target().ToString());
2486 EXPECT_EQ(occlusion_above_surface.ToString(),
2487 occlusion.occlusion_from_outside_target().ToString());
2490 // The surface has a background blur, so it blurs non-opaque pixels below
2491 // it.
2492 this->VisitContributingSurface(filtered_surface, &occlusion);
2494 // The filter is completely occluded, so it should not blur anything and
2495 // reduce any occlusion.
2496 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
2498 EXPECT_EQ(occlusion_above_surface.ToString(),
2499 occlusion.occlusion_from_inside_target().ToString());
2500 EXPECT_EQ(gfx::Rect().ToString(),
2501 occlusion.occlusion_from_outside_target().ToString());
2506 ALL_OCCLUSIONTRACKER_TEST(
2507 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
2509 template <class Types>
2510 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
2511 : public OcclusionTrackerTest<Types> {
2512 protected:
2513 explicit
2514 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
2515 bool opaque_layers)
2516 : OcclusionTrackerTest<Types>(opaque_layers) {}
2517 void RunMyTest() override {
2518 gfx::Transform scale_by_half;
2519 scale_by_half.Scale(0.5, 0.5);
2521 // Make a surface and its replica, each 50x50, that are partially occluded
2522 // by opaque layers which are above them in the z-order. The surface is
2523 // scaled to test that the pixel moving is done in the target space, where
2524 // the background filter is applied, but the surface appears at 50, 50 and
2525 // the replica at 200, 50.
2526 typename Types::ContentLayerType* parent = this->CreateRoot(
2527 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
2528 typename Types::LayerType* filtered_surface =
2529 this->CreateDrawingLayer(parent,
2530 scale_by_half,
2531 gfx::PointF(50.f, 50.f),
2532 gfx::Size(100, 100),
2533 false);
2534 this->CreateReplicaLayer(filtered_surface,
2535 this->identity_matrix,
2536 gfx::PointF(300.f, 0.f),
2537 gfx::Size());
2538 typename Types::LayerType* above_surface_layer =
2539 this->CreateDrawingLayer(parent,
2540 this->identity_matrix,
2541 gfx::PointF(70.f, 50.f),
2542 gfx::Size(30, 50),
2543 true);
2544 typename Types::LayerType* above_replica_layer =
2545 this->CreateDrawingLayer(parent,
2546 this->identity_matrix,
2547 gfx::PointF(200.f, 50.f),
2548 gfx::Size(30, 50),
2549 true);
2550 typename Types::LayerType* beside_surface_layer =
2551 this->CreateDrawingLayer(parent,
2552 this->identity_matrix,
2553 gfx::PointF(90.f, 40.f),
2554 gfx::Size(10, 10),
2555 true);
2556 typename Types::LayerType* beside_replica_layer =
2557 this->CreateDrawingLayer(parent,
2558 this->identity_matrix,
2559 gfx::PointF(200.f, 40.f),
2560 gfx::Size(10, 10),
2561 true);
2563 // Filters make the layer own a surface.
2564 Types::SetForceRenderSurface(filtered_surface, true);
2565 FilterOperations filters;
2566 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2567 filtered_surface->SetBackgroundFilters(filters);
2569 // Save the distance of influence for the blur effect.
2570 int outset_top, outset_right, outset_bottom, outset_left;
2571 filters.GetOutsets(
2572 &outset_top, &outset_right, &outset_bottom, &outset_left);
2574 this->CalcDrawEtc(parent);
2576 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2577 gfx::Rect(0, 0, 1000, 1000));
2579 this->VisitLayer(beside_replica_layer, &occlusion);
2580 this->VisitLayer(beside_surface_layer, &occlusion);
2581 this->VisitLayer(above_replica_layer, &occlusion);
2582 this->VisitLayer(above_surface_layer, &occlusion);
2584 // The surface has a background blur, so it blurs non-opaque pixels below
2585 // it.
2586 this->VisitLayer(filtered_surface, &occlusion);
2587 this->VisitContributingSurface(filtered_surface, &occlusion);
2589 // The filter in the surface and replica are partially unoccluded. Only the
2590 // unoccluded parts should reduce occlusion. This means it will push back
2591 // the occlusion that touches the unoccluded part (occlusion_above___), but
2592 // it will not touch occlusion_beside____ since that is not beside the
2593 // unoccluded part of the surface, even though it is beside the occluded
2594 // part of the surface.
2595 gfx::Rect occlusion_above_surface =
2596 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
2597 gfx::Rect occlusion_above_replica =
2598 gfx::Rect(200, 50, 30 - outset_left, 50);
2599 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
2600 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
2602 SimpleEnclosedRegion expected_occlusion;
2603 expected_occlusion.Union(occlusion_beside_replica);
2604 expected_occlusion.Union(occlusion_beside_surface);
2605 expected_occlusion.Union(occlusion_above_replica);
2606 expected_occlusion.Union(occlusion_above_surface);
2608 EXPECT_EQ(expected_occlusion.ToString(),
2609 occlusion.occlusion_from_inside_target().ToString());
2610 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2612 const SimpleEnclosedRegion& actual_occlusion =
2613 occlusion.occlusion_from_inside_target();
2614 for (size_t i = 0; i < expected_occlusion.GetRegionComplexity(); ++i) {
2615 ASSERT_LT(i, actual_occlusion.GetRegionComplexity());
2616 EXPECT_EQ(expected_occlusion.GetRect(i), actual_occlusion.GetRect(i));
2621 ALL_OCCLUSIONTRACKER_TEST(
2622 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
2624 template <class Types>
2625 class OcclusionTrackerTestBlendModeDoesNotOcclude
2626 : public OcclusionTrackerTest<Types> {
2627 protected:
2628 explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers)
2629 : OcclusionTrackerTest<Types>(opaque_layers) {}
2630 void RunMyTest() override {
2631 typename Types::ContentLayerType* parent = this->CreateRoot(
2632 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2633 typename Types::LayerType* blend_mode_layer = this->CreateDrawingLayer(
2634 parent, this->identity_matrix, gfx::PointF(0.f, 0.f),
2635 gfx::Size(100, 100), true);
2636 typename Types::LayerType* top_layer = this->CreateDrawingLayer(
2637 parent, this->identity_matrix, gfx::PointF(10.f, 12.f),
2638 gfx::Size(20, 22), true);
2640 // Blend mode makes the layer own a surface.
2641 Types::SetForceRenderSurface(blend_mode_layer, true);
2642 blend_mode_layer->SetBlendMode(SkXfermode::kMultiply_Mode);
2644 this->CalcDrawEtc(parent);
2646 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2647 gfx::Rect(0, 0, 1000, 1000));
2649 this->VisitLayer(top_layer, &occlusion);
2650 // |top_layer| occludes.
2651 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2652 occlusion.occlusion_from_inside_target().ToString());
2653 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2655 this->VisitLayer(blend_mode_layer, &occlusion);
2656 // |top_layer| occludes but not |blend_mode_layer|.
2657 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2658 occlusion.occlusion_from_outside_target().ToString());
2659 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2661 this->VisitContributingSurface(blend_mode_layer, &occlusion);
2662 // |top_layer| occludes but not |blend_mode_layer|.
2663 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
2664 occlusion.occlusion_from_inside_target().ToString());
2665 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2669 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude);
2671 template <class Types>
2672 class OcclusionTrackerTestMinimumTrackingSize
2673 : public OcclusionTrackerTest<Types> {
2674 protected:
2675 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
2676 : OcclusionTrackerTest<Types>(opaque_layers) {}
2677 void RunMyTest() override {
2678 gfx::Size tracking_size(100, 100);
2679 gfx::Size below_tracking_size(99, 99);
2681 typename Types::ContentLayerType* parent = this->CreateRoot(
2682 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2683 typename Types::LayerType* large = this->CreateDrawingLayer(
2684 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
2685 typename Types::LayerType* small =
2686 this->CreateDrawingLayer(parent,
2687 this->identity_matrix,
2688 gfx::PointF(),
2689 below_tracking_size,
2690 true);
2691 this->CalcDrawEtc(parent);
2693 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2694 gfx::Rect(0, 0, 1000, 1000));
2695 occlusion.set_minimum_tracking_size(tracking_size);
2697 // The small layer is not tracked because it is too small.
2698 this->VisitLayer(small, &occlusion);
2700 EXPECT_EQ(gfx::Rect().ToString(),
2701 occlusion.occlusion_from_outside_target().ToString());
2702 EXPECT_EQ(gfx::Rect().ToString(),
2703 occlusion.occlusion_from_inside_target().ToString());
2705 // The large layer is tracked as it is large enough.
2706 this->VisitLayer(large, &occlusion);
2708 EXPECT_EQ(gfx::Rect().ToString(),
2709 occlusion.occlusion_from_outside_target().ToString());
2710 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
2711 occlusion.occlusion_from_inside_target().ToString());
2715 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
2717 template <class Types>
2718 class OcclusionTrackerTestScaledLayerIsClipped
2719 : public OcclusionTrackerTest<Types> {
2720 protected:
2721 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
2722 : OcclusionTrackerTest<Types>(opaque_layers) {}
2723 void RunMyTest() override {
2724 gfx::Transform scale_transform;
2725 scale_transform.Scale(512.0, 512.0);
2727 typename Types::ContentLayerType* parent = this->CreateRoot(
2728 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2729 typename Types::LayerType* clip = this->CreateLayer(parent,
2730 this->identity_matrix,
2731 gfx::PointF(10.f, 10.f),
2732 gfx::Size(50, 50));
2733 clip->SetMasksToBounds(true);
2734 typename Types::LayerType* scale = this->CreateLayer(
2735 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
2736 typename Types::LayerType* scaled = this->CreateDrawingLayer(
2737 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
2738 this->CalcDrawEtc(parent);
2740 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2741 gfx::Rect(0, 0, 1000, 1000));
2743 this->VisitLayer(scaled, &occlusion);
2745 EXPECT_EQ(gfx::Rect().ToString(),
2746 occlusion.occlusion_from_outside_target().ToString());
2747 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2748 occlusion.occlusion_from_inside_target().ToString());
2752 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
2754 template <class Types>
2755 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
2756 : public OcclusionTrackerTest<Types> {
2757 protected:
2758 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
2759 : OcclusionTrackerTest<Types>(opaque_layers) {}
2760 void RunMyTest() override {
2761 gfx::Transform scale_transform;
2762 scale_transform.Scale(512.0, 512.0);
2764 typename Types::ContentLayerType* parent = this->CreateRoot(
2765 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2766 typename Types::LayerType* clip = this->CreateLayer(parent,
2767 this->identity_matrix,
2768 gfx::PointF(10.f, 10.f),
2769 gfx::Size(50, 50));
2770 clip->SetMasksToBounds(true);
2771 typename Types::LayerType* surface = this->CreateDrawingSurface(
2772 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
2773 typename Types::LayerType* scale = this->CreateLayer(
2774 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
2775 typename Types::LayerType* scaled = this->CreateDrawingLayer(
2776 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
2777 this->CalcDrawEtc(parent);
2779 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2780 gfx::Rect(0, 0, 1000, 1000));
2782 this->VisitLayer(scaled, &occlusion);
2783 this->VisitLayer(surface, &occlusion);
2784 this->VisitContributingSurface(surface, &occlusion);
2786 EXPECT_EQ(gfx::Rect().ToString(),
2787 occlusion.occlusion_from_outside_target().ToString());
2788 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2789 occlusion.occlusion_from_inside_target().ToString());
2793 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
2795 template <class Types>
2796 class OcclusionTrackerTestCopyRequestDoesOcclude
2797 : public OcclusionTrackerTest<Types> {
2798 protected:
2799 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
2800 : OcclusionTrackerTest<Types>(opaque_layers) {}
2801 void RunMyTest() override {
2802 typename Types::ContentLayerType* root = this->CreateRoot(
2803 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2804 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
2805 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2806 typename Types::LayerType* copy = this->CreateLayer(parent,
2807 this->identity_matrix,
2808 gfx::Point(100, 0),
2809 gfx::Size(200, 400));
2810 this->AddCopyRequest(copy);
2811 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
2812 copy,
2813 this->identity_matrix,
2814 gfx::PointF(),
2815 gfx::Size(200, 400),
2816 true);
2817 typename Types::LayerType* top_layer =
2818 this->CreateDrawingLayer(root, this->identity_matrix,
2819 gfx::PointF(50, 0), gfx::Size(50, 400), true);
2820 this->CalcDrawEtc(root);
2822 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2823 gfx::Rect(0, 0, 1000, 1000));
2825 this->VisitLayer(top_layer, &occlusion);
2826 EXPECT_EQ(gfx::Rect().ToString(),
2827 occlusion.occlusion_from_outside_target().ToString());
2828 EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(),
2829 occlusion.occlusion_from_inside_target().ToString());
2831 this->VisitLayer(copy_child, &occlusion);
2832 // Layers outside the copy request do not occlude.
2833 EXPECT_EQ(gfx::Rect().ToString(),
2834 occlusion.occlusion_from_outside_target().ToString());
2835 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2836 occlusion.occlusion_from_inside_target().ToString());
2838 // CopyRequests cause the layer to own a surface.
2839 this->VisitContributingSurface(copy, &occlusion);
2841 // The occlusion from the copy should be kept.
2842 EXPECT_EQ(gfx::Rect().ToString(),
2843 occlusion.occlusion_from_outside_target().ToString());
2844 EXPECT_EQ(gfx::Rect(50, 0, 250, 400).ToString(),
2845 occlusion.occlusion_from_inside_target().ToString());
2849 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
2851 template <class Types>
2852 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2853 : public OcclusionTrackerTest<Types> {
2854 protected:
2855 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2856 bool opaque_layers)
2857 : OcclusionTrackerTest<Types>(opaque_layers) {}
2858 void RunMyTest() override {
2859 typename Types::ContentLayerType* root = this->CreateRoot(
2860 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2861 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
2862 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2863 typename Types::LayerType* hide = this->CreateLayer(
2864 parent, this->identity_matrix, gfx::Point(), gfx::Size());
2865 typename Types::LayerType* copy = this->CreateLayer(
2866 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
2867 this->AddCopyRequest(copy);
2868 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
2869 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
2871 // The |copy| layer is hidden but since it is being copied, it will be
2872 // drawn.
2873 hide->SetHideLayerAndSubtree(true);
2875 this->CalcDrawEtc(root);
2877 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2878 gfx::Rect(0, 0, 1000, 1000));
2880 this->VisitLayer(copy_child, &occlusion);
2881 EXPECT_EQ(gfx::Rect().ToString(),
2882 occlusion.occlusion_from_outside_target().ToString());
2883 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2884 occlusion.occlusion_from_inside_target().ToString());
2886 // CopyRequests cause the layer to own a surface.
2887 this->VisitContributingSurface(copy, &occlusion);
2889 // The occlusion from the copy should be dropped since it is hidden.
2890 EXPECT_EQ(gfx::Rect().ToString(),
2891 occlusion.occlusion_from_outside_target().ToString());
2892 EXPECT_EQ(gfx::Rect().ToString(),
2893 occlusion.occlusion_from_inside_target().ToString());
2897 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
2899 template <class Types>
2900 class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest<Types> {
2901 protected:
2902 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers)
2903 : OcclusionTrackerTest<Types>(opaque_layers) {}
2904 void RunMyTest() override {
2905 gfx::Transform translate;
2906 translate.Translate(10.0, 20.0);
2907 typename Types::ContentLayerType* root = this->CreateRoot(
2908 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2909 typename Types::LayerType* surface = this->CreateSurface(
2910 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2911 typename Types::LayerType* layer = this->CreateDrawingLayer(
2912 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2913 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
2914 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2915 this->CalcDrawEtc(root);
2917 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2918 gfx::Rect(0, 0, 200, 200));
2919 this->VisitLayer(outside_layer, &occlusion);
2920 this->EnterLayer(layer, &occlusion);
2922 // No occlusion, is not occluded.
2923 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2924 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2925 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100)));
2927 // Partial occlusion from outside, is not occluded.
2928 occlusion.set_occlusion_from_outside_target(
2929 SimpleEnclosedRegion(50, 50, 100, 100));
2930 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2931 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2932 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2933 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2934 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2935 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2936 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2937 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2938 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2940 // Full occlusion from outside, is occluded.
2941 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2942 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2943 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2944 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2946 // Partial occlusion from inside, is not occluded.
2947 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2948 occlusion.set_occlusion_from_inside_target(
2949 SimpleEnclosedRegion(50, 50, 100, 100));
2950 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2951 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2952 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2953 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2954 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2955 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2956 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2957 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2959 // Full occlusion from inside, is occluded.
2960 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2961 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2962 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2963 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2965 // Partial occlusion from both, is not occluded.
2966 occlusion.set_occlusion_from_outside_target(
2967 SimpleEnclosedRegion(50, 50, 100, 50));
2968 occlusion.set_occlusion_from_inside_target(
2969 SimpleEnclosedRegion(50, 100, 100, 50));
2970 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2971 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2972 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2973 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2974 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2975 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2976 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2977 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2979 // Full occlusion from both, is occluded.
2980 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2981 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2982 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2983 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2987 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer)
2989 template <class Types>
2990 class OcclusionTrackerTestUnoccludedLayerQuery
2991 : public OcclusionTrackerTest<Types> {
2992 protected:
2993 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers)
2994 : OcclusionTrackerTest<Types>(opaque_layers) {}
2995 void RunMyTest() override {
2996 gfx::Transform translate;
2997 translate.Translate(10.0, 20.0);
2998 typename Types::ContentLayerType* root = this->CreateRoot(
2999 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
3000 typename Types::LayerType* surface = this->CreateSurface(
3001 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
3002 typename Types::LayerType* layer = this->CreateDrawingLayer(
3003 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
3004 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
3005 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
3006 this->CalcDrawEtc(root);
3008 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3009 gfx::Rect(0, 0, 200, 200));
3010 this->VisitLayer(outside_layer, &occlusion);
3011 this->EnterLayer(layer, &occlusion);
3013 // No occlusion, is not occluded.
3014 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3015 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3016 EXPECT_EQ(gfx::Rect(100, 100),
3017 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(100, 100)));
3019 // Partial occlusion from outside.
3020 occlusion.set_occlusion_from_outside_target(
3021 SimpleEnclosedRegion(50, 50, 100, 100));
3022 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3023 EXPECT_EQ(
3024 gfx::Rect(0, 0, 100, 100),
3025 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3026 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3027 occlusion.UnoccludedLayerContentRect(
3028 layer, gfx::Rect(90, 30, 100, 100)));
3029 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3030 occlusion.UnoccludedLayerContentRect(layer,
3031 gfx::Rect(40, 0, 100, 100)));
3032 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3033 occlusion.UnoccludedLayerContentRect(
3034 layer, gfx::Rect(40, 80, 100, 100)));
3035 EXPECT_EQ(
3036 gfx::Rect(0, 0, 80, 100),
3037 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3038 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3039 occlusion.UnoccludedLayerContentRect(
3040 layer, gfx::Rect(90, 80, 100, 100)));
3041 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3042 occlusion.UnoccludedLayerContentRect(layer,
3043 gfx::Rect(0, 80, 100, 100)));
3044 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3045 occlusion.UnoccludedLayerContentRect(layer,
3046 gfx::Rect(90, 0, 100, 100)));
3048 // Full occlusion from outside, is occluded.
3049 EXPECT_EQ(gfx::Rect(),
3050 occlusion.UnoccludedLayerContentRect(
3051 layer, gfx::Rect(40, 30, 100, 100)));
3052 EXPECT_EQ(
3053 gfx::Rect(),
3054 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3055 EXPECT_EQ(gfx::Rect(),
3056 occlusion.UnoccludedLayerContentRect(
3057 layer, gfx::Rect(130, 120, 10, 10)));
3058 EXPECT_EQ(
3059 gfx::Rect(),
3060 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3062 // Partial occlusion from inside, is not occluded.
3063 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3064 occlusion.set_occlusion_from_inside_target(
3065 SimpleEnclosedRegion(50, 50, 100, 100));
3066 EXPECT_EQ(
3067 gfx::Rect(0, 0, 100, 100),
3068 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3069 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3070 occlusion.UnoccludedLayerContentRect(
3071 layer, gfx::Rect(90, 30, 100, 100)));
3072 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3073 occlusion.UnoccludedLayerContentRect(layer,
3074 gfx::Rect(40, 0, 100, 100)));
3075 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3076 occlusion.UnoccludedLayerContentRect(
3077 layer, gfx::Rect(40, 80, 100, 100)));
3078 EXPECT_EQ(
3079 gfx::Rect(0, 0, 80, 100),
3080 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3081 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3082 occlusion.UnoccludedLayerContentRect(
3083 layer, gfx::Rect(90, 80, 100, 100)));
3084 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3085 occlusion.UnoccludedLayerContentRect(layer,
3086 gfx::Rect(0, 80, 100, 100)));
3087 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3088 occlusion.UnoccludedLayerContentRect(layer,
3089 gfx::Rect(90, 0, 100, 100)));
3091 // Full occlusion from inside, is occluded.
3092 EXPECT_EQ(gfx::Rect(),
3093 occlusion.UnoccludedLayerContentRect(
3094 layer, gfx::Rect(40, 30, 100, 100)));
3095 EXPECT_EQ(
3096 gfx::Rect(),
3097 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3098 EXPECT_EQ(gfx::Rect(),
3099 occlusion.UnoccludedLayerContentRect(
3100 layer, gfx::Rect(130, 120, 10, 10)));
3101 EXPECT_EQ(
3102 gfx::Rect(),
3103 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3105 // Partial occlusion from both, is not occluded.
3106 occlusion.set_occlusion_from_outside_target(
3107 SimpleEnclosedRegion(50, 50, 100, 50));
3108 occlusion.set_occlusion_from_inside_target(
3109 SimpleEnclosedRegion(50, 100, 100, 50));
3110 EXPECT_EQ(
3111 gfx::Rect(0, 0, 100, 100),
3112 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3113 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3114 // it's larger.
3115 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3116 occlusion.UnoccludedLayerContentRect(
3117 layer, gfx::Rect(90, 30, 100, 100)));
3118 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3119 occlusion.UnoccludedLayerContentRect(layer,
3120 gfx::Rect(40, 0, 100, 100)));
3121 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3122 occlusion.UnoccludedLayerContentRect(
3123 layer, gfx::Rect(40, 80, 100, 100)));
3124 EXPECT_EQ(
3125 gfx::Rect(0, 0, 80, 100),
3126 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3127 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3128 occlusion.UnoccludedLayerContentRect(
3129 layer, gfx::Rect(90, 80, 100, 100)));
3130 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3131 occlusion.UnoccludedLayerContentRect(layer,
3132 gfx::Rect(0, 80, 100, 100)));
3133 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3134 occlusion.UnoccludedLayerContentRect(layer,
3135 gfx::Rect(90, 0, 100, 100)));
3137 // Full occlusion from both, is occluded.
3138 EXPECT_EQ(gfx::Rect(),
3139 occlusion.UnoccludedLayerContentRect(
3140 layer, gfx::Rect(40, 30, 100, 100)));
3141 EXPECT_EQ(
3142 gfx::Rect(),
3143 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3144 EXPECT_EQ(gfx::Rect(),
3145 occlusion.UnoccludedLayerContentRect(
3146 layer, gfx::Rect(130, 120, 10, 10)));
3147 EXPECT_EQ(
3148 gfx::Rect(),
3149 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3153 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery)
3155 template <class Types>
3156 class OcclusionTrackerTestUnoccludedSurfaceQuery
3157 : public OcclusionTrackerTest<Types> {
3158 protected:
3159 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers)
3160 : OcclusionTrackerTest<Types>(opaque_layers) {}
3161 void RunMyTest() override {
3162 gfx::Transform translate;
3163 translate.Translate(10.0, 20.0);
3164 typename Types::ContentLayerType* root = this->CreateRoot(
3165 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
3166 typename Types::LayerType* surface =
3167 this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200));
3168 typename Types::LayerType* layer =
3169 this->CreateDrawingLayer(surface,
3170 this->identity_matrix,
3171 gfx::Point(),
3172 gfx::Size(200, 200),
3173 false);
3174 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
3175 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
3176 this->CalcDrawEtc(root);
3178 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3179 gfx::Rect(0, 0, 200, 200));
3180 this->VisitLayer(outside_layer, &occlusion);
3181 this->VisitLayer(layer, &occlusion);
3182 this->EnterContributingSurface(surface, &occlusion);
3184 // No occlusion, is not occluded.
3185 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3186 SimpleEnclosedRegion());
3187 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3188 SimpleEnclosedRegion());
3189 EXPECT_EQ(
3190 gfx::Rect(100, 100),
3191 occlusion.UnoccludedSurfaceContentRect(surface, gfx::Rect(100, 100)));
3193 // Partial occlusion from outside.
3194 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3195 SimpleEnclosedRegion(50, 50, 100, 100));
3196 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3197 SimpleEnclosedRegion());
3198 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3199 occlusion.UnoccludedSurfaceContentRect(
3200 surface, gfx::Rect(0, 0, 100, 100)));
3201 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3202 occlusion.UnoccludedSurfaceContentRect(
3203 surface, gfx::Rect(90, 30, 100, 100)));
3204 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3205 occlusion.UnoccludedSurfaceContentRect(
3206 surface, gfx::Rect(40, 0, 100, 100)));
3207 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3208 occlusion.UnoccludedSurfaceContentRect(
3209 surface, gfx::Rect(40, 80, 100, 100)));
3210 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3211 occlusion.UnoccludedSurfaceContentRect(surface,
3212 gfx::Rect(0, 0, 80, 100)));
3213 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3214 occlusion.UnoccludedSurfaceContentRect(
3215 surface, gfx::Rect(90, 80, 100, 100)));
3216 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3217 occlusion.UnoccludedSurfaceContentRect(
3218 surface, gfx::Rect(0, 80, 100, 100)));
3219 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3220 occlusion.UnoccludedSurfaceContentRect(
3221 surface, gfx::Rect(90, 0, 100, 100)));
3223 // Full occlusion from outside, is occluded.
3224 EXPECT_EQ(gfx::Rect(),
3225 occlusion.UnoccludedSurfaceContentRect(
3226 surface, gfx::Rect(40, 30, 100, 100)));
3227 EXPECT_EQ(gfx::Rect(),
3228 occlusion.UnoccludedSurfaceContentRect(
3229 surface, gfx::Rect(40, 30, 10, 10)));
3230 EXPECT_EQ(gfx::Rect(),
3231 occlusion.UnoccludedSurfaceContentRect(
3232 surface, gfx::Rect(130, 120, 10, 10)));
3233 EXPECT_EQ(gfx::Rect(),
3234 occlusion.UnoccludedSurfaceContentRect(
3235 surface, gfx::Rect(80, 70, 50, 50)));
3237 // Partial occlusion from inside, is not occluded.
3238 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3239 SimpleEnclosedRegion());
3240 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3241 SimpleEnclosedRegion(50, 50, 100, 100));
3242 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3243 occlusion.UnoccludedSurfaceContentRect(
3244 surface, gfx::Rect(0, 0, 100, 100)));
3245 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3246 occlusion.UnoccludedSurfaceContentRect(
3247 surface, gfx::Rect(90, 30, 100, 100)));
3248 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3249 occlusion.UnoccludedSurfaceContentRect(
3250 surface, gfx::Rect(40, 0, 100, 100)));
3251 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3252 occlusion.UnoccludedSurfaceContentRect(
3253 surface, gfx::Rect(40, 80, 100, 100)));
3254 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3255 occlusion.UnoccludedSurfaceContentRect(surface,
3256 gfx::Rect(0, 0, 80, 100)));
3257 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3258 occlusion.UnoccludedSurfaceContentRect(
3259 surface, gfx::Rect(90, 80, 100, 100)));
3260 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3261 occlusion.UnoccludedSurfaceContentRect(
3262 surface, gfx::Rect(0, 80, 100, 100)));
3263 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3264 occlusion.UnoccludedSurfaceContentRect(
3265 surface, gfx::Rect(90, 0, 100, 100)));
3267 // Full occlusion from inside, is occluded.
3268 EXPECT_EQ(gfx::Rect(),
3269 occlusion.UnoccludedSurfaceContentRect(
3270 surface, gfx::Rect(40, 30, 100, 100)));
3271 EXPECT_EQ(gfx::Rect(),
3272 occlusion.UnoccludedSurfaceContentRect(
3273 surface, gfx::Rect(40, 30, 10, 10)));
3274 EXPECT_EQ(gfx::Rect(),
3275 occlusion.UnoccludedSurfaceContentRect(
3276 surface, gfx::Rect(130, 120, 10, 10)));
3277 EXPECT_EQ(gfx::Rect(),
3278 occlusion.UnoccludedSurfaceContentRect(
3279 surface, gfx::Rect(80, 70, 50, 50)));
3281 // Partial occlusion from both, is not occluded.
3282 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3283 SimpleEnclosedRegion(50, 50, 100, 50));
3284 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3285 SimpleEnclosedRegion(50, 100, 100, 50));
3286 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3287 occlusion.UnoccludedSurfaceContentRect(
3288 surface, gfx::Rect(0, 0, 100, 100)));
3289 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3290 // it's larger.
3291 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3292 occlusion.UnoccludedSurfaceContentRect(
3293 surface, gfx::Rect(90, 30, 100, 100)));
3294 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3295 occlusion.UnoccludedSurfaceContentRect(
3296 surface, gfx::Rect(40, 0, 100, 100)));
3297 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3298 occlusion.UnoccludedSurfaceContentRect(
3299 surface, gfx::Rect(40, 80, 100, 100)));
3300 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3301 occlusion.UnoccludedSurfaceContentRect(surface,
3302 gfx::Rect(0, 0, 80, 100)));
3303 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3304 occlusion.UnoccludedSurfaceContentRect(
3305 surface, gfx::Rect(90, 80, 100, 100)));
3306 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3307 occlusion.UnoccludedSurfaceContentRect(
3308 surface, gfx::Rect(0, 80, 100, 100)));
3309 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3310 occlusion.UnoccludedSurfaceContentRect(
3311 surface, gfx::Rect(90, 0, 100, 100)));
3313 // Full occlusion from both, is occluded.
3314 EXPECT_EQ(gfx::Rect(),
3315 occlusion.UnoccludedSurfaceContentRect(
3316 surface, gfx::Rect(40, 30, 100, 100)));
3317 EXPECT_EQ(gfx::Rect(),
3318 occlusion.UnoccludedSurfaceContentRect(
3319 surface, gfx::Rect(40, 30, 10, 10)));
3320 EXPECT_EQ(gfx::Rect(),
3321 occlusion.UnoccludedSurfaceContentRect(
3322 surface, gfx::Rect(130, 120, 10, 10)));
3323 EXPECT_EQ(gfx::Rect(),
3324 occlusion.UnoccludedSurfaceContentRect(
3325 surface, gfx::Rect(80, 70, 50, 50)));
3329 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery)
3331 } // namespace
3332 } // namespace cc