This sets up API to release OutputSurface from LTHClient.
[chromium-blink-merge.git] / cc / trees / occlusion_tracker_unittest.cc
blob88779d018c33c51538fb31f5e2c0d5a538f5bdf7
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_impl_.clear();
199 replica_layers_.clear();
200 mask_layers_.clear();
201 ResetLayerIterator();
204 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
206 void AddCopyRequest(Layer* layer) {
207 layer->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
208 base::Bind(&OcclusionTrackerTest::CopyOutputCallback,
209 base::Unretained(this))));
212 void AddCopyRequest(LayerImpl* layer) {
213 ScopedPtrVector<CopyOutputRequest> requests;
214 requests.push_back(CopyOutputRequest::CreateBitmapRequest(base::Bind(
215 &OcclusionTrackerTest::CopyOutputCallback, base::Unretained(this))));
216 layer->SetHasRenderSurface(true);
217 layer->PassCopyRequests(&requests);
220 void CalcDrawEtc(TestContentLayerImpl* root) {
221 DCHECK(root == root_.get());
223 // These occlusion tests attach and detach layers in multiple
224 // iterations, so rebuild property trees every time.
225 root->layer_tree_impl()->property_trees()->needs_rebuild = true;
227 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root);
229 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
230 root, root->bounds(), &render_surface_layer_list_impl_);
231 inputs.can_adjust_raster_scales = true;
232 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
234 layer_iterator_ = layer_iterator_begin_ =
235 LayerIterator::Begin(&render_surface_layer_list_impl_);
238 void EnterLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
239 ASSERT_EQ(*layer_iterator_, layer);
240 ASSERT_TRUE(layer_iterator_.represents_itself());
241 occlusion->EnterLayer(layer_iterator_);
244 void LeaveLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
245 ASSERT_EQ(*layer_iterator_, layer);
246 ASSERT_TRUE(layer_iterator_.represents_itself());
247 occlusion->LeaveLayer(layer_iterator_);
248 ++layer_iterator_;
251 void VisitLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
252 EnterLayer(layer, occlusion);
253 LeaveLayer(layer, occlusion);
256 void EnterContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
257 ASSERT_EQ(*layer_iterator_, layer);
258 ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
259 occlusion->EnterLayer(layer_iterator_);
260 occlusion->LeaveLayer(layer_iterator_);
261 ++layer_iterator_;
262 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
263 occlusion->EnterLayer(layer_iterator_);
266 void LeaveContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
267 ASSERT_EQ(*layer_iterator_, layer);
268 ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
269 occlusion->LeaveLayer(layer_iterator_);
270 ++layer_iterator_;
273 void VisitContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
274 EnterContributingSurface(layer, occlusion);
275 LeaveContributingSurface(layer, occlusion);
278 void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
280 const gfx::Transform identity_matrix;
282 private:
283 void SetRootLayerOnMainThread(Layer* root) {
284 host_->SetRootLayer(scoped_refptr<Layer>(root));
287 void SetRootLayerOnMainThread(LayerImpl* root) {}
289 void SetProperties(LayerImpl* layer,
290 const gfx::Transform& transform,
291 const gfx::PointF& position,
292 const gfx::Size& bounds) {
293 layer->SetTransform(transform);
294 layer->SetPosition(position);
295 layer->SetBounds(bounds);
298 void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
299 owning_layer->SetReplicaLayer(layer.Pass());
302 void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
303 owning_layer->SetMaskLayer(layer.Pass());
306 bool opaque_layers_;
307 FakeLayerTreeHostClient client_;
308 TestTaskGraphRunner task_graph_runner_;
309 scoped_ptr<FakeLayerTreeHost> host_;
310 // These hold ownership of the layers for the duration of the test.
311 scoped_ptr<LayerImpl> root_;
312 LayerImplList render_surface_layer_list_impl_;
313 LayerIterator layer_iterator_begin_;
314 LayerIterator layer_iterator_;
315 LayerList replica_layers_;
316 LayerList mask_layers_;
317 int next_layer_impl_id_;
320 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
321 class ClassName##ImplThreadOpaqueLayers : public ClassName { \
322 public: /* NOLINT(whitespace/indent) */ \
323 ClassName##ImplThreadOpaqueLayers() : ClassName(true) {} \
324 }; \
325 TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
326 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
327 class ClassName##ImplThreadOpaquePaints : public ClassName { \
328 public: /* NOLINT(whitespace/indent) */ \
329 ClassName##ImplThreadOpaquePaints() : ClassName(false) {} \
330 }; \
331 TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
333 #define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
334 RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
335 RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
337 class OcclusionTrackerTestIdentityTransforms : public OcclusionTrackerTest {
338 protected:
339 explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
340 : OcclusionTrackerTest(opaque_layers) {}
342 void RunMyTest() override {
343 TestContentLayerImpl* root = this->CreateRoot(
344 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
345 TestContentLayerImpl* parent = this->CreateDrawingLayer(
346 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
347 TestContentLayerImpl* layer = this->CreateDrawingLayer(
348 parent, this->identity_matrix, gfx::PointF(30.f, 30.f),
349 gfx::Size(500, 500), true);
350 parent->SetMasksToBounds(true);
351 this->CalcDrawEtc(root);
353 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
355 this->VisitLayer(layer, &occlusion);
356 this->EnterLayer(parent, &occlusion);
358 EXPECT_EQ(gfx::Rect().ToString(),
359 occlusion.occlusion_from_outside_target().ToString());
360 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
361 occlusion.occlusion_from_inside_target().ToString());
365 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
367 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest {
368 protected:
369 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
370 : OcclusionTrackerTest(opaque_layers) {}
371 void RunMyTest() override {
372 gfx::Transform layer_transform;
373 layer_transform.Translate(250.0, 250.0);
374 layer_transform.Rotate(90.0);
375 layer_transform.Translate(-250.0, -250.0);
377 TestContentLayerImpl* root = this->CreateRoot(
378 this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
379 TestContentLayerImpl* parent = this->CreateDrawingLayer(
380 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
381 TestContentLayerImpl* layer = this->CreateDrawingLayer(
382 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
383 true);
384 parent->SetMasksToBounds(true);
385 this->CalcDrawEtc(root);
387 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
389 this->VisitLayer(layer, &occlusion);
390 this->EnterLayer(parent, &occlusion);
392 EXPECT_EQ(gfx::Rect().ToString(),
393 occlusion.occlusion_from_outside_target().ToString());
394 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
395 occlusion.occlusion_from_inside_target().ToString());
399 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
401 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest {
402 protected:
403 explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
404 : OcclusionTrackerTest(opaque_layers) {}
405 void RunMyTest() override {
406 gfx::Transform layer_transform;
407 layer_transform.Translate(20.0, 20.0);
409 TestContentLayerImpl* root = this->CreateRoot(
410 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
411 TestContentLayerImpl* parent = this->CreateDrawingLayer(
412 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
413 TestContentLayerImpl* layer = this->CreateDrawingLayer(
414 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
415 true);
416 parent->SetMasksToBounds(true);
417 this->CalcDrawEtc(root);
419 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
421 this->VisitLayer(layer, &occlusion);
422 this->EnterLayer(parent, &occlusion);
424 EXPECT_EQ(gfx::Rect().ToString(),
425 occlusion.occlusion_from_outside_target().ToString());
426 EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
427 occlusion.occlusion_from_inside_target().ToString());
431 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
433 class OcclusionTrackerTestChildInRotatedChild : public OcclusionTrackerTest {
434 protected:
435 explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
436 : OcclusionTrackerTest(opaque_layers) {}
437 void RunMyTest() override {
438 gfx::Transform child_transform;
439 child_transform.Translate(250.0, 250.0);
440 child_transform.Rotate(90.0);
441 child_transform.Translate(-250.0, -250.0);
443 TestContentLayerImpl* parent = this->CreateRoot(
444 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
445 parent->SetMasksToBounds(true);
446 LayerImpl* child = this->CreateSurface(
447 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
448 child->SetMasksToBounds(true);
449 TestContentLayerImpl* layer = this->CreateDrawingLayer(
450 child, this->identity_matrix, gfx::PointF(10.f, 10.f),
451 gfx::Size(500, 500), true);
452 this->CalcDrawEtc(parent);
454 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
456 this->VisitLayer(layer, &occlusion);
457 this->EnterContributingSurface(child, &occlusion);
459 EXPECT_EQ(gfx::Rect().ToString(),
460 occlusion.occlusion_from_outside_target().ToString());
461 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
462 occlusion.occlusion_from_inside_target().ToString());
464 this->LeaveContributingSurface(child, &occlusion);
465 this->EnterLayer(parent, &occlusion);
467 EXPECT_EQ(gfx::Rect().ToString(),
468 occlusion.occlusion_from_outside_target().ToString());
469 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
470 occlusion.occlusion_from_inside_target().ToString());
472 /* Justification for the above occlusion from |layer|:
474 +---------------------+
476 | 30 | rotate(90)
477 | 30 + ---------------------------------+
478 100 | | 10 | | ==>
479 | |10+---------------------------------+
480 | | | | | |
481 | | | | | |
482 | | | | | |
483 +----|--|-------------+ | |
484 | | | |
485 | | | |
486 | | | |500
487 | | | |
488 | | | |
489 | | | |
490 | | | |
491 +--|-------------------------------+ |
493 +---------------------------------+
496 +---------------------+
497 | |30 Visible region of |layer|: /////
499 | +---------------------------------+
500 100| | |10 |
501 | +---------------------------------+ |
502 | | |///////////////| 420 | |
503 | | |///////////////|60 | |
504 | | |///////////////| | |
505 +--|--|---------------+ | |
506 20|10| 70 | |
507 | | | |
508 | | | |
509 | | | |
510 | | | |
511 | | | |
512 | | |10|
513 | +------------------------------|--+
514 | 490 |
515 +---------------------------------+
522 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
524 class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest {
525 protected:
526 explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
527 : OcclusionTrackerTest(opaque_layers) {}
529 void RunMyTest() override {
530 TestContentLayerImpl* parent = this->CreateRoot(
531 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
533 gfx::Transform layer1_matrix;
534 layer1_matrix.Scale(2.0, 2.0);
535 TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
536 parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
537 layer1->SetHasRenderSurface(true);
539 gfx::Transform layer2_matrix;
540 layer2_matrix.Translate(25.0, 25.0);
541 TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
542 layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
543 TestContentLayerImpl* occluder = this->CreateDrawingLayer(
544 parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
545 gfx::Size(500, 500), true);
546 this->CalcDrawEtc(parent);
548 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
550 this->VisitLayer(occluder, &occlusion);
551 this->EnterLayer(layer2, &occlusion);
553 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
554 occlusion.occlusion_from_outside_target().ToString());
555 EXPECT_EQ(gfx::Rect().ToString(),
556 occlusion.occlusion_from_inside_target().ToString());
560 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
562 class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest {
563 protected:
564 explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
565 : OcclusionTrackerTest(opaque_layers) {}
566 void RunMyTest() override {
567 TestContentLayerImpl* root = this->CreateRoot(
568 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
569 LayerImpl* surface = this->CreateSurface(
570 root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size());
571 TestContentLayerImpl* surface_child = this->CreateDrawingLayer(
572 surface, this->identity_matrix, gfx::PointF(10.f, 10.f),
573 gfx::Size(50, 50), true);
574 // |top_layer| makes |root|'s surface get considered by OcclusionTracker
575 // first, instead of |surface|'s. This exercises different code in
576 // LeaveToRenderTarget, as the target surface has already been seen when
577 // leaving |surface| later.
578 TestContentLayerImpl* top_layer = this->CreateDrawingLayer(
579 root, this->identity_matrix, gfx::PointF(40.f, 90.f), gfx::Size(50, 20),
580 true);
581 this->CalcDrawEtc(root);
583 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
585 this->VisitLayer(top_layer, &occlusion);
587 EXPECT_EQ(gfx::Rect().ToString(),
588 occlusion.occlusion_from_outside_target().ToString());
589 EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(),
590 occlusion.occlusion_from_inside_target().ToString());
592 this->VisitLayer(surface_child, &occlusion);
594 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
595 occlusion.occlusion_from_outside_target().ToString());
596 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
597 occlusion.occlusion_from_inside_target().ToString());
599 this->EnterContributingSurface(surface, &occlusion);
601 EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(),
602 occlusion.occlusion_from_outside_target().ToString());
603 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
604 occlusion.occlusion_from_inside_target().ToString());
606 // Occlusion from |top_layer| already in the root target should get merged
607 // with the occlusion from the |surface| we are leaving now.
608 this->LeaveContributingSurface(surface, &occlusion);
609 this->EnterLayer(root, &occlusion);
611 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
612 EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(),
613 occlusion.occlusion_from_inside_target().ToString());
617 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
619 class OcclusionTrackerTestSurfaceRotatedOffAxis : public OcclusionTrackerTest {
620 protected:
621 explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
622 : OcclusionTrackerTest(opaque_layers) {}
623 void RunMyTest() override {
624 gfx::Transform child_transform;
625 child_transform.Translate(250.0, 250.0);
626 child_transform.Rotate(95.0);
627 child_transform.Translate(-250.0, -250.0);
629 gfx::Transform layer_transform;
630 layer_transform.Translate(10.0, 10.0);
632 TestContentLayerImpl* root = this->CreateRoot(
633 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
634 TestContentLayerImpl* parent = this->CreateDrawingLayer(
635 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
636 LayerImpl* child = this->CreateSurface(
637 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
638 TestContentLayerImpl* layer = this->CreateDrawingLayer(
639 child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
640 this->CalcDrawEtc(root);
642 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
644 gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect(
645 layer_transform, layer->visible_layer_rect());
647 this->VisitLayer(layer, &occlusion);
648 this->EnterContributingSurface(child, &occlusion);
650 EXPECT_EQ(gfx::Rect().ToString(),
651 occlusion.occlusion_from_outside_target().ToString());
652 EXPECT_EQ(clipped_layer_in_child.ToString(),
653 occlusion.occlusion_from_inside_target().ToString());
655 this->LeaveContributingSurface(child, &occlusion);
656 this->EnterLayer(parent, &occlusion);
658 EXPECT_EQ(gfx::Rect().ToString(),
659 occlusion.occlusion_from_outside_target().ToString());
660 EXPECT_EQ(gfx::Rect().ToString(),
661 occlusion.occlusion_from_inside_target().ToString());
665 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
667 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
668 : public OcclusionTrackerTest {
669 protected:
670 explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
671 : OcclusionTrackerTest(opaque_layers) {}
672 void RunMyTest() override {
673 gfx::Transform child_transform;
674 child_transform.Translate(250.0, 250.0);
675 child_transform.Rotate(90.0);
676 child_transform.Translate(-250.0, -250.0);
678 TestContentLayerImpl* root = this->CreateRoot(
679 this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
680 TestContentLayerImpl* parent = this->CreateDrawingLayer(
681 root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
682 parent->SetMasksToBounds(true);
683 TestContentLayerImpl* child = this->CreateDrawingSurface(
684 parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
685 false);
686 child->SetMasksToBounds(true);
687 TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
688 child, this->identity_matrix, gfx::PointF(10.f, 10.f),
689 gfx::Size(500, 500), true);
690 TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
691 child, this->identity_matrix, gfx::PointF(10.f, 450.f),
692 gfx::Size(500, 60), true);
693 this->CalcDrawEtc(root);
695 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
697 this->VisitLayer(layer2, &occlusion);
698 this->VisitLayer(layer1, &occlusion);
699 this->VisitLayer(child, &occlusion);
700 this->EnterContributingSurface(child, &occlusion);
702 EXPECT_EQ(gfx::Rect().ToString(),
703 occlusion.occlusion_from_outside_target().ToString());
704 EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
705 occlusion.occlusion_from_inside_target().ToString());
707 this->LeaveContributingSurface(child, &occlusion);
708 this->EnterLayer(parent, &occlusion);
710 EXPECT_EQ(gfx::Rect().ToString(),
711 occlusion.occlusion_from_outside_target().ToString());
712 EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
713 occlusion.occlusion_from_inside_target().ToString());
715 /* Justification for the above occlusion from |layer1| and |layer2|:
717 +---------------------+
718 | |30 Visible region of |layer1|: /////
719 | | Visible region of |layer2|: \\\\\
720 | +---------------------------------+
721 | | |10 |
722 | +---------------+-----------------+ |
723 | | |\\\\\\\\\\\\|//| 420 | |
724 | | |\\\\\\\\\\\\|//|60 | |
725 | | |\\\\\\\\\\\\|//| | |
726 +--|--|------------|--+ | |
727 20|10| 70 | | |
728 | | | | |
729 | | | | |
730 | | | | |
731 | | | | |
732 | | | | |
733 | | | |10|
734 | +------------|-----------------|--+
735 | | 490 |
736 +---------------+-----------------+
737 60 440
742 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
744 class OcclusionTrackerTestOverlappingSurfaceSiblings
745 : public OcclusionTrackerTest {
746 protected:
747 explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
748 : OcclusionTrackerTest(opaque_layers) {}
749 void RunMyTest() override {
750 TestContentLayerImpl* parent = this->CreateRoot(
751 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
752 parent->SetMasksToBounds(true);
753 LayerImpl* child1 = this->CreateSurface(
754 parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size());
755 LayerImpl* child2 = this->CreateSurface(
756 parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size());
757 TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
758 child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true);
759 TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
760 child2, this->identity_matrix, gfx::PointF(10.f, 0.f),
761 gfx::Size(40, 50), true);
762 this->CalcDrawEtc(parent);
764 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
766 this->VisitLayer(layer2, &occlusion);
767 this->EnterContributingSurface(child2, &occlusion);
769 // layer2's occlusion.
770 EXPECT_EQ(gfx::Rect().ToString(),
771 occlusion.occlusion_from_outside_target().ToString());
772 EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(),
773 occlusion.occlusion_from_inside_target().ToString());
775 this->LeaveContributingSurface(child2, &occlusion);
776 this->VisitLayer(layer1, &occlusion);
777 this->EnterContributingSurface(child1, &occlusion);
779 // layer2's occlusion in the target space of layer1.
780 EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(),
781 occlusion.occlusion_from_outside_target().ToString());
782 // layer1's occlusion.
783 EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(),
784 occlusion.occlusion_from_inside_target().ToString());
786 this->LeaveContributingSurface(child1, &occlusion);
787 this->EnterLayer(parent, &occlusion);
789 // The occlusion from from layer1 and layer2 is merged.
790 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
791 EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(),
792 occlusion.occlusion_from_inside_target().ToString());
796 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
798 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
799 : public OcclusionTrackerTest {
800 protected:
801 explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
802 bool opaque_layers)
803 : OcclusionTrackerTest(opaque_layers) {}
804 void RunMyTest() override {
805 gfx::Transform child1_transform;
806 child1_transform.Translate(250.0, 250.0);
807 child1_transform.Rotate(-90.0);
808 child1_transform.Translate(-250.0, -250.0);
810 gfx::Transform child2_transform;
811 child2_transform.Translate(250.0, 250.0);
812 child2_transform.Rotate(90.0);
813 child2_transform.Translate(-250.0, -250.0);
815 TestContentLayerImpl* parent = this->CreateRoot(
816 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
817 parent->SetMasksToBounds(true);
818 LayerImpl* child1 = this->CreateSurface(
819 parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
820 LayerImpl* child2 = this->CreateDrawingSurface(parent, child2_transform,
821 gfx::PointF(20.f, 40.f),
822 gfx::Size(10, 10), false);
823 TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
824 child1, this->identity_matrix, gfx::PointF(-10.f, -20.f),
825 gfx::Size(510, 510), true);
826 TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
827 child2, this->identity_matrix, gfx::PointF(-10.f, -10.f),
828 gfx::Size(510, 510), true);
829 this->CalcDrawEtc(parent);
831 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
833 this->VisitLayer(layer2, &occlusion);
834 this->EnterLayer(child2, &occlusion);
836 EXPECT_EQ(gfx::Rect().ToString(),
837 occlusion.occlusion_from_outside_target().ToString());
838 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
839 occlusion.occlusion_from_inside_target().ToString());
841 this->LeaveLayer(child2, &occlusion);
842 this->EnterContributingSurface(child2, &occlusion);
844 EXPECT_EQ(gfx::Rect().ToString(),
845 occlusion.occlusion_from_outside_target().ToString());
846 EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
847 occlusion.occlusion_from_inside_target().ToString());
849 this->LeaveContributingSurface(child2, &occlusion);
850 this->VisitLayer(layer1, &occlusion);
851 this->EnterContributingSurface(child1, &occlusion);
853 EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
854 occlusion.occlusion_from_outside_target().ToString());
855 EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
856 occlusion.occlusion_from_inside_target().ToString());
858 this->LeaveContributingSurface(child1, &occlusion);
859 this->EnterLayer(parent, &occlusion);
861 EXPECT_EQ(gfx::Rect().ToString(),
862 occlusion.occlusion_from_outside_target().ToString());
863 EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
864 occlusion.occlusion_from_inside_target().ToString());
866 /* Justification for the above occlusion:
868 +---------------------+
869 |20 | layer1
870 10+----------------------------------+
871 100 || 30 | layer2 |
872 |20+----------------------------------+
873 || | | | |
874 || | | | |
875 || | | | |
876 +|-|------------------+ | |
877 | | | | 510
878 | | 510 | |
879 | | | |
880 | | | |
881 | | | |
882 | | | |
883 | | 520 | |
884 +----------------------------------+ |
886 +----------------------------------+
892 ALL_OCCLUSIONTRACKER_TEST(
893 OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
895 class OcclusionTrackerTestFilters : public OcclusionTrackerTest {
896 protected:
897 explicit OcclusionTrackerTestFilters(bool opaque_layers)
898 : OcclusionTrackerTest(opaque_layers) {}
899 void RunMyTest() override {
900 gfx::Transform layer_transform;
901 layer_transform.Translate(250.0, 250.0);
902 layer_transform.Rotate(90.0);
903 layer_transform.Translate(-250.0, -250.0);
905 TestContentLayerImpl* parent = this->CreateRoot(
906 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
907 parent->SetMasksToBounds(true);
908 TestContentLayerImpl* blur_layer = this->CreateDrawingLayer(
909 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
910 true);
911 TestContentLayerImpl* opaque_layer = this->CreateDrawingLayer(
912 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
913 true);
914 TestContentLayerImpl* opacity_layer = this->CreateDrawingLayer(
915 parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
916 true);
918 blur_layer->SetHasRenderSurface(true);
919 FilterOperations filters;
920 filters.Append(FilterOperation::CreateBlurFilter(10.f));
921 blur_layer->SetFilters(filters);
923 opaque_layer->SetHasRenderSurface(true);
924 filters.Clear();
925 filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
926 opaque_layer->SetFilters(filters);
928 opacity_layer->SetHasRenderSurface(true);
929 filters.Clear();
930 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
931 opacity_layer->SetFilters(filters);
933 this->CalcDrawEtc(parent);
935 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
937 // Opacity layer won't contribute to occlusion.
938 this->VisitLayer(opacity_layer, &occlusion);
939 this->EnterContributingSurface(opacity_layer, &occlusion);
941 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
942 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
944 // And has nothing to contribute to its parent surface.
945 this->LeaveContributingSurface(opacity_layer, &occlusion);
946 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
947 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
949 // Opaque layer will contribute to occlusion.
950 this->VisitLayer(opaque_layer, &occlusion);
951 this->EnterContributingSurface(opaque_layer, &occlusion);
953 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
954 EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
955 occlusion.occlusion_from_inside_target().ToString());
957 // And it gets translated to the parent surface.
958 this->LeaveContributingSurface(opaque_layer, &occlusion);
959 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
960 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
961 occlusion.occlusion_from_inside_target().ToString());
963 // The blur layer needs to throw away any occlusion from outside its
964 // subtree.
965 this->EnterLayer(blur_layer, &occlusion);
966 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
967 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
969 // And it won't contribute to occlusion.
970 this->LeaveLayer(blur_layer, &occlusion);
971 this->EnterContributingSurface(blur_layer, &occlusion);
972 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
973 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
975 // But the opaque layer's occlusion is preserved on the parent.
976 this->LeaveContributingSurface(blur_layer, &occlusion);
977 this->EnterLayer(parent, &occlusion);
978 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
979 EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
980 occlusion.occlusion_from_inside_target().ToString());
984 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
986 class OcclusionTrackerTestReplicaDoesOcclude : public OcclusionTrackerTest {
987 protected:
988 explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
989 : OcclusionTrackerTest(opaque_layers) {}
990 void RunMyTest() override {
991 TestContentLayerImpl* parent = this->CreateRoot(
992 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
993 LayerImpl* surface = this->CreateDrawingSurface(
994 parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
995 this->CreateReplicaLayer(
996 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
997 this->CalcDrawEtc(parent);
999 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1001 this->VisitLayer(surface, &occlusion);
1003 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1004 occlusion.occlusion_from_inside_target().ToString());
1006 this->VisitContributingSurface(surface, &occlusion);
1007 this->EnterLayer(parent, &occlusion);
1009 // The surface and replica should both be occluding the parent.
1010 EXPECT_EQ(gfx::Rect(50, 100).ToString(),
1011 occlusion.occlusion_from_inside_target().ToString());
1015 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1017 class OcclusionTrackerTestReplicaWithClipping : public OcclusionTrackerTest {
1018 protected:
1019 explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1020 : OcclusionTrackerTest(opaque_layers) {}
1021 void RunMyTest() override {
1022 TestContentLayerImpl* parent = this->CreateRoot(
1023 this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1024 parent->SetMasksToBounds(true);
1025 LayerImpl* surface = this->CreateDrawingSurface(
1026 parent, this->identity_matrix, gfx::PointF(0.f, 100.f),
1027 gfx::Size(50, 50), true);
1028 this->CreateReplicaLayer(
1029 surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
1030 this->CalcDrawEtc(parent);
1032 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1034 this->VisitLayer(surface, &occlusion);
1036 // The surface layer's occlusion in its own space.
1037 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1038 occlusion.occlusion_from_inside_target().ToString());
1039 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1041 this->VisitContributingSurface(surface, &occlusion);
1042 this->EnterLayer(parent, &occlusion);
1044 // The surface and replica should both be occluding the parent, the
1045 // replica's occlusion is clipped by the parent.
1046 EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(),
1047 occlusion.occlusion_from_inside_target().ToString());
1048 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1052 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1054 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest {
1055 protected:
1056 explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1057 : OcclusionTrackerTest(opaque_layers) {}
1058 void RunMyTest() override {
1059 TestContentLayerImpl* parent = this->CreateRoot(
1060 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1061 LayerImpl* surface = this->CreateDrawingSurface(
1062 parent, this->identity_matrix, gfx::PointF(0.f, 100.f),
1063 gfx::Size(50, 50), true);
1064 LayerImpl* replica = this->CreateReplicaLayer(
1065 surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1066 this->CreateMaskLayer(replica, gfx::Size(10, 10));
1067 this->CalcDrawEtc(parent);
1069 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1071 this->VisitLayer(surface, &occlusion);
1073 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1074 occlusion.occlusion_from_inside_target().ToString());
1076 this->VisitContributingSurface(surface, &occlusion);
1077 this->EnterLayer(parent, &occlusion);
1079 // The replica should not be occluding the parent, since it has a mask
1080 // applied to it.
1081 EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1082 occlusion.occlusion_from_inside_target().ToString());
1086 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1088 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1089 : public OcclusionTrackerTest {
1090 protected:
1091 explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1092 : OcclusionTrackerTest(opaque_layers) {}
1093 void RunMyTest() override {
1094 TestContentLayerImpl* parent = this->CreateRoot(
1095 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1096 TestContentLayerImpl* layer =
1097 this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
1098 gfx::Size(200, 200), false);
1099 this->CalcDrawEtc(parent);
1101 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1102 this->EnterLayer(layer, &occlusion);
1104 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1105 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1107 this->LeaveLayer(layer, &occlusion);
1108 this->VisitContributingSurface(layer, &occlusion);
1109 this->EnterLayer(parent, &occlusion);
1111 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1112 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1116 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1118 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1119 : public OcclusionTrackerTest {
1120 protected:
1121 explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1122 : OcclusionTrackerTest(opaque_layers) {}
1123 void RunMyTest() override {
1124 TestContentLayerImpl* parent = this->CreateRoot(
1125 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1126 TestContentLayerImpl* layer = this->CreateDrawingLayer(
1127 parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
1128 gfx::Size(200, 200), false);
1129 this->CalcDrawEtc(parent);
1131 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1132 layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1134 this->ResetLayerIterator();
1135 this->VisitLayer(layer, &occlusion);
1136 this->EnterLayer(parent, &occlusion);
1138 EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1139 occlusion.occlusion_from_inside_target().ToString());
1142 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1143 layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1145 this->ResetLayerIterator();
1146 this->VisitLayer(layer, &occlusion);
1147 this->EnterLayer(parent, &occlusion);
1149 EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1150 occlusion.occlusion_from_inside_target().ToString());
1153 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1154 layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1156 this->ResetLayerIterator();
1157 this->VisitLayer(layer, &occlusion);
1158 this->EnterLayer(parent, &occlusion);
1160 EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1161 occlusion.occlusion_from_inside_target().ToString());
1166 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1168 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
1169 : public OcclusionTrackerTest {
1170 protected:
1171 explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
1172 bool opaque_layers)
1173 : OcclusionTrackerTest(opaque_layers) {}
1174 void RunMyTest() override {
1175 gfx::Transform transform;
1176 transform.Translate(50.0, 50.0);
1177 transform.ApplyPerspectiveDepth(100.0);
1178 transform.Translate3d(0.0, 0.0, 110.0);
1179 transform.Translate(-50.0, -50.0);
1181 TestContentLayerImpl* parent = this->CreateRoot(
1182 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1183 TestContentLayerImpl* layer = this->CreateDrawingLayer(
1184 parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
1185 parent->SetShouldFlattenTransform(false);
1186 parent->Set3dSortingContextId(1);
1187 layer->SetShouldFlattenTransform(false);
1188 layer->Set3dSortingContextId(1);
1189 this->CalcDrawEtc(parent);
1191 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1193 // The |layer| is entirely behind the camera and should not occlude.
1194 this->VisitLayer(layer, &occlusion);
1195 this->EnterLayer(parent, &occlusion);
1196 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1197 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1201 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
1202 : public OcclusionTrackerTest {
1203 protected:
1204 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
1205 bool opaque_layers)
1206 : OcclusionTrackerTest(opaque_layers) {}
1207 void RunMyTest() override {
1208 gfx::Transform surface_transform;
1209 surface_transform.Translate(300.0, 300.0);
1210 surface_transform.Scale(2.0, 2.0);
1211 surface_transform.Translate(-150.0, -150.0);
1213 TestContentLayerImpl* parent = this->CreateRoot(
1214 this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
1215 TestContentLayerImpl* surface = this->CreateDrawingSurface(
1216 parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
1217 TestContentLayerImpl* surface2 = this->CreateDrawingSurface(
1218 parent, this->identity_matrix, gfx::PointF(50.f, 50.f),
1219 gfx::Size(300, 300), false);
1220 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1221 surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
1222 this->CalcDrawEtc(parent);
1224 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1226 this->VisitLayer(surface2, &occlusion);
1227 this->VisitContributingSurface(surface2, &occlusion);
1229 EXPECT_EQ(gfx::Rect().ToString(),
1230 occlusion.occlusion_from_outside_target().ToString());
1231 EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
1232 occlusion.occlusion_from_inside_target().ToString());
1234 // Clear any stored occlusion.
1235 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
1236 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1238 this->VisitLayer(surface, &occlusion);
1239 this->VisitContributingSurface(surface, &occlusion);
1241 EXPECT_EQ(gfx::Rect().ToString(),
1242 occlusion.occlusion_from_outside_target().ToString());
1243 EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
1244 occlusion.occlusion_from_inside_target().ToString());
1248 ALL_OCCLUSIONTRACKER_TEST(
1249 OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
1251 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
1252 : public OcclusionTrackerTest {
1253 protected:
1254 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
1255 bool opaque_layers)
1256 : OcclusionTrackerTest(opaque_layers) {}
1257 void RunMyTest() override {
1258 TestContentLayerImpl* parent = this->CreateRoot(
1259 this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1260 parent->SetMasksToBounds(true);
1261 TestContentLayerImpl* surface =
1262 this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
1263 gfx::Size(500, 300), false);
1264 surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
1265 this->CalcDrawEtc(parent);
1267 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1269 this->VisitLayer(surface, &occlusion);
1270 this->VisitContributingSurface(surface, &occlusion);
1272 EXPECT_EQ(gfx::Rect().ToString(),
1273 occlusion.occlusion_from_outside_target().ToString());
1274 EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
1275 occlusion.occlusion_from_inside_target().ToString());
1279 ALL_OCCLUSIONTRACKER_TEST(
1280 OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
1282 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
1283 : public OcclusionTrackerTest {
1284 protected:
1285 explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
1286 : OcclusionTrackerTest(opaque_layers) {}
1287 void RunMyTest() override {
1288 TestContentLayerImpl* parent = this->CreateRoot(
1289 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1290 LayerImpl* surface =
1291 this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
1292 gfx::Size(100, 100), true);
1293 this->CreateReplicaLayer(surface,
1294 this->identity_matrix,
1295 gfx::PointF(0.f, 100.f),
1296 gfx::Size(100, 100));
1297 LayerImpl* topmost =
1298 this->CreateDrawingLayer(parent, this->identity_matrix, gfx::PointF(),
1299 gfx::Size(100, 110), true);
1300 this->CalcDrawEtc(parent);
1302 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1304 // |topmost| occludes the surface, but not the entire surface's replica.
1305 this->VisitLayer(topmost, &occlusion);
1307 EXPECT_EQ(gfx::Rect().ToString(),
1308 occlusion.occlusion_from_outside_target().ToString());
1309 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
1310 occlusion.occlusion_from_inside_target().ToString());
1312 this->VisitLayer(surface, &occlusion);
1314 // Render target with replica ignores occlusion from outside.
1315 EXPECT_EQ(gfx::Rect().ToString(),
1316 occlusion.occlusion_from_outside_target().ToString());
1317 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
1318 occlusion.occlusion_from_inside_target().ToString());
1320 this->EnterContributingSurface(surface, &occlusion);
1322 // Only occlusion from outside the surface occludes the surface/replica.
1323 EXPECT_EQ(gfx::Rect().ToString(),
1324 occlusion.occlusion_on_contributing_surface_from_outside_target()
1325 .ToString());
1326 EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
1327 occlusion.occlusion_on_contributing_surface_from_inside_target()
1328 .ToString());
1332 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
1334 class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest {
1335 protected:
1336 explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
1337 : OcclusionTrackerTest(opaque_layers) {}
1338 void RunMyTest() override {
1339 // This test verifies that the surface cliprect does not end up empty and
1340 // clip away the entire unoccluded rect.
1342 TestContentLayerImpl* parent = this->CreateRoot(
1343 this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1344 LayerImpl* surface =
1345 this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
1346 gfx::Size(100, 100), false);
1347 LayerImpl* surface_child = this->CreateDrawingSurface(
1348 surface, this->identity_matrix, gfx::PointF(0.f, 10.f),
1349 gfx::Size(100, 50), true);
1350 LayerImpl* topmost = this->CreateDrawingLayer(
1351 parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
1352 this->CalcDrawEtc(parent);
1354 TestOcclusionTrackerWithClip occlusion(gfx::Rect(-100, -100, 1000, 1000));
1356 // |topmost| occludes everything partially so we know occlusion is happening
1357 // at all.
1358 this->VisitLayer(topmost, &occlusion);
1360 EXPECT_EQ(gfx::Rect().ToString(),
1361 occlusion.occlusion_from_outside_target().ToString());
1362 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1363 occlusion.occlusion_from_inside_target().ToString());
1365 this->VisitLayer(surface_child, &occlusion);
1367 // surface_child increases the occlusion in the screen by a narrow sliver.
1368 EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
1369 occlusion.occlusion_from_outside_target().ToString());
1370 // In its own surface, surface_child is at 0,0 as is its occlusion.
1371 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1372 occlusion.occlusion_from_inside_target().ToString());
1374 // The root layer always has a clip rect. So the parent of |surface| has a
1375 // clip rect. However, the owning layer for |surface| does not mask to
1376 // bounds, so it doesn't have a clip rect of its own. Thus the parent of
1377 // |surface_child| exercises different code paths as its parent does not
1378 // have a clip rect.
1380 this->EnterContributingSurface(surface_child, &occlusion);
1381 // The |surface_child| can't occlude its own surface, but occlusion from
1382 // |topmost| can.
1383 EXPECT_EQ(gfx::Rect().ToString(),
1384 occlusion.occlusion_on_contributing_surface_from_outside_target()
1385 .ToString());
1386 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1387 occlusion.occlusion_on_contributing_surface_from_inside_target()
1388 .ToString());
1389 this->LeaveContributingSurface(surface_child, &occlusion);
1391 // When the surface_child's occlusion is transformed up to its parent, make
1392 // sure it is not clipped away inappropriately.
1393 this->EnterLayer(surface, &occlusion);
1394 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1395 occlusion.occlusion_from_outside_target().ToString());
1396 EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
1397 occlusion.occlusion_from_inside_target().ToString());
1398 this->LeaveLayer(surface, &occlusion);
1400 this->EnterContributingSurface(surface, &occlusion);
1401 // The occlusion from inside |surface| can't affect the surface, but
1402 // |topmost| can.
1403 EXPECT_EQ(gfx::Rect().ToString(),
1404 occlusion.occlusion_on_contributing_surface_from_outside_target()
1405 .ToString());
1406 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
1407 occlusion.occlusion_on_contributing_surface_from_inside_target()
1408 .ToString());
1410 this->LeaveContributingSurface(surface, &occlusion);
1411 this->EnterLayer(parent, &occlusion);
1412 // The occlusion in |surface| and without are merged into the parent.
1413 EXPECT_EQ(gfx::Rect().ToString(),
1414 occlusion.occlusion_from_outside_target().ToString());
1415 EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(),
1416 occlusion.occlusion_from_inside_target().ToString());
1420 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
1422 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
1423 : public OcclusionTrackerTest {
1424 protected:
1425 explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
1426 bool opaque_layers)
1427 : OcclusionTrackerTest(opaque_layers) {}
1428 void RunMyTest() override {
1429 gfx::Transform scale_by_half;
1430 scale_by_half.Scale(0.5, 0.5);
1432 FilterOperations filters;
1433 filters.Append(FilterOperation::CreateBlurFilter(10.f));
1435 // Save the distance of influence for the blur effect.
1436 int outset_top, outset_right, outset_bottom, outset_left;
1437 filters.GetOutsets(
1438 &outset_top, &outset_right, &outset_bottom, &outset_left);
1440 enum Direction {
1441 LEFT,
1442 RIGHT,
1443 TOP,
1444 BOTTOM,
1445 LAST_DIRECTION = BOTTOM,
1448 for (int i = 0; i <= LAST_DIRECTION; ++i) {
1449 SCOPED_TRACE(i);
1451 // Make a 50x50 filtered surface that is adjacent to occluding layers
1452 // which are above it in the z-order in various configurations. The
1453 // surface is scaled to test that the pixel moving is done in the target
1454 // space, where the background filter is applied.
1455 TestContentLayerImpl* parent = this->CreateRoot(
1456 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
1457 LayerImpl* filtered_surface = this->CreateDrawingLayer(
1458 parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100),
1459 false);
1460 filtered_surface->SetHasRenderSurface(true);
1461 filtered_surface->SetBackgroundFilters(filters);
1462 gfx::Rect occlusion_rect;
1463 switch (i) {
1464 case LEFT:
1465 occlusion_rect = gfx::Rect(0, 0, 50, 200);
1466 break;
1467 case RIGHT:
1468 occlusion_rect = gfx::Rect(100, 0, 50, 200);
1469 break;
1470 case TOP:
1471 occlusion_rect = gfx::Rect(0, 0, 200, 50);
1472 break;
1473 case BOTTOM:
1474 occlusion_rect = gfx::Rect(0, 100, 200, 50);
1475 break;
1478 LayerImpl* occluding_layer = this->CreateDrawingLayer(
1479 parent, this->identity_matrix, occlusion_rect.origin(),
1480 occlusion_rect.size(), true);
1481 this->CalcDrawEtc(parent);
1483 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
1485 // This layer occludes pixels directly beside the filtered_surface.
1486 // Because filtered surface blends pixels in a radius, it will need to see
1487 // some of the pixels (up to radius far) underneath the occluding layers.
1488 this->VisitLayer(occluding_layer, &occlusion);
1490 EXPECT_EQ(occlusion_rect.ToString(),
1491 occlusion.occlusion_from_inside_target().ToString());
1492 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1494 this->VisitLayer(filtered_surface, &occlusion);
1496 // The occlusion is used fully inside the surface.
1497 gfx::Rect occlusion_inside_surface =
1498 occlusion_rect - gfx::Vector2d(50, 50);
1499 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1500 EXPECT_EQ(occlusion_inside_surface.ToString(),
1501 occlusion.occlusion_from_outside_target().ToString());
1503 // The surface has a background blur, so it needs pixels that are
1504 // currently considered occluded in order to be drawn. So the pixels it
1505 // needs should be removed some the occluded area so that when we get to
1506 // the parent they are drawn.
1507 this->VisitContributingSurface(filtered_surface, &occlusion);
1508 this->EnterLayer(parent, &occlusion);
1510 gfx::Rect expected_occlusion = occlusion_rect;
1511 switch (i) {
1512 case LEFT:
1513 expected_occlusion.Inset(0, 0, outset_right, 0);
1514 break;
1515 case RIGHT:
1516 expected_occlusion.Inset(outset_right, 0, 0, 0);
1517 break;
1518 case TOP:
1519 expected_occlusion.Inset(0, 0, 0, outset_right);
1520 break;
1521 case BOTTOM:
1522 expected_occlusion.Inset(0, outset_right, 0, 0);
1523 break;
1526 EXPECT_EQ(expected_occlusion.ToString(),
1527 occlusion.occlusion_from_inside_target().ToString());
1528 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1530 this->DestroyLayers();
1535 ALL_OCCLUSIONTRACKER_TEST(
1536 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
1538 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
1539 : public OcclusionTrackerTest {
1540 protected:
1541 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
1542 bool opaque_layers)
1543 : OcclusionTrackerTest(opaque_layers) {}
1544 void RunMyTest() override {
1545 gfx::Transform scale_by_half;
1546 scale_by_half.Scale(0.5, 0.5);
1548 // Makes two surfaces that completely cover |parent|. The occlusion both
1549 // above and below the filters will be reduced by each of them.
1550 TestContentLayerImpl* root = this->CreateRoot(
1551 this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
1552 LayerImpl* parent = this->CreateSurface(root, scale_by_half, gfx::PointF(),
1553 gfx::Size(150, 150));
1554 parent->SetMasksToBounds(true);
1555 LayerImpl* filtered_surface1 = this->CreateDrawingLayer(
1556 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
1557 LayerImpl* filtered_surface2 = this->CreateDrawingLayer(
1558 parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
1559 LayerImpl* occluding_layer_above = this->CreateDrawingLayer(
1560 parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
1561 gfx::Size(50, 50), true);
1563 // Filters make the layers own surfaces.
1564 filtered_surface1->SetHasRenderSurface(true);
1565 filtered_surface2->SetHasRenderSurface(true);
1566 FilterOperations filters;
1567 filters.Append(FilterOperation::CreateBlurFilter(1.f));
1568 filtered_surface1->SetBackgroundFilters(filters);
1569 filtered_surface2->SetBackgroundFilters(filters);
1571 // Save the distance of influence for the blur effect.
1572 int outset_top, outset_right, outset_bottom, outset_left;
1573 filters.GetOutsets(
1574 &outset_top, &outset_right, &outset_bottom, &outset_left);
1576 this->CalcDrawEtc(root);
1578 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1580 this->VisitLayer(occluding_layer_above, &occlusion);
1581 EXPECT_EQ(gfx::Rect().ToString(),
1582 occlusion.occlusion_from_outside_target().ToString());
1583 EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
1584 occlusion.occlusion_from_inside_target().ToString());
1586 this->VisitLayer(filtered_surface2, &occlusion);
1587 this->VisitContributingSurface(filtered_surface2, &occlusion);
1588 this->VisitLayer(filtered_surface1, &occlusion);
1589 this->VisitContributingSurface(filtered_surface1, &occlusion);
1591 // Test expectations in the target.
1592 gfx::Rect expected_occlusion =
1593 gfx::Rect(100 / 2 + outset_right * 2,
1594 100 / 2 + outset_bottom * 2,
1595 50 / 2 - (outset_left + outset_right) * 2,
1596 50 / 2 - (outset_top + outset_bottom) * 2);
1597 EXPECT_EQ(expected_occlusion.ToString(),
1598 occlusion.occlusion_from_inside_target().ToString());
1600 // Test expectations in the screen are the same as in the target, as the
1601 // render surface is 1:1 with the screen.
1602 EXPECT_EQ(expected_occlusion.ToString(),
1603 occlusion.occlusion_from_outside_target().ToString());
1607 ALL_OCCLUSIONTRACKER_TEST(
1608 OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
1610 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
1611 : public OcclusionTrackerTest {
1612 protected:
1613 explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
1614 bool opaque_layers)
1615 : OcclusionTrackerTest(opaque_layers) {}
1616 void RunMyTest() override {
1617 gfx::Transform scale_by_half;
1618 scale_by_half.Scale(0.5, 0.5);
1620 // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
1621 // centered below each. The surface is scaled to test that the pixel moving
1622 // is done in the target space, where the background filter is applied, but
1623 // the surface appears at 50, 50 and the replica at 200, 50.
1624 TestContentLayerImpl* parent = this->CreateRoot(
1625 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
1626 LayerImpl* behind_surface_layer = this->CreateDrawingLayer(
1627 parent, this->identity_matrix, gfx::PointF(60.f, 60.f),
1628 gfx::Size(30, 30), true);
1629 LayerImpl* behind_replica_layer = this->CreateDrawingLayer(
1630 parent, this->identity_matrix, gfx::PointF(210.f, 60.f),
1631 gfx::Size(30, 30), true);
1632 LayerImpl* filtered_surface =
1633 this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
1634 gfx::Size(100, 100), false);
1635 this->CreateReplicaLayer(filtered_surface,
1636 this->identity_matrix,
1637 gfx::PointF(300.f, 0.f),
1638 gfx::Size());
1640 // Filters make the layer own a surface.
1641 filtered_surface->SetHasRenderSurface(true);
1642 FilterOperations filters;
1643 filters.Append(FilterOperation::CreateBlurFilter(3.f));
1644 filtered_surface->SetBackgroundFilters(filters);
1646 this->CalcDrawEtc(parent);
1648 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1650 // The surface has a background blur, so it blurs non-opaque pixels below
1651 // it.
1652 this->VisitLayer(filtered_surface, &occlusion);
1653 this->VisitContributingSurface(filtered_surface, &occlusion);
1655 this->VisitLayer(behind_replica_layer, &occlusion);
1657 // The layers behind the surface are not blurred, and their occlusion does
1658 // not change, until we leave the surface. So it should not be modified by
1659 // the filter here.
1660 gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
1661 EXPECT_EQ(occlusion_behind_replica.ToString(),
1662 occlusion.occlusion_from_inside_target().ToString());
1663 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1665 // Clear the occlusion so the |behind_surface_layer| can add its occlusion
1666 // without existing occlusion interfering.
1667 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
1669 this->VisitLayer(behind_surface_layer, &occlusion);
1671 // The layers behind the surface are not blurred, and their occlusion does
1672 // not change, until we leave the surface. So it should not be modified by
1673 // the filter here.
1674 gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
1675 EXPECT_EQ(occlusion_behind_surface.ToString(),
1676 occlusion.occlusion_from_inside_target().ToString());
1677 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1681 ALL_OCCLUSIONTRACKER_TEST(
1682 OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
1684 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
1685 : public OcclusionTrackerTest {
1686 protected:
1687 explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
1688 bool opaque_layers)
1689 : OcclusionTrackerTest(opaque_layers) {}
1690 void RunMyTest() override {
1691 gfx::Transform scale_by_half;
1692 scale_by_half.Scale(0.5, 0.5);
1694 // Make a 50x50 filtered surface that is completely occluded by an opaque
1695 // layer which is above it in the z-order. The surface is
1696 // scaled to test that the pixel moving is done in the target space, where
1697 // the background filter is applied, but the surface appears at 50, 50.
1698 TestContentLayerImpl* parent = this->CreateRoot(
1699 this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
1700 LayerImpl* filtered_surface =
1701 this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
1702 gfx::Size(100, 100), false);
1703 LayerImpl* occluding_layer = this->CreateDrawingLayer(
1704 parent, this->identity_matrix, gfx::PointF(50.f, 50.f),
1705 gfx::Size(50, 50), true);
1707 // Filters make the layer own a surface.
1708 filtered_surface->SetHasRenderSurface(true);
1709 FilterOperations filters;
1710 filters.Append(FilterOperation::CreateBlurFilter(3.f));
1711 filtered_surface->SetBackgroundFilters(filters);
1713 this->CalcDrawEtc(parent);
1715 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1717 this->VisitLayer(occluding_layer, &occlusion);
1719 this->VisitLayer(filtered_surface, &occlusion);
1721 // The layers above the filtered surface occlude from outside.
1722 gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
1724 EXPECT_EQ(gfx::Rect().ToString(),
1725 occlusion.occlusion_from_inside_target().ToString());
1726 EXPECT_EQ(occlusion_above_surface.ToString(),
1727 occlusion.occlusion_from_outside_target().ToString());
1730 // The surface has a background blur, so it blurs non-opaque pixels below
1731 // it.
1732 this->VisitContributingSurface(filtered_surface, &occlusion);
1734 // The filter is completely occluded, so it should not blur anything and
1735 // reduce any occlusion.
1736 gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
1738 EXPECT_EQ(occlusion_above_surface.ToString(),
1739 occlusion.occlusion_from_inside_target().ToString());
1740 EXPECT_EQ(gfx::Rect().ToString(),
1741 occlusion.occlusion_from_outside_target().ToString());
1746 ALL_OCCLUSIONTRACKER_TEST(
1747 OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
1749 class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
1750 : public OcclusionTrackerTest {
1751 protected:
1752 explicit OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded(
1753 bool opaque_layers)
1754 : OcclusionTrackerTest(opaque_layers) {}
1755 void RunMyTest() override {
1756 gfx::Transform scale_by_half;
1757 scale_by_half.Scale(0.5, 0.5);
1759 // Make a surface and its replica, each 50x50, that are partially occluded
1760 // by opaque layers which are above them in the z-order. The surface is
1761 // scaled to test that the pixel moving is done in the target space, where
1762 // the background filter is applied, but the surface appears at 50, 50 and
1763 // the replica at 200, 50.
1764 TestContentLayerImpl* parent = this->CreateRoot(
1765 this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
1766 LayerImpl* filtered_surface =
1767 this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
1768 gfx::Size(100, 100), false);
1769 this->CreateReplicaLayer(filtered_surface,
1770 this->identity_matrix,
1771 gfx::PointF(300.f, 0.f),
1772 gfx::Size());
1773 LayerImpl* above_surface_layer = this->CreateDrawingLayer(
1774 parent, this->identity_matrix, gfx::PointF(70.f, 50.f),
1775 gfx::Size(30, 50), true);
1776 LayerImpl* above_replica_layer = this->CreateDrawingLayer(
1777 parent, this->identity_matrix, gfx::PointF(200.f, 50.f),
1778 gfx::Size(30, 50), true);
1779 LayerImpl* beside_surface_layer = this->CreateDrawingLayer(
1780 parent, this->identity_matrix, gfx::PointF(90.f, 40.f),
1781 gfx::Size(10, 10), true);
1782 LayerImpl* beside_replica_layer = this->CreateDrawingLayer(
1783 parent, this->identity_matrix, gfx::PointF(200.f, 40.f),
1784 gfx::Size(10, 10), true);
1786 // Filters make the layer own a surface.
1787 filtered_surface->SetHasRenderSurface(true);
1788 FilterOperations filters;
1789 filters.Append(FilterOperation::CreateBlurFilter(3.f));
1790 filtered_surface->SetBackgroundFilters(filters);
1792 // Save the distance of influence for the blur effect.
1793 int outset_top, outset_right, outset_bottom, outset_left;
1794 filters.GetOutsets(
1795 &outset_top, &outset_right, &outset_bottom, &outset_left);
1797 this->CalcDrawEtc(parent);
1799 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1801 this->VisitLayer(beside_replica_layer, &occlusion);
1802 this->VisitLayer(beside_surface_layer, &occlusion);
1803 this->VisitLayer(above_replica_layer, &occlusion);
1804 this->VisitLayer(above_surface_layer, &occlusion);
1806 // The surface has a background blur, so it blurs non-opaque pixels below
1807 // it.
1808 this->VisitLayer(filtered_surface, &occlusion);
1809 this->VisitContributingSurface(filtered_surface, &occlusion);
1811 // The filter in the surface and replica are partially unoccluded. Only the
1812 // unoccluded parts should reduce occlusion. This means it will push back
1813 // the occlusion that touches the unoccluded part (occlusion_above___), but
1814 // it will not touch occlusion_beside____ since that is not beside the
1815 // unoccluded part of the surface, even though it is beside the occluded
1816 // part of the surface.
1817 gfx::Rect occlusion_above_surface =
1818 gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
1819 gfx::Rect occlusion_above_replica =
1820 gfx::Rect(200, 50, 30 - outset_left, 50);
1821 gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
1822 gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
1824 SimpleEnclosedRegion expected_occlusion;
1825 expected_occlusion.Union(occlusion_beside_replica);
1826 expected_occlusion.Union(occlusion_beside_surface);
1827 expected_occlusion.Union(occlusion_above_replica);
1828 expected_occlusion.Union(occlusion_above_surface);
1830 EXPECT_EQ(expected_occlusion.ToString(),
1831 occlusion.occlusion_from_inside_target().ToString());
1832 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1834 const SimpleEnclosedRegion& actual_occlusion =
1835 occlusion.occlusion_from_inside_target();
1836 for (size_t i = 0; i < expected_occlusion.GetRegionComplexity(); ++i) {
1837 ASSERT_LT(i, actual_occlusion.GetRegionComplexity());
1838 EXPECT_EQ(expected_occlusion.GetRect(i), actual_occlusion.GetRect(i));
1843 ALL_OCCLUSIONTRACKER_TEST(
1844 OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded);
1846 class OcclusionTrackerTestBlendModeDoesNotOcclude
1847 : public OcclusionTrackerTest {
1848 protected:
1849 explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers)
1850 : OcclusionTrackerTest(opaque_layers) {}
1851 void RunMyTest() override {
1852 TestContentLayerImpl* parent = this->CreateRoot(
1853 this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1854 LayerImpl* blend_mode_layer = this->CreateDrawingLayer(
1855 parent, this->identity_matrix, gfx::PointF(0.f, 0.f),
1856 gfx::Size(100, 100), true);
1857 LayerImpl* top_layer = this->CreateDrawingLayer(
1858 parent, this->identity_matrix, gfx::PointF(10.f, 12.f),
1859 gfx::Size(20, 22), true);
1861 // Blend mode makes the layer own a surface.
1862 blend_mode_layer->SetHasRenderSurface(true);
1863 blend_mode_layer->SetBlendMode(SkXfermode::kMultiply_Mode);
1865 this->CalcDrawEtc(parent);
1867 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1869 this->VisitLayer(top_layer, &occlusion);
1870 // |top_layer| occludes.
1871 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1872 occlusion.occlusion_from_inside_target().ToString());
1873 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1875 this->VisitLayer(blend_mode_layer, &occlusion);
1876 // |top_layer| occludes but not |blend_mode_layer|.
1877 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1878 occlusion.occlusion_from_outside_target().ToString());
1879 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1881 this->VisitContributingSurface(blend_mode_layer, &occlusion);
1882 // |top_layer| occludes but not |blend_mode_layer|.
1883 EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(),
1884 occlusion.occlusion_from_inside_target().ToString());
1885 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1889 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude);
1891 class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest {
1892 protected:
1893 explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
1894 : OcclusionTrackerTest(opaque_layers) {}
1895 void RunMyTest() override {
1896 gfx::Size tracking_size(100, 100);
1897 gfx::Size below_tracking_size(99, 99);
1899 TestContentLayerImpl* parent = this->CreateRoot(
1900 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
1901 LayerImpl* large = this->CreateDrawingLayer(
1902 parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
1903 LayerImpl* small =
1904 this->CreateDrawingLayer(parent, this->identity_matrix, gfx::PointF(),
1905 below_tracking_size, true);
1906 this->CalcDrawEtc(parent);
1908 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1909 occlusion.set_minimum_tracking_size(tracking_size);
1911 // The small layer is not tracked because it is too small.
1912 this->VisitLayer(small, &occlusion);
1914 EXPECT_EQ(gfx::Rect().ToString(),
1915 occlusion.occlusion_from_outside_target().ToString());
1916 EXPECT_EQ(gfx::Rect().ToString(),
1917 occlusion.occlusion_from_inside_target().ToString());
1919 // The large layer is tracked as it is large enough.
1920 this->VisitLayer(large, &occlusion);
1922 EXPECT_EQ(gfx::Rect().ToString(),
1923 occlusion.occlusion_from_outside_target().ToString());
1924 EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
1925 occlusion.occlusion_from_inside_target().ToString());
1929 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
1931 class OcclusionTrackerTestScaledLayerIsClipped : public OcclusionTrackerTest {
1932 protected:
1933 explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
1934 : OcclusionTrackerTest(opaque_layers) {}
1935 void RunMyTest() override {
1936 gfx::Transform scale_transform;
1937 scale_transform.Scale(512.0, 512.0);
1939 TestContentLayerImpl* parent = this->CreateRoot(
1940 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
1941 LayerImpl* clip =
1942 this->CreateLayer(parent, this->identity_matrix,
1943 gfx::PointF(10.f, 10.f), gfx::Size(50, 50));
1944 clip->SetMasksToBounds(true);
1945 LayerImpl* scale = this->CreateLayer(clip, scale_transform, gfx::PointF(),
1946 gfx::Size(1, 1));
1947 LayerImpl* scaled = this->CreateDrawingLayer(
1948 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
1949 this->CalcDrawEtc(parent);
1951 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1953 this->VisitLayer(scaled, &occlusion);
1955 EXPECT_EQ(gfx::Rect().ToString(),
1956 occlusion.occlusion_from_outside_target().ToString());
1957 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
1958 occlusion.occlusion_from_inside_target().ToString());
1962 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
1964 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
1965 : public OcclusionTrackerTest {
1966 protected:
1967 explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
1968 : OcclusionTrackerTest(opaque_layers) {}
1969 void RunMyTest() override {
1970 gfx::Transform scale_transform;
1971 scale_transform.Scale(512.0, 512.0);
1973 TestContentLayerImpl* parent = this->CreateRoot(
1974 this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
1975 LayerImpl* clip =
1976 this->CreateLayer(parent, this->identity_matrix,
1977 gfx::PointF(10.f, 10.f), gfx::Size(50, 50));
1978 clip->SetMasksToBounds(true);
1979 LayerImpl* surface = this->CreateDrawingSurface(
1980 clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
1981 LayerImpl* scale = this->CreateLayer(surface, scale_transform,
1982 gfx::PointF(), gfx::Size(1, 1));
1983 LayerImpl* scaled = this->CreateDrawingLayer(
1984 scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
1985 this->CalcDrawEtc(parent);
1987 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
1989 this->VisitLayer(scaled, &occlusion);
1990 this->VisitLayer(surface, &occlusion);
1991 this->VisitContributingSurface(surface, &occlusion);
1993 EXPECT_EQ(gfx::Rect().ToString(),
1994 occlusion.occlusion_from_outside_target().ToString());
1995 EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
1996 occlusion.occlusion_from_inside_target().ToString());
2000 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
2002 class OcclusionTrackerTestCopyRequestDoesOcclude : public OcclusionTrackerTest {
2003 protected:
2004 explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
2005 : OcclusionTrackerTest(opaque_layers) {}
2006 void RunMyTest() override {
2007 TestContentLayerImpl* root = this->CreateRoot(
2008 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2009 TestContentLayerImpl* parent = this->CreateDrawingLayer(
2010 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2011 LayerImpl* copy = this->CreateLayer(
2012 parent, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
2013 this->AddCopyRequest(copy);
2014 LayerImpl* copy_child = this->CreateDrawingLayer(
2015 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
2016 LayerImpl* top_layer =
2017 this->CreateDrawingLayer(root, this->identity_matrix,
2018 gfx::PointF(50, 0), gfx::Size(50, 400), true);
2019 this->CalcDrawEtc(root);
2021 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
2023 this->VisitLayer(top_layer, &occlusion);
2024 EXPECT_EQ(gfx::Rect().ToString(),
2025 occlusion.occlusion_from_outside_target().ToString());
2026 EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(),
2027 occlusion.occlusion_from_inside_target().ToString());
2029 this->VisitLayer(copy_child, &occlusion);
2030 // Layers outside the copy request do not occlude.
2031 EXPECT_EQ(gfx::Rect().ToString(),
2032 occlusion.occlusion_from_outside_target().ToString());
2033 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2034 occlusion.occlusion_from_inside_target().ToString());
2036 // CopyRequests cause the layer to own a surface.
2037 this->VisitContributingSurface(copy, &occlusion);
2039 // The occlusion from the copy should be kept.
2040 EXPECT_EQ(gfx::Rect().ToString(),
2041 occlusion.occlusion_from_outside_target().ToString());
2042 EXPECT_EQ(gfx::Rect(50, 0, 250, 400).ToString(),
2043 occlusion.occlusion_from_inside_target().ToString());
2047 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
2049 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
2050 : public OcclusionTrackerTest {
2051 protected:
2052 explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
2053 bool opaque_layers)
2054 : OcclusionTrackerTest(opaque_layers) {}
2055 void RunMyTest() override {
2056 TestContentLayerImpl* root = this->CreateRoot(
2057 this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
2058 TestContentLayerImpl* parent = this->CreateDrawingLayer(
2059 root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
2060 LayerImpl* hide = this->CreateLayer(parent, this->identity_matrix,
2061 gfx::Point(), gfx::Size());
2062 LayerImpl* copy = this->CreateLayer(
2063 hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
2064 this->AddCopyRequest(copy);
2065 LayerImpl* copy_child = this->CreateDrawingLayer(
2066 copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
2068 // The |copy| layer is hidden but since it is being copied, it will be
2069 // drawn.
2070 hide->SetHideLayerAndSubtree(true);
2072 this->CalcDrawEtc(root);
2074 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
2076 this->VisitLayer(copy_child, &occlusion);
2077 EXPECT_EQ(gfx::Rect().ToString(),
2078 occlusion.occlusion_from_outside_target().ToString());
2079 EXPECT_EQ(gfx::Rect(200, 400).ToString(),
2080 occlusion.occlusion_from_inside_target().ToString());
2082 // CopyRequests cause the layer to own a surface.
2083 this->VisitContributingSurface(copy, &occlusion);
2085 // The occlusion from the copy should be dropped since it is hidden.
2086 EXPECT_EQ(gfx::Rect().ToString(),
2087 occlusion.occlusion_from_outside_target().ToString());
2088 EXPECT_EQ(gfx::Rect().ToString(),
2089 occlusion.occlusion_from_inside_target().ToString());
2093 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
2095 class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest {
2096 protected:
2097 explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers)
2098 : OcclusionTrackerTest(opaque_layers) {}
2099 void RunMyTest() override {
2100 gfx::Transform translate;
2101 translate.Translate(10.0, 20.0);
2102 TestContentLayerImpl* root = this->CreateRoot(
2103 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2104 LayerImpl* surface = this->CreateSurface(root, this->identity_matrix,
2105 gfx::Point(), gfx::Size(200, 200));
2106 LayerImpl* layer = this->CreateDrawingLayer(
2107 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2108 TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
2109 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2110 this->CalcDrawEtc(root);
2112 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
2113 this->VisitLayer(outside_layer, &occlusion);
2114 this->EnterLayer(layer, &occlusion);
2116 // No occlusion, is not occluded.
2117 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2118 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2119 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100)));
2121 // Partial occlusion from outside, is not occluded.
2122 occlusion.set_occlusion_from_outside_target(
2123 SimpleEnclosedRegion(50, 50, 100, 100));
2124 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2125 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2126 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2127 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2128 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2129 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2130 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2131 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2132 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2134 // Full occlusion from outside, is occluded.
2135 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2136 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2137 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2138 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2140 // Partial occlusion from inside, is not occluded.
2141 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2142 occlusion.set_occlusion_from_inside_target(
2143 SimpleEnclosedRegion(50, 50, 100, 100));
2144 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2145 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2146 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2147 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2148 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2149 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2150 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2151 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2153 // Full occlusion from inside, is occluded.
2154 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2155 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2156 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2157 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2159 // Partial occlusion from both, is not occluded.
2160 occlusion.set_occlusion_from_outside_target(
2161 SimpleEnclosedRegion(50, 50, 100, 50));
2162 occlusion.set_occlusion_from_inside_target(
2163 SimpleEnclosedRegion(50, 100, 100, 50));
2164 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
2165 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100)));
2166 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100)));
2167 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100)));
2168 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100)));
2169 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100)));
2170 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100)));
2171 EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100)));
2173 // Full occlusion from both, is occluded.
2174 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100)));
2175 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10)));
2176 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10)));
2177 EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50)));
2181 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer)
2183 class OcclusionTrackerTestUnoccludedLayerQuery : public OcclusionTrackerTest {
2184 protected:
2185 explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers)
2186 : OcclusionTrackerTest(opaque_layers) {}
2187 void RunMyTest() override {
2188 gfx::Transform translate;
2189 translate.Translate(10.0, 20.0);
2190 TestContentLayerImpl* root = this->CreateRoot(
2191 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2192 LayerImpl* surface = this->CreateSurface(root, this->identity_matrix,
2193 gfx::Point(), gfx::Size(200, 200));
2194 LayerImpl* layer = this->CreateDrawingLayer(
2195 surface, translate, gfx::Point(), gfx::Size(200, 200), false);
2196 TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
2197 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2198 this->CalcDrawEtc(root);
2200 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
2201 this->VisitLayer(outside_layer, &occlusion);
2202 this->EnterLayer(layer, &occlusion);
2204 // No occlusion, is not occluded.
2205 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2206 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2207 EXPECT_EQ(gfx::Rect(100, 100),
2208 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(100, 100)));
2210 // Partial occlusion from outside.
2211 occlusion.set_occlusion_from_outside_target(
2212 SimpleEnclosedRegion(50, 50, 100, 100));
2213 occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion());
2214 EXPECT_EQ(
2215 gfx::Rect(0, 0, 100, 100),
2216 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
2217 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2218 occlusion.UnoccludedLayerContentRect(
2219 layer, gfx::Rect(90, 30, 100, 100)));
2220 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2221 occlusion.UnoccludedLayerContentRect(layer,
2222 gfx::Rect(40, 0, 100, 100)));
2223 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2224 occlusion.UnoccludedLayerContentRect(
2225 layer, gfx::Rect(40, 80, 100, 100)));
2226 EXPECT_EQ(
2227 gfx::Rect(0, 0, 80, 100),
2228 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
2229 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2230 occlusion.UnoccludedLayerContentRect(
2231 layer, gfx::Rect(90, 80, 100, 100)));
2232 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2233 occlusion.UnoccludedLayerContentRect(layer,
2234 gfx::Rect(0, 80, 100, 100)));
2235 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2236 occlusion.UnoccludedLayerContentRect(layer,
2237 gfx::Rect(90, 0, 100, 100)));
2239 // Full occlusion from outside, is occluded.
2240 EXPECT_EQ(gfx::Rect(),
2241 occlusion.UnoccludedLayerContentRect(
2242 layer, gfx::Rect(40, 30, 100, 100)));
2243 EXPECT_EQ(
2244 gfx::Rect(),
2245 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
2246 EXPECT_EQ(gfx::Rect(),
2247 occlusion.UnoccludedLayerContentRect(
2248 layer, gfx::Rect(130, 120, 10, 10)));
2249 EXPECT_EQ(
2250 gfx::Rect(),
2251 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
2253 // Partial occlusion from inside, is not occluded.
2254 occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion());
2255 occlusion.set_occlusion_from_inside_target(
2256 SimpleEnclosedRegion(50, 50, 100, 100));
2257 EXPECT_EQ(
2258 gfx::Rect(0, 0, 100, 100),
2259 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
2260 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2261 occlusion.UnoccludedLayerContentRect(
2262 layer, gfx::Rect(90, 30, 100, 100)));
2263 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2264 occlusion.UnoccludedLayerContentRect(layer,
2265 gfx::Rect(40, 0, 100, 100)));
2266 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2267 occlusion.UnoccludedLayerContentRect(
2268 layer, gfx::Rect(40, 80, 100, 100)));
2269 EXPECT_EQ(
2270 gfx::Rect(0, 0, 80, 100),
2271 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
2272 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2273 occlusion.UnoccludedLayerContentRect(
2274 layer, gfx::Rect(90, 80, 100, 100)));
2275 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2276 occlusion.UnoccludedLayerContentRect(layer,
2277 gfx::Rect(0, 80, 100, 100)));
2278 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2279 occlusion.UnoccludedLayerContentRect(layer,
2280 gfx::Rect(90, 0, 100, 100)));
2282 // Full occlusion from inside, is occluded.
2283 EXPECT_EQ(gfx::Rect(),
2284 occlusion.UnoccludedLayerContentRect(
2285 layer, gfx::Rect(40, 30, 100, 100)));
2286 EXPECT_EQ(
2287 gfx::Rect(),
2288 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
2289 EXPECT_EQ(gfx::Rect(),
2290 occlusion.UnoccludedLayerContentRect(
2291 layer, gfx::Rect(130, 120, 10, 10)));
2292 EXPECT_EQ(
2293 gfx::Rect(),
2294 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
2296 // Partial occlusion from both, is not occluded.
2297 occlusion.set_occlusion_from_outside_target(
2298 SimpleEnclosedRegion(50, 50, 100, 50));
2299 occlusion.set_occlusion_from_inside_target(
2300 SimpleEnclosedRegion(50, 100, 100, 50));
2301 EXPECT_EQ(
2302 gfx::Rect(0, 0, 100, 100),
2303 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100)));
2304 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
2305 // it's larger.
2306 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
2307 occlusion.UnoccludedLayerContentRect(
2308 layer, gfx::Rect(90, 30, 100, 100)));
2309 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2310 occlusion.UnoccludedLayerContentRect(layer,
2311 gfx::Rect(40, 0, 100, 100)));
2312 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2313 occlusion.UnoccludedLayerContentRect(
2314 layer, gfx::Rect(40, 80, 100, 100)));
2315 EXPECT_EQ(
2316 gfx::Rect(0, 0, 80, 100),
2317 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100)));
2318 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2319 occlusion.UnoccludedLayerContentRect(
2320 layer, gfx::Rect(90, 80, 100, 100)));
2321 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2322 occlusion.UnoccludedLayerContentRect(layer,
2323 gfx::Rect(0, 80, 100, 100)));
2324 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2325 occlusion.UnoccludedLayerContentRect(layer,
2326 gfx::Rect(90, 0, 100, 100)));
2328 // Full occlusion from both, is occluded.
2329 EXPECT_EQ(gfx::Rect(),
2330 occlusion.UnoccludedLayerContentRect(
2331 layer, gfx::Rect(40, 30, 100, 100)));
2332 EXPECT_EQ(
2333 gfx::Rect(),
2334 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10)));
2335 EXPECT_EQ(gfx::Rect(),
2336 occlusion.UnoccludedLayerContentRect(
2337 layer, gfx::Rect(130, 120, 10, 10)));
2338 EXPECT_EQ(
2339 gfx::Rect(),
2340 occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50)));
2344 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery)
2346 class OcclusionTrackerTestUnoccludedSurfaceQuery : public OcclusionTrackerTest {
2347 protected:
2348 explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers)
2349 : OcclusionTrackerTest(opaque_layers) {}
2350 void RunMyTest() override {
2351 gfx::Transform translate;
2352 translate.Translate(10.0, 20.0);
2353 TestContentLayerImpl* root = this->CreateRoot(
2354 this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
2355 LayerImpl* surface =
2356 this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200));
2357 LayerImpl* layer =
2358 this->CreateDrawingLayer(surface, this->identity_matrix, gfx::Point(),
2359 gfx::Size(200, 200), false);
2360 TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
2361 root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
2362 this->CalcDrawEtc(root);
2364 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
2365 this->VisitLayer(outside_layer, &occlusion);
2366 this->VisitLayer(layer, &occlusion);
2367 this->EnterContributingSurface(surface, &occlusion);
2369 // No occlusion, is not occluded.
2370 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
2371 SimpleEnclosedRegion());
2372 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
2373 SimpleEnclosedRegion());
2374 EXPECT_EQ(
2375 gfx::Rect(100, 100),
2376 occlusion.UnoccludedSurfaceContentRect(surface, gfx::Rect(100, 100)));
2378 // Partial occlusion from outside.
2379 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
2380 SimpleEnclosedRegion(50, 50, 100, 100));
2381 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
2382 SimpleEnclosedRegion());
2383 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2384 occlusion.UnoccludedSurfaceContentRect(
2385 surface, gfx::Rect(0, 0, 100, 100)));
2386 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2387 occlusion.UnoccludedSurfaceContentRect(
2388 surface, gfx::Rect(90, 30, 100, 100)));
2389 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2390 occlusion.UnoccludedSurfaceContentRect(
2391 surface, gfx::Rect(40, 0, 100, 100)));
2392 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2393 occlusion.UnoccludedSurfaceContentRect(
2394 surface, gfx::Rect(40, 80, 100, 100)));
2395 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2396 occlusion.UnoccludedSurfaceContentRect(surface,
2397 gfx::Rect(0, 0, 80, 100)));
2398 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2399 occlusion.UnoccludedSurfaceContentRect(
2400 surface, gfx::Rect(90, 80, 100, 100)));
2401 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2402 occlusion.UnoccludedSurfaceContentRect(
2403 surface, gfx::Rect(0, 80, 100, 100)));
2404 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2405 occlusion.UnoccludedSurfaceContentRect(
2406 surface, gfx::Rect(90, 0, 100, 100)));
2408 // Full occlusion from outside, is occluded.
2409 EXPECT_EQ(gfx::Rect(),
2410 occlusion.UnoccludedSurfaceContentRect(
2411 surface, gfx::Rect(40, 30, 100, 100)));
2412 EXPECT_EQ(gfx::Rect(),
2413 occlusion.UnoccludedSurfaceContentRect(
2414 surface, gfx::Rect(40, 30, 10, 10)));
2415 EXPECT_EQ(gfx::Rect(),
2416 occlusion.UnoccludedSurfaceContentRect(
2417 surface, gfx::Rect(130, 120, 10, 10)));
2418 EXPECT_EQ(gfx::Rect(),
2419 occlusion.UnoccludedSurfaceContentRect(
2420 surface, gfx::Rect(80, 70, 50, 50)));
2422 // Partial occlusion from inside, is not occluded.
2423 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
2424 SimpleEnclosedRegion());
2425 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
2426 SimpleEnclosedRegion(50, 50, 100, 100));
2427 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2428 occlusion.UnoccludedSurfaceContentRect(
2429 surface, gfx::Rect(0, 0, 100, 100)));
2430 EXPECT_EQ(gfx::Rect(140, 30, 50, 100),
2431 occlusion.UnoccludedSurfaceContentRect(
2432 surface, gfx::Rect(90, 30, 100, 100)));
2433 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2434 occlusion.UnoccludedSurfaceContentRect(
2435 surface, gfx::Rect(40, 0, 100, 100)));
2436 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2437 occlusion.UnoccludedSurfaceContentRect(
2438 surface, gfx::Rect(40, 80, 100, 100)));
2439 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2440 occlusion.UnoccludedSurfaceContentRect(surface,
2441 gfx::Rect(0, 0, 80, 100)));
2442 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2443 occlusion.UnoccludedSurfaceContentRect(
2444 surface, gfx::Rect(90, 80, 100, 100)));
2445 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2446 occlusion.UnoccludedSurfaceContentRect(
2447 surface, gfx::Rect(0, 80, 100, 100)));
2448 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2449 occlusion.UnoccludedSurfaceContentRect(
2450 surface, gfx::Rect(90, 0, 100, 100)));
2452 // Full occlusion from inside, is occluded.
2453 EXPECT_EQ(gfx::Rect(),
2454 occlusion.UnoccludedSurfaceContentRect(
2455 surface, gfx::Rect(40, 30, 100, 100)));
2456 EXPECT_EQ(gfx::Rect(),
2457 occlusion.UnoccludedSurfaceContentRect(
2458 surface, gfx::Rect(40, 30, 10, 10)));
2459 EXPECT_EQ(gfx::Rect(),
2460 occlusion.UnoccludedSurfaceContentRect(
2461 surface, gfx::Rect(130, 120, 10, 10)));
2462 EXPECT_EQ(gfx::Rect(),
2463 occlusion.UnoccludedSurfaceContentRect(
2464 surface, gfx::Rect(80, 70, 50, 50)));
2466 // Partial occlusion from both, is not occluded.
2467 occlusion.set_occlusion_on_contributing_surface_from_outside_target(
2468 SimpleEnclosedRegion(50, 50, 100, 50));
2469 occlusion.set_occlusion_on_contributing_surface_from_inside_target(
2470 SimpleEnclosedRegion(50, 100, 100, 50));
2471 EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
2472 occlusion.UnoccludedSurfaceContentRect(
2473 surface, gfx::Rect(0, 0, 100, 100)));
2474 // This could be (140, 30, 50, 100). But because we do a lossy subtract,
2475 // it's larger.
2476 EXPECT_EQ(gfx::Rect(90, 30, 100, 100),
2477 occlusion.UnoccludedSurfaceContentRect(
2478 surface, gfx::Rect(90, 30, 100, 100)));
2479 EXPECT_EQ(gfx::Rect(40, 0, 100, 30),
2480 occlusion.UnoccludedSurfaceContentRect(
2481 surface, gfx::Rect(40, 0, 100, 100)));
2482 EXPECT_EQ(gfx::Rect(40, 130, 100, 50),
2483 occlusion.UnoccludedSurfaceContentRect(
2484 surface, gfx::Rect(40, 80, 100, 100)));
2485 EXPECT_EQ(gfx::Rect(0, 0, 80, 100),
2486 occlusion.UnoccludedSurfaceContentRect(surface,
2487 gfx::Rect(0, 0, 80, 100)));
2488 EXPECT_EQ(gfx::Rect(90, 80, 100, 100),
2489 occlusion.UnoccludedSurfaceContentRect(
2490 surface, gfx::Rect(90, 80, 100, 100)));
2491 EXPECT_EQ(gfx::Rect(0, 80, 100, 100),
2492 occlusion.UnoccludedSurfaceContentRect(
2493 surface, gfx::Rect(0, 80, 100, 100)));
2494 EXPECT_EQ(gfx::Rect(90, 0, 100, 100),
2495 occlusion.UnoccludedSurfaceContentRect(
2496 surface, gfx::Rect(90, 0, 100, 100)));
2498 // Full occlusion from both, is occluded.
2499 EXPECT_EQ(gfx::Rect(),
2500 occlusion.UnoccludedSurfaceContentRect(
2501 surface, gfx::Rect(40, 30, 100, 100)));
2502 EXPECT_EQ(gfx::Rect(),
2503 occlusion.UnoccludedSurfaceContentRect(
2504 surface, gfx::Rect(40, 30, 10, 10)));
2505 EXPECT_EQ(gfx::Rect(),
2506 occlusion.UnoccludedSurfaceContentRect(
2507 surface, gfx::Rect(130, 120, 10, 10)));
2508 EXPECT_EQ(gfx::Rect(),
2509 occlusion.UnoccludedSurfaceContentRect(
2510 surface, gfx::Rect(80, 70, 50, 50)));
2514 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery)
2516 } // namespace
2517 } // namespace cc