Add ICU message format support
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob08cfcf7290e22baedc72b0f8bde399c3593b355f
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/test/test_task_graph_runner.h"
22 #include "cc/trees/layer_tree_host_common.h"
23 #include "cc/trees/single_thread_proxy.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/transform.h"
28 namespace cc {
29 namespace {
31 class TestContentLayerImpl : public LayerImpl {
32 public:
33 TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
34 : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
35 SetDrawsContent(true);
38 SimpleEnclosedRegion VisibleOpaqueRegion() const override {
39 if (override_opaque_contents_rect_) {
40 return SimpleEnclosedRegion(
41 gfx::IntersectRects(opaque_contents_rect_, visible_layer_rect()));
43 return LayerImpl::VisibleOpaqueRegion();
45 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
46 override_opaque_contents_rect_ = true;
47 opaque_contents_rect_ = opaque_contents_rect;
50 private:
51 bool override_opaque_contents_rect_;
52 gfx::Rect opaque_contents_rect_;
55 class TestOcclusionTrackerWithClip : public TestOcclusionTracker {
56 public:
57 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect)
58 : TestOcclusionTracker(viewport_rect) {}
60 bool OccludedLayer(const LayerImpl* layer,
61 const gfx::Rect& content_rect) const {
62 DCHECK(layer->visible_layer_rect().Contains(content_rect));
63 return this->GetCurrentOcclusionForLayer(layer->draw_transform())
64 .IsOccluded(content_rect);
67 // Gives an unoccluded sub-rect of |content_rect| in the content space of the
68 // layer. Simple wrapper around GetUnoccludedContentRect.
69 gfx::Rect UnoccludedLayerContentRect(const LayerImpl* layer,
70 const gfx::Rect& content_rect) const {
71 DCHECK(layer->visible_layer_rect().Contains(content_rect));
72 return this->GetCurrentOcclusionForLayer(layer->draw_transform())
73 .GetUnoccludedContentRect(content_rect);
76 gfx::Rect UnoccludedSurfaceContentRect(const LayerImpl* layer,
77 const gfx::Rect& content_rect) const {
78 RenderSurfaceImpl* surface = layer->render_surface();
79 return this->GetCurrentOcclusionForContributingSurface(
80 surface->draw_transform())
81 .GetUnoccludedContentRect(content_rect);
85 class OcclusionTrackerTest : public testing::Test {
86 protected:
87 explicit OcclusionTrackerTest(bool opaque_layers)
88 : opaque_layers_(opaque_layers),
89 client_(FakeLayerTreeHostClient::DIRECT_3D),
90 host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)),
91 next_layer_impl_id_(1) {}
93 virtual void RunMyTest() = 0;
95 void TearDown() override { DestroyLayers(); }
97 TestContentLayerImpl* CreateRoot(const gfx::Transform& transform,
98 const gfx::PointF& position,
99 const gfx::Size& bounds) {
100 LayerTreeImpl* tree = host_->host_impl()->active_tree();
101 int id = next_layer_impl_id_++;
102 scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id));
103 TestContentLayerImpl* layer_ptr = layer.get();
104 SetProperties(layer_ptr, transform, position, bounds);
106 DCHECK(!root_.get());
107 root_ = layer.Pass();
109 layer_ptr->SetHasRenderSurface(true);
110 SetRootLayerOnMainThread(layer_ptr);
112 return layer_ptr;
115 LayerImpl* CreateLayer(LayerImpl* parent,
116 const gfx::Transform& transform,
117 const gfx::PointF& position,
118 const gfx::Size& bounds) {
119 LayerTreeImpl* tree = host_->host_impl()->active_tree();
120 int id = next_layer_impl_id_++;
121 scoped_ptr<LayerImpl> layer = LayerImpl::Create(tree, id);
122 LayerImpl* layer_ptr = layer.get();
123 SetProperties(layer_ptr, transform, position, bounds);
124 parent->AddChild(layer.Pass());
125 return layer_ptr;
128 LayerImpl* CreateSurface(LayerImpl* parent,
129 const gfx::Transform& transform,
130 const gfx::PointF& position,
131 const gfx::Size& bounds) {
132 LayerImpl* layer = CreateLayer(parent, transform, position, bounds);
133 layer->SetHasRenderSurface(true);
134 return layer;
137 TestContentLayerImpl* CreateDrawingLayer(LayerImpl* parent,
138 const gfx::Transform& transform,
139 const gfx::PointF& position,
140 const gfx::Size& bounds,
141 bool opaque) {
142 LayerTreeImpl* tree = host_->host_impl()->active_tree();
143 int id = next_layer_impl_id_++;
144 scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id));
145 TestContentLayerImpl* layer_ptr = layer.get();
146 SetProperties(layer_ptr, transform, position, bounds);
148 if (opaque_layers_) {
149 layer_ptr->SetContentsOpaque(opaque);
150 } else {
151 layer_ptr->SetContentsOpaque(false);
152 if (opaque)
153 layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
154 else
155 layer_ptr->SetOpaqueContentsRect(gfx::Rect());
158 parent->AddChild(layer.Pass());
159 return layer_ptr;
162 LayerImpl* CreateReplicaLayer(LayerImpl* owning_layer,
163 const gfx::Transform& transform,
164 const gfx::PointF& position,
165 const gfx::Size& bounds) {
166 LayerTreeImpl* tree = host_->host_impl()->active_tree();
167 int id = next_layer_impl_id_++;
168 scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id));
169 TestContentLayerImpl* layer_ptr = layer.get();
170 SetProperties(layer_ptr, transform, position, bounds);
171 SetReplica(owning_layer, layer.Pass());
172 return layer_ptr;
175 LayerImpl* CreateMaskLayer(LayerImpl* owning_layer, const gfx::Size& bounds) {
176 LayerTreeImpl* tree = host_->host_impl()->active_tree();
177 int id = next_layer_impl_id_++;
178 scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id));
179 TestContentLayerImpl* layer_ptr = layer.get();
180 SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
181 SetMask(owning_layer, layer.Pass());
182 return layer_ptr;
185 TestContentLayerImpl* CreateDrawingSurface(LayerImpl* parent,
186 const gfx::Transform& transform,
187 const gfx::PointF& position,
188 const gfx::Size& bounds,
189 bool opaque) {
190 TestContentLayerImpl* layer =
191 CreateDrawingLayer(parent, transform, position, bounds, opaque);
192 layer->SetHasRenderSurface(true);
193 return layer;
196 void DestroyLayers() {
197 root_ = nullptr;
198 render_surface_layer_list_ = nullptr;
199 render_surface_layer_list_impl_.clear();
200 replica_layers_.clear();
201 mask_layers_.clear();
202 ResetLayerIterator();
205 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
207 void AddCopyRequest(Layer* layer) {
208 layer->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
209 base::Bind(&OcclusionTrackerTest::CopyOutputCallback,
210 base::Unretained(this))));
213 void AddCopyRequest(LayerImpl* layer) {
214 ScopedPtrVector<CopyOutputRequest> requests;
215 requests.push_back(CopyOutputRequest::CreateBitmapRequest(base::Bind(
216 &OcclusionTrackerTest::CopyOutputCallback, base::Unretained(this))));
217 layer->SetHasRenderSurface(true);
218 layer->PassCopyRequests(&requests);
221 void CalcDrawEtc(TestContentLayerImpl* root) {
222 DCHECK(root == root_.get());
224 // These occlusion tests attach and detach layers in multiple
225 // iterations, so rebuild property trees every time.
226 root->layer_tree_impl()->property_trees()->needs_rebuild = true;
228 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root);
230 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
231 root, root->bounds(), &render_surface_layer_list_impl_);
232 inputs.can_adjust_raster_scales = true;
233 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
235 layer_iterator_ = layer_iterator_begin_ =
236 LayerIterator::Begin(&render_surface_layer_list_impl_);
239 void EnterLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
240 ASSERT_EQ(*layer_iterator_, layer);
241 ASSERT_TRUE(layer_iterator_.represents_itself());
242 occlusion->EnterLayer(layer_iterator_);
245 void LeaveLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
246 ASSERT_EQ(*layer_iterator_, layer);
247 ASSERT_TRUE(layer_iterator_.represents_itself());
248 occlusion->LeaveLayer(layer_iterator_);
249 ++layer_iterator_;
252 void VisitLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
253 EnterLayer(layer, occlusion);
254 LeaveLayer(layer, occlusion);
257 void EnterContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
258 ASSERT_EQ(*layer_iterator_, layer);
259 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
260 occlusion->EnterLayer(layer_iterator_);
261 occlusion->LeaveLayer(layer_iterator_);
262 ++layer_iterator_;
263 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
264 occlusion->EnterLayer(layer_iterator_);
267 void LeaveContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
268 ASSERT_EQ(*layer_iterator_, layer);
269 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
270 occlusion->LeaveLayer(layer_iterator_);
271 ++layer_iterator_;
274 void VisitContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
275 EnterContributingSurface(layer, occlusion);
276 LeaveContributingSurface(layer, occlusion);
279 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
281 const gfx::Transform identity_matrix;
283 private:
284 void SetRootLayerOnMainThread(Layer* root) {
285 host_->SetRootLayer(scoped_refptr<Layer>(root));
288 void SetRootLayerOnMainThread(LayerImpl* root) {}
290 void SetProperties(LayerImpl* layer,
291 const gfx::Transform& transform,
292 const gfx::PointF& position,
293 const gfx::Size& bounds) {
294 layer->SetTransform(transform);
295 layer->SetPosition(position);
296 layer->SetBounds(bounds);
299 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
300 owning_layer->SetReplicaLayer(layer.Pass());
303 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
304 owning_layer->SetMaskLayer(layer.Pass());
307 bool opaque_layers_;
308 FakeLayerTreeHostClient client_;
309 TestTaskGraphRunner task_graph_runner_;
310 scoped_ptr<FakeLayerTreeHost> host_;
311 // These hold ownership of the layers for the duration of the test.
312 scoped_ptr<LayerImpl> root_;
313 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
314 LayerImplList render_surface_layer_list_impl_;
315 LayerIterator layer_iterator_begin_;
316 LayerIterator layer_iterator_;
317 LayerList replica_layers_;
318 LayerList mask_layers_;
319 int next_layer_impl_id_;
322 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
323 class ClassName##ImplThreadOpaqueLayers : public ClassName { \
324 public: /* NOLINT(whitespace/indent) */ \
325 ClassName##ImplThreadOpaqueLayers() : ClassName(true) {} \
326 }; \
327 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
328 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
329 class ClassName##ImplThreadOpaquePaints : public ClassName { \
330 public: /* NOLINT(whitespace/indent) */ \
331 ClassName##ImplThreadOpaquePaints() : ClassName(false) {} \
332 }; \
333 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
335 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
336 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
337 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
339 class OcclusionTrackerTestIdentityTransforms : public OcclusionTrackerTest {
340 protected:
341 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
342 : OcclusionTrackerTest(opaque_layers) {}
344 void RunMyTest() override {
345 TestContentLayerImpl* root = this->CreateRoot(
346 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
347 TestContentLayerImpl* parent = this->CreateDrawingLayer(
348 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
349 TestContentLayerImpl* layer = this->CreateDrawingLayer(
350 parent, this->identity_matrix, gfx::PointF(30.f, 30.f),
351 gfx::Size(500, 500), true);
352 parent->SetMasksToBounds(true);
353 this->CalcDrawEtc(root);
355 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
357 this->VisitLayer(layer, &occlusion);
358 this->EnterLayer(parent, &occlusion);
360 EXPECT_EQ(gfx::Rect().ToString(),
361 occlusion.occlusion_from_outside_target().ToString());
362 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
363 occlusion.occlusion_from_inside_target().ToString());
367 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
369 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest {
370 protected:
371 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
372 : OcclusionTrackerTest(opaque_layers) {}
373 void RunMyTest() override {
374 gfx::Transform layer_transform;
375 layer_transform.Translate(250.0, 250.0);
376 layer_transform.Rotate(90.0);
377 layer_transform.Translate(-250.0, -250.0);
379 TestContentLayerImpl* root = this->CreateRoot(
380 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
381 TestContentLayerImpl* parent = this->CreateDrawingLayer(
382 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
383 TestContentLayerImpl* layer = this->CreateDrawingLayer(
384 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
385 true);
386 parent->SetMasksToBounds(true);
387 this->CalcDrawEtc(root);
389 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
391 this->VisitLayer(layer, &occlusion);
392 this->EnterLayer(parent, &occlusion);
394 EXPECT_EQ(gfx::Rect().ToString(),
395 occlusion.occlusion_from_outside_target().ToString());
396 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
397 occlusion.occlusion_from_inside_target().ToString());
401 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
403 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest {
404 protected:
405 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
406 : OcclusionTrackerTest(opaque_layers) {}
407 void RunMyTest() override {
408 gfx::Transform layer_transform;
409 layer_transform.Translate(20.0, 20.0);
411 TestContentLayerImpl* root = this->CreateRoot(
412 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
413 TestContentLayerImpl* parent = this->CreateDrawingLayer(
414 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
415 TestContentLayerImpl* layer = this->CreateDrawingLayer(
416 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
417 true);
418 parent->SetMasksToBounds(true);
419 this->CalcDrawEtc(root);
421 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
423 this->VisitLayer(layer, &occlusion);
424 this->EnterLayer(parent, &occlusion);
426 EXPECT_EQ(gfx::Rect().ToString(),
427 occlusion.occlusion_from_outside_target().ToString());
428 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
429 occlusion.occlusion_from_inside_target().ToString());
433 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
435 class OcclusionTrackerTestChildInRotatedChild : public OcclusionTrackerTest {
436 protected:
437 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
438 : OcclusionTrackerTest(opaque_layers) {}
439 void RunMyTest() override {
440 gfx::Transform child_transform;
441 child_transform.Translate(250.0, 250.0);
442 child_transform.Rotate(90.0);
443 child_transform.Translate(-250.0, -250.0);
445 TestContentLayerImpl* parent = this->CreateRoot(
446 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
447 parent->SetMasksToBounds(true);
448 LayerImpl* child = this->CreateSurface(
449 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
450 child->SetMasksToBounds(true);
451 TestContentLayerImpl* layer = this->CreateDrawingLayer(
452 child, this->identity_matrix, gfx::PointF(10.f, 10.f),
453 gfx::Size(500, 500), true);
454 this->CalcDrawEtc(parent);
456 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
458 this->VisitLayer(layer, &occlusion);
459 this->EnterContributingSurface(child, &occlusion);
461 EXPECT_EQ(gfx::Rect().ToString(),
462 occlusion.occlusion_from_outside_target().ToString());
463 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
464 occlusion.occlusion_from_inside_target().ToString());
466 this->LeaveContributingSurface(child, &occlusion);
467 this->EnterLayer(parent, &occlusion);
469 EXPECT_EQ(gfx::Rect().ToString(),
470 occlusion.occlusion_from_outside_target().ToString());
471 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
472 occlusion.occlusion_from_inside_target().ToString());
474 /* Justification for the above occlusion from |layer|:
476 +---------------------+
478 | 30 | rotate(90)
479 | 30 + ---------------------------------+
480 100 | | 10 | | ==>
481 | |10+---------------------------------+
482 | | | | | |
483 | | | | | |
484 | | | | | |
485 +----|--|-------------+ | |
486 | | | |
487 | | | |
488 | | | |500
489 | | | |
490 | | | |
491 | | | |
492 | | | |
493 +--|-------------------------------+ |
495 +---------------------------------+
498 +---------------------+
499 | |30 Visible region of |layer|: /////
501 | +---------------------------------+
502 100| | |10 |
503 | +---------------------------------+ |
504 | | |///////////////| 420 | |
505 | | |///////////////|60 | |
506 | | |///////////////| | |
507 +--|--|---------------+ | |
508 20|10| 70 | |
509 | | | |
510 | | | |
511 | | | |
512 | | | |
513 | | | |
514 | | |10|
515 | +------------------------------|--+
516 | 490 |
517 +---------------------------------+
524 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
526 class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest {
527 protected:
528 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
529 : OcclusionTrackerTest(opaque_layers) {}
531 void RunMyTest() override {
532 TestContentLayerImpl* parent = this->CreateRoot(
533 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
535 gfx::Transform layer1_matrix;
536 layer1_matrix.Scale(2.0, 2.0);
537 TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
538 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
539 layer1->SetHasRenderSurface(true);
541 gfx::Transform layer2_matrix;
542 layer2_matrix.Translate(25.0, 25.0);
543 TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
544 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
545 TestContentLayerImpl* occluder = this->CreateDrawingLayer(
546 parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
547 gfx::Size(500, 500), true);
548 this->CalcDrawEtc(parent);
550 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
552 this->VisitLayer(occluder, &occlusion);
553 this->EnterLayer(layer2, &occlusion);
555 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
556 occlusion.occlusion_from_outside_target().ToString());
557 EXPECT_EQ(gfx::Rect().ToString(),
558 occlusion.occlusion_from_inside_target().ToString());
562 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
564 class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest {
565 protected:
566 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
567 : OcclusionTrackerTest(opaque_layers) {}
568 void RunMyTest() override {
569 TestContentLayerImpl* root = this->CreateRoot(
570 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
571 LayerImpl* surface = this->CreateSurface(
572 root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size());
573 TestContentLayerImpl* surface_child = this->CreateDrawingLayer(
574 surface, this->identity_matrix, gfx::PointF(10.f, 10.f),
575 gfx::Size(50, 50), true);
576 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
577 // first, instead of |surface|'s. This exercises different code in
578 // LeaveToRenderTarget, as the target surface has already been seen when
579 // leaving |surface| later.
580 TestContentLayerImpl* top_layer = this->CreateDrawingLayer(
581 root, this->identity_matrix, gfx::PointF(40.f, 90.f), gfx::Size(50, 20),
582 true);
583 this->CalcDrawEtc(root);
585 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
587 this->VisitLayer(top_layer, &occlusion);
589 EXPECT_EQ(gfx::Rect().ToString(),
590 occlusion.occlusion_from_outside_target().ToString());
591 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
592 occlusion.occlusion_from_inside_target().ToString());
594 this->VisitLayer(surface_child, &occlusion);
596 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
597 occlusion.occlusion_from_outside_target().ToString());
598 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
599 occlusion.occlusion_from_inside_target().ToString());
601 this->EnterContributingSurface(surface, &occlusion);
603 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
604 occlusion.occlusion_from_outside_target().ToString());
605 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
606 occlusion.occlusion_from_inside_target().ToString());
608 // Occlusion from |top_layer| already in the root target should get merged
609 // with the occlusion from the |surface| we are leaving now.
610 this->LeaveContributingSurface(surface, &occlusion);
611 this->EnterLayer(root, &occlusion);
613 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
614 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
615 occlusion.occlusion_from_inside_target().ToString());
619 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
621 class OcclusionTrackerTestSurfaceRotatedOffAxis : public OcclusionTrackerTest {
622 protected:
623 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
624 : OcclusionTrackerTest(opaque_layers) {}
625 void RunMyTest() override {
626 gfx::Transform child_transform;
627 child_transform.Translate(250.0, 250.0);
628 child_transform.Rotate(95.0);
629 child_transform.Translate(-250.0, -250.0);
631 gfx::Transform layer_transform;
632 layer_transform.Translate(10.0, 10.0);
634 TestContentLayerImpl* root = this->CreateRoot(
635 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
636 TestContentLayerImpl* parent = this->CreateDrawingLayer(
637 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
638 LayerImpl* child = this->CreateSurface(
639 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
640 TestContentLayerImpl* layer = this->CreateDrawingLayer(
641 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
642 this->CalcDrawEtc(root);
644 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
646 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect(
647 layer_transform, layer->visible_layer_rect());
649 this->VisitLayer(layer, &occlusion);
650 this->EnterContributingSurface(child, &occlusion);
652 EXPECT_EQ(gfx::Rect().ToString(),
653 occlusion.occlusion_from_outside_target().ToString());
654 EXPECT_EQ(clipped_layer_in_child.ToString(),
655 occlusion.occlusion_from_inside_target().ToString());
657 this->LeaveContributingSurface(child, &occlusion);
658 this->EnterLayer(parent, &occlusion);
660 EXPECT_EQ(gfx::Rect().ToString(),
661 occlusion.occlusion_from_outside_target().ToString());
662 EXPECT_EQ(gfx::Rect().ToString(),
663 occlusion.occlusion_from_inside_target().ToString());
667 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
669 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
670 : public OcclusionTrackerTest {
671 protected:
672 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
673 : OcclusionTrackerTest(opaque_layers) {}
674 void RunMyTest() override {
675 gfx::Transform child_transform;
676 child_transform.Translate(250.0, 250.0);
677 child_transform.Rotate(90.0);
678 child_transform.Translate(-250.0, -250.0);
680 TestContentLayerImpl* root = this->CreateRoot(
681 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
682 TestContentLayerImpl* parent = this->CreateDrawingLayer(
683 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
684 parent->SetMasksToBounds(true);
685 TestContentLayerImpl* child = this->CreateDrawingSurface(
686 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
687 false);
688 child->SetMasksToBounds(true);
689 TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
690 child, this->identity_matrix, gfx::PointF(10.f, 10.f),
691 gfx::Size(500, 500), true);
692 TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
693 child, this->identity_matrix, gfx::PointF(10.f, 450.f),
694 gfx::Size(500, 60), true);
695 this->CalcDrawEtc(root);
697 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
699 this->VisitLayer(layer2, &occlusion);
700 this->VisitLayer(layer1, &occlusion);
701 this->VisitLayer(child, &occlusion);
702 this->EnterContributingSurface(child, &occlusion);
704 EXPECT_EQ(gfx::Rect().ToString(),
705 occlusion.occlusion_from_outside_target().ToString());
706 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
707 occlusion.occlusion_from_inside_target().ToString());
709 this->LeaveContributingSurface(child, &occlusion);
710 this->EnterLayer(parent, &occlusion);
712 EXPECT_EQ(gfx::Rect().ToString(),
713 occlusion.occlusion_from_outside_target().ToString());
714 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
715 occlusion.occlusion_from_inside_target().ToString());
717 /* Justification for the above occlusion from |layer1| and |layer2|:
719 +---------------------+
720 | |30 Visible region of |layer1|: /////
721 | | Visible region of |layer2|: \\\\\
722 | +---------------------------------+
723 | | |10 |
724 | +---------------+-----------------+ |
725 | | |\\\\\\\\\\\\|//| 420 | |
726 | | |\\\\\\\\\\\\|//|60 | |
727 | | |\\\\\\\\\\\\|//| | |
728 +--|--|------------|--+ | |
729 20|10| 70 | | |
730 | | | | |
731 | | | | |
732 | | | | |
733 | | | | |
734 | | | | |
735 | | | |10|
736 | +------------|-----------------|--+
737 | | 490 |
738 +---------------+-----------------+
739 60 440
744 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
746 class OcclusionTrackerTestOverlappingSurfaceSiblings
747 : public OcclusionTrackerTest {
748 protected:
749 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
750 : OcclusionTrackerTest(opaque_layers) {}
751 void RunMyTest() override {
752 TestContentLayerImpl* parent = this->CreateRoot(
753 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
754 parent->SetMasksToBounds(true);
755 LayerImpl* child1 = this->CreateSurface(
756 parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size());
757 LayerImpl* child2 = this->CreateSurface(
758 parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size());
759 TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
760 child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true);
761 TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
762 child2, this->identity_matrix, gfx::PointF(10.f, 0.f),
763 gfx::Size(40, 50), true);
764 this->CalcDrawEtc(parent);
766 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
768 this->VisitLayer(layer2, &occlusion);
769 this->EnterContributingSurface(child2, &occlusion);
771 // layer2's occlusion.
772 EXPECT_EQ(gfx::Rect().ToString(),
773 occlusion.occlusion_from_outside_target().ToString());
774 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
775 occlusion.occlusion_from_inside_target().ToString());
777 this->LeaveContributingSurface(child2, &occlusion);
778 this->VisitLayer(layer1, &occlusion);
779 this->EnterContributingSurface(child1, &occlusion);
781 // layer2's occlusion in the target space of layer1.
782 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
783 occlusion.occlusion_from_outside_target().ToString());
784 // layer1's occlusion.
785 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
786 occlusion.occlusion_from_inside_target().ToString());
788 this->LeaveContributingSurface(child1, &occlusion);
789 this->EnterLayer(parent, &occlusion);
791 // The occlusion from from layer1 and layer2 is merged.
792 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
793 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
794 occlusion.occlusion_from_inside_target().ToString());
798 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
800 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
801 : public OcclusionTrackerTest {
802 protected:
803 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
804 bool opaque_layers)
805 : OcclusionTrackerTest(opaque_layers) {}
806 void RunMyTest() override {
807 gfx::Transform child1_transform;
808 child1_transform.Translate(250.0, 250.0);
809 child1_transform.Rotate(-90.0);
810 child1_transform.Translate(-250.0, -250.0);
812 gfx::Transform child2_transform;
813 child2_transform.Translate(250.0, 250.0);
814 child2_transform.Rotate(90.0);
815 child2_transform.Translate(-250.0, -250.0);
817 TestContentLayerImpl* parent = this->CreateRoot(
818 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
819 parent->SetMasksToBounds(true);
820 LayerImpl* child1 = this->CreateSurface(
821 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
822 LayerImpl* child2 = this->CreateDrawingSurface(parent, child2_transform,
823 gfx::PointF(20.f, 40.f),
824 gfx::Size(10, 10), false);
825 TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
826 child1, this->identity_matrix, gfx::PointF(-10.f, -20.f),
827 gfx::Size(510, 510), true);
828 TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
829 child2, this->identity_matrix, gfx::PointF(-10.f, -10.f),
830 gfx::Size(510, 510), true);
831 this->CalcDrawEtc(parent);
833 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
835 this->VisitLayer(layer2, &occlusion);
836 this->EnterLayer(child2, &occlusion);
838 EXPECT_EQ(gfx::Rect().ToString(),
839 occlusion.occlusion_from_outside_target().ToString());
840 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
841 occlusion.occlusion_from_inside_target().ToString());
843 this->LeaveLayer(child2, &occlusion);
844 this->EnterContributingSurface(child2, &occlusion);
846 EXPECT_EQ(gfx::Rect().ToString(),
847 occlusion.occlusion_from_outside_target().ToString());
848 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
849 occlusion.occlusion_from_inside_target().ToString());
851 this->LeaveContributingSurface(child2, &occlusion);
852 this->VisitLayer(layer1, &occlusion);
853 this->EnterContributingSurface(child1, &occlusion);
855 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
856 occlusion.occlusion_from_outside_target().ToString());
857 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
858 occlusion.occlusion_from_inside_target().ToString());
860 this->LeaveContributingSurface(child1, &occlusion);
861 this->EnterLayer(parent, &occlusion);
863 EXPECT_EQ(gfx::Rect().ToString(),
864 occlusion.occlusion_from_outside_target().ToString());
865 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
866 occlusion.occlusion_from_inside_target().ToString());
868 /* Justification for the above occlusion:
870 +---------------------+
871 |20 | layer1
872 10+----------------------------------+
873 100 || 30 | layer2 |
874 |20+----------------------------------+
875 || | | | |
876 || | | | |
877 || | | | |
878 +|-|------------------+ | |
879 | | | | 510
880 | | 510 | |
881 | | | |
882 | | | |
883 | | | |
884 | | | |
885 | | 520 | |
886 +----------------------------------+ |
888 +----------------------------------+
894 ALL_OCCLUSIONTRACKER_TEST(
895 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
897 class OcclusionTrackerTestFilters : public OcclusionTrackerTest {
898 protected:
899 explicit OcclusionTrackerTestFilters(bool opaque_layers)
900 : OcclusionTrackerTest(opaque_layers) {}
901 void RunMyTest() override {
902 gfx::Transform layer_transform;
903 layer_transform.Translate(250.0, 250.0);
904 layer_transform.Rotate(90.0);
905 layer_transform.Translate(-250.0, -250.0);
907 TestContentLayerImpl* parent = this->CreateRoot(
908 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
909 parent->SetMasksToBounds(true);
910 TestContentLayerImpl* blur_layer = this->CreateDrawingLayer(
911 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
912 true);
913 TestContentLayerImpl* opaque_layer = this->CreateDrawingLayer(
914 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
915 true);
916 TestContentLayerImpl* opacity_layer = this->CreateDrawingLayer(
917 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
918 true);
920 blur_layer->SetHasRenderSurface(true);
921 FilterOperations filters;
922 filters.Append(FilterOperation::CreateBlurFilter(10.f));
923 blur_layer->SetFilters(filters);
925 opaque_layer->SetHasRenderSurface(true);
926 filters.Clear();
927 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
928 opaque_layer->SetFilters(filters);
930 opacity_layer->SetHasRenderSurface(true);
931 filters.Clear();
932 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
933 opacity_layer->SetFilters(filters);
935 this->CalcDrawEtc(parent);
937 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
939 // Opacity layer won't contribute to occlusion.
940 this->VisitLayer(opacity_layer, &occlusion);
941 this->EnterContributingSurface(opacity_layer, &occlusion);
943 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
944 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
946 // And has nothing to contribute to its parent surface.
947 this->LeaveContributingSurface(opacity_layer, &occlusion);
948 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
949 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
951 // Opaque layer will contribute to occlusion.
952 this->VisitLayer(opaque_layer, &occlusion);
953 this->EnterContributingSurface(opaque_layer, &occlusion);
955 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
956 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
957 occlusion.occlusion_from_inside_target().ToString());
959 // And it gets translated to the parent surface.
960 this->LeaveContributingSurface(opaque_layer, &occlusion);
961 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
962 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
963 occlusion.occlusion_from_inside_target().ToString());
965 // The blur layer needs to throw away any occlusion from outside its
966 // subtree.
967 this->EnterLayer(blur_layer, &occlusion);
968 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
969 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
971 // And it won't contribute to occlusion.
972 this->LeaveLayer(blur_layer, &occlusion);
973 this->EnterContributingSurface(blur_layer, &occlusion);
974 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
975 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
977 // But the opaque layer's occlusion is preserved on the parent.
978 this->LeaveContributingSurface(blur_layer, &occlusion);
979 this->EnterLayer(parent, &occlusion);
980 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
981 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
982 occlusion.occlusion_from_inside_target().ToString());
986 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
988 class OcclusionTrackerTestReplicaDoesOcclude : public OcclusionTrackerTest {
989 protected:
990 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
991 : OcclusionTrackerTest(opaque_layers) {}
992 void RunMyTest() override {
993 TestContentLayerImpl* parent = this->CreateRoot(
994 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
995 LayerImpl* surface = this->CreateDrawingSurface(
996 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
997 this->CreateReplicaLayer(
998 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
999 this->CalcDrawEtc(parent);
1001 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1003 this->VisitLayer(surface, &occlusion);
1005 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1006 occlusion.occlusion_from_inside_target().ToString());
1008 this->VisitContributingSurface(surface, &occlusion);
1009 this->EnterLayer(parent, &occlusion);
1011 // The surface and replica should both be occluding the parent.
1012 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1013 occlusion.occlusion_from_inside_target().ToString());
1017 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1019 class OcclusionTrackerTestReplicaWithClipping : public OcclusionTrackerTest {
1020 protected:
1021 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1022 : OcclusionTrackerTest(opaque_layers) {}
1023 void RunMyTest() override {
1024 TestContentLayerImpl* parent = this->CreateRoot(
1025 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1026 parent->SetMasksToBounds(true);
1027 LayerImpl* surface = this->CreateDrawingSurface(
1028 parent, this->identity_matrix, gfx::PointF(0.f, 100.f),
1029 gfx::Size(50, 50), true);
1030 this->CreateReplicaLayer(
1031 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
1032 this->CalcDrawEtc(parent);
1034 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1036 this->VisitLayer(surface, &occlusion);
1038 // The surface layer's occlusion in its own space.
1039 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1040 occlusion.occlusion_from_inside_target().ToString());
1041 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1043 this->VisitContributingSurface(surface, &occlusion);
1044 this->EnterLayer(parent, &occlusion);
1046 // The surface and replica should both be occluding the parent, the
1047 // replica's occlusion is clipped by the parent.
1048 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1049 occlusion.occlusion_from_inside_target().ToString());
1050 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1054 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1056 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest {
1057 protected:
1058 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1059 : OcclusionTrackerTest(opaque_layers) {}
1060 void RunMyTest() override {
1061 TestContentLayerImpl* parent = this->CreateRoot(
1062 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1063 LayerImpl* surface = this->CreateDrawingSurface(
1064 parent, this->identity_matrix, gfx::PointF(0.f, 100.f),
1065 gfx::Size(50, 50), true);
1066 LayerImpl* replica = this->CreateReplicaLayer(
1067 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1068 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1069 this->CalcDrawEtc(parent);
1071 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1073 this->VisitLayer(surface, &occlusion);
1075 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1076 occlusion.occlusion_from_inside_target().ToString());
1078 this->VisitContributingSurface(surface, &occlusion);
1079 this->EnterLayer(parent, &occlusion);
1081 // The replica should not be occluding the parent, since it has a mask
1082 // applied to it.
1083 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1084 occlusion.occlusion_from_inside_target().ToString());
1088 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1090 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1091 : public OcclusionTrackerTest {
1092 protected:
1093 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1094 : OcclusionTrackerTest(opaque_layers) {}
1095 void RunMyTest() override {
1096 TestContentLayerImpl* parent = this->CreateRoot(
1097 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1098 TestContentLayerImpl* layer =
1099 this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
1100 gfx::Size(200, 200), false);
1101 this->CalcDrawEtc(parent);
1103 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1104 this->EnterLayer(layer, &occlusion);
1106 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1107 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1109 this->LeaveLayer(layer, &occlusion);
1110 this->VisitContributingSurface(layer, &occlusion);
1111 this->EnterLayer(parent, &occlusion);
1113 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1114 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1118 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1120 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1121 : public OcclusionTrackerTest {
1122 protected:
1123 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1124 : OcclusionTrackerTest(opaque_layers) {}
1125 void RunMyTest() override {
1126 TestContentLayerImpl* parent = this->CreateRoot(
1127 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1128 TestContentLayerImpl* layer = this->CreateDrawingLayer(
1129 parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
1130 gfx::Size(200, 200), false);
1131 this->CalcDrawEtc(parent);
1133 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1134 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1136 this->ResetLayerIterator();
1137 this->VisitLayer(layer, &occlusion);
1138 this->EnterLayer(parent, &occlusion);
1140 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1141 occlusion.occlusion_from_inside_target().ToString());
1144 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1145 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1147 this->ResetLayerIterator();
1148 this->VisitLayer(layer, &occlusion);
1149 this->EnterLayer(parent, &occlusion);
1151 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1152 occlusion.occlusion_from_inside_target().ToString());
1155 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1156 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1158 this->ResetLayerIterator();
1159 this->VisitLayer(layer, &occlusion);
1160 this->EnterLayer(parent, &occlusion);
1162 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1163 occlusion.occlusion_from_inside_target().ToString());
1168 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1170 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1171 : public OcclusionTrackerTest {
1172 protected:
1173 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1174 bool opaque_layers)
1175 : OcclusionTrackerTest(opaque_layers) {}
1176 void RunMyTest() override {
1177 gfx::Transform transform;
1178 transform.Translate(50.0, 50.0);
1179 transform.ApplyPerspectiveDepth(100.0);
1180 transform.Translate3d(0.0, 0.0, 110.0);
1181 transform.Translate(-50.0, -50.0);
1183 TestContentLayerImpl* parent = this->CreateRoot(
1184 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1185 TestContentLayerImpl* layer = this->CreateDrawingLayer(
1186 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
1187 parent->SetShouldFlattenTransform(false);
1188 parent->Set3dSortingContextId(1);
1189 layer->SetShouldFlattenTransform(false);
1190 layer->Set3dSortingContextId(1);
1191 this->CalcDrawEtc(parent);
1193 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1195 // The |layer| is entirely behind the camera and should not occlude.
1196 this->VisitLayer(layer, &occlusion);
1197 this->EnterLayer(parent, &occlusion);
1198 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1199 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1203 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1204 : public OcclusionTrackerTest {
1205 protected:
1206 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1207 bool opaque_layers)
1208 : OcclusionTrackerTest(opaque_layers) {}
1209 void RunMyTest() override {
1210 gfx::Transform surface_transform;
1211 surface_transform.Translate(300.0, 300.0);
1212 surface_transform.Scale(2.0, 2.0);
1213 surface_transform.Translate(-150.0, -150.0);
1215 TestContentLayerImpl* parent = this->CreateRoot(
1216 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
1217 TestContentLayerImpl* surface = this->CreateDrawingSurface(
1218 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
1219 TestContentLayerImpl* surface2 = this->CreateDrawingSurface(
1220 parent, this->identity_matrix, gfx::PointF(50.f, 50.f),
1221 gfx::Size(300, 300), false);
1222 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1223 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1224 this->CalcDrawEtc(parent);
1226 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1228 this->VisitLayer(surface2, &occlusion);
1229 this->VisitContributingSurface(surface2, &occlusion);
1231 EXPECT_EQ(gfx::Rect().ToString(),
1232 occlusion.occlusion_from_outside_target().ToString());
1233 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1234 occlusion.occlusion_from_inside_target().ToString());
1236 // Clear any stored occlusion.
1237 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1238 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1240 this->VisitLayer(surface, &occlusion);
1241 this->VisitContributingSurface(surface, &occlusion);
1243 EXPECT_EQ(gfx::Rect().ToString(),
1244 occlusion.occlusion_from_outside_target().ToString());
1245 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1246 occlusion.occlusion_from_inside_target().ToString());
1250 ALL_OCCLUSIONTRACKER_TEST(
1251 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
1253 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1254 : public OcclusionTrackerTest {
1255 protected:
1256 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
1257 bool opaque_layers)
1258 : OcclusionTrackerTest(opaque_layers) {}
1259 void RunMyTest() override {
1260 TestContentLayerImpl* parent = this->CreateRoot(
1261 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1262 parent->SetMasksToBounds(true);
1263 TestContentLayerImpl* surface =
1264 this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
1265 gfx::Size(500, 300), false);
1266 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
1267 this->CalcDrawEtc(parent);
1269 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1271 this->VisitLayer(surface, &occlusion);
1272 this->VisitContributingSurface(surface, &occlusion);
1274 EXPECT_EQ(gfx::Rect().ToString(),
1275 occlusion.occlusion_from_outside_target().ToString());
1276 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
1277 occlusion.occlusion_from_inside_target().ToString());
1281 ALL_OCCLUSIONTRACKER_TEST(
1282 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
1284 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
1285 : public OcclusionTrackerTest {
1286 protected:
1287 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
1288 : OcclusionTrackerTest(opaque_layers) {}
1289 void RunMyTest() override {
1290 TestContentLayerImpl* parent = this->CreateRoot(
1291 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1292 LayerImpl* surface =
1293 this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
1294 gfx::Size(100, 100), true);
1295 this->CreateReplicaLayer(surface,
1296 this->identity_matrix,
1297 gfx::PointF(0.f, 100.f),
1298 gfx::Size(100, 100));
1299 LayerImpl* topmost =
1300 this->CreateDrawingLayer(parent, this->identity_matrix, gfx::PointF(),
1301 gfx::Size(100, 110), true);
1302 this->CalcDrawEtc(parent);
1304 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1306 // |topmost| occludes the surface, but not the entire surface's replica.
1307 this->VisitLayer(topmost, &occlusion);
1309 EXPECT_EQ(gfx::Rect().ToString(),
1310 occlusion.occlusion_from_outside_target().ToString());
1311 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
1312 occlusion.occlusion_from_inside_target().ToString());
1314 this->VisitLayer(surface, &occlusion);
1316 // Render target with replica ignores occlusion from outside.
1317 EXPECT_EQ(gfx::Rect().ToString(),
1318 occlusion.occlusion_from_outside_target().ToString());
1319 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
1320 occlusion.occlusion_from_inside_target().ToString());
1322 this->EnterContributingSurface(surface, &occlusion);
1324 // Only occlusion from outside the surface occludes the surface/replica.
1325 EXPECT_EQ(gfx::Rect().ToString(),
1326 occlusion.occlusion_on_contributing_surface_from_outside_target()
1327 .ToString());
1328 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
1329 occlusion.occlusion_on_contributing_surface_from_inside_target()
1330 .ToString());
1334 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
1336 class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest {
1337 protected:
1338 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
1339 : OcclusionTrackerTest(opaque_layers) {}
1340 void RunMyTest() override {
1341 // This test verifies that the surface cliprect does not end up empty and
1342 // clip away the entire unoccluded rect.
1344 TestContentLayerImpl* parent = this->CreateRoot(
1345 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1346 LayerImpl* surface =
1347 this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
1348 gfx::Size(100, 100), false);
1349 LayerImpl* surface_child = this->CreateDrawingSurface(
1350 surface, this->identity_matrix, gfx::PointF(0.f, 10.f),
1351 gfx::Size(100, 50), true);
1352 LayerImpl* topmost = this->CreateDrawingLayer(
1353 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
1354 this->CalcDrawEtc(parent);
1356 TestOcclusionTrackerWithClip occlusion(gfx::Rect(-100, -100, 1000, 1000));
1358 // |topmost| occludes everything partially so we know occlusion is happening
1359 // at all.
1360 this->VisitLayer(topmost, &occlusion);
1362 EXPECT_EQ(gfx::Rect().ToString(),
1363 occlusion.occlusion_from_outside_target().ToString());
1364 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1365 occlusion.occlusion_from_inside_target().ToString());
1367 this->VisitLayer(surface_child, &occlusion);
1369 // surface_child increases the occlusion in the screen by a narrow sliver.
1370 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
1371 occlusion.occlusion_from_outside_target().ToString());
1372 // In its own surface, surface_child is at 0,0 as is its occlusion.
1373 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1374 occlusion.occlusion_from_inside_target().ToString());
1376 // The root layer always has a clip rect. So the parent of |surface| has a
1377 // clip rect. However, the owning layer for |surface| does not mask to
1378 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
1379 // |surface_child| exercises different code paths as its parent does not
1380 // have a clip rect.
1382 this->EnterContributingSurface(surface_child, &occlusion);
1383 // The |surface_child| can't occlude its own surface, but occlusion from
1384 // |topmost| can.
1385 EXPECT_EQ(gfx::Rect().ToString(),
1386 occlusion.occlusion_on_contributing_surface_from_outside_target()
1387 .ToString());
1388 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1389 occlusion.occlusion_on_contributing_surface_from_inside_target()
1390 .ToString());
1391 this->LeaveContributingSurface(surface_child, &occlusion);
1393 // When the surface_child's occlusion is transformed up to its parent, make
1394 // sure it is not clipped away inappropriately.
1395 this->EnterLayer(surface, &occlusion);
1396 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1397 occlusion.occlusion_from_outside_target().ToString());
1398 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
1399 occlusion.occlusion_from_inside_target().ToString());
1400 this->LeaveLayer(surface, &occlusion);
1402 this->EnterContributingSurface(surface, &occlusion);
1403 // The occlusion from inside |surface| can't affect the surface, but
1404 // |topmost| can.
1405 EXPECT_EQ(gfx::Rect().ToString(),
1406 occlusion.occlusion_on_contributing_surface_from_outside_target()
1407 .ToString());
1408 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1409 occlusion.occlusion_on_contributing_surface_from_inside_target()
1410 .ToString());
1412 this->LeaveContributingSurface(surface, &occlusion);
1413 this->EnterLayer(parent, &occlusion);
1414 // The occlusion in |surface| and without are merged into the parent.
1415 EXPECT_EQ(gfx::Rect().ToString(),
1416 occlusion.occlusion_from_outside_target().ToString());
1417 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
1418 occlusion.occlusion_from_inside_target().ToString());
1422 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
1424 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
1425 : public OcclusionTrackerTest {
1426 protected:
1427 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
1428 bool opaque_layers)
1429 : OcclusionTrackerTest(opaque_layers) {}
1430 void RunMyTest() override {
1431 gfx::Transform scale_by_half;
1432 scale_by_half.Scale(0.5, 0.5);
1434 FilterOperations filters;
1435 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1437 // Save the distance of influence for the blur effect.
1438 int outset_top, outset_right, outset_bottom, outset_left;
1439 filters.GetOutsets(
1440 &outset_top, &outset_right, &outset_bottom, &outset_left);
1442 enum Direction {
1443 LEFT,
1444 RIGHT,
1445 TOP,
1446 BOTTOM,
1447 LAST_DIRECTION = BOTTOM,
1450 for (int i = 0; i <= LAST_DIRECTION; ++i) {
1451 SCOPED_TRACE(i);
1453 // Make a 50x50 filtered surface that is adjacent to occluding layers
1454 // which are above it in the z-order in various configurations. The
1455 // surface is scaled to test that the pixel moving is done in the target
1456 // space, where the background filter is applied.
1457 TestContentLayerImpl* parent = this->CreateRoot(
1458 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
1459 LayerImpl* filtered_surface = this->CreateDrawingLayer(
1460 parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100),
1461 false);
1462 filtered_surface->SetHasRenderSurface(true);
1463 filtered_surface->SetBackgroundFilters(filters);
1464 gfx::Rect occlusion_rect;
1465 switch (i) {
1466 case LEFT:
1467 occlusion_rect = gfx::Rect(0, 0, 50, 200);
1468 break;
1469 case RIGHT:
1470 occlusion_rect = gfx::Rect(100, 0, 50, 200);
1471 break;
1472 case TOP:
1473 occlusion_rect = gfx::Rect(0, 0, 200, 50);
1474 break;
1475 case BOTTOM:
1476 occlusion_rect = gfx::Rect(0, 100, 200, 50);
1477 break;
1480 LayerImpl* occluding_layer = this->CreateDrawingLayer(
1481 parent, this->identity_matrix, occlusion_rect.origin(),
1482 occlusion_rect.size(), true);
1483 this->CalcDrawEtc(parent);
1485 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
1487 // This layer occludes pixels directly beside the filtered_surface.
1488 // Because filtered surface blends pixels in a radius, it will need to see
1489 // some of the pixels (up to radius far) underneath the occluding layers.
1490 this->VisitLayer(occluding_layer, &occlusion);
1492 EXPECT_EQ(occlusion_rect.ToString(),
1493 occlusion.occlusion_from_inside_target().ToString());
1494 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1496 this->VisitLayer(filtered_surface, &occlusion);
1498 // The occlusion is used fully inside the surface.
1499 gfx::Rect occlusion_inside_surface =
1500 occlusion_rect - gfx::Vector2d(50, 50);
1501 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1502 EXPECT_EQ(occlusion_inside_surface.ToString(),
1503 occlusion.occlusion_from_outside_target().ToString());
1505 // The surface has a background blur, so it needs pixels that are
1506 // currently considered occluded in order to be drawn. So the pixels it
1507 // needs should be removed some the occluded area so that when we get to
1508 // the parent they are drawn.
1509 this->VisitContributingSurface(filtered_surface, &occlusion);
1510 this->EnterLayer(parent, &occlusion);
1512 gfx::Rect expected_occlusion = occlusion_rect;
1513 switch (i) {
1514 case LEFT:
1515 expected_occlusion.Inset(0, 0, outset_right, 0);
1516 break;
1517 case RIGHT:
1518 expected_occlusion.Inset(outset_right, 0, 0, 0);
1519 break;
1520 case TOP:
1521 expected_occlusion.Inset(0, 0, 0, outset_right);
1522 break;
1523 case BOTTOM:
1524 expected_occlusion.Inset(0, outset_right, 0, 0);
1525 break;
1528 EXPECT_EQ(expected_occlusion.ToString(),
1529 occlusion.occlusion_from_inside_target().ToString());
1530 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1532 this->DestroyLayers();
1537 ALL_OCCLUSIONTRACKER_TEST(
1538 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
1540 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
1541 : public OcclusionTrackerTest {
1542 protected:
1543 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
1544 bool opaque_layers)
1545 : OcclusionTrackerTest(opaque_layers) {}
1546 void RunMyTest() override {
1547 gfx::Transform scale_by_half;
1548 scale_by_half.Scale(0.5, 0.5);
1550 // Makes two surfaces that completely cover |parent|. The occlusion both
1551 // above and below the filters will be reduced by each of them.
1552 TestContentLayerImpl* root = this->CreateRoot(
1553 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
1554 LayerImpl* parent = this->CreateSurface(root, scale_by_half, gfx::PointF(),
1555 gfx::Size(150, 150));
1556 parent->SetMasksToBounds(true);
1557 LayerImpl* filtered_surface1 = this->CreateDrawingLayer(
1558 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
1559 LayerImpl* filtered_surface2 = this->CreateDrawingLayer(
1560 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
1561 LayerImpl* occluding_layer_above = this->CreateDrawingLayer(
1562 parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
1563 gfx::Size(50, 50), true);
1565 // Filters make the layers own surfaces.
1566 filtered_surface1->SetHasRenderSurface(true);
1567 filtered_surface2->SetHasRenderSurface(true);
1568 FilterOperations filters;
1569 filters.Append(FilterOperation::CreateBlurFilter(1.f));
1570 filtered_surface1->SetBackgroundFilters(filters);
1571 filtered_surface2->SetBackgroundFilters(filters);
1573 // Save the distance of influence for the blur effect.
1574 int outset_top, outset_right, outset_bottom, outset_left;
1575 filters.GetOutsets(
1576 &outset_top, &outset_right, &outset_bottom, &outset_left);
1578 this->CalcDrawEtc(root);
1580 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1582 this->VisitLayer(occluding_layer_above, &occlusion);
1583 EXPECT_EQ(gfx::Rect().ToString(),
1584 occlusion.occlusion_from_outside_target().ToString());
1585 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
1586 occlusion.occlusion_from_inside_target().ToString());
1588 this->VisitLayer(filtered_surface2, &occlusion);
1589 this->VisitContributingSurface(filtered_surface2, &occlusion);
1590 this->VisitLayer(filtered_surface1, &occlusion);
1591 this->VisitContributingSurface(filtered_surface1, &occlusion);
1593 // Test expectations in the target.
1594 gfx::Rect expected_occlusion =
1595 gfx::Rect(100 / 2 + outset_right * 2,
1596 100 / 2 + outset_bottom * 2,
1597 50 / 2 - (outset_left + outset_right) * 2,
1598 50 / 2 - (outset_top + outset_bottom) * 2);
1599 EXPECT_EQ(expected_occlusion.ToString(),
1600 occlusion.occlusion_from_inside_target().ToString());
1602 // Test expectations in the screen are the same as in the target, as the
1603 // render surface is 1:1 with the screen.
1604 EXPECT_EQ(expected_occlusion.ToString(),
1605 occlusion.occlusion_from_outside_target().ToString());
1609 ALL_OCCLUSIONTRACKER_TEST(
1610 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
1612 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
1613 : public OcclusionTrackerTest {
1614 protected:
1615 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
1616 bool opaque_layers)
1617 : OcclusionTrackerTest(opaque_layers) {}
1618 void RunMyTest() override {
1619 gfx::Transform scale_by_half;
1620 scale_by_half.Scale(0.5, 0.5);
1622 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
1623 // centered below each. The surface is scaled to test that the pixel moving
1624 // is done in the target space, where the background filter is applied, but
1625 // the surface appears at 50, 50 and the replica at 200, 50.
1626 TestContentLayerImpl* parent = this->CreateRoot(
1627 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
1628 LayerImpl* behind_surface_layer = this->CreateDrawingLayer(
1629 parent, this->identity_matrix, gfx::PointF(60.f, 60.f),
1630 gfx::Size(30, 30), true);
1631 LayerImpl* behind_replica_layer = this->CreateDrawingLayer(
1632 parent, this->identity_matrix, gfx::PointF(210.f, 60.f),
1633 gfx::Size(30, 30), true);
1634 LayerImpl* filtered_surface =
1635 this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
1636 gfx::Size(100, 100), false);
1637 this->CreateReplicaLayer(filtered_surface,
1638 this->identity_matrix,
1639 gfx::PointF(300.f, 0.f),
1640 gfx::Size());
1642 // Filters make the layer own a surface.
1643 filtered_surface->SetHasRenderSurface(true);
1644 FilterOperations filters;
1645 filters.Append(FilterOperation::CreateBlurFilter(3.f));
1646 filtered_surface->SetBackgroundFilters(filters);
1648 this->CalcDrawEtc(parent);
1650 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1652 // The surface has a background blur, so it blurs non-opaque pixels below
1653 // it.
1654 this->VisitLayer(filtered_surface, &occlusion);
1655 this->VisitContributingSurface(filtered_surface, &occlusion);
1657 this->VisitLayer(behind_replica_layer, &occlusion);
1659 // The layers behind the surface are not blurred, and their occlusion does
1660 // not change, until we leave the surface. So it should not be modified by
1661 // the filter here.
1662 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
1663 EXPECT_EQ(occlusion_behind_replica.ToString(),
1664 occlusion.occlusion_from_inside_target().ToString());
1665 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1667 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
1668 // without existing occlusion interfering.
1669 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1671 this->VisitLayer(behind_surface_layer, &occlusion);
1673 // The layers behind the surface are not blurred, and their occlusion does
1674 // not change, until we leave the surface. So it should not be modified by
1675 // the filter here.
1676 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
1677 EXPECT_EQ(occlusion_behind_surface.ToString(),
1678 occlusion.occlusion_from_inside_target().ToString());
1679 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1683 ALL_OCCLUSIONTRACKER_TEST(
1684 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
1686 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
1687 : public OcclusionTrackerTest {
1688 protected:
1689 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
1690 bool opaque_layers)
1691 : OcclusionTrackerTest(opaque_layers) {}
1692 void RunMyTest() override {
1693 gfx::Transform scale_by_half;
1694 scale_by_half.Scale(0.5, 0.5);
1696 // Make a 50x50 filtered surface that is completely occluded by an opaque
1697 // layer which is above it in the z-order. The surface is
1698 // scaled to test that the pixel moving is done in the target space, where
1699 // the background filter is applied, but the surface appears at 50, 50.
1700 TestContentLayerImpl* parent = this->CreateRoot(
1701 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
1702 LayerImpl* filtered_surface =
1703 this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
1704 gfx::Size(100, 100), false);
1705 LayerImpl* occluding_layer = this->CreateDrawingLayer(
1706 parent, this->identity_matrix, gfx::PointF(50.f, 50.f),
1707 gfx::Size(50, 50), true);
1709 // Filters make the layer own a surface.
1710 filtered_surface->SetHasRenderSurface(true);
1711 FilterOperations filters;
1712 filters.Append(FilterOperation::CreateBlurFilter(3.f));
1713 filtered_surface->SetBackgroundFilters(filters);
1715 this->CalcDrawEtc(parent);
1717 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1719 this->VisitLayer(occluding_layer, &occlusion);
1721 this->VisitLayer(filtered_surface, &occlusion);
1723 // The layers above the filtered surface occlude from outside.
1724 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
1726 EXPECT_EQ(gfx::Rect().ToString(),
1727 occlusion.occlusion_from_inside_target().ToString());
1728 EXPECT_EQ(occlusion_above_surface.ToString(),
1729 occlusion.occlusion_from_outside_target().ToString());
1732 // The surface has a background blur, so it blurs non-opaque pixels below
1733 // it.
1734 this->VisitContributingSurface(filtered_surface, &occlusion);
1736 // The filter is completely occluded, so it should not blur anything and
1737 // reduce any occlusion.
1738 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
1740 EXPECT_EQ(occlusion_above_surface.ToString(),
1741 occlusion.occlusion_from_inside_target().ToString());
1742 EXPECT_EQ(gfx::Rect().ToString(),
1743 occlusion.occlusion_from_outside_target().ToString());
1748 ALL_OCCLUSIONTRACKER_TEST(
1749 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
1751 class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
1752 : public OcclusionTrackerTest {
1753 protected:
1754 explicit OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded(
1755 bool opaque_layers)
1756 : OcclusionTrackerTest(opaque_layers) {}
1757 void RunMyTest() override {
1758 gfx::Transform scale_by_half;
1759 scale_by_half.Scale(0.5, 0.5);
1761 // Make a surface and its replica, each 50x50, that are partially occluded
1762 // by opaque layers which are above them in the z-order. The surface is
1763 // scaled to test that the pixel moving is done in the target space, where
1764 // the background filter is applied, but the surface appears at 50, 50 and
1765 // the replica at 200, 50.
1766 TestContentLayerImpl* parent = this->CreateRoot(
1767 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
1768 LayerImpl* filtered_surface =
1769 this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
1770 gfx::Size(100, 100), false);
1771 this->CreateReplicaLayer(filtered_surface,
1772 this->identity_matrix,
1773 gfx::PointF(300.f, 0.f),
1774 gfx::Size());
1775 LayerImpl* above_surface_layer = this->CreateDrawingLayer(
1776 parent, this->identity_matrix, gfx::PointF(70.f, 50.f),
1777 gfx::Size(30, 50), true);
1778 LayerImpl* above_replica_layer = this->CreateDrawingLayer(
1779 parent, this->identity_matrix, gfx::PointF(200.f, 50.f),
1780 gfx::Size(30, 50), true);
1781 LayerImpl* beside_surface_layer = this->CreateDrawingLayer(
1782 parent, this->identity_matrix, gfx::PointF(90.f, 40.f),
1783 gfx::Size(10, 10), true);
1784 LayerImpl* beside_replica_layer = this->CreateDrawingLayer(
1785 parent, this->identity_matrix, gfx::PointF(200.f, 40.f),
1786 gfx::Size(10, 10), true);
1788 // Filters make the layer own a surface.
1789 filtered_surface->SetHasRenderSurface(true);
1790 FilterOperations filters;
1791 filters.Append(FilterOperation::CreateBlurFilter(3.f));
1792 filtered_surface->SetBackgroundFilters(filters);
1794 // Save the distance of influence for the blur effect.
1795 int outset_top, outset_right, outset_bottom, outset_left;
1796 filters.GetOutsets(
1797 &outset_top, &outset_right, &outset_bottom, &outset_left);
1799 this->CalcDrawEtc(parent);
1801 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1803 this->VisitLayer(beside_replica_layer, &occlusion);
1804 this->VisitLayer(beside_surface_layer, &occlusion);
1805 this->VisitLayer(above_replica_layer, &occlusion);
1806 this->VisitLayer(above_surface_layer, &occlusion);
1808 // The surface has a background blur, so it blurs non-opaque pixels below
1809 // it.
1810 this->VisitLayer(filtered_surface, &occlusion);
1811 this->VisitContributingSurface(filtered_surface, &occlusion);
1813 // The filter in the surface and replica are partially unoccluded. Only the
1814 // unoccluded parts should reduce occlusion. This means it will push back
1815 // the occlusion that touches the unoccluded part (occlusion_above___), but
1816 // it will not touch occlusion_beside____ since that is not beside the
1817 // unoccluded part of the surface, even though it is beside the occluded
1818 // part of the surface.
1819 gfx::Rect occlusion_above_surface =
1820 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
1821 gfx::Rect occlusion_above_replica =
1822 gfx::Rect(200, 50, 30 - outset_left, 50);
1823 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
1824 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
1826 SimpleEnclosedRegion expected_occlusion;
1827 expected_occlusion.Union(occlusion_beside_replica);
1828 expected_occlusion.Union(occlusion_beside_surface);
1829 expected_occlusion.Union(occlusion_above_replica);
1830 expected_occlusion.Union(occlusion_above_surface);
1832 EXPECT_EQ(expected_occlusion.ToString(),
1833 occlusion.occlusion_from_inside_target().ToString());
1834 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1836 const SimpleEnclosedRegion& actual_occlusion =
1837 occlusion.occlusion_from_inside_target();
1838 for (size_t i = 0; i < expected_occlusion.GetRegionComplexity(); ++i) {
1839 ASSERT_LT(i, actual_occlusion.GetRegionComplexity());
1840 EXPECT_EQ(expected_occlusion.GetRect(i), actual_occlusion.GetRect(i));
1845 ALL_OCCLUSIONTRACKER_TEST(
1846 OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded);
1848 class OcclusionTrackerTestBlendModeDoesNotOcclude
1849 : public OcclusionTrackerTest {
1850 protected:
1851 explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers)
1852 : OcclusionTrackerTest(opaque_layers) {}
1853 void RunMyTest() override {
1854 TestContentLayerImpl* parent = this->CreateRoot(
1855 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1856 LayerImpl* blend_mode_layer = this->CreateDrawingLayer(
1857 parent, this->identity_matrix, gfx::PointF(0.f, 0.f),
1858 gfx::Size(100, 100), true);
1859 LayerImpl* top_layer = this->CreateDrawingLayer(
1860 parent, this->identity_matrix, gfx::PointF(10.f, 12.f),
1861 gfx::Size(20, 22), true);
1863 // Blend mode makes the layer own a surface.
1864 blend_mode_layer->SetHasRenderSurface(true);
1865 blend_mode_layer->SetBlendMode(SkXfermode::kMultiply_Mode);
1867 this->CalcDrawEtc(parent);
1869 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1871 this->VisitLayer(top_layer, &occlusion);
1872 // |top_layer| occludes.
1873 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1874 occlusion.occlusion_from_inside_target().ToString());
1875 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1877 this->VisitLayer(blend_mode_layer, &occlusion);
1878 // |top_layer| occludes but not |blend_mode_layer|.
1879 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1880 occlusion.occlusion_from_outside_target().ToString());
1881 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1883 this->VisitContributingSurface(blend_mode_layer, &occlusion);
1884 // |top_layer| occludes but not |blend_mode_layer|.
1885 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1886 occlusion.occlusion_from_inside_target().ToString());
1887 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1891 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude);
1893 class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest {
1894 protected:
1895 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
1896 : OcclusionTrackerTest(opaque_layers) {}
1897 void RunMyTest() override {
1898 gfx::Size tracking_size(100, 100);
1899 gfx::Size below_tracking_size(99, 99);
1901 TestContentLayerImpl* parent = this->CreateRoot(
1902 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
1903 LayerImpl* large = this->CreateDrawingLayer(
1904 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
1905 LayerImpl* small =
1906 this->CreateDrawingLayer(parent, this->identity_matrix, gfx::PointF(),
1907 below_tracking_size, true);
1908 this->CalcDrawEtc(parent);
1910 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1911 occlusion.set_minimum_tracking_size(tracking_size);
1913 // The small layer is not tracked because it is too small.
1914 this->VisitLayer(small, &occlusion);
1916 EXPECT_EQ(gfx::Rect().ToString(),
1917 occlusion.occlusion_from_outside_target().ToString());
1918 EXPECT_EQ(gfx::Rect().ToString(),
1919 occlusion.occlusion_from_inside_target().ToString());
1921 // The large layer is tracked as it is large enough.
1922 this->VisitLayer(large, &occlusion);
1924 EXPECT_EQ(gfx::Rect().ToString(),
1925 occlusion.occlusion_from_outside_target().ToString());
1926 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
1927 occlusion.occlusion_from_inside_target().ToString());
1931 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
1933 class OcclusionTrackerTestScaledLayerIsClipped : public OcclusionTrackerTest {
1934 protected:
1935 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
1936 : OcclusionTrackerTest(opaque_layers) {}
1937 void RunMyTest() override {
1938 gfx::Transform scale_transform;
1939 scale_transform.Scale(512.0, 512.0);
1941 TestContentLayerImpl* parent = this->CreateRoot(
1942 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
1943 LayerImpl* clip =
1944 this->CreateLayer(parent, this->identity_matrix,
1945 gfx::PointF(10.f, 10.f), gfx::Size(50, 50));
1946 clip->SetMasksToBounds(true);
1947 LayerImpl* scale = this->CreateLayer(clip, scale_transform, gfx::PointF(),
1948 gfx::Size(1, 1));
1949 LayerImpl* scaled = this->CreateDrawingLayer(
1950 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
1951 this->CalcDrawEtc(parent);
1953 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1955 this->VisitLayer(scaled, &occlusion);
1957 EXPECT_EQ(gfx::Rect().ToString(),
1958 occlusion.occlusion_from_outside_target().ToString());
1959 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
1960 occlusion.occlusion_from_inside_target().ToString());
1964 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
1966 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
1967 : public OcclusionTrackerTest {
1968 protected:
1969 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
1970 : OcclusionTrackerTest(opaque_layers) {}
1971 void RunMyTest() override {
1972 gfx::Transform scale_transform;
1973 scale_transform.Scale(512.0, 512.0);
1975 TestContentLayerImpl* parent = this->CreateRoot(
1976 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
1977 LayerImpl* clip =
1978 this->CreateLayer(parent, this->identity_matrix,
1979 gfx::PointF(10.f, 10.f), gfx::Size(50, 50));
1980 clip->SetMasksToBounds(true);
1981 LayerImpl* surface = this->CreateDrawingSurface(
1982 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
1983 LayerImpl* scale = this->CreateLayer(surface, scale_transform,
1984 gfx::PointF(), gfx::Size(1, 1));
1985 LayerImpl* scaled = this->CreateDrawingLayer(
1986 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
1987 this->CalcDrawEtc(parent);
1989 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1991 this->VisitLayer(scaled, &occlusion);
1992 this->VisitLayer(surface, &occlusion);
1993 this->VisitContributingSurface(surface, &occlusion);
1995 EXPECT_EQ(gfx::Rect().ToString(),
1996 occlusion.occlusion_from_outside_target().ToString());
1997 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
1998 occlusion.occlusion_from_inside_target().ToString());
2002 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
2004 class OcclusionTrackerTestCopyRequestDoesOcclude : public OcclusionTrackerTest {
2005 protected:
2006 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
2007 : OcclusionTrackerTest(opaque_layers) {}
2008 void RunMyTest() override {
2009 TestContentLayerImpl* root = this->CreateRoot(
2010 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2011 TestContentLayerImpl* parent = this->CreateDrawingLayer(
2012 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2013 LayerImpl* copy = this->CreateLayer(
2014 parent, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
2015 this->AddCopyRequest(copy);
2016 LayerImpl* copy_child = this->CreateDrawingLayer(
2017 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
2018 LayerImpl* top_layer =
2019 this->CreateDrawingLayer(root, this->identity_matrix,
2020 gfx::PointF(50, 0), gfx::Size(50, 400), true);
2021 this->CalcDrawEtc(root);
2023 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
2025 this->VisitLayer(top_layer, &occlusion);
2026 EXPECT_EQ(gfx::Rect().ToString(),
2027 occlusion.occlusion_from_outside_target().ToString());
2028 EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(),
2029 occlusion.occlusion_from_inside_target().ToString());
2031 this->VisitLayer(copy_child, &occlusion);
2032 // Layers outside the copy request do not occlude.
2033 EXPECT_EQ(gfx::Rect().ToString(),
2034 occlusion.occlusion_from_outside_target().ToString());
2035 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2036 occlusion.occlusion_from_inside_target().ToString());
2038 // CopyRequests cause the layer to own a surface.
2039 this->VisitContributingSurface(copy, &occlusion);
2041 // The occlusion from the copy should be kept.
2042 EXPECT_EQ(gfx::Rect().ToString(),
2043 occlusion.occlusion_from_outside_target().ToString());
2044 EXPECT_EQ(gfx::Rect(50, 0, 250, 400).ToString(),
2045 occlusion.occlusion_from_inside_target().ToString());
2049 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
2051 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2052 : public OcclusionTrackerTest {
2053 protected:
2054 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2055 bool opaque_layers)
2056 : OcclusionTrackerTest(opaque_layers) {}
2057 void RunMyTest() override {
2058 TestContentLayerImpl* root = this->CreateRoot(
2059 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2060 TestContentLayerImpl* parent = this->CreateDrawingLayer(
2061 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2062 LayerImpl* hide = this->CreateLayer(parent, this->identity_matrix,
2063 gfx::Point(), gfx::Size());
2064 LayerImpl* copy = this->CreateLayer(
2065 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
2066 this->AddCopyRequest(copy);
2067 LayerImpl* copy_child = this->CreateDrawingLayer(
2068 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
2070 // The |copy| layer is hidden but since it is being copied, it will be
2071 // drawn.
2072 hide->SetHideLayerAndSubtree(true);
2074 this->CalcDrawEtc(root);
2076 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
2078 this->VisitLayer(copy_child, &occlusion);
2079 EXPECT_EQ(gfx::Rect().ToString(),
2080 occlusion.occlusion_from_outside_target().ToString());
2081 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2082 occlusion.occlusion_from_inside_target().ToString());
2084 // CopyRequests cause the layer to own a surface.
2085 this->VisitContributingSurface(copy, &occlusion);
2087 // The occlusion from the copy should be dropped since it is hidden.
2088 EXPECT_EQ(gfx::Rect().ToString(),
2089 occlusion.occlusion_from_outside_target().ToString());
2090 EXPECT_EQ(gfx::Rect().ToString(),
2091 occlusion.occlusion_from_inside_target().ToString());
2095 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
2097 class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest {
2098 protected:
2099 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers)
2100 : OcclusionTrackerTest(opaque_layers) {}
2101 void RunMyTest() override {
2102 gfx::Transform translate;
2103 translate.Translate(10.0, 20.0);
2104 TestContentLayerImpl* root = this->CreateRoot(
2105 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2106 LayerImpl* surface = this->CreateSurface(root, this->identity_matrix,
2107 gfx::Point(), gfx::Size(200, 200));
2108 LayerImpl* layer = this->CreateDrawingLayer(
2109 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2110 TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
2111 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2112 this->CalcDrawEtc(root);
2114 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
2115 this->VisitLayer(outside_layer, &occlusion);
2116 this->EnterLayer(layer, &occlusion);
2118 // No occlusion, is not occluded.
2119 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2120 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2121 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100)));
2123 // Partial occlusion from outside, is not occluded.
2124 occlusion.set_occlusion_from_outside_target(
2125 SimpleEnclosedRegion(50, 50, 100, 100));
2126 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2127 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2128 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2129 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2130 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2131 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2132 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2133 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2134 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2136 // Full occlusion from outside, is occluded.
2137 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2138 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2139 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2140 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2142 // Partial occlusion from inside, is not occluded.
2143 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2144 occlusion.set_occlusion_from_inside_target(
2145 SimpleEnclosedRegion(50, 50, 100, 100));
2146 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2147 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2148 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2149 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2150 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2151 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2152 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2153 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2155 // Full occlusion from inside, is occluded.
2156 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2157 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2158 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2159 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2161 // Partial occlusion from both, is not occluded.
2162 occlusion.set_occlusion_from_outside_target(
2163 SimpleEnclosedRegion(50, 50, 100, 50));
2164 occlusion.set_occlusion_from_inside_target(
2165 SimpleEnclosedRegion(50, 100, 100, 50));
2166 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2167 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2168 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2169 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2170 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2171 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2172 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2173 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2175 // Full occlusion from both, is occluded.
2176 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2177 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2178 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2179 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2183 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer)
2185 class OcclusionTrackerTestUnoccludedLayerQuery : public OcclusionTrackerTest {
2186 protected:
2187 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers)
2188 : OcclusionTrackerTest(opaque_layers) {}
2189 void RunMyTest() override {
2190 gfx::Transform translate;
2191 translate.Translate(10.0, 20.0);
2192 TestContentLayerImpl* root = this->CreateRoot(
2193 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2194 LayerImpl* surface = this->CreateSurface(root, this->identity_matrix,
2195 gfx::Point(), gfx::Size(200, 200));
2196 LayerImpl* layer = this->CreateDrawingLayer(
2197 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2198 TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
2199 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2200 this->CalcDrawEtc(root);
2202 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
2203 this->VisitLayer(outside_layer, &occlusion);
2204 this->EnterLayer(layer, &occlusion);
2206 // No occlusion, is not occluded.
2207 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2208 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2209 EXPECT_EQ(gfx::Rect(100, 100),
2210 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(100, 100)));
2212 // Partial occlusion from outside.
2213 occlusion.set_occlusion_from_outside_target(
2214 SimpleEnclosedRegion(50, 50, 100, 100));
2215 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2216 EXPECT_EQ(
2217 gfx::Rect(0, 0, 100, 100),
2218 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
2219 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2220 occlusion.UnoccludedLayerContentRect(
2221 layer, gfx::Rect(90, 30, 100, 100)));
2222 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2223 occlusion.UnoccludedLayerContentRect(layer,
2224 gfx::Rect(40, 0, 100, 100)));
2225 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2226 occlusion.UnoccludedLayerContentRect(
2227 layer, gfx::Rect(40, 80, 100, 100)));
2228 EXPECT_EQ(
2229 gfx::Rect(0, 0, 80, 100),
2230 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
2231 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2232 occlusion.UnoccludedLayerContentRect(
2233 layer, gfx::Rect(90, 80, 100, 100)));
2234 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2235 occlusion.UnoccludedLayerContentRect(layer,
2236 gfx::Rect(0, 80, 100, 100)));
2237 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2238 occlusion.UnoccludedLayerContentRect(layer,
2239 gfx::Rect(90, 0, 100, 100)));
2241 // Full occlusion from outside, is occluded.
2242 EXPECT_EQ(gfx::Rect(),
2243 occlusion.UnoccludedLayerContentRect(
2244 layer, gfx::Rect(40, 30, 100, 100)));
2245 EXPECT_EQ(
2246 gfx::Rect(),
2247 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
2248 EXPECT_EQ(gfx::Rect(),
2249 occlusion.UnoccludedLayerContentRect(
2250 layer, gfx::Rect(130, 120, 10, 10)));
2251 EXPECT_EQ(
2252 gfx::Rect(),
2253 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
2255 // Partial occlusion from inside, is not occluded.
2256 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2257 occlusion.set_occlusion_from_inside_target(
2258 SimpleEnclosedRegion(50, 50, 100, 100));
2259 EXPECT_EQ(
2260 gfx::Rect(0, 0, 100, 100),
2261 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
2262 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2263 occlusion.UnoccludedLayerContentRect(
2264 layer, gfx::Rect(90, 30, 100, 100)));
2265 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2266 occlusion.UnoccludedLayerContentRect(layer,
2267 gfx::Rect(40, 0, 100, 100)));
2268 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2269 occlusion.UnoccludedLayerContentRect(
2270 layer, gfx::Rect(40, 80, 100, 100)));
2271 EXPECT_EQ(
2272 gfx::Rect(0, 0, 80, 100),
2273 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
2274 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2275 occlusion.UnoccludedLayerContentRect(
2276 layer, gfx::Rect(90, 80, 100, 100)));
2277 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2278 occlusion.UnoccludedLayerContentRect(layer,
2279 gfx::Rect(0, 80, 100, 100)));
2280 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2281 occlusion.UnoccludedLayerContentRect(layer,
2282 gfx::Rect(90, 0, 100, 100)));
2284 // Full occlusion from inside, is occluded.
2285 EXPECT_EQ(gfx::Rect(),
2286 occlusion.UnoccludedLayerContentRect(
2287 layer, gfx::Rect(40, 30, 100, 100)));
2288 EXPECT_EQ(
2289 gfx::Rect(),
2290 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
2291 EXPECT_EQ(gfx::Rect(),
2292 occlusion.UnoccludedLayerContentRect(
2293 layer, gfx::Rect(130, 120, 10, 10)));
2294 EXPECT_EQ(
2295 gfx::Rect(),
2296 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
2298 // Partial occlusion from both, is not occluded.
2299 occlusion.set_occlusion_from_outside_target(
2300 SimpleEnclosedRegion(50, 50, 100, 50));
2301 occlusion.set_occlusion_from_inside_target(
2302 SimpleEnclosedRegion(50, 100, 100, 50));
2303 EXPECT_EQ(
2304 gfx::Rect(0, 0, 100, 100),
2305 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
2306 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
2307 // it's larger.
2308 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
2309 occlusion.UnoccludedLayerContentRect(
2310 layer, gfx::Rect(90, 30, 100, 100)));
2311 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2312 occlusion.UnoccludedLayerContentRect(layer,
2313 gfx::Rect(40, 0, 100, 100)));
2314 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2315 occlusion.UnoccludedLayerContentRect(
2316 layer, gfx::Rect(40, 80, 100, 100)));
2317 EXPECT_EQ(
2318 gfx::Rect(0, 0, 80, 100),
2319 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
2320 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2321 occlusion.UnoccludedLayerContentRect(
2322 layer, gfx::Rect(90, 80, 100, 100)));
2323 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2324 occlusion.UnoccludedLayerContentRect(layer,
2325 gfx::Rect(0, 80, 100, 100)));
2326 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2327 occlusion.UnoccludedLayerContentRect(layer,
2328 gfx::Rect(90, 0, 100, 100)));
2330 // Full occlusion from both, is occluded.
2331 EXPECT_EQ(gfx::Rect(),
2332 occlusion.UnoccludedLayerContentRect(
2333 layer, gfx::Rect(40, 30, 100, 100)));
2334 EXPECT_EQ(
2335 gfx::Rect(),
2336 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
2337 EXPECT_EQ(gfx::Rect(),
2338 occlusion.UnoccludedLayerContentRect(
2339 layer, gfx::Rect(130, 120, 10, 10)));
2340 EXPECT_EQ(
2341 gfx::Rect(),
2342 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
2346 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery)
2348 class OcclusionTrackerTestUnoccludedSurfaceQuery : public OcclusionTrackerTest {
2349 protected:
2350 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers)
2351 : OcclusionTrackerTest(opaque_layers) {}
2352 void RunMyTest() override {
2353 gfx::Transform translate;
2354 translate.Translate(10.0, 20.0);
2355 TestContentLayerImpl* root = this->CreateRoot(
2356 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2357 LayerImpl* surface =
2358 this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200));
2359 LayerImpl* layer =
2360 this->CreateDrawingLayer(surface, this->identity_matrix, gfx::Point(),
2361 gfx::Size(200, 200), false);
2362 TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
2363 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2364 this->CalcDrawEtc(root);
2366 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
2367 this->VisitLayer(outside_layer, &occlusion);
2368 this->VisitLayer(layer, &occlusion);
2369 this->EnterContributingSurface(surface, &occlusion);
2371 // No occlusion, is not occluded.
2372 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
2373 SimpleEnclosedRegion());
2374 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
2375 SimpleEnclosedRegion());
2376 EXPECT_EQ(
2377 gfx::Rect(100, 100),
2378 occlusion.UnoccludedSurfaceContentRect(surface, gfx::Rect(100, 100)));
2380 // Partial occlusion from outside.
2381 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
2382 SimpleEnclosedRegion(50, 50, 100, 100));
2383 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
2384 SimpleEnclosedRegion());
2385 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2386 occlusion.UnoccludedSurfaceContentRect(
2387 surface, gfx::Rect(0, 0, 100, 100)));
2388 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2389 occlusion.UnoccludedSurfaceContentRect(
2390 surface, gfx::Rect(90, 30, 100, 100)));
2391 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2392 occlusion.UnoccludedSurfaceContentRect(
2393 surface, gfx::Rect(40, 0, 100, 100)));
2394 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2395 occlusion.UnoccludedSurfaceContentRect(
2396 surface, gfx::Rect(40, 80, 100, 100)));
2397 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2398 occlusion.UnoccludedSurfaceContentRect(surface,
2399 gfx::Rect(0, 0, 80, 100)));
2400 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2401 occlusion.UnoccludedSurfaceContentRect(
2402 surface, gfx::Rect(90, 80, 100, 100)));
2403 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2404 occlusion.UnoccludedSurfaceContentRect(
2405 surface, gfx::Rect(0, 80, 100, 100)));
2406 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2407 occlusion.UnoccludedSurfaceContentRect(
2408 surface, gfx::Rect(90, 0, 100, 100)));
2410 // Full occlusion from outside, is occluded.
2411 EXPECT_EQ(gfx::Rect(),
2412 occlusion.UnoccludedSurfaceContentRect(
2413 surface, gfx::Rect(40, 30, 100, 100)));
2414 EXPECT_EQ(gfx::Rect(),
2415 occlusion.UnoccludedSurfaceContentRect(
2416 surface, gfx::Rect(40, 30, 10, 10)));
2417 EXPECT_EQ(gfx::Rect(),
2418 occlusion.UnoccludedSurfaceContentRect(
2419 surface, gfx::Rect(130, 120, 10, 10)));
2420 EXPECT_EQ(gfx::Rect(),
2421 occlusion.UnoccludedSurfaceContentRect(
2422 surface, gfx::Rect(80, 70, 50, 50)));
2424 // Partial occlusion from inside, is not occluded.
2425 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
2426 SimpleEnclosedRegion());
2427 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
2428 SimpleEnclosedRegion(50, 50, 100, 100));
2429 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2430 occlusion.UnoccludedSurfaceContentRect(
2431 surface, gfx::Rect(0, 0, 100, 100)));
2432 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2433 occlusion.UnoccludedSurfaceContentRect(
2434 surface, gfx::Rect(90, 30, 100, 100)));
2435 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2436 occlusion.UnoccludedSurfaceContentRect(
2437 surface, gfx::Rect(40, 0, 100, 100)));
2438 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2439 occlusion.UnoccludedSurfaceContentRect(
2440 surface, gfx::Rect(40, 80, 100, 100)));
2441 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2442 occlusion.UnoccludedSurfaceContentRect(surface,
2443 gfx::Rect(0, 0, 80, 100)));
2444 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2445 occlusion.UnoccludedSurfaceContentRect(
2446 surface, gfx::Rect(90, 80, 100, 100)));
2447 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2448 occlusion.UnoccludedSurfaceContentRect(
2449 surface, gfx::Rect(0, 80, 100, 100)));
2450 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2451 occlusion.UnoccludedSurfaceContentRect(
2452 surface, gfx::Rect(90, 0, 100, 100)));
2454 // Full occlusion from inside, is occluded.
2455 EXPECT_EQ(gfx::Rect(),
2456 occlusion.UnoccludedSurfaceContentRect(
2457 surface, gfx::Rect(40, 30, 100, 100)));
2458 EXPECT_EQ(gfx::Rect(),
2459 occlusion.UnoccludedSurfaceContentRect(
2460 surface, gfx::Rect(40, 30, 10, 10)));
2461 EXPECT_EQ(gfx::Rect(),
2462 occlusion.UnoccludedSurfaceContentRect(
2463 surface, gfx::Rect(130, 120, 10, 10)));
2464 EXPECT_EQ(gfx::Rect(),
2465 occlusion.UnoccludedSurfaceContentRect(
2466 surface, gfx::Rect(80, 70, 50, 50)));
2468 // Partial occlusion from both, is not occluded.
2469 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
2470 SimpleEnclosedRegion(50, 50, 100, 50));
2471 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
2472 SimpleEnclosedRegion(50, 100, 100, 50));
2473 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2474 occlusion.UnoccludedSurfaceContentRect(
2475 surface, gfx::Rect(0, 0, 100, 100)));
2476 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
2477 // it's larger.
2478 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
2479 occlusion.UnoccludedSurfaceContentRect(
2480 surface, gfx::Rect(90, 30, 100, 100)));
2481 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2482 occlusion.UnoccludedSurfaceContentRect(
2483 surface, gfx::Rect(40, 0, 100, 100)));
2484 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2485 occlusion.UnoccludedSurfaceContentRect(
2486 surface, gfx::Rect(40, 80, 100, 100)));
2487 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2488 occlusion.UnoccludedSurfaceContentRect(surface,
2489 gfx::Rect(0, 0, 80, 100)));
2490 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2491 occlusion.UnoccludedSurfaceContentRect(
2492 surface, gfx::Rect(90, 80, 100, 100)));
2493 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2494 occlusion.UnoccludedSurfaceContentRect(
2495 surface, gfx::Rect(0, 80, 100, 100)));
2496 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2497 occlusion.UnoccludedSurfaceContentRect(
2498 surface, gfx::Rect(90, 0, 100, 100)));
2500 // Full occlusion from both, is occluded.
2501 EXPECT_EQ(gfx::Rect(),
2502 occlusion.UnoccludedSurfaceContentRect(
2503 surface, gfx::Rect(40, 30, 100, 100)));
2504 EXPECT_EQ(gfx::Rect(),
2505 occlusion.UnoccludedSurfaceContentRect(
2506 surface, gfx::Rect(40, 30, 10, 10)));
2507 EXPECT_EQ(gfx::Rect(),
2508 occlusion.UnoccludedSurfaceContentRect(
2509 surface, gfx::Rect(130, 120, 10, 10)));
2510 EXPECT_EQ(gfx::Rect(),
2511 occlusion.UnoccludedSurfaceContentRect(
2512 surface, gfx::Rect(80, 70, 50, 50)));
2516 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery)
2518 } // namespace
2519 } // namespace cc