[WebView] Add unique visual state request ids.
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob172b22798b28a4423826613db2b01d80b4d34003
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/occlusion_tracker.h"
7 #include "cc/animation/layer_animation_controller.h"
8 #include "cc/base/math_util.h"
9 #include "cc/layers/layer.h"
10 #include "cc/layers/layer_impl.h"
11 #include "cc/output/copy_output_request.h"
12 #include "cc/output/copy_output_result.h"
13 #include "cc/output/filter_operation.h"
14 #include "cc/output/filter_operations.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_impl_proxy.h"
17 #include "cc/test/fake_layer_tree_host.h"
18 #include "cc/test/fake_layer_tree_host_impl.h"
19 #include "cc/test/geometry_test_utils.h"
20 #include "cc/test/test_occlusion_tracker.h"
21 #include "cc/trees/layer_tree_host_common.h"
22 #include "cc/trees/single_thread_proxy.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/gfx/transform.h"
27 namespace cc {
28 namespace {
30 class TestContentLayer : public Layer {
31 public:
32 TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
33 SetIsDrawable(true);
36 SimpleEnclosedRegion VisibleContentOpaqueRegion() const override {
37 if (override_opaque_contents_rect_) {
38 return SimpleEnclosedRegion(
39 gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()));
41 return Layer::VisibleContentOpaqueRegion();
43 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
44 override_opaque_contents_rect_ = true;
45 opaque_contents_rect_ = opaque_contents_rect;
48 private:
49 ~TestContentLayer() override {}
51 bool override_opaque_contents_rect_;
52 gfx::Rect opaque_contents_rect_;
55 class TestContentLayerImpl : public LayerImpl {
56 public:
57 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
58 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
59 SetDrawsContent(true);
62 SimpleEnclosedRegion VisibleContentOpaqueRegion() const override {
63 if (override_opaque_contents_rect_) {
64 return SimpleEnclosedRegion(
65 gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()));
67 return LayerImpl::VisibleContentOpaqueRegion();
69 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
70 override_opaque_contents_rect_ = true;
71 opaque_contents_rect_ = opaque_contents_rect;
74 private:
75 bool override_opaque_contents_rect_;
76 gfx::Rect opaque_contents_rect_;
79 template <typename LayerType>
80 class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> {
81 public:
82 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect)
83 : TestOcclusionTracker<LayerType>(viewport_rect) {}
85 bool OccludedLayer(const LayerType* layer,
86 const gfx::Rect& content_rect) const {
87 DCHECK(layer->visible_content_rect().Contains(content_rect));
88 return this->GetCurrentOcclusionForLayer(layer->draw_transform())
89 .IsOccluded(content_rect);
92 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
93 // layer. Simple wrapper around GetUnoccludedContentRect.
94 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
95 const gfx::Rect& content_rect) const {
96 DCHECK(layer->visible_content_rect().Contains(content_rect));
97 return this->GetCurrentOcclusionForLayer(layer->draw_transform())
98 .GetUnoccludedContentRect(content_rect);
101 gfx::Rect UnoccludedSurfaceContentRect(const LayerType* layer,
102 const gfx::Rect& content_rect) const {
103 typename LayerType::RenderSurfaceType* surface = layer->render_surface();
104 return this->UnoccludedContributingSurfaceContentRect(
105 content_rect, surface->draw_transform());
109 struct OcclusionTrackerTestMainThreadTypes {
110 typedef Layer LayerType;
111 typedef FakeLayerTreeHost HostType;
112 typedef RenderSurface RenderSurfaceType;
113 typedef TestContentLayer ContentLayerType;
114 typedef scoped_refptr<Layer> LayerPtrType;
115 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
116 typedef LayerIterator<Layer> TestLayerIterator;
117 typedef OcclusionTracker<Layer> OcclusionTrackerType;
119 static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
120 static ContentLayerPtrType CreateContentLayer(HostType* host) {
121 return make_scoped_refptr(new ContentLayerType());
124 template <typename T>
125 static LayerPtrType PassLayerPtr(T* layer) {
126 LayerPtrType ref(*layer);
127 *layer = NULL;
128 return ref;
130 static void SetForceRenderSurface(LayerType* layer, bool force) {
131 layer->SetForceRenderSurface(force);
134 static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
136 static void RecursiveUpdateNumChildren(LayerType* layerType) {}
139 struct OcclusionTrackerTestImplThreadTypes {
140 typedef LayerImpl LayerType;
141 typedef LayerTreeImpl HostType;
142 typedef RenderSurfaceImpl RenderSurfaceType;
143 typedef TestContentLayerImpl ContentLayerType;
144 typedef scoped_ptr<LayerImpl> LayerPtrType;
145 typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
146 typedef LayerIterator<LayerImpl> TestLayerIterator;
147 typedef OcclusionTracker<LayerImpl> OcclusionTrackerType;
149 static LayerPtrType CreateLayer(HostType* host) {
150 return LayerImpl::Create(host, next_layer_impl_id++);
152 static ContentLayerPtrType CreateContentLayer(HostType* host) {
153 return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
155 static int next_layer_impl_id;
157 template <typename T>
158 static LayerPtrType PassLayerPtr(T* layer) {
159 return layer->Pass();
162 static void SetForceRenderSurface(LayerType* layer, bool force) {
163 layer->SetHasRenderSurface(force);
165 static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
167 static void RecursiveUpdateNumChildren(LayerType* layer) {
168 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer);
172 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
174 template <typename Types> class OcclusionTrackerTest : public testing::Test {
175 protected:
176 explicit OcclusionTrackerTest(bool opaque_layers)
177 : opaque_layers_(opaque_layers),
178 client_(FakeLayerTreeHostClient::DIRECT_3D),
179 host_(FakeLayerTreeHost::Create(&client_)) {}
181 virtual void RunMyTest() = 0;
183 void TearDown() override { DestroyLayers(); }
185 typename Types::HostType* GetHost();
187 typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
188 const gfx::PointF& position,
189 const gfx::Size& bounds) {
190 typename Types::ContentLayerPtrType layer(
191 Types::CreateContentLayer(GetHost()));
192 typename Types::ContentLayerType* layer_ptr = layer.get();
193 SetProperties(layer_ptr, transform, position, bounds);
195 DCHECK(!root_.get());
196 root_ = Types::PassLayerPtr(&layer);
198 Types::SetForceRenderSurface(layer_ptr, true);
199 SetRootLayerOnMainThread(layer_ptr);
201 return layer_ptr;
204 typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
205 const gfx::Transform& transform,
206 const gfx::PointF& position,
207 const gfx::Size& bounds) {
208 typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
209 typename Types::LayerType* layer_ptr = layer.get();
210 SetProperties(layer_ptr, transform, position, bounds);
211 parent->AddChild(Types::PassLayerPtr(&layer));
212 return layer_ptr;
215 typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
216 const gfx::Transform& transform,
217 const gfx::PointF& position,
218 const gfx::Size& bounds) {
219 typename Types::LayerType* layer =
220 CreateLayer(parent, transform, position, bounds);
221 Types::SetForceRenderSurface(layer, true);
222 return layer;
225 typename Types::ContentLayerType* CreateDrawingLayer(
226 typename Types::LayerType* parent,
227 const gfx::Transform& transform,
228 const gfx::PointF& position,
229 const gfx::Size& bounds,
230 bool opaque) {
231 typename Types::ContentLayerPtrType layer(
232 Types::CreateContentLayer(GetHost()));
233 typename Types::ContentLayerType* layer_ptr = layer.get();
234 SetProperties(layer_ptr, transform, position, bounds);
236 if (opaque_layers_) {
237 layer_ptr->SetContentsOpaque(opaque);
238 } else {
239 layer_ptr->SetContentsOpaque(false);
240 if (opaque)
241 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
242 else
243 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
246 parent->AddChild(Types::PassLayerPtr(&layer));
247 return layer_ptr;
250 typename Types::LayerType* CreateReplicaLayer(
251 typename Types::LayerType* owning_layer,
252 const gfx::Transform& transform,
253 const gfx::PointF& position,
254 const gfx::Size& bounds) {
255 typename Types::ContentLayerPtrType layer(
256 Types::CreateContentLayer(GetHost()));
257 typename Types::ContentLayerType* layer_ptr = layer.get();
258 SetProperties(layer_ptr, transform, position, bounds);
259 SetReplica(owning_layer, Types::PassLayerPtr(&layer));
260 return layer_ptr;
263 typename Types::LayerType* CreateMaskLayer(
264 typename Types::LayerType* owning_layer,
265 const gfx::Size& bounds) {
266 typename Types::ContentLayerPtrType layer(
267 Types::CreateContentLayer(GetHost()));
268 typename Types::ContentLayerType* layer_ptr = layer.get();
269 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
270 SetMask(owning_layer, Types::PassLayerPtr(&layer));
271 return layer_ptr;
274 typename Types::ContentLayerType* CreateDrawingSurface(
275 typename Types::LayerType* parent,
276 const gfx::Transform& transform,
277 const gfx::PointF& position,
278 const gfx::Size& bounds,
279 bool opaque) {
280 typename Types::ContentLayerType* layer =
281 CreateDrawingLayer(parent, transform, position, bounds, opaque);
282 Types::SetForceRenderSurface(layer, true);
283 return layer;
286 void DestroyLayers() {
287 Types::DestroyLayer(&root_);
288 render_surface_layer_list_ = nullptr;
289 render_surface_layer_list_impl_.clear();
290 replica_layers_.clear();
291 mask_layers_.clear();
292 ResetLayerIterator();
295 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
297 void AddCopyRequest(Layer* layer) {
298 layer->RequestCopyOfOutput(
299 CopyOutputRequest::CreateBitmapRequest(base::Bind(
300 &OcclusionTrackerTest<Types>::CopyOutputCallback,
301 base::Unretained(this))));
304 void AddCopyRequest(LayerImpl* layer) {
305 ScopedPtrVector<CopyOutputRequest> requests;
306 requests.push_back(
307 CopyOutputRequest::CreateBitmapRequest(base::Bind(
308 &OcclusionTrackerTest<Types>::CopyOutputCallback,
309 base::Unretained(this))));
310 layer->SetHasRenderSurface(true);
311 layer->PassCopyRequests(&requests);
314 void CalcDrawEtc(TestContentLayerImpl* root) {
315 DCHECK(root == root_.get());
317 Types::RecursiveUpdateNumChildren(root);
318 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
319 root, root->bounds(), &render_surface_layer_list_impl_);
320 inputs.can_adjust_raster_scales = true;
321 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
323 layer_iterator_ = layer_iterator_begin_ =
324 Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
327 void CalcDrawEtc(TestContentLayer* root) {
328 DCHECK(root == root_.get());
329 DCHECK(!root->render_surface());
331 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
332 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
333 root, root->bounds(), render_surface_layer_list_.get());
334 inputs.can_adjust_raster_scales = true;
335 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
337 layer_iterator_ = layer_iterator_begin_ =
338 Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
341 void EnterLayer(typename Types::LayerType* layer,
342 typename Types::OcclusionTrackerType* occlusion) {
343 ASSERT_EQ(*layer_iterator_, layer);
344 ASSERT_TRUE(layer_iterator_.represents_itself());
345 occlusion->EnterLayer(layer_iterator_);
348 void LeaveLayer(typename Types::LayerType* layer,
349 typename Types::OcclusionTrackerType* occlusion) {
350 ASSERT_EQ(*layer_iterator_, layer);
351 ASSERT_TRUE(layer_iterator_.represents_itself());
352 occlusion->LeaveLayer(layer_iterator_);
353 ++layer_iterator_;
356 void VisitLayer(typename Types::LayerType* layer,
357 typename Types::OcclusionTrackerType* occlusion) {
358 EnterLayer(layer, occlusion);
359 LeaveLayer(layer, occlusion);
362 void EnterContributingSurface(
363 typename Types::LayerType* layer,
364 typename Types::OcclusionTrackerType* occlusion) {
365 ASSERT_EQ(*layer_iterator_, layer);
366 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
367 occlusion->EnterLayer(layer_iterator_);
368 occlusion->LeaveLayer(layer_iterator_);
369 ++layer_iterator_;
370 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
371 occlusion->EnterLayer(layer_iterator_);
374 void LeaveContributingSurface(
375 typename Types::LayerType* layer,
376 typename Types::OcclusionTrackerType* occlusion) {
377 ASSERT_EQ(*layer_iterator_, layer);
378 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
379 occlusion->LeaveLayer(layer_iterator_);
380 ++layer_iterator_;
383 void VisitContributingSurface(
384 typename Types::LayerType* layer,
385 typename Types::OcclusionTrackerType* occlusion) {
386 EnterContributingSurface(layer, occlusion);
387 LeaveContributingSurface(layer, occlusion);
390 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
392 const gfx::Transform identity_matrix;
394 private:
395 void SetRootLayerOnMainThread(Layer* root) {
396 host_->SetRootLayer(scoped_refptr<Layer>(root));
399 void SetRootLayerOnMainThread(LayerImpl* root) {}
401 void SetBaseProperties(typename Types::LayerType* layer,
402 const gfx::Transform& transform,
403 const gfx::PointF& position,
404 const gfx::Size& bounds) {
405 layer->SetTransform(transform);
406 layer->SetPosition(position);
407 layer->SetBounds(bounds);
410 void SetProperties(Layer* layer,
411 const gfx::Transform& transform,
412 const gfx::PointF& position,
413 const gfx::Size& bounds) {
414 SetBaseProperties(layer, transform, position, bounds);
417 void SetProperties(LayerImpl* layer,
418 const gfx::Transform& transform,
419 const gfx::PointF& position,
420 const gfx::Size& bounds) {
421 SetBaseProperties(layer, transform, position, bounds);
423 layer->SetContentBounds(layer->bounds());
426 void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
427 owning_layer->SetReplicaLayer(layer.get());
428 replica_layers_.push_back(layer);
431 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
432 owning_layer->SetReplicaLayer(layer.Pass());
435 void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
436 owning_layer->SetMaskLayer(layer.get());
437 mask_layers_.push_back(layer);
440 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
441 owning_layer->SetMaskLayer(layer.Pass());
444 bool opaque_layers_;
445 FakeLayerTreeHostClient client_;
446 scoped_ptr<FakeLayerTreeHost> host_;
447 // These hold ownership of the layers for the duration of the test.
448 typename Types::LayerPtrType root_;
449 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
450 LayerImplList render_surface_layer_list_impl_;
451 typename Types::TestLayerIterator layer_iterator_begin_;
452 typename Types::TestLayerIterator layer_iterator_;
453 typename Types::LayerType* last_layer_visited_;
454 LayerList replica_layers_;
455 LayerList mask_layers_;
458 template <>
459 FakeLayerTreeHost*
460 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
461 return host_.get();
464 template <>
465 LayerTreeImpl*
466 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
467 return host_->host_impl()->active_tree();
470 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
471 class ClassName##MainThreadOpaqueLayers \
472 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
473 public: /* NOLINT(whitespace/indent) */ \
474 ClassName##MainThreadOpaqueLayers() \
475 : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
476 }; \
477 TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
478 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
479 class ClassName##MainThreadOpaquePaints \
480 : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
481 public: /* NOLINT(whitespace/indent) */ \
482 ClassName##MainThreadOpaquePaints() \
483 : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
484 }; \
485 TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
487 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
488 class ClassName##ImplThreadOpaqueLayers \
489 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
490 public: /* NOLINT(whitespace/indent) */ \
491 ClassName##ImplThreadOpaqueLayers() \
492 : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
493 }; \
494 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
495 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
496 class ClassName##ImplThreadOpaquePaints \
497 : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
498 public: /* NOLINT(whitespace/indent) */ \
499 ClassName##ImplThreadOpaquePaints() \
500 : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
501 }; \
502 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
504 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
505 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
506 RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
507 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
508 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
510 #define MAIN_THREAD_TEST(ClassName) \
511 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
513 #define IMPL_THREAD_TEST(ClassName) \
514 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
516 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
517 RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
518 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
520 template <class Types>
521 class OcclusionTrackerTestIdentityTransforms
522 : public OcclusionTrackerTest<Types> {
523 protected:
524 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
525 : OcclusionTrackerTest<Types>(opaque_layers) {}
527 void RunMyTest() override {
528 typename Types::ContentLayerType* root = this->CreateRoot(
529 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
530 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
531 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
532 typename Types::ContentLayerType* layer =
533 this->CreateDrawingLayer(parent,
534 this->identity_matrix,
535 gfx::PointF(30.f, 30.f),
536 gfx::Size(500, 500),
537 true);
538 parent->SetMasksToBounds(true);
539 this->CalcDrawEtc(root);
541 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
542 gfx::Rect(0, 0, 1000, 1000));
544 this->VisitLayer(layer, &occlusion);
545 this->EnterLayer(parent, &occlusion);
547 EXPECT_EQ(gfx::Rect().ToString(),
548 occlusion.occlusion_from_outside_target().ToString());
549 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
550 occlusion.occlusion_from_inside_target().ToString());
554 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
556 template <class Types>
557 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
558 protected:
559 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
560 : OcclusionTrackerTest<Types>(opaque_layers) {}
561 void RunMyTest() override {
562 gfx::Transform layer_transform;
563 layer_transform.Translate(250.0, 250.0);
564 layer_transform.Rotate(90.0);
565 layer_transform.Translate(-250.0, -250.0);
567 typename Types::ContentLayerType* root = this->CreateRoot(
568 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
569 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
570 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
571 typename Types::ContentLayerType* layer =
572 this->CreateDrawingLayer(parent,
573 layer_transform,
574 gfx::PointF(30.f, 30.f),
575 gfx::Size(500, 500),
576 true);
577 parent->SetMasksToBounds(true);
578 this->CalcDrawEtc(root);
580 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
581 gfx::Rect(0, 0, 1000, 1000));
583 this->VisitLayer(layer, &occlusion);
584 this->EnterLayer(parent, &occlusion);
586 EXPECT_EQ(gfx::Rect().ToString(),
587 occlusion.occlusion_from_outside_target().ToString());
588 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
589 occlusion.occlusion_from_inside_target().ToString());
593 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
595 template <class Types>
596 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
597 protected:
598 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
599 : OcclusionTrackerTest<Types>(opaque_layers) {}
600 void RunMyTest() override {
601 gfx::Transform layer_transform;
602 layer_transform.Translate(20.0, 20.0);
604 typename Types::ContentLayerType* root = this->CreateRoot(
605 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
606 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
607 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
608 typename Types::ContentLayerType* layer =
609 this->CreateDrawingLayer(parent,
610 layer_transform,
611 gfx::PointF(30.f, 30.f),
612 gfx::Size(500, 500),
613 true);
614 parent->SetMasksToBounds(true);
615 this->CalcDrawEtc(root);
617 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
618 gfx::Rect(0, 0, 1000, 1000));
620 this->VisitLayer(layer, &occlusion);
621 this->EnterLayer(parent, &occlusion);
623 EXPECT_EQ(gfx::Rect().ToString(),
624 occlusion.occlusion_from_outside_target().ToString());
625 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
626 occlusion.occlusion_from_inside_target().ToString());
630 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
632 template <class Types>
633 class OcclusionTrackerTestChildInRotatedChild
634 : public OcclusionTrackerTest<Types> {
635 protected:
636 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
637 : OcclusionTrackerTest<Types>(opaque_layers) {}
638 void RunMyTest() override {
639 gfx::Transform child_transform;
640 child_transform.Translate(250.0, 250.0);
641 child_transform.Rotate(90.0);
642 child_transform.Translate(-250.0, -250.0);
644 typename Types::ContentLayerType* parent = this->CreateRoot(
645 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
646 parent->SetMasksToBounds(true);
647 typename Types::LayerType* child = this->CreateSurface(
648 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
649 child->SetMasksToBounds(true);
650 typename Types::ContentLayerType* layer =
651 this->CreateDrawingLayer(child,
652 this->identity_matrix,
653 gfx::PointF(10.f, 10.f),
654 gfx::Size(500, 500),
655 true);
656 this->CalcDrawEtc(parent);
658 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
659 gfx::Rect(0, 0, 1000, 1000));
661 this->VisitLayer(layer, &occlusion);
662 this->EnterContributingSurface(child, &occlusion);
664 EXPECT_EQ(gfx::Rect().ToString(),
665 occlusion.occlusion_from_outside_target().ToString());
666 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
667 occlusion.occlusion_from_inside_target().ToString());
669 this->LeaveContributingSurface(child, &occlusion);
670 this->EnterLayer(parent, &occlusion);
672 EXPECT_EQ(gfx::Rect().ToString(),
673 occlusion.occlusion_from_outside_target().ToString());
674 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
675 occlusion.occlusion_from_inside_target().ToString());
677 /* Justification for the above occlusion from |layer|:
679 +---------------------+
681 | 30 | rotate(90)
682 | 30 + ---------------------------------+
683 100 | | 10 | | ==>
684 | |10+---------------------------------+
685 | | | | | |
686 | | | | | |
687 | | | | | |
688 +----|--|-------------+ | |
689 | | | |
690 | | | |
691 | | | |500
692 | | | |
693 | | | |
694 | | | |
695 | | | |
696 +--|-------------------------------+ |
698 +---------------------------------+
701 +---------------------+
702 | |30 Visible region of |layer|: /////
704 | +---------------------------------+
705 100| | |10 |
706 | +---------------------------------+ |
707 | | |///////////////| 420 | |
708 | | |///////////////|60 | |
709 | | |///////////////| | |
710 +--|--|---------------+ | |
711 20|10| 70 | |
712 | | | |
713 | | | |
714 | | | |
715 | | | |
716 | | | |
717 | | |10|
718 | +------------------------------|--+
719 | 490 |
720 +---------------------------------+
727 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
729 template <class Types>
730 class OcclusionTrackerTestScaledRenderSurface
731 : public OcclusionTrackerTest<Types> {
732 protected:
733 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
734 : OcclusionTrackerTest<Types>(opaque_layers) {}
736 void RunMyTest() override {
737 typename Types::ContentLayerType* parent = this->CreateRoot(
738 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
740 gfx::Transform layer1_matrix;
741 layer1_matrix.Scale(2.0, 2.0);
742 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
743 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
744 Types::SetForceRenderSurface(layer1, true);
746 gfx::Transform layer2_matrix;
747 layer2_matrix.Translate(25.0, 25.0);
748 typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
749 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
750 typename Types::ContentLayerType* occluder =
751 this->CreateDrawingLayer(parent,
752 this->identity_matrix,
753 gfx::PointF(100.f, 100.f),
754 gfx::Size(500, 500),
755 true);
756 this->CalcDrawEtc(parent);
758 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
759 gfx::Rect(0, 0, 1000, 1000));
761 this->VisitLayer(occluder, &occlusion);
762 this->EnterLayer(layer2, &occlusion);
764 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
765 occlusion.occlusion_from_outside_target().ToString());
766 EXPECT_EQ(gfx::Rect().ToString(),
767 occlusion.occlusion_from_inside_target().ToString());
771 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
773 template <class Types>
774 class OcclusionTrackerTestVisitTargetTwoTimes
775 : public OcclusionTrackerTest<Types> {
776 protected:
777 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
778 : OcclusionTrackerTest<Types>(opaque_layers) {}
779 void RunMyTest() override {
780 typename Types::ContentLayerType* root = this->CreateRoot(
781 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
782 typename Types::LayerType* surface = this->CreateSurface(
783 root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size());
784 typename Types::ContentLayerType* surface_child =
785 this->CreateDrawingLayer(surface,
786 this->identity_matrix,
787 gfx::PointF(10.f, 10.f),
788 gfx::Size(50, 50),
789 true);
790 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
791 // first, instead of |surface|'s. This exercises different code in
792 // LeaveToRenderTarget, as the target surface has already been seen when
793 // leaving |surface| later.
794 typename Types::ContentLayerType* top_layer =
795 this->CreateDrawingLayer(root,
796 this->identity_matrix,
797 gfx::PointF(40.f, 90.f),
798 gfx::Size(50, 20),
799 true);
800 this->CalcDrawEtc(root);
802 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
803 gfx::Rect(0, 0, 1000, 1000));
805 this->VisitLayer(top_layer, &occlusion);
807 EXPECT_EQ(gfx::Rect().ToString(),
808 occlusion.occlusion_from_outside_target().ToString());
809 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
810 occlusion.occlusion_from_inside_target().ToString());
812 this->VisitLayer(surface_child, &occlusion);
814 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
815 occlusion.occlusion_from_outside_target().ToString());
816 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
817 occlusion.occlusion_from_inside_target().ToString());
819 this->EnterContributingSurface(surface, &occlusion);
821 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
822 occlusion.occlusion_from_outside_target().ToString());
823 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
824 occlusion.occlusion_from_inside_target().ToString());
826 // Occlusion from |top_layer| already in the root target should get merged
827 // with the occlusion from the |surface| we are leaving now.
828 this->LeaveContributingSurface(surface, &occlusion);
829 this->EnterLayer(root, &occlusion);
831 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
832 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
833 occlusion.occlusion_from_inside_target().ToString());
837 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
839 template <class Types>
840 class OcclusionTrackerTestSurfaceRotatedOffAxis
841 : public OcclusionTrackerTest<Types> {
842 protected:
843 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
844 : OcclusionTrackerTest<Types>(opaque_layers) {}
845 void RunMyTest() override {
846 gfx::Transform child_transform;
847 child_transform.Translate(250.0, 250.0);
848 child_transform.Rotate(95.0);
849 child_transform.Translate(-250.0, -250.0);
851 gfx::Transform layer_transform;
852 layer_transform.Translate(10.0, 10.0);
854 typename Types::ContentLayerType* root = this->CreateRoot(
855 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
856 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
857 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
858 typename Types::LayerType* child = this->CreateSurface(
859 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
860 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
861 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
862 this->CalcDrawEtc(root);
864 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
865 gfx::Rect(0, 0, 1000, 1000));
867 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect(
868 layer_transform, layer->visible_content_rect());
870 this->VisitLayer(layer, &occlusion);
871 this->EnterContributingSurface(child, &occlusion);
873 EXPECT_EQ(gfx::Rect().ToString(),
874 occlusion.occlusion_from_outside_target().ToString());
875 EXPECT_EQ(clipped_layer_in_child.ToString(),
876 occlusion.occlusion_from_inside_target().ToString());
878 this->LeaveContributingSurface(child, &occlusion);
879 this->EnterLayer(parent, &occlusion);
881 EXPECT_EQ(gfx::Rect().ToString(),
882 occlusion.occlusion_from_outside_target().ToString());
883 EXPECT_EQ(gfx::Rect().ToString(),
884 occlusion.occlusion_from_inside_target().ToString());
888 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
890 template <class Types>
891 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
892 : public OcclusionTrackerTest<Types> {
893 protected:
894 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
895 : OcclusionTrackerTest<Types>(opaque_layers) {}
896 void RunMyTest() override {
897 gfx::Transform child_transform;
898 child_transform.Translate(250.0, 250.0);
899 child_transform.Rotate(90.0);
900 child_transform.Translate(-250.0, -250.0);
902 typename Types::ContentLayerType* root = this->CreateRoot(
903 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
904 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
905 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
906 parent->SetMasksToBounds(true);
907 typename Types::ContentLayerType* child =
908 this->CreateDrawingSurface(parent,
909 child_transform,
910 gfx::PointF(30.f, 30.f),
911 gfx::Size(500, 500),
912 false);
913 child->SetMasksToBounds(true);
914 typename Types::ContentLayerType* layer1 =
915 this->CreateDrawingLayer(child,
916 this->identity_matrix,
917 gfx::PointF(10.f, 10.f),
918 gfx::Size(500, 500),
919 true);
920 typename Types::ContentLayerType* layer2 =
921 this->CreateDrawingLayer(child,
922 this->identity_matrix,
923 gfx::PointF(10.f, 450.f),
924 gfx::Size(500, 60),
925 true);
926 this->CalcDrawEtc(root);
928 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
929 gfx::Rect(0, 0, 1000, 1000));
931 this->VisitLayer(layer2, &occlusion);
932 this->VisitLayer(layer1, &occlusion);
933 this->VisitLayer(child, &occlusion);
934 this->EnterContributingSurface(child, &occlusion);
936 EXPECT_EQ(gfx::Rect().ToString(),
937 occlusion.occlusion_from_outside_target().ToString());
938 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
939 occlusion.occlusion_from_inside_target().ToString());
941 this->LeaveContributingSurface(child, &occlusion);
942 this->EnterLayer(parent, &occlusion);
944 EXPECT_EQ(gfx::Rect().ToString(),
945 occlusion.occlusion_from_outside_target().ToString());
946 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
947 occlusion.occlusion_from_inside_target().ToString());
949 /* Justification for the above occlusion from |layer1| and |layer2|:
951 +---------------------+
952 | |30 Visible region of |layer1|: /////
953 | | Visible region of |layer2|: \\\\\
954 | +---------------------------------+
955 | | |10 |
956 | +---------------+-----------------+ |
957 | | |\\\\\\\\\\\\|//| 420 | |
958 | | |\\\\\\\\\\\\|//|60 | |
959 | | |\\\\\\\\\\\\|//| | |
960 +--|--|------------|--+ | |
961 20|10| 70 | | |
962 | | | | |
963 | | | | |
964 | | | | |
965 | | | | |
966 | | | | |
967 | | | |10|
968 | +------------|-----------------|--+
969 | | 490 |
970 +---------------+-----------------+
971 60 440
976 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
978 template <class Types>
979 class OcclusionTrackerTestOverlappingSurfaceSiblings
980 : public OcclusionTrackerTest<Types> {
981 protected:
982 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
983 : OcclusionTrackerTest<Types>(opaque_layers) {}
984 void RunMyTest() override {
985 typename Types::ContentLayerType* parent = this->CreateRoot(
986 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
987 parent->SetMasksToBounds(true);
988 typename Types::LayerType* child1 = this->CreateSurface(
989 parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size());
990 typename Types::LayerType* child2 = this->CreateSurface(
991 parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size());
992 typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
993 child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true);
994 typename Types::ContentLayerType* layer2 =
995 this->CreateDrawingLayer(child2,
996 this->identity_matrix,
997 gfx::PointF(10.f, 0.f),
998 gfx::Size(40, 50),
999 true);
1000 this->CalcDrawEtc(parent);
1002 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1003 gfx::Rect(0, 0, 1000, 1000));
1005 this->VisitLayer(layer2, &occlusion);
1006 this->EnterContributingSurface(child2, &occlusion);
1008 // layer2's occlusion.
1009 EXPECT_EQ(gfx::Rect().ToString(),
1010 occlusion.occlusion_from_outside_target().ToString());
1011 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
1012 occlusion.occlusion_from_inside_target().ToString());
1014 this->LeaveContributingSurface(child2, &occlusion);
1015 this->VisitLayer(layer1, &occlusion);
1016 this->EnterContributingSurface(child1, &occlusion);
1018 // layer2's occlusion in the target space of layer1.
1019 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
1020 occlusion.occlusion_from_outside_target().ToString());
1021 // layer1's occlusion.
1022 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
1023 occlusion.occlusion_from_inside_target().ToString());
1025 this->LeaveContributingSurface(child1, &occlusion);
1026 this->EnterLayer(parent, &occlusion);
1028 // The occlusion from from layer1 and layer2 is merged.
1029 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1030 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
1031 occlusion.occlusion_from_inside_target().ToString());
1035 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1037 template <class Types>
1038 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1039 : public OcclusionTrackerTest<Types> {
1040 protected:
1041 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1042 bool opaque_layers)
1043 : OcclusionTrackerTest<Types>(opaque_layers) {}
1044 void RunMyTest() override {
1045 gfx::Transform child1_transform;
1046 child1_transform.Translate(250.0, 250.0);
1047 child1_transform.Rotate(-90.0);
1048 child1_transform.Translate(-250.0, -250.0);
1050 gfx::Transform child2_transform;
1051 child2_transform.Translate(250.0, 250.0);
1052 child2_transform.Rotate(90.0);
1053 child2_transform.Translate(-250.0, -250.0);
1055 typename Types::ContentLayerType* parent = this->CreateRoot(
1056 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1057 parent->SetMasksToBounds(true);
1058 typename Types::LayerType* child1 = this->CreateSurface(
1059 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1060 typename Types::LayerType* child2 =
1061 this->CreateDrawingSurface(parent,
1062 child2_transform,
1063 gfx::PointF(20.f, 40.f),
1064 gfx::Size(10, 10),
1065 false);
1066 typename Types::ContentLayerType* layer1 =
1067 this->CreateDrawingLayer(child1,
1068 this->identity_matrix,
1069 gfx::PointF(-10.f, -20.f),
1070 gfx::Size(510, 510),
1071 true);
1072 typename Types::ContentLayerType* layer2 =
1073 this->CreateDrawingLayer(child2,
1074 this->identity_matrix,
1075 gfx::PointF(-10.f, -10.f),
1076 gfx::Size(510, 510),
1077 true);
1078 this->CalcDrawEtc(parent);
1080 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1081 gfx::Rect(0, 0, 1000, 1000));
1083 this->VisitLayer(layer2, &occlusion);
1084 this->EnterLayer(child2, &occlusion);
1086 EXPECT_EQ(gfx::Rect().ToString(),
1087 occlusion.occlusion_from_outside_target().ToString());
1088 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1089 occlusion.occlusion_from_inside_target().ToString());
1091 this->LeaveLayer(child2, &occlusion);
1092 this->EnterContributingSurface(child2, &occlusion);
1094 EXPECT_EQ(gfx::Rect().ToString(),
1095 occlusion.occlusion_from_outside_target().ToString());
1096 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1097 occlusion.occlusion_from_inside_target().ToString());
1099 this->LeaveContributingSurface(child2, &occlusion);
1100 this->VisitLayer(layer1, &occlusion);
1101 this->EnterContributingSurface(child1, &occlusion);
1103 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1104 occlusion.occlusion_from_outside_target().ToString());
1105 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1106 occlusion.occlusion_from_inside_target().ToString());
1108 this->LeaveContributingSurface(child1, &occlusion);
1109 this->EnterLayer(parent, &occlusion);
1111 EXPECT_EQ(gfx::Rect().ToString(),
1112 occlusion.occlusion_from_outside_target().ToString());
1113 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1114 occlusion.occlusion_from_inside_target().ToString());
1116 /* Justification for the above occlusion:
1118 +---------------------+
1119 |20 | layer1
1120 10+----------------------------------+
1121 100 || 30 | layer2 |
1122 |20+----------------------------------+
1123 || | | | |
1124 || | | | |
1125 || | | | |
1126 +|-|------------------+ | |
1127 | | | | 510
1128 | | 510 | |
1129 | | | |
1130 | | | |
1131 | | | |
1132 | | | |
1133 | | 520 | |
1134 +----------------------------------+ |
1136 +----------------------------------+
1142 ALL_OCCLUSIONTRACKER_TEST(
1143 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1145 template <class Types>
1146 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1147 protected:
1148 explicit OcclusionTrackerTestFilters(bool opaque_layers)
1149 : OcclusionTrackerTest<Types>(opaque_layers) {}
1150 void RunMyTest() override {
1151 gfx::Transform layer_transform;
1152 layer_transform.Translate(250.0, 250.0);
1153 layer_transform.Rotate(90.0);
1154 layer_transform.Translate(-250.0, -250.0);
1156 typename Types::ContentLayerType* parent = this->CreateRoot(
1157 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1158 parent->SetMasksToBounds(true);
1159 typename Types::ContentLayerType* blur_layer =
1160 this->CreateDrawingLayer(parent,
1161 layer_transform,
1162 gfx::PointF(30.f, 30.f),
1163 gfx::Size(500, 500),
1164 true);
1165 typename Types::ContentLayerType* opaque_layer =
1166 this->CreateDrawingLayer(parent,
1167 layer_transform,
1168 gfx::PointF(30.f, 30.f),
1169 gfx::Size(500, 500),
1170 true);
1171 typename Types::ContentLayerType* opacity_layer =
1172 this->CreateDrawingLayer(parent,
1173 layer_transform,
1174 gfx::PointF(30.f, 30.f),
1175 gfx::Size(500, 500),
1176 true);
1178 Types::SetForceRenderSurface(blur_layer, true);
1179 FilterOperations filters;
1180 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1181 blur_layer->SetFilters(filters);
1183 Types::SetForceRenderSurface(opaque_layer, true);
1184 filters.Clear();
1185 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1186 opaque_layer->SetFilters(filters);
1188 Types::SetForceRenderSurface(opacity_layer, true);
1189 filters.Clear();
1190 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1191 opacity_layer->SetFilters(filters);
1193 this->CalcDrawEtc(parent);
1195 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1196 gfx::Rect(0, 0, 1000, 1000));
1198 // Opacity layer won't contribute to occlusion.
1199 this->VisitLayer(opacity_layer, &occlusion);
1200 this->EnterContributingSurface(opacity_layer, &occlusion);
1202 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1203 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1205 // And has nothing to contribute to its parent surface.
1206 this->LeaveContributingSurface(opacity_layer, &occlusion);
1207 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1208 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1210 // Opaque layer will contribute to occlusion.
1211 this->VisitLayer(opaque_layer, &occlusion);
1212 this->EnterContributingSurface(opaque_layer, &occlusion);
1214 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1215 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1216 occlusion.occlusion_from_inside_target().ToString());
1218 // And it gets translated to the parent surface.
1219 this->LeaveContributingSurface(opaque_layer, &occlusion);
1220 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1221 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1222 occlusion.occlusion_from_inside_target().ToString());
1224 // The blur layer needs to throw away any occlusion from outside its
1225 // subtree.
1226 this->EnterLayer(blur_layer, &occlusion);
1227 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1228 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1230 // And it won't contribute to occlusion.
1231 this->LeaveLayer(blur_layer, &occlusion);
1232 this->EnterContributingSurface(blur_layer, &occlusion);
1233 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1234 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1236 // But the opaque layer's occlusion is preserved on the parent.
1237 this->LeaveContributingSurface(blur_layer, &occlusion);
1238 this->EnterLayer(parent, &occlusion);
1239 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1240 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1241 occlusion.occlusion_from_inside_target().ToString());
1245 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1247 template <class Types>
1248 class OcclusionTrackerTestReplicaDoesOcclude
1249 : public OcclusionTrackerTest<Types> {
1250 protected:
1251 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1252 : OcclusionTrackerTest<Types>(opaque_layers) {}
1253 void RunMyTest() override {
1254 typename Types::ContentLayerType* parent = this->CreateRoot(
1255 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1256 typename Types::LayerType* surface = this->CreateDrawingSurface(
1257 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
1258 this->CreateReplicaLayer(
1259 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
1260 this->CalcDrawEtc(parent);
1262 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1263 gfx::Rect(0, 0, 1000, 1000));
1265 this->VisitLayer(surface, &occlusion);
1267 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1268 occlusion.occlusion_from_inside_target().ToString());
1270 this->VisitContributingSurface(surface, &occlusion);
1271 this->EnterLayer(parent, &occlusion);
1273 // The surface and replica should both be occluding the parent.
1274 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1275 occlusion.occlusion_from_inside_target().ToString());
1279 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1281 template <class Types>
1282 class OcclusionTrackerTestReplicaWithClipping
1283 : public OcclusionTrackerTest<Types> {
1284 protected:
1285 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1286 : OcclusionTrackerTest<Types>(opaque_layers) {}
1287 void RunMyTest() override {
1288 typename Types::ContentLayerType* parent = this->CreateRoot(
1289 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1290 parent->SetMasksToBounds(true);
1291 typename Types::LayerType* surface =
1292 this->CreateDrawingSurface(parent,
1293 this->identity_matrix,
1294 gfx::PointF(0.f, 100.f),
1295 gfx::Size(50, 50),
1296 true);
1297 this->CreateReplicaLayer(
1298 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
1299 this->CalcDrawEtc(parent);
1301 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1302 gfx::Rect(0, 0, 1000, 1000));
1304 this->VisitLayer(surface, &occlusion);
1306 // The surface layer's occlusion in its own space.
1307 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1308 occlusion.occlusion_from_inside_target().ToString());
1309 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1311 this->VisitContributingSurface(surface, &occlusion);
1312 this->EnterLayer(parent, &occlusion);
1314 // The surface and replica should both be occluding the parent, the
1315 // replica's occlusion is clipped by the parent.
1316 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1317 occlusion.occlusion_from_inside_target().ToString());
1318 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1322 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1324 template <class Types>
1325 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1326 protected:
1327 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1328 : OcclusionTrackerTest<Types>(opaque_layers) {}
1329 void RunMyTest() override {
1330 typename Types::ContentLayerType* parent = this->CreateRoot(
1331 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1332 typename Types::LayerType* surface =
1333 this->CreateDrawingSurface(parent,
1334 this->identity_matrix,
1335 gfx::PointF(0.f, 100.f),
1336 gfx::Size(50, 50),
1337 true);
1338 typename Types::LayerType* replica = this->CreateReplicaLayer(
1339 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1340 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1341 this->CalcDrawEtc(parent);
1343 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1344 gfx::Rect(0, 0, 1000, 1000));
1346 this->VisitLayer(surface, &occlusion);
1348 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1349 occlusion.occlusion_from_inside_target().ToString());
1351 this->VisitContributingSurface(surface, &occlusion);
1352 this->EnterLayer(parent, &occlusion);
1354 // The replica should not be occluding the parent, since it has a mask
1355 // applied to it.
1356 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1357 occlusion.occlusion_from_inside_target().ToString());
1361 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1363 template <class Types>
1364 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1365 : public OcclusionTrackerTest<Types> {
1366 protected:
1367 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1368 : OcclusionTrackerTest<Types>(opaque_layers) {}
1369 void RunMyTest() override {
1370 typename Types::ContentLayerType* parent = this->CreateRoot(
1371 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1372 typename Types::ContentLayerType* layer =
1373 this->CreateDrawingSurface(parent,
1374 this->identity_matrix,
1375 gfx::PointF(),
1376 gfx::Size(200, 200),
1377 false);
1378 this->CalcDrawEtc(parent);
1380 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1381 gfx::Rect(0, 0, 1000, 1000));
1382 this->EnterLayer(layer, &occlusion);
1384 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1385 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1387 this->LeaveLayer(layer, &occlusion);
1388 this->VisitContributingSurface(layer, &occlusion);
1389 this->EnterLayer(parent, &occlusion);
1391 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1392 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1396 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1398 template <class Types>
1399 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1400 : public OcclusionTrackerTest<Types> {
1401 protected:
1402 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1403 : OcclusionTrackerTest<Types>(opaque_layers) {}
1404 void RunMyTest() override {
1405 typename Types::ContentLayerType* parent = this->CreateRoot(
1406 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1407 typename Types::ContentLayerType* layer =
1408 this->CreateDrawingLayer(parent,
1409 this->identity_matrix,
1410 gfx::PointF(100.f, 100.f),
1411 gfx::Size(200, 200),
1412 false);
1413 this->CalcDrawEtc(parent);
1415 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1416 gfx::Rect(0, 0, 1000, 1000));
1417 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1419 this->ResetLayerIterator();
1420 this->VisitLayer(layer, &occlusion);
1421 this->EnterLayer(parent, &occlusion);
1423 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1424 occlusion.occlusion_from_inside_target().ToString());
1427 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1428 gfx::Rect(0, 0, 1000, 1000));
1429 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1431 this->ResetLayerIterator();
1432 this->VisitLayer(layer, &occlusion);
1433 this->EnterLayer(parent, &occlusion);
1435 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1436 occlusion.occlusion_from_inside_target().ToString());
1439 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1440 gfx::Rect(0, 0, 1000, 1000));
1441 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1443 this->ResetLayerIterator();
1444 this->VisitLayer(layer, &occlusion);
1445 this->EnterLayer(parent, &occlusion);
1447 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1448 occlusion.occlusion_from_inside_target().ToString());
1453 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1455 template <class Types>
1456 class OcclusionTrackerTestUnsorted3dLayers
1457 : public OcclusionTrackerTest<Types> {
1458 protected:
1459 explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
1460 : OcclusionTrackerTest<Types>(opaque_layers) {}
1461 void RunMyTest() override {
1462 // Currently, The main thread layer iterator does not iterate over 3d items
1463 // in sorted order, because layer sorting is not performed on the main
1464 // thread. Because of this, the occlusion tracker cannot assume that a 3d
1465 // layer occludes other layers that have not yet been iterated over. For
1466 // now, the expected behavior is that a 3d layer simply does not add any
1467 // occlusion to the occlusion tracker.
1469 gfx::Transform translation_to_front;
1470 translation_to_front.Translate3d(0.0, 0.0, -10.0);
1471 gfx::Transform translation_to_back;
1472 translation_to_front.Translate3d(0.0, 0.0, -100.0);
1474 typename Types::ContentLayerType* parent = this->CreateRoot(
1475 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1476 typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
1477 parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
1478 typename Types::ContentLayerType* child2 =
1479 this->CreateDrawingLayer(parent,
1480 translation_to_front,
1481 gfx::PointF(50.f, 50.f),
1482 gfx::Size(100, 100),
1483 true);
1484 parent->SetShouldFlattenTransform(false);
1485 parent->Set3dSortingContextId(1);
1486 child1->Set3dSortingContextId(1);
1487 child2->Set3dSortingContextId(1);
1489 this->CalcDrawEtc(parent);
1491 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1492 gfx::Rect(0, 0, 1000, 1000));
1493 this->VisitLayer(child2, &occlusion);
1494 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1495 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1497 this->VisitLayer(child1, &occlusion);
1498 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1499 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1503 // This test will have different layer ordering on the impl thread; the test
1504 // will only work on the main thread.
1505 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1507 template <class Types>
1508 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1509 : public OcclusionTrackerTest<Types> {
1510 protected:
1511 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1512 bool opaque_layers)
1513 : OcclusionTrackerTest<Types>(opaque_layers) {}
1514 void RunMyTest() override {
1515 gfx::Transform transform;
1516 transform.Translate(50.0, 50.0);
1517 transform.ApplyPerspectiveDepth(100.0);
1518 transform.Translate3d(0.0, 0.0, 110.0);
1519 transform.Translate(-50.0, -50.0);
1521 typename Types::ContentLayerType* parent = this->CreateRoot(
1522 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1523 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1524 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
1525 parent->SetShouldFlattenTransform(false);
1526 parent->Set3dSortingContextId(1);
1527 layer->SetShouldFlattenTransform(false);
1528 layer->Set3dSortingContextId(1);
1529 this->CalcDrawEtc(parent);
1531 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1532 gfx::Rect(0, 0, 1000, 1000));
1534 // The |layer| is entirely behind the camera and should not occlude.
1535 this->VisitLayer(layer, &occlusion);
1536 this->EnterLayer(parent, &occlusion);
1537 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1538 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1542 // This test requires accumulating occlusion of 3d layers, which are skipped by
1543 // the occlusion tracker on the main thread. So this test should run on the impl
1544 // thread.
1545 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
1547 template <class Types>
1548 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
1549 : public OcclusionTrackerTest<Types> {
1550 protected:
1551 explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
1552 bool opaque_layers)
1553 : OcclusionTrackerTest<Types>(opaque_layers) {}
1554 void RunMyTest() override {
1555 gfx::Transform transform;
1556 transform.Translate(50.0, 50.0);
1557 transform.ApplyPerspectiveDepth(100.0);
1558 transform.Translate3d(0.0, 0.0, 99.0);
1559 transform.Translate(-50.0, -50.0);
1561 typename Types::ContentLayerType* parent = this->CreateRoot(
1562 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1563 parent->SetMasksToBounds(true);
1564 typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1565 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
1566 parent->SetShouldFlattenTransform(false);
1567 parent->Set3dSortingContextId(1);
1568 layer->SetShouldFlattenTransform(false);
1569 layer->Set3dSortingContextId(1);
1570 this->CalcDrawEtc(parent);
1572 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1573 gfx::Rect(0, 0, 1000, 1000));
1575 // This is very close to the camera, so pixels in its visible_content_rect()
1576 // will actually go outside of the layer's clip rect. Ensure that those
1577 // pixels don't occlude things outside the clip rect.
1578 this->VisitLayer(layer, &occlusion);
1579 this->EnterLayer(parent, &occlusion);
1580 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
1581 occlusion.occlusion_from_inside_target().ToString());
1582 EXPECT_EQ(gfx::Rect().ToString(),
1583 occlusion.occlusion_from_outside_target().ToString());
1587 // This test requires accumulating occlusion of 3d layers, which are skipped by
1588 // the occlusion tracker on the main thread. So this test should run on the impl
1589 // thread.
1590 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
1592 template <class Types>
1593 class OcclusionTrackerTestAnimationOpacity1OnMainThread
1594 : public OcclusionTrackerTest<Types> {
1595 protected:
1596 explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
1597 : OcclusionTrackerTest<Types>(opaque_layers) {}
1598 void RunMyTest() override {
1599 // parent
1600 // +--layer
1601 // +--surface
1602 // | +--surface_child
1603 // | +--surface_child2
1604 // +--parent2
1605 // +--topmost
1607 typename Types::ContentLayerType* parent = this->CreateRoot(
1608 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1609 typename Types::ContentLayerType* layer =
1610 this->CreateDrawingLayer(parent,
1611 this->identity_matrix,
1612 gfx::PointF(),
1613 gfx::Size(300, 300),
1614 true);
1615 typename Types::ContentLayerType* surface =
1616 this->CreateDrawingSurface(parent,
1617 this->identity_matrix,
1618 gfx::PointF(),
1619 gfx::Size(300, 300),
1620 true);
1621 typename Types::ContentLayerType* surface_child =
1622 this->CreateDrawingLayer(surface,
1623 this->identity_matrix,
1624 gfx::PointF(),
1625 gfx::Size(200, 300),
1626 true);
1627 typename Types::ContentLayerType* surface_child2 =
1628 this->CreateDrawingLayer(surface,
1629 this->identity_matrix,
1630 gfx::PointF(),
1631 gfx::Size(100, 300),
1632 true);
1633 typename Types::ContentLayerType* parent2 =
1634 this->CreateDrawingLayer(parent,
1635 this->identity_matrix,
1636 gfx::PointF(),
1637 gfx::Size(300, 300),
1638 false);
1639 typename Types::ContentLayerType* topmost =
1640 this->CreateDrawingLayer(parent,
1641 this->identity_matrix,
1642 gfx::PointF(250.f, 0.f),
1643 gfx::Size(50, 300),
1644 true);
1646 AddOpacityTransitionToController(
1647 layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
1648 AddOpacityTransitionToController(
1649 surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
1650 this->CalcDrawEtc(parent);
1652 EXPECT_TRUE(layer->draw_opacity_is_animating());
1653 EXPECT_FALSE(surface->draw_opacity_is_animating());
1654 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
1656 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1657 gfx::Rect(0, 0, 1000, 1000));
1659 this->VisitLayer(topmost, &occlusion);
1660 this->EnterLayer(parent2, &occlusion);
1662 // This occlusion will affect all surfaces.
1663 EXPECT_EQ(gfx::Rect().ToString(),
1664 occlusion.occlusion_from_outside_target().ToString());
1665 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1666 occlusion.occlusion_from_inside_target().ToString());
1668 this->LeaveLayer(parent2, &occlusion);
1669 this->VisitLayer(surface_child2, &occlusion);
1670 this->EnterLayer(surface_child, &occlusion);
1671 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1672 occlusion.occlusion_from_outside_target().ToString());
1673 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1674 occlusion.occlusion_from_inside_target().ToString());
1676 this->LeaveLayer(surface_child, &occlusion);
1677 this->EnterLayer(surface, &occlusion);
1678 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1679 occlusion.occlusion_from_outside_target().ToString());
1680 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1681 occlusion.occlusion_from_inside_target().ToString());
1683 this->LeaveLayer(surface, &occlusion);
1684 this->EnterContributingSurface(surface, &occlusion);
1685 // Occlusion within the surface is lost when leaving the animating surface.
1686 EXPECT_EQ(gfx::Rect().ToString(),
1687 occlusion.occlusion_from_outside_target().ToString());
1688 EXPECT_EQ(gfx::Rect().ToString(),
1689 occlusion.occlusion_from_inside_target().ToString());
1691 this->LeaveContributingSurface(surface, &occlusion);
1692 // Occlusion from outside the animating surface still exists.
1693 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1694 occlusion.occlusion_from_inside_target().ToString());
1695 EXPECT_EQ(gfx::Rect().ToString(),
1696 occlusion.occlusion_from_outside_target().ToString());
1698 this->VisitLayer(layer, &occlusion);
1699 this->EnterLayer(parent, &occlusion);
1701 // Occlusion is not added for the animating |layer|.
1702 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1703 occlusion.occlusion_from_inside_target().ToString());
1704 EXPECT_EQ(gfx::Rect().ToString(),
1705 occlusion.occlusion_from_outside_target().ToString());
1709 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
1711 template <class Types>
1712 class OcclusionTrackerTestAnimationOpacity0OnMainThread
1713 : public OcclusionTrackerTest<Types> {
1714 protected:
1715 explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
1716 : OcclusionTrackerTest<Types>(opaque_layers) {}
1717 void RunMyTest() override {
1718 typename Types::ContentLayerType* parent = this->CreateRoot(
1719 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1720 typename Types::ContentLayerType* layer =
1721 this->CreateDrawingLayer(parent,
1722 this->identity_matrix,
1723 gfx::PointF(),
1724 gfx::Size(300, 300),
1725 true);
1726 typename Types::ContentLayerType* surface =
1727 this->CreateDrawingSurface(parent,
1728 this->identity_matrix,
1729 gfx::PointF(),
1730 gfx::Size(300, 300),
1731 true);
1732 typename Types::ContentLayerType* surface_child =
1733 this->CreateDrawingLayer(surface,
1734 this->identity_matrix,
1735 gfx::PointF(),
1736 gfx::Size(200, 300),
1737 true);
1738 typename Types::ContentLayerType* surface_child2 =
1739 this->CreateDrawingLayer(surface,
1740 this->identity_matrix,
1741 gfx::PointF(),
1742 gfx::Size(100, 300),
1743 true);
1744 typename Types::ContentLayerType* parent2 =
1745 this->CreateDrawingLayer(parent,
1746 this->identity_matrix,
1747 gfx::PointF(),
1748 gfx::Size(300, 300),
1749 false);
1750 typename Types::ContentLayerType* topmost =
1751 this->CreateDrawingLayer(parent,
1752 this->identity_matrix,
1753 gfx::PointF(250.f, 0.f),
1754 gfx::Size(50, 300),
1755 true);
1757 AddOpacityTransitionToController(
1758 layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
1759 AddOpacityTransitionToController(
1760 surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
1761 this->CalcDrawEtc(parent);
1763 EXPECT_TRUE(layer->draw_opacity_is_animating());
1764 EXPECT_FALSE(surface->draw_opacity_is_animating());
1765 EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
1767 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1768 gfx::Rect(0, 0, 1000, 1000));
1770 this->VisitLayer(topmost, &occlusion);
1771 this->EnterLayer(parent2, &occlusion);
1772 // This occlusion will affect all surfaces.
1773 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1774 occlusion.occlusion_from_inside_target().ToString());
1775 EXPECT_EQ(gfx::Rect().ToString(),
1776 occlusion.occlusion_from_outside_target().ToString());
1778 this->LeaveLayer(parent2, &occlusion);
1779 this->VisitLayer(surface_child2, &occlusion);
1780 this->EnterLayer(surface_child, &occlusion);
1781 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1782 occlusion.occlusion_from_inside_target().ToString());
1783 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1784 occlusion.occlusion_from_outside_target().ToString());
1786 this->LeaveLayer(surface_child, &occlusion);
1787 this->EnterLayer(surface, &occlusion);
1788 EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
1789 occlusion.occlusion_from_inside_target().ToString());
1790 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1791 occlusion.occlusion_from_outside_target().ToString());
1793 this->LeaveLayer(surface, &occlusion);
1794 this->EnterContributingSurface(surface, &occlusion);
1795 // Occlusion within the surface is lost when leaving the animating surface.
1796 EXPECT_EQ(gfx::Rect().ToString(),
1797 occlusion.occlusion_from_inside_target().ToString());
1798 EXPECT_EQ(gfx::Rect().ToString(),
1799 occlusion.occlusion_from_outside_target().ToString());
1801 this->LeaveContributingSurface(surface, &occlusion);
1802 // Occlusion from outside the animating surface still exists.
1803 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1804 occlusion.occlusion_from_inside_target().ToString());
1805 EXPECT_EQ(gfx::Rect().ToString(),
1806 occlusion.occlusion_from_outside_target().ToString());
1808 this->VisitLayer(layer, &occlusion);
1809 this->EnterLayer(parent, &occlusion);
1811 // Occlusion is not added for the animating |layer|.
1812 EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
1813 occlusion.occlusion_from_inside_target().ToString());
1814 EXPECT_EQ(gfx::Rect().ToString(),
1815 occlusion.occlusion_from_outside_target().ToString());
1819 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
1821 template <class Types>
1822 class OcclusionTrackerTestAnimationTranslateOnMainThread
1823 : public OcclusionTrackerTest<Types> {
1824 protected:
1825 explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
1826 bool opaque_layers)
1827 : OcclusionTrackerTest<Types>(opaque_layers) {}
1828 void RunMyTest() override {
1829 typename Types::ContentLayerType* parent = this->CreateRoot(
1830 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1831 typename Types::ContentLayerType* layer =
1832 this->CreateDrawingLayer(parent,
1833 this->identity_matrix,
1834 gfx::PointF(),
1835 gfx::Size(300, 300),
1836 true);
1837 typename Types::ContentLayerType* surface =
1838 this->CreateDrawingSurface(parent,
1839 this->identity_matrix,
1840 gfx::PointF(),
1841 gfx::Size(300, 300),
1842 true);
1843 typename Types::ContentLayerType* surface_child =
1844 this->CreateDrawingLayer(surface,
1845 this->identity_matrix,
1846 gfx::PointF(),
1847 gfx::Size(200, 300),
1848 true);
1849 typename Types::ContentLayerType* surface_child2 =
1850 this->CreateDrawingLayer(surface,
1851 this->identity_matrix,
1852 gfx::PointF(),
1853 gfx::Size(100, 300),
1854 true);
1855 typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
1856 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
1858 AddAnimatedTransformToController(
1859 layer->layer_animation_controller(), 10.0, 30, 0);
1860 AddAnimatedTransformToController(
1861 surface->layer_animation_controller(), 10.0, 30, 0);
1862 AddAnimatedTransformToController(
1863 surface_child->layer_animation_controller(), 10.0, 30, 0);
1864 this->CalcDrawEtc(parent);
1866 EXPECT_TRUE(layer->draw_transform_is_animating());
1867 EXPECT_TRUE(layer->screen_space_transform_is_animating());
1868 EXPECT_TRUE(
1869 surface->render_surface()->target_surface_transforms_are_animating());
1870 EXPECT_TRUE(
1871 surface->render_surface()->screen_space_transforms_are_animating());
1872 // The surface owning layer doesn't animate against its own surface.
1873 EXPECT_FALSE(surface->draw_transform_is_animating());
1874 EXPECT_TRUE(surface->screen_space_transform_is_animating());
1875 EXPECT_TRUE(surface_child->draw_transform_is_animating());
1876 EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
1878 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1879 gfx::Rect(0, 0, 1000, 1000));
1881 this->VisitLayer(surface2, &occlusion);
1882 this->EnterContributingSurface(surface2, &occlusion);
1884 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1885 occlusion.occlusion_from_inside_target().ToString());
1887 this->LeaveContributingSurface(surface2, &occlusion);
1888 this->EnterLayer(surface_child2, &occlusion);
1889 // surface_child2 is moving in screen space but not relative to its target,
1890 // so occlusion should happen in its target space only. It also means that
1891 // things occluding from outside the target (e.g. surface2) cannot occlude
1892 // this layer.
1893 EXPECT_EQ(gfx::Rect().ToString(),
1894 occlusion.occlusion_from_outside_target().ToString());
1895 EXPECT_EQ(gfx::Rect().ToString(),
1896 occlusion.occlusion_from_inside_target().ToString());
1898 this->LeaveLayer(surface_child2, &occlusion);
1899 this->EnterLayer(surface_child, &occlusion);
1900 // surface_child2 added to the occlusion since it is not moving relative
1901 // to its target.
1902 EXPECT_EQ(gfx::Rect().ToString(),
1903 occlusion.occlusion_from_outside_target().ToString());
1904 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1905 occlusion.occlusion_from_inside_target().ToString());
1907 this->LeaveLayer(surface_child, &occlusion);
1908 // surface_child is moving relative to its target, so it does not add
1909 // occlusion.
1910 EXPECT_EQ(gfx::Rect().ToString(),
1911 occlusion.occlusion_from_outside_target().ToString());
1912 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1913 occlusion.occlusion_from_inside_target().ToString());
1915 this->EnterLayer(surface, &occlusion);
1916 EXPECT_EQ(gfx::Rect().ToString(),
1917 occlusion.occlusion_from_outside_target().ToString());
1918 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
1919 occlusion.occlusion_from_inside_target().ToString());
1921 this->LeaveLayer(surface, &occlusion);
1922 // The surface's owning layer is moving in screen space but not relative to
1923 // its target, so it adds to the occlusion.
1924 EXPECT_EQ(gfx::Rect().ToString(),
1925 occlusion.occlusion_from_outside_target().ToString());
1926 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
1927 occlusion.occlusion_from_inside_target().ToString());
1929 this->EnterContributingSurface(surface, &occlusion);
1930 this->LeaveContributingSurface(surface, &occlusion);
1931 // The |surface| is moving in the screen and in its target, so all occlusion
1932 // within the surface is lost when leaving it. Only the |surface2| occlusion
1933 // is left.
1934 EXPECT_EQ(gfx::Rect().ToString(),
1935 occlusion.occlusion_from_outside_target().ToString());
1936 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1937 occlusion.occlusion_from_inside_target().ToString());
1939 this->VisitLayer(layer, &occlusion);
1940 // The |layer| is animating in the screen and in its target, so no occlusion
1941 // is added.
1942 EXPECT_EQ(gfx::Rect().ToString(),
1943 occlusion.occlusion_from_outside_target().ToString());
1944 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
1945 occlusion.occlusion_from_inside_target().ToString());
1949 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
1951 template <class Types>
1952 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1953 : public OcclusionTrackerTest<Types> {
1954 protected:
1955 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1956 bool opaque_layers)
1957 : OcclusionTrackerTest<Types>(opaque_layers) {}
1958 void RunMyTest() override {
1959 gfx::Transform surface_transform;
1960 surface_transform.Translate(300.0, 300.0);
1961 surface_transform.Scale(2.0, 2.0);
1962 surface_transform.Translate(-150.0, -150.0);
1964 typename Types::ContentLayerType* parent = this->CreateRoot(
1965 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
1966 typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
1967 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
1968 typename Types::ContentLayerType* surface2 =
1969 this->CreateDrawingSurface(parent,
1970 this->identity_matrix,
1971 gfx::PointF(50.f, 50.f),
1972 gfx::Size(300, 300),
1973 false);
1974 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1975 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1976 this->CalcDrawEtc(parent);
1978 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
1979 gfx::Rect(0, 0, 1000, 1000));
1981 this->VisitLayer(surface2, &occlusion);
1982 this->VisitContributingSurface(surface2, &occlusion);
1984 EXPECT_EQ(gfx::Rect().ToString(),
1985 occlusion.occlusion_from_outside_target().ToString());
1986 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1987 occlusion.occlusion_from_inside_target().ToString());
1989 // Clear any stored occlusion.
1990 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1991 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1993 this->VisitLayer(surface, &occlusion);
1994 this->VisitContributingSurface(surface, &occlusion);
1996 EXPECT_EQ(gfx::Rect().ToString(),
1997 occlusion.occlusion_from_outside_target().ToString());
1998 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1999 occlusion.occlusion_from_inside_target().ToString());
2003 MAIN_AND_IMPL_THREAD_TEST(
2004 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2006 template <class Types>
2007 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2008 : public OcclusionTrackerTest<Types> {
2009 protected:
2010 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2011 bool opaque_layers)
2012 : OcclusionTrackerTest<Types>(opaque_layers) {}
2013 void RunMyTest() override {
2014 typename Types::ContentLayerType* parent = this->CreateRoot(
2015 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2016 parent->SetMasksToBounds(true);
2017 typename Types::ContentLayerType* surface =
2018 this->CreateDrawingSurface(parent,
2019 this->identity_matrix,
2020 gfx::PointF(),
2021 gfx::Size(500, 300),
2022 false);
2023 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2024 this->CalcDrawEtc(parent);
2026 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2027 gfx::Rect(0, 0, 1000, 1000));
2029 this->VisitLayer(surface, &occlusion);
2030 this->VisitContributingSurface(surface, &occlusion);
2032 EXPECT_EQ(gfx::Rect().ToString(),
2033 occlusion.occlusion_from_outside_target().ToString());
2034 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2035 occlusion.occlusion_from_inside_target().ToString());
2039 MAIN_AND_IMPL_THREAD_TEST(
2040 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2042 template <class Types>
2043 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2044 : public OcclusionTrackerTest<Types> {
2045 protected:
2046 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
2047 : OcclusionTrackerTest<Types>(opaque_layers) {}
2048 void RunMyTest() override {
2049 typename Types::ContentLayerType* parent = this->CreateRoot(
2050 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2051 typename Types::LayerType* surface =
2052 this->CreateDrawingSurface(parent,
2053 this->identity_matrix,
2054 gfx::PointF(),
2055 gfx::Size(100, 100),
2056 true);
2057 this->CreateReplicaLayer(surface,
2058 this->identity_matrix,
2059 gfx::PointF(0.f, 100.f),
2060 gfx::Size(100, 100));
2061 typename Types::LayerType* topmost =
2062 this->CreateDrawingLayer(parent,
2063 this->identity_matrix,
2064 gfx::PointF(),
2065 gfx::Size(100, 110),
2066 true);
2067 this->CalcDrawEtc(parent);
2069 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2070 gfx::Rect(0, 0, 1000, 1000));
2072 // |topmost| occludes the surface, but not the entire surface's replica.
2073 this->VisitLayer(topmost, &occlusion);
2075 EXPECT_EQ(gfx::Rect().ToString(),
2076 occlusion.occlusion_from_outside_target().ToString());
2077 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2078 occlusion.occlusion_from_inside_target().ToString());
2080 this->VisitLayer(surface, &occlusion);
2082 // Render target with replica ignores occlusion from outside.
2083 EXPECT_EQ(gfx::Rect().ToString(),
2084 occlusion.occlusion_from_outside_target().ToString());
2085 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2086 occlusion.occlusion_from_inside_target().ToString());
2088 this->EnterContributingSurface(surface, &occlusion);
2090 // Only occlusion from outside the surface occludes the surface/replica.
2091 EXPECT_EQ(gfx::Rect().ToString(),
2092 occlusion.occlusion_on_contributing_surface_from_outside_target()
2093 .ToString());
2094 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2095 occlusion.occlusion_on_contributing_surface_from_inside_target()
2096 .ToString());
2100 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2102 template <class Types>
2103 class OcclusionTrackerTestSurfaceChildOfSurface
2104 : public OcclusionTrackerTest<Types> {
2105 protected:
2106 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
2107 : OcclusionTrackerTest<Types>(opaque_layers) {}
2108 void RunMyTest() override {
2109 // This test verifies that the surface cliprect does not end up empty and
2110 // clip away the entire unoccluded rect.
2112 typename Types::ContentLayerType* parent = this->CreateRoot(
2113 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2114 typename Types::LayerType* surface =
2115 this->CreateDrawingSurface(parent,
2116 this->identity_matrix,
2117 gfx::PointF(),
2118 gfx::Size(100, 100),
2119 false);
2120 typename Types::LayerType* surface_child =
2121 this->CreateDrawingSurface(surface,
2122 this->identity_matrix,
2123 gfx::PointF(0.f, 10.f),
2124 gfx::Size(100, 50),
2125 true);
2126 typename Types::LayerType* topmost = this->CreateDrawingLayer(
2127 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2128 this->CalcDrawEtc(parent);
2130 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2131 gfx::Rect(-100, -100, 1000, 1000));
2133 // |topmost| occludes everything partially so we know occlusion is happening
2134 // at all.
2135 this->VisitLayer(topmost, &occlusion);
2137 EXPECT_EQ(gfx::Rect().ToString(),
2138 occlusion.occlusion_from_outside_target().ToString());
2139 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2140 occlusion.occlusion_from_inside_target().ToString());
2142 this->VisitLayer(surface_child, &occlusion);
2144 // surface_child increases the occlusion in the screen by a narrow sliver.
2145 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2146 occlusion.occlusion_from_outside_target().ToString());
2147 // In its own surface, surface_child is at 0,0 as is its occlusion.
2148 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2149 occlusion.occlusion_from_inside_target().ToString());
2151 // The root layer always has a clip rect. So the parent of |surface| has a
2152 // clip rect. However, the owning layer for |surface| does not mask to
2153 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2154 // |surface_child| exercises different code paths as its parent does not
2155 // have a clip rect.
2157 this->EnterContributingSurface(surface_child, &occlusion);
2158 // The |surface_child| can't occlude its own surface, but occlusion from
2159 // |topmost| can.
2160 EXPECT_EQ(gfx::Rect().ToString(),
2161 occlusion.occlusion_on_contributing_surface_from_outside_target()
2162 .ToString());
2163 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2164 occlusion.occlusion_on_contributing_surface_from_inside_target()
2165 .ToString());
2166 this->LeaveContributingSurface(surface_child, &occlusion);
2168 // When the surface_child's occlusion is transformed up to its parent, make
2169 // sure it is not clipped away inappropriately.
2170 this->EnterLayer(surface, &occlusion);
2171 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2172 occlusion.occlusion_from_outside_target().ToString());
2173 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2174 occlusion.occlusion_from_inside_target().ToString());
2175 this->LeaveLayer(surface, &occlusion);
2177 this->EnterContributingSurface(surface, &occlusion);
2178 // The occlusion from inside |surface| can't affect the surface, but
2179 // |topmost| can.
2180 EXPECT_EQ(gfx::Rect().ToString(),
2181 occlusion.occlusion_on_contributing_surface_from_outside_target()
2182 .ToString());
2183 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2184 occlusion.occlusion_on_contributing_surface_from_inside_target()
2185 .ToString());
2187 this->LeaveContributingSurface(surface, &occlusion);
2188 this->EnterLayer(parent, &occlusion);
2189 // The occlusion in |surface| and without are merged into the parent.
2190 EXPECT_EQ(gfx::Rect().ToString(),
2191 occlusion.occlusion_from_outside_target().ToString());
2192 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
2193 occlusion.occlusion_from_inside_target().ToString());
2197 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2199 template <class Types>
2200 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
2201 : public OcclusionTrackerTest<Types> {
2202 protected:
2203 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
2204 bool opaque_layers)
2205 : OcclusionTrackerTest<Types>(opaque_layers) {}
2206 void RunMyTest() override {
2207 gfx::Transform scale_by_half;
2208 scale_by_half.Scale(0.5, 0.5);
2210 FilterOperations filters;
2211 filters.Append(FilterOperation::CreateBlurFilter(10.f));
2213 // Save the distance of influence for the blur effect.
2214 int outset_top, outset_right, outset_bottom, outset_left;
2215 filters.GetOutsets(
2216 &outset_top, &outset_right, &outset_bottom, &outset_left);
2218 enum Direction {
2219 LEFT,
2220 RIGHT,
2221 TOP,
2222 BOTTOM,
2223 LAST_DIRECTION = BOTTOM,
2226 for (int i = 0; i <= LAST_DIRECTION; ++i) {
2227 SCOPED_TRACE(i);
2229 // Make a 50x50 filtered surface that is adjacent to occluding layers
2230 // which are above it in the z-order in various configurations. The
2231 // surface is scaled to test that the pixel moving is done in the target
2232 // space, where the background filter is applied.
2233 typename Types::ContentLayerType* parent = this->CreateRoot(
2234 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
2235 typename Types::LayerType* filtered_surface =
2236 this->CreateDrawingLayer(parent,
2237 scale_by_half,
2238 gfx::PointF(50.f, 50.f),
2239 gfx::Size(100, 100),
2240 false);
2241 Types::SetForceRenderSurface(filtered_surface, true);
2242 filtered_surface->SetBackgroundFilters(filters);
2243 gfx::Rect occlusion_rect;
2244 switch (i) {
2245 case LEFT:
2246 occlusion_rect = gfx::Rect(0, 0, 50, 200);
2247 break;
2248 case RIGHT:
2249 occlusion_rect = gfx::Rect(100, 0, 50, 200);
2250 break;
2251 case TOP:
2252 occlusion_rect = gfx::Rect(0, 0, 200, 50);
2253 break;
2254 case BOTTOM:
2255 occlusion_rect = gfx::Rect(0, 100, 200, 50);
2256 break;
2259 typename Types::LayerType* occluding_layer =
2260 this->CreateDrawingLayer(parent,
2261 this->identity_matrix,
2262 occlusion_rect.origin(),
2263 occlusion_rect.size(),
2264 true);
2265 this->CalcDrawEtc(parent);
2267 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2268 gfx::Rect(0, 0, 200, 200));
2270 // This layer occludes pixels directly beside the filtered_surface.
2271 // Because filtered surface blends pixels in a radius, it will need to see
2272 // some of the pixels (up to radius far) underneath the occluding layers.
2273 this->VisitLayer(occluding_layer, &occlusion);
2275 EXPECT_EQ(occlusion_rect.ToString(),
2276 occlusion.occlusion_from_inside_target().ToString());
2277 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2279 this->VisitLayer(filtered_surface, &occlusion);
2281 // The occlusion is used fully inside the surface.
2282 gfx::Rect occlusion_inside_surface =
2283 occlusion_rect - gfx::Vector2d(50, 50);
2284 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2285 EXPECT_EQ(occlusion_inside_surface.ToString(),
2286 occlusion.occlusion_from_outside_target().ToString());
2288 // The surface has a background blur, so it needs pixels that are
2289 // currently considered occluded in order to be drawn. So the pixels it
2290 // needs should be removed some the occluded area so that when we get to
2291 // the parent they are drawn.
2292 this->VisitContributingSurface(filtered_surface, &occlusion);
2293 this->EnterLayer(parent, &occlusion);
2295 gfx::Rect expected_occlusion = occlusion_rect;
2296 switch (i) {
2297 case LEFT:
2298 expected_occlusion.Inset(0, 0, outset_right, 0);
2299 break;
2300 case RIGHT:
2301 expected_occlusion.Inset(outset_right, 0, 0, 0);
2302 break;
2303 case TOP:
2304 expected_occlusion.Inset(0, 0, 0, outset_right);
2305 break;
2306 case BOTTOM:
2307 expected_occlusion.Inset(0, outset_right, 0, 0);
2308 break;
2311 EXPECT_EQ(expected_occlusion.ToString(),
2312 occlusion.occlusion_from_inside_target().ToString());
2313 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2315 this->DestroyLayers();
2320 ALL_OCCLUSIONTRACKER_TEST(
2321 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
2323 template <class Types>
2324 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
2325 : public OcclusionTrackerTest<Types> {
2326 protected:
2327 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
2328 bool opaque_layers)
2329 : OcclusionTrackerTest<Types>(opaque_layers) {}
2330 void RunMyTest() override {
2331 gfx::Transform scale_by_half;
2332 scale_by_half.Scale(0.5, 0.5);
2334 // Makes two surfaces that completely cover |parent|. The occlusion both
2335 // above and below the filters will be reduced by each of them.
2336 typename Types::ContentLayerType* root = this->CreateRoot(
2337 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
2338 typename Types::LayerType* parent = this->CreateSurface(
2339 root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
2340 parent->SetMasksToBounds(true);
2341 typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
2342 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
2343 typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
2344 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
2345 typename Types::LayerType* occluding_layer_above =
2346 this->CreateDrawingLayer(parent,
2347 this->identity_matrix,
2348 gfx::PointF(100.f, 100.f),
2349 gfx::Size(50, 50),
2350 true);
2352 // Filters make the layers own surfaces.
2353 Types::SetForceRenderSurface(filtered_surface1, true);
2354 Types::SetForceRenderSurface(filtered_surface2, true);
2355 FilterOperations filters;
2356 filters.Append(FilterOperation::CreateBlurFilter(1.f));
2357 filtered_surface1->SetBackgroundFilters(filters);
2358 filtered_surface2->SetBackgroundFilters(filters);
2360 // Save the distance of influence for the blur effect.
2361 int outset_top, outset_right, outset_bottom, outset_left;
2362 filters.GetOutsets(
2363 &outset_top, &outset_right, &outset_bottom, &outset_left);
2365 this->CalcDrawEtc(root);
2367 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2368 gfx::Rect(0, 0, 1000, 1000));
2370 this->VisitLayer(occluding_layer_above, &occlusion);
2371 EXPECT_EQ(gfx::Rect().ToString(),
2372 occlusion.occlusion_from_outside_target().ToString());
2373 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
2374 occlusion.occlusion_from_inside_target().ToString());
2376 this->VisitLayer(filtered_surface2, &occlusion);
2377 this->VisitContributingSurface(filtered_surface2, &occlusion);
2378 this->VisitLayer(filtered_surface1, &occlusion);
2379 this->VisitContributingSurface(filtered_surface1, &occlusion);
2381 // Test expectations in the target.
2382 gfx::Rect expected_occlusion =
2383 gfx::Rect(100 / 2 + outset_right * 2,
2384 100 / 2 + outset_bottom * 2,
2385 50 / 2 - (outset_left + outset_right) * 2,
2386 50 / 2 - (outset_top + outset_bottom) * 2);
2387 EXPECT_EQ(expected_occlusion.ToString(),
2388 occlusion.occlusion_from_inside_target().ToString());
2390 // Test expectations in the screen are the same as in the target, as the
2391 // render surface is 1:1 with the screen.
2392 EXPECT_EQ(expected_occlusion.ToString(),
2393 occlusion.occlusion_from_outside_target().ToString());
2397 ALL_OCCLUSIONTRACKER_TEST(
2398 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
2400 template <class Types>
2401 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
2402 : public OcclusionTrackerTest<Types> {
2403 protected:
2404 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
2405 bool opaque_layers)
2406 : OcclusionTrackerTest<Types>(opaque_layers) {}
2407 void RunMyTest() override {
2408 gfx::Transform scale_by_half;
2409 scale_by_half.Scale(0.5, 0.5);
2411 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
2412 // centered below each. The surface is scaled to test that the pixel moving
2413 // is done in the target space, where the background filter is applied, but
2414 // the surface appears at 50, 50 and the replica at 200, 50.
2415 typename Types::ContentLayerType* parent = this->CreateRoot(
2416 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
2417 typename Types::LayerType* behind_surface_layer =
2418 this->CreateDrawingLayer(parent,
2419 this->identity_matrix,
2420 gfx::PointF(60.f, 60.f),
2421 gfx::Size(30, 30),
2422 true);
2423 typename Types::LayerType* behind_replica_layer =
2424 this->CreateDrawingLayer(parent,
2425 this->identity_matrix,
2426 gfx::PointF(210.f, 60.f),
2427 gfx::Size(30, 30),
2428 true);
2429 typename Types::LayerType* filtered_surface =
2430 this->CreateDrawingLayer(parent,
2431 scale_by_half,
2432 gfx::PointF(50.f, 50.f),
2433 gfx::Size(100, 100),
2434 false);
2435 this->CreateReplicaLayer(filtered_surface,
2436 this->identity_matrix,
2437 gfx::PointF(300.f, 0.f),
2438 gfx::Size());
2440 // Filters make the layer own a surface.
2441 Types::SetForceRenderSurface(filtered_surface, true);
2442 FilterOperations filters;
2443 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2444 filtered_surface->SetBackgroundFilters(filters);
2446 this->CalcDrawEtc(parent);
2448 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2449 gfx::Rect(0, 0, 1000, 1000));
2451 // The surface has a background blur, so it blurs non-opaque pixels below
2452 // it.
2453 this->VisitLayer(filtered_surface, &occlusion);
2454 this->VisitContributingSurface(filtered_surface, &occlusion);
2456 this->VisitLayer(behind_replica_layer, &occlusion);
2458 // The layers behind the surface are not blurred, and their occlusion does
2459 // not change, until we leave the surface. So it should not be modified by
2460 // the filter here.
2461 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
2462 EXPECT_EQ(occlusion_behind_replica.ToString(),
2463 occlusion.occlusion_from_inside_target().ToString());
2464 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2466 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
2467 // without existing occlusion interfering.
2468 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2470 this->VisitLayer(behind_surface_layer, &occlusion);
2472 // The layers behind the surface are not blurred, and their occlusion does
2473 // not change, until we leave the surface. So it should not be modified by
2474 // the filter here.
2475 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
2476 EXPECT_EQ(occlusion_behind_surface.ToString(),
2477 occlusion.occlusion_from_inside_target().ToString());
2478 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2482 ALL_OCCLUSIONTRACKER_TEST(
2483 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
2485 template <class Types>
2486 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
2487 : public OcclusionTrackerTest<Types> {
2488 protected:
2489 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
2490 bool opaque_layers)
2491 : OcclusionTrackerTest<Types>(opaque_layers) {}
2492 void RunMyTest() override {
2493 gfx::Transform scale_by_half;
2494 scale_by_half.Scale(0.5, 0.5);
2496 // Make a 50x50 filtered surface that is completely occluded by an opaque
2497 // layer which is above it in the z-order. The surface is
2498 // scaled to test that the pixel moving is done in the target space, where
2499 // the background filter is applied, but the surface appears at 50, 50.
2500 typename Types::ContentLayerType* parent = this->CreateRoot(
2501 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
2502 typename Types::LayerType* filtered_surface =
2503 this->CreateDrawingLayer(parent,
2504 scale_by_half,
2505 gfx::PointF(50.f, 50.f),
2506 gfx::Size(100, 100),
2507 false);
2508 typename Types::LayerType* occluding_layer =
2509 this->CreateDrawingLayer(parent,
2510 this->identity_matrix,
2511 gfx::PointF(50.f, 50.f),
2512 gfx::Size(50, 50),
2513 true);
2515 // Filters make the layer own a surface.
2516 Types::SetForceRenderSurface(filtered_surface, true);
2517 FilterOperations filters;
2518 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2519 filtered_surface->SetBackgroundFilters(filters);
2521 this->CalcDrawEtc(parent);
2523 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2524 gfx::Rect(0, 0, 1000, 1000));
2526 this->VisitLayer(occluding_layer, &occlusion);
2528 this->VisitLayer(filtered_surface, &occlusion);
2530 // The layers above the filtered surface occlude from outside.
2531 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
2533 EXPECT_EQ(gfx::Rect().ToString(),
2534 occlusion.occlusion_from_inside_target().ToString());
2535 EXPECT_EQ(occlusion_above_surface.ToString(),
2536 occlusion.occlusion_from_outside_target().ToString());
2539 // The surface has a background blur, so it blurs non-opaque pixels below
2540 // it.
2541 this->VisitContributingSurface(filtered_surface, &occlusion);
2543 // The filter is completely occluded, so it should not blur anything and
2544 // reduce any occlusion.
2545 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
2547 EXPECT_EQ(occlusion_above_surface.ToString(),
2548 occlusion.occlusion_from_inside_target().ToString());
2549 EXPECT_EQ(gfx::Rect().ToString(),
2550 occlusion.occlusion_from_outside_target().ToString());
2555 ALL_OCCLUSIONTRACKER_TEST(
2556 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
2558 template <class Types>
2559 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
2560 : public OcclusionTrackerTest<Types> {
2561 protected:
2562 explicit
2563 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
2564 bool opaque_layers)
2565 : OcclusionTrackerTest<Types>(opaque_layers) {}
2566 void RunMyTest() override {
2567 gfx::Transform scale_by_half;
2568 scale_by_half.Scale(0.5, 0.5);
2570 // Make a surface and its replica, each 50x50, that are partially occluded
2571 // by opaque layers which are above them in the z-order. The surface is
2572 // scaled to test that the pixel moving is done in the target space, where
2573 // the background filter is applied, but the surface appears at 50, 50 and
2574 // the replica at 200, 50.
2575 typename Types::ContentLayerType* parent = this->CreateRoot(
2576 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
2577 typename Types::LayerType* filtered_surface =
2578 this->CreateDrawingLayer(parent,
2579 scale_by_half,
2580 gfx::PointF(50.f, 50.f),
2581 gfx::Size(100, 100),
2582 false);
2583 this->CreateReplicaLayer(filtered_surface,
2584 this->identity_matrix,
2585 gfx::PointF(300.f, 0.f),
2586 gfx::Size());
2587 typename Types::LayerType* above_surface_layer =
2588 this->CreateDrawingLayer(parent,
2589 this->identity_matrix,
2590 gfx::PointF(70.f, 50.f),
2591 gfx::Size(30, 50),
2592 true);
2593 typename Types::LayerType* above_replica_layer =
2594 this->CreateDrawingLayer(parent,
2595 this->identity_matrix,
2596 gfx::PointF(200.f, 50.f),
2597 gfx::Size(30, 50),
2598 true);
2599 typename Types::LayerType* beside_surface_layer =
2600 this->CreateDrawingLayer(parent,
2601 this->identity_matrix,
2602 gfx::PointF(90.f, 40.f),
2603 gfx::Size(10, 10),
2604 true);
2605 typename Types::LayerType* beside_replica_layer =
2606 this->CreateDrawingLayer(parent,
2607 this->identity_matrix,
2608 gfx::PointF(200.f, 40.f),
2609 gfx::Size(10, 10),
2610 true);
2612 // Filters make the layer own a surface.
2613 Types::SetForceRenderSurface(filtered_surface, true);
2614 FilterOperations filters;
2615 filters.Append(FilterOperation::CreateBlurFilter(3.f));
2616 filtered_surface->SetBackgroundFilters(filters);
2618 // Save the distance of influence for the blur effect.
2619 int outset_top, outset_right, outset_bottom, outset_left;
2620 filters.GetOutsets(
2621 &outset_top, &outset_right, &outset_bottom, &outset_left);
2623 this->CalcDrawEtc(parent);
2625 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2626 gfx::Rect(0, 0, 1000, 1000));
2628 this->VisitLayer(beside_replica_layer, &occlusion);
2629 this->VisitLayer(beside_surface_layer, &occlusion);
2630 this->VisitLayer(above_replica_layer, &occlusion);
2631 this->VisitLayer(above_surface_layer, &occlusion);
2633 // The surface has a background blur, so it blurs non-opaque pixels below
2634 // it.
2635 this->VisitLayer(filtered_surface, &occlusion);
2636 this->VisitContributingSurface(filtered_surface, &occlusion);
2638 // The filter in the surface and replica are partially unoccluded. Only the
2639 // unoccluded parts should reduce occlusion. This means it will push back
2640 // the occlusion that touches the unoccluded part (occlusion_above___), but
2641 // it will not touch occlusion_beside____ since that is not beside the
2642 // unoccluded part of the surface, even though it is beside the occluded
2643 // part of the surface.
2644 gfx::Rect occlusion_above_surface =
2645 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
2646 gfx::Rect occlusion_above_replica =
2647 gfx::Rect(200, 50, 30 - outset_left, 50);
2648 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
2649 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
2651 SimpleEnclosedRegion expected_occlusion;
2652 expected_occlusion.Union(occlusion_beside_replica);
2653 expected_occlusion.Union(occlusion_beside_surface);
2654 expected_occlusion.Union(occlusion_above_replica);
2655 expected_occlusion.Union(occlusion_above_surface);
2657 EXPECT_EQ(expected_occlusion.ToString(),
2658 occlusion.occlusion_from_inside_target().ToString());
2659 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2661 const SimpleEnclosedRegion& actual_occlusion =
2662 occlusion.occlusion_from_inside_target();
2663 for (size_t i = 0; i < expected_occlusion.GetRegionComplexity(); ++i) {
2664 ASSERT_LT(i, actual_occlusion.GetRegionComplexity());
2665 EXPECT_EQ(expected_occlusion.GetRect(i), actual_occlusion.GetRect(i));
2670 ALL_OCCLUSIONTRACKER_TEST(
2671 OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
2673 template <class Types>
2674 class OcclusionTrackerTestMinimumTrackingSize
2675 : public OcclusionTrackerTest<Types> {
2676 protected:
2677 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
2678 : OcclusionTrackerTest<Types>(opaque_layers) {}
2679 void RunMyTest() override {
2680 gfx::Size tracking_size(100, 100);
2681 gfx::Size below_tracking_size(99, 99);
2683 typename Types::ContentLayerType* parent = this->CreateRoot(
2684 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2685 typename Types::LayerType* large = this->CreateDrawingLayer(
2686 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
2687 typename Types::LayerType* small =
2688 this->CreateDrawingLayer(parent,
2689 this->identity_matrix,
2690 gfx::PointF(),
2691 below_tracking_size,
2692 true);
2693 this->CalcDrawEtc(parent);
2695 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2696 gfx::Rect(0, 0, 1000, 1000));
2697 occlusion.set_minimum_tracking_size(tracking_size);
2699 // The small layer is not tracked because it is too small.
2700 this->VisitLayer(small, &occlusion);
2702 EXPECT_EQ(gfx::Rect().ToString(),
2703 occlusion.occlusion_from_outside_target().ToString());
2704 EXPECT_EQ(gfx::Rect().ToString(),
2705 occlusion.occlusion_from_inside_target().ToString());
2707 // The large layer is tracked as it is large enough.
2708 this->VisitLayer(large, &occlusion);
2710 EXPECT_EQ(gfx::Rect().ToString(),
2711 occlusion.occlusion_from_outside_target().ToString());
2712 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
2713 occlusion.occlusion_from_inside_target().ToString());
2717 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
2719 template <class Types>
2720 class OcclusionTrackerTestScaledLayerIsClipped
2721 : public OcclusionTrackerTest<Types> {
2722 protected:
2723 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
2724 : OcclusionTrackerTest<Types>(opaque_layers) {}
2725 void RunMyTest() override {
2726 gfx::Transform scale_transform;
2727 scale_transform.Scale(512.0, 512.0);
2729 typename Types::ContentLayerType* parent = this->CreateRoot(
2730 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2731 typename Types::LayerType* clip = this->CreateLayer(parent,
2732 this->identity_matrix,
2733 gfx::PointF(10.f, 10.f),
2734 gfx::Size(50, 50));
2735 clip->SetMasksToBounds(true);
2736 typename Types::LayerType* scale = this->CreateLayer(
2737 clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
2738 typename Types::LayerType* scaled = this->CreateDrawingLayer(
2739 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
2740 this->CalcDrawEtc(parent);
2742 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2743 gfx::Rect(0, 0, 1000, 1000));
2745 this->VisitLayer(scaled, &occlusion);
2747 EXPECT_EQ(gfx::Rect().ToString(),
2748 occlusion.occlusion_from_outside_target().ToString());
2749 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2750 occlusion.occlusion_from_inside_target().ToString());
2754 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
2756 template <class Types>
2757 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
2758 : public OcclusionTrackerTest<Types> {
2759 protected:
2760 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
2761 : OcclusionTrackerTest<Types>(opaque_layers) {}
2762 void RunMyTest() override {
2763 gfx::Transform scale_transform;
2764 scale_transform.Scale(512.0, 512.0);
2766 typename Types::ContentLayerType* parent = this->CreateRoot(
2767 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
2768 typename Types::LayerType* clip = this->CreateLayer(parent,
2769 this->identity_matrix,
2770 gfx::PointF(10.f, 10.f),
2771 gfx::Size(50, 50));
2772 clip->SetMasksToBounds(true);
2773 typename Types::LayerType* surface = this->CreateDrawingSurface(
2774 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
2775 typename Types::LayerType* scale = this->CreateLayer(
2776 surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
2777 typename Types::LayerType* scaled = this->CreateDrawingLayer(
2778 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
2779 this->CalcDrawEtc(parent);
2781 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2782 gfx::Rect(0, 0, 1000, 1000));
2784 this->VisitLayer(scaled, &occlusion);
2785 this->VisitLayer(surface, &occlusion);
2786 this->VisitContributingSurface(surface, &occlusion);
2788 EXPECT_EQ(gfx::Rect().ToString(),
2789 occlusion.occlusion_from_outside_target().ToString());
2790 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
2791 occlusion.occlusion_from_inside_target().ToString());
2795 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
2797 template <class Types>
2798 class OcclusionTrackerTestCopyRequestDoesOcclude
2799 : public OcclusionTrackerTest<Types> {
2800 protected:
2801 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
2802 : OcclusionTrackerTest<Types>(opaque_layers) {}
2803 void RunMyTest() override {
2804 typename Types::ContentLayerType* root = this->CreateRoot(
2805 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2806 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
2807 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2808 typename Types::LayerType* copy = this->CreateLayer(parent,
2809 this->identity_matrix,
2810 gfx::Point(100, 0),
2811 gfx::Size(200, 400));
2812 this->AddCopyRequest(copy);
2813 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
2814 copy,
2815 this->identity_matrix,
2816 gfx::PointF(),
2817 gfx::Size(200, 400),
2818 true);
2819 this->CalcDrawEtc(root);
2821 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2822 gfx::Rect(0, 0, 1000, 1000));
2824 this->VisitLayer(copy_child, &occlusion);
2825 EXPECT_EQ(gfx::Rect().ToString(),
2826 occlusion.occlusion_from_outside_target().ToString());
2827 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2828 occlusion.occlusion_from_inside_target().ToString());
2830 // CopyRequests cause the layer to own a surface.
2831 this->VisitContributingSurface(copy, &occlusion);
2833 // The occlusion from the copy should be kept.
2834 EXPECT_EQ(gfx::Rect().ToString(),
2835 occlusion.occlusion_from_outside_target().ToString());
2836 EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
2837 occlusion.occlusion_from_inside_target().ToString());
2841 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
2843 template <class Types>
2844 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2845 : public OcclusionTrackerTest<Types> {
2846 protected:
2847 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2848 bool opaque_layers)
2849 : OcclusionTrackerTest<Types>(opaque_layers) {}
2850 void RunMyTest() override {
2851 typename Types::ContentLayerType* root = this->CreateRoot(
2852 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2853 typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
2854 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2855 typename Types::LayerType* hide = this->CreateLayer(
2856 parent, this->identity_matrix, gfx::Point(), gfx::Size());
2857 typename Types::LayerType* copy = this->CreateLayer(
2858 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
2859 this->AddCopyRequest(copy);
2860 typename Types::LayerType* copy_child = this->CreateDrawingLayer(
2861 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
2863 // The |copy| layer is hidden but since it is being copied, it will be
2864 // drawn.
2865 hide->SetHideLayerAndSubtree(true);
2867 this->CalcDrawEtc(root);
2869 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2870 gfx::Rect(0, 0, 1000, 1000));
2872 this->VisitLayer(copy_child, &occlusion);
2873 EXPECT_EQ(gfx::Rect().ToString(),
2874 occlusion.occlusion_from_outside_target().ToString());
2875 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2876 occlusion.occlusion_from_inside_target().ToString());
2878 // CopyRequests cause the layer to own a surface.
2879 this->VisitContributingSurface(copy, &occlusion);
2881 // The occlusion from the copy should be dropped since it is hidden.
2882 EXPECT_EQ(gfx::Rect().ToString(),
2883 occlusion.occlusion_from_outside_target().ToString());
2884 EXPECT_EQ(gfx::Rect().ToString(),
2885 occlusion.occlusion_from_inside_target().ToString());
2889 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
2891 template <class Types>
2892 class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest<Types> {
2893 protected:
2894 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers)
2895 : OcclusionTrackerTest<Types>(opaque_layers) {}
2896 void RunMyTest() override {
2897 gfx::Transform translate;
2898 translate.Translate(10.0, 20.0);
2899 typename Types::ContentLayerType* root = this->CreateRoot(
2900 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2901 typename Types::LayerType* surface = this->CreateSurface(
2902 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2903 typename Types::LayerType* layer = this->CreateDrawingLayer(
2904 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2905 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
2906 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2907 this->CalcDrawEtc(root);
2909 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
2910 gfx::Rect(0, 0, 200, 200));
2911 this->VisitLayer(outside_layer, &occlusion);
2912 this->EnterLayer(layer, &occlusion);
2914 // No occlusion, is not occluded.
2915 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2916 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2917 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100)));
2919 // Partial occlusion from outside, is not occluded.
2920 occlusion.set_occlusion_from_outside_target(
2921 SimpleEnclosedRegion(50, 50, 100, 100));
2922 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2923 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2924 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2925 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2926 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2927 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2928 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2929 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2930 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2932 // Full occlusion from outside, is occluded.
2933 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2934 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2935 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2936 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2938 // Partial occlusion from inside, is not occluded.
2939 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2940 occlusion.set_occlusion_from_inside_target(
2941 SimpleEnclosedRegion(50, 50, 100, 100));
2942 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2943 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2944 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2945 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2946 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2947 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2948 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2949 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2951 // Full occlusion from inside, is occluded.
2952 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2953 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2954 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2955 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2957 // Partial occlusion from both, is not occluded.
2958 occlusion.set_occlusion_from_outside_target(
2959 SimpleEnclosedRegion(50, 50, 100, 50));
2960 occlusion.set_occlusion_from_inside_target(
2961 SimpleEnclosedRegion(50, 100, 100, 50));
2962 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2963 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2964 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2965 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2966 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2967 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2968 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2969 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2971 // Full occlusion from both, is occluded.
2972 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2973 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2974 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2975 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2979 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer)
2981 template <class Types>
2982 class OcclusionTrackerTestUnoccludedLayerQuery
2983 : public OcclusionTrackerTest<Types> {
2984 protected:
2985 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers)
2986 : OcclusionTrackerTest<Types>(opaque_layers) {}
2987 void RunMyTest() override {
2988 gfx::Transform translate;
2989 translate.Translate(10.0, 20.0);
2990 typename Types::ContentLayerType* root = this->CreateRoot(
2991 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2992 typename Types::LayerType* surface = this->CreateSurface(
2993 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2994 typename Types::LayerType* layer = this->CreateDrawingLayer(
2995 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2996 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
2997 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2998 this->CalcDrawEtc(root);
3000 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3001 gfx::Rect(0, 0, 200, 200));
3002 this->VisitLayer(outside_layer, &occlusion);
3003 this->EnterLayer(layer, &occlusion);
3005 // No occlusion, is not occluded.
3006 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3007 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3008 EXPECT_EQ(gfx::Rect(100, 100),
3009 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(100, 100)));
3011 // Partial occlusion from outside.
3012 occlusion.set_occlusion_from_outside_target(
3013 SimpleEnclosedRegion(50, 50, 100, 100));
3014 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
3015 EXPECT_EQ(
3016 gfx::Rect(0, 0, 100, 100),
3017 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3018 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3019 occlusion.UnoccludedLayerContentRect(
3020 layer, gfx::Rect(90, 30, 100, 100)));
3021 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3022 occlusion.UnoccludedLayerContentRect(layer,
3023 gfx::Rect(40, 0, 100, 100)));
3024 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3025 occlusion.UnoccludedLayerContentRect(
3026 layer, gfx::Rect(40, 80, 100, 100)));
3027 EXPECT_EQ(
3028 gfx::Rect(0, 0, 80, 100),
3029 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3030 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3031 occlusion.UnoccludedLayerContentRect(
3032 layer, gfx::Rect(90, 80, 100, 100)));
3033 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3034 occlusion.UnoccludedLayerContentRect(layer,
3035 gfx::Rect(0, 80, 100, 100)));
3036 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3037 occlusion.UnoccludedLayerContentRect(layer,
3038 gfx::Rect(90, 0, 100, 100)));
3040 // Full occlusion from outside, is occluded.
3041 EXPECT_EQ(gfx::Rect(),
3042 occlusion.UnoccludedLayerContentRect(
3043 layer, gfx::Rect(40, 30, 100, 100)));
3044 EXPECT_EQ(
3045 gfx::Rect(),
3046 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3047 EXPECT_EQ(gfx::Rect(),
3048 occlusion.UnoccludedLayerContentRect(
3049 layer, gfx::Rect(130, 120, 10, 10)));
3050 EXPECT_EQ(
3051 gfx::Rect(),
3052 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3054 // Partial occlusion from inside, is not occluded.
3055 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
3056 occlusion.set_occlusion_from_inside_target(
3057 SimpleEnclosedRegion(50, 50, 100, 100));
3058 EXPECT_EQ(
3059 gfx::Rect(0, 0, 100, 100),
3060 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3061 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3062 occlusion.UnoccludedLayerContentRect(
3063 layer, gfx::Rect(90, 30, 100, 100)));
3064 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3065 occlusion.UnoccludedLayerContentRect(layer,
3066 gfx::Rect(40, 0, 100, 100)));
3067 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3068 occlusion.UnoccludedLayerContentRect(
3069 layer, gfx::Rect(40, 80, 100, 100)));
3070 EXPECT_EQ(
3071 gfx::Rect(0, 0, 80, 100),
3072 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3073 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3074 occlusion.UnoccludedLayerContentRect(
3075 layer, gfx::Rect(90, 80, 100, 100)));
3076 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3077 occlusion.UnoccludedLayerContentRect(layer,
3078 gfx::Rect(0, 80, 100, 100)));
3079 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3080 occlusion.UnoccludedLayerContentRect(layer,
3081 gfx::Rect(90, 0, 100, 100)));
3083 // Full occlusion from inside, is occluded.
3084 EXPECT_EQ(gfx::Rect(),
3085 occlusion.UnoccludedLayerContentRect(
3086 layer, gfx::Rect(40, 30, 100, 100)));
3087 EXPECT_EQ(
3088 gfx::Rect(),
3089 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3090 EXPECT_EQ(gfx::Rect(),
3091 occlusion.UnoccludedLayerContentRect(
3092 layer, gfx::Rect(130, 120, 10, 10)));
3093 EXPECT_EQ(
3094 gfx::Rect(),
3095 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3097 // Partial occlusion from both, is not occluded.
3098 occlusion.set_occlusion_from_outside_target(
3099 SimpleEnclosedRegion(50, 50, 100, 50));
3100 occlusion.set_occlusion_from_inside_target(
3101 SimpleEnclosedRegion(50, 100, 100, 50));
3102 EXPECT_EQ(
3103 gfx::Rect(0, 0, 100, 100),
3104 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
3105 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3106 // it's larger.
3107 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3108 occlusion.UnoccludedLayerContentRect(
3109 layer, gfx::Rect(90, 30, 100, 100)));
3110 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3111 occlusion.UnoccludedLayerContentRect(layer,
3112 gfx::Rect(40, 0, 100, 100)));
3113 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3114 occlusion.UnoccludedLayerContentRect(
3115 layer, gfx::Rect(40, 80, 100, 100)));
3116 EXPECT_EQ(
3117 gfx::Rect(0, 0, 80, 100),
3118 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
3119 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3120 occlusion.UnoccludedLayerContentRect(
3121 layer, gfx::Rect(90, 80, 100, 100)));
3122 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3123 occlusion.UnoccludedLayerContentRect(layer,
3124 gfx::Rect(0, 80, 100, 100)));
3125 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3126 occlusion.UnoccludedLayerContentRect(layer,
3127 gfx::Rect(90, 0, 100, 100)));
3129 // Full occlusion from both, is occluded.
3130 EXPECT_EQ(gfx::Rect(),
3131 occlusion.UnoccludedLayerContentRect(
3132 layer, gfx::Rect(40, 30, 100, 100)));
3133 EXPECT_EQ(
3134 gfx::Rect(),
3135 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
3136 EXPECT_EQ(gfx::Rect(),
3137 occlusion.UnoccludedLayerContentRect(
3138 layer, gfx::Rect(130, 120, 10, 10)));
3139 EXPECT_EQ(
3140 gfx::Rect(),
3141 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
3145 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery)
3147 template <class Types>
3148 class OcclusionTrackerTestUnoccludedSurfaceQuery
3149 : public OcclusionTrackerTest<Types> {
3150 protected:
3151 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers)
3152 : OcclusionTrackerTest<Types>(opaque_layers) {}
3153 void RunMyTest() override {
3154 gfx::Transform translate;
3155 translate.Translate(10.0, 20.0);
3156 typename Types::ContentLayerType* root = this->CreateRoot(
3157 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
3158 typename Types::LayerType* surface =
3159 this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200));
3160 typename Types::LayerType* layer =
3161 this->CreateDrawingLayer(surface,
3162 this->identity_matrix,
3163 gfx::Point(),
3164 gfx::Size(200, 200),
3165 false);
3166 typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
3167 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
3168 this->CalcDrawEtc(root);
3170 TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
3171 gfx::Rect(0, 0, 200, 200));
3172 this->VisitLayer(outside_layer, &occlusion);
3173 this->VisitLayer(layer, &occlusion);
3174 this->EnterContributingSurface(surface, &occlusion);
3176 // No occlusion, is not occluded.
3177 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3178 SimpleEnclosedRegion());
3179 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3180 SimpleEnclosedRegion());
3181 EXPECT_EQ(
3182 gfx::Rect(100, 100),
3183 occlusion.UnoccludedSurfaceContentRect(surface, gfx::Rect(100, 100)));
3185 // Partial occlusion from outside.
3186 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3187 SimpleEnclosedRegion(50, 50, 100, 100));
3188 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3189 SimpleEnclosedRegion());
3190 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3191 occlusion.UnoccludedSurfaceContentRect(
3192 surface, gfx::Rect(0, 0, 100, 100)));
3193 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3194 occlusion.UnoccludedSurfaceContentRect(
3195 surface, gfx::Rect(90, 30, 100, 100)));
3196 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3197 occlusion.UnoccludedSurfaceContentRect(
3198 surface, gfx::Rect(40, 0, 100, 100)));
3199 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3200 occlusion.UnoccludedSurfaceContentRect(
3201 surface, gfx::Rect(40, 80, 100, 100)));
3202 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3203 occlusion.UnoccludedSurfaceContentRect(surface,
3204 gfx::Rect(0, 0, 80, 100)));
3205 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3206 occlusion.UnoccludedSurfaceContentRect(
3207 surface, gfx::Rect(90, 80, 100, 100)));
3208 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3209 occlusion.UnoccludedSurfaceContentRect(
3210 surface, gfx::Rect(0, 80, 100, 100)));
3211 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3212 occlusion.UnoccludedSurfaceContentRect(
3213 surface, gfx::Rect(90, 0, 100, 100)));
3215 // Full occlusion from outside, is occluded.
3216 EXPECT_EQ(gfx::Rect(),
3217 occlusion.UnoccludedSurfaceContentRect(
3218 surface, gfx::Rect(40, 30, 100, 100)));
3219 EXPECT_EQ(gfx::Rect(),
3220 occlusion.UnoccludedSurfaceContentRect(
3221 surface, gfx::Rect(40, 30, 10, 10)));
3222 EXPECT_EQ(gfx::Rect(),
3223 occlusion.UnoccludedSurfaceContentRect(
3224 surface, gfx::Rect(130, 120, 10, 10)));
3225 EXPECT_EQ(gfx::Rect(),
3226 occlusion.UnoccludedSurfaceContentRect(
3227 surface, gfx::Rect(80, 70, 50, 50)));
3229 // Partial occlusion from inside, is not occluded.
3230 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3231 SimpleEnclosedRegion());
3232 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3233 SimpleEnclosedRegion(50, 50, 100, 100));
3234 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3235 occlusion.UnoccludedSurfaceContentRect(
3236 surface, gfx::Rect(0, 0, 100, 100)));
3237 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
3238 occlusion.UnoccludedSurfaceContentRect(
3239 surface, gfx::Rect(90, 30, 100, 100)));
3240 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3241 occlusion.UnoccludedSurfaceContentRect(
3242 surface, gfx::Rect(40, 0, 100, 100)));
3243 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3244 occlusion.UnoccludedSurfaceContentRect(
3245 surface, gfx::Rect(40, 80, 100, 100)));
3246 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3247 occlusion.UnoccludedSurfaceContentRect(surface,
3248 gfx::Rect(0, 0, 80, 100)));
3249 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3250 occlusion.UnoccludedSurfaceContentRect(
3251 surface, gfx::Rect(90, 80, 100, 100)));
3252 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3253 occlusion.UnoccludedSurfaceContentRect(
3254 surface, gfx::Rect(0, 80, 100, 100)));
3255 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3256 occlusion.UnoccludedSurfaceContentRect(
3257 surface, gfx::Rect(90, 0, 100, 100)));
3259 // Full occlusion from inside, is occluded.
3260 EXPECT_EQ(gfx::Rect(),
3261 occlusion.UnoccludedSurfaceContentRect(
3262 surface, gfx::Rect(40, 30, 100, 100)));
3263 EXPECT_EQ(gfx::Rect(),
3264 occlusion.UnoccludedSurfaceContentRect(
3265 surface, gfx::Rect(40, 30, 10, 10)));
3266 EXPECT_EQ(gfx::Rect(),
3267 occlusion.UnoccludedSurfaceContentRect(
3268 surface, gfx::Rect(130, 120, 10, 10)));
3269 EXPECT_EQ(gfx::Rect(),
3270 occlusion.UnoccludedSurfaceContentRect(
3271 surface, gfx::Rect(80, 70, 50, 50)));
3273 // Partial occlusion from both, is not occluded.
3274 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
3275 SimpleEnclosedRegion(50, 50, 100, 50));
3276 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
3277 SimpleEnclosedRegion(50, 100, 100, 50));
3278 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
3279 occlusion.UnoccludedSurfaceContentRect(
3280 surface, gfx::Rect(0, 0, 100, 100)));
3281 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
3282 // it's larger.
3283 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
3284 occlusion.UnoccludedSurfaceContentRect(
3285 surface, gfx::Rect(90, 30, 100, 100)));
3286 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
3287 occlusion.UnoccludedSurfaceContentRect(
3288 surface, gfx::Rect(40, 0, 100, 100)));
3289 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
3290 occlusion.UnoccludedSurfaceContentRect(
3291 surface, gfx::Rect(40, 80, 100, 100)));
3292 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
3293 occlusion.UnoccludedSurfaceContentRect(surface,
3294 gfx::Rect(0, 0, 80, 100)));
3295 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
3296 occlusion.UnoccludedSurfaceContentRect(
3297 surface, gfx::Rect(90, 80, 100, 100)));
3298 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
3299 occlusion.UnoccludedSurfaceContentRect(
3300 surface, gfx::Rect(0, 80, 100, 100)));
3301 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
3302 occlusion.UnoccludedSurfaceContentRect(
3303 surface, gfx::Rect(90, 0, 100, 100)));
3305 // Full occlusion from both, is occluded.
3306 EXPECT_EQ(gfx::Rect(),
3307 occlusion.UnoccludedSurfaceContentRect(
3308 surface, gfx::Rect(40, 30, 100, 100)));
3309 EXPECT_EQ(gfx::Rect(),
3310 occlusion.UnoccludedSurfaceContentRect(
3311 surface, gfx::Rect(40, 30, 10, 10)));
3312 EXPECT_EQ(gfx::Rect(),
3313 occlusion.UnoccludedSurfaceContentRect(
3314 surface, gfx::Rect(130, 120, 10, 10)));
3315 EXPECT_EQ(gfx::Rect(),
3316 occlusion.UnoccludedSurfaceContentRect(
3317 surface, gfx::Rect(80, 70, 50, 50)));
3321 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery)
3323 } // namespace
3324 } // namespace cc