| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/trees/occlusion_tracker.h" | 5 #include "cc/trees/occlusion_tracker.h" |
| 6 | 6 |
| 7 #include "cc/animation/layer_animation_controller.h" | 7 #include "cc/animation/layer_animation_controller.h" |
| 8 #include "cc/base/math_util.h" | 8 #include "cc/base/math_util.h" |
| 9 #include "cc/debug/overdraw_metrics.h" | 9 #include "cc/debug/overdraw_metrics.h" |
| 10 #include "cc/layers/layer.h" | 10 #include "cc/layers/layer.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) { | 66 void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) { |
| 67 override_opaque_contents_rect_ = true; | 67 override_opaque_contents_rect_ = true; |
| 68 opaque_contents_rect_ = opaque_contents_rect; | 68 opaque_contents_rect_ = opaque_contents_rect; |
| 69 } | 69 } |
| 70 | 70 |
| 71 private: | 71 private: |
| 72 bool override_opaque_contents_rect_; | 72 bool override_opaque_contents_rect_; |
| 73 gfx::Rect opaque_contents_rect_; | 73 gfx::Rect opaque_contents_rect_; |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 static inline bool LayerImplDrawTransformIsUnknown(const Layer* layer) { | |
| 77 return layer->draw_transform_is_animating(); | |
| 78 } | |
| 79 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl* layer) { | |
| 80 return false; | |
| 81 } | |
| 82 | |
| 83 template <typename LayerType> | 76 template <typename LayerType> |
| 84 class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> { | 77 class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> { |
| 85 public: | 78 public: |
| 86 TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect, | 79 TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect, |
| 87 bool record_metrics_for_frame) | 80 bool record_metrics_for_frame) |
| 88 : TestOcclusionTracker<LayerType>(viewport_rect, | 81 : TestOcclusionTracker<LayerType>(viewport_rect, |
| 89 record_metrics_for_frame) {} | 82 record_metrics_for_frame) {} |
| 90 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect) | 83 explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect) |
| 91 : TestOcclusionTracker<LayerType>(viewport_rect, false) {} | 84 : TestOcclusionTracker<LayerType>(viewport_rect, false) {} |
| 92 | 85 |
| 93 bool OccludedLayer(const LayerType* layer, | 86 bool OccludedLayer(const LayerType* layer, |
| 94 const gfx::Rect& content_rect) const { | 87 const gfx::Rect& content_rect) const { |
| 95 DCHECK(layer->visible_content_rect().Contains(content_rect)); | 88 DCHECK(layer->visible_content_rect().Contains(content_rect)); |
| 96 return this->Occluded(layer->render_target(), | 89 return this->Occluded( |
| 97 content_rect, | 90 layer->render_target(), content_rect, layer->draw_transform()); |
| 98 layer->draw_transform(), | |
| 99 LayerImplDrawTransformIsUnknown(layer)); | |
| 100 } | 91 } |
| 101 | 92 |
| 102 // Gives an unoccluded sub-rect of |content_rect| in the content space of the | 93 // Gives an unoccluded sub-rect of |content_rect| in the content space of the |
| 103 // layer. Simple wrapper around UnoccludedContentRect. | 94 // layer. Simple wrapper around UnoccludedContentRect. |
| 104 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer, | 95 gfx::Rect UnoccludedLayerContentRect(const LayerType* layer, |
| 105 const gfx::Rect& content_rect) const { | 96 const gfx::Rect& content_rect) const { |
| 106 DCHECK(layer->visible_content_rect().Contains(content_rect)); | 97 DCHECK(layer->visible_content_rect().Contains(content_rect)); |
| 107 return this->UnoccludedContentRect( | 98 return this->UnoccludedContentRect( |
| 108 layer->render_target(), | 99 layer->render_target(), content_rect, layer->draw_transform()); |
| 109 content_rect, | |
| 110 layer->draw_transform(), | |
| 111 LayerImplDrawTransformIsUnknown(layer)); | |
| 112 } | 100 } |
| 113 }; | 101 }; |
| 114 | 102 |
| 115 struct OcclusionTrackerTestMainThreadTypes { | 103 struct OcclusionTrackerTestMainThreadTypes { |
| 116 typedef Layer LayerType; | 104 typedef Layer LayerType; |
| 117 typedef FakeLayerTreeHost HostType; | 105 typedef FakeLayerTreeHost HostType; |
| 118 typedef RenderSurface RenderSurfaceType; | 106 typedef RenderSurface RenderSurfaceType; |
| 119 typedef TestContentLayer ContentLayerType; | 107 typedef TestContentLayer ContentLayerType; |
| 120 typedef scoped_refptr<Layer> LayerPtrType; | 108 typedef scoped_refptr<Layer> LayerPtrType; |
| 121 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType; | 109 typedef scoped_refptr<ContentLayerType> ContentLayerPtrType; |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 | 609 |
| 622 // This checks cases where the quads don't match their "containing" | 610 // This checks cases where the quads don't match their "containing" |
| 623 // layers, e.g. in terms of transforms or clip rect. This is typical for | 611 // layers, e.g. in terms of transforms or clip rect. This is typical for |
| 624 // DelegatedRendererLayer. | 612 // DelegatedRendererLayer. |
| 625 | 613 |
| 626 gfx::Transform quad_transform; | 614 gfx::Transform quad_transform; |
| 627 quad_transform.Translate(30.0, 30.0); | 615 quad_transform.Translate(30.0, 30.0); |
| 628 | 616 |
| 629 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent, | 617 EXPECT_TRUE(occlusion.UnoccludedContentRect(parent, |
| 630 gfx::Rect(0, 0, 10, 10), | 618 gfx::Rect(0, 0, 10, 10), |
| 631 quad_transform, | 619 quad_transform).IsEmpty()); |
| 632 false).IsEmpty()); | |
| 633 EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10), | |
| 634 occlusion.UnoccludedContentRect(parent, | |
| 635 gfx::Rect(0, 0, 10, 10), | |
| 636 quad_transform, | |
| 637 true)); | |
| 638 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), | 620 EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), |
| 639 occlusion.UnoccludedContentRect(parent, | 621 occlusion.UnoccludedContentRect( |
| 640 gfx::Rect(40, 40, 10, 10), | 622 parent, gfx::Rect(40, 40, 10, 10), quad_transform)); |
| 641 quad_transform, | |
| 642 false)); | |
| 643 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), | 623 EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), |
| 644 occlusion.UnoccludedContentRect(parent, | 624 occlusion.UnoccludedContentRect( |
| 645 gfx::Rect(35, 30, 10, 10), | 625 parent, gfx::Rect(35, 30, 10, 10), quad_transform)); |
| 646 quad_transform, | |
| 647 false)); | |
| 648 } | 626 } |
| 649 }; | 627 }; |
| 650 | 628 |
| 651 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer); | 629 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer); |
| 652 | 630 |
| 653 template <class Types> | 631 template <class Types> |
| 654 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> { | 632 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> { |
| 655 protected: | 633 protected: |
| 656 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers) | 634 explicit OcclusionTrackerTestRotatedChild(bool opaque_layers) |
| 657 : OcclusionTrackerTest<Types>(opaque_layers) {} | 635 : OcclusionTrackerTest<Types>(opaque_layers) {} |
| (...skipping 1784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2442 gfx::Rect(0, 0, 1000, 1000)); | 2420 gfx::Rect(0, 0, 1000, 1000)); |
| 2443 | 2421 |
| 2444 this->VisitLayer(surface2, &occlusion); | 2422 this->VisitLayer(surface2, &occlusion); |
| 2445 this->EnterContributingSurface(surface2, &occlusion); | 2423 this->EnterContributingSurface(surface2, &occlusion); |
| 2446 | 2424 |
| 2447 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), | 2425 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), |
| 2448 occlusion.occlusion_from_inside_target().ToString()); | 2426 occlusion.occlusion_from_inside_target().ToString()); |
| 2449 | 2427 |
| 2450 this->LeaveContributingSurface(surface2, &occlusion); | 2428 this->LeaveContributingSurface(surface2, &occlusion); |
| 2451 this->EnterLayer(surface_child2, &occlusion); | 2429 this->EnterLayer(surface_child2, &occlusion); |
| 2452 | |
| 2453 // surface_child2 is moving in screen space but not relative to its target, | 2430 // surface_child2 is moving in screen space but not relative to its target, |
| 2454 // so occlusion should happen in its target space only. It also means that | 2431 // so occlusion should happen in its target space only. It also means that |
| 2455 // things occluding from outside the target (e.g. surface2) cannot occlude | 2432 // things occluding from outside the target (e.g. surface2) cannot occlude |
| 2456 // this layer. | 2433 // this layer. |
| 2457 EXPECT_EQ(gfx::Rect().ToString(), | 2434 EXPECT_EQ(gfx::Rect().ToString(), |
| 2458 occlusion.occlusion_from_outside_target().ToString()); | 2435 occlusion.occlusion_from_outside_target().ToString()); |
| 2459 | 2436 EXPECT_EQ(gfx::Rect().ToString(), |
| 2460 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300), | 2437 occlusion.occlusion_from_inside_target().ToString()); |
| 2461 occlusion.UnoccludedLayerContentRect( | |
| 2462 surface_child2, gfx::Rect(0, 0, 100, 300))); | |
| 2463 EXPECT_FALSE( | |
| 2464 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300))); | |
| 2465 | 2438 |
| 2466 this->LeaveLayer(surface_child2, &occlusion); | 2439 this->LeaveLayer(surface_child2, &occlusion); |
| 2467 this->EnterLayer(surface_child, &occlusion); | 2440 this->EnterLayer(surface_child, &occlusion); |
| 2468 EXPECT_FALSE( | 2441 // surface_child2 added to the occlusion since it is not moving relative |
| 2469 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300))); | 2442 // to its target. |
| 2470 EXPECT_EQ(gfx::Rect().ToString(), | 2443 EXPECT_EQ(gfx::Rect().ToString(), |
| 2471 occlusion.occlusion_from_outside_target().ToString()); | 2444 occlusion.occlusion_from_outside_target().ToString()); |
| 2472 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), | 2445 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), |
| 2473 occlusion.occlusion_from_inside_target().ToString()); | 2446 occlusion.occlusion_from_inside_target().ToString()); |
| 2474 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), | |
| 2475 occlusion.UnoccludedLayerContentRect( | |
| 2476 surface, gfx::Rect(0, 0, 300, 300))); | |
| 2477 | |
| 2478 // The surface_child is occluded by the surface_child2, but is moving | |
| 2479 // relative its target, so it can't be occluded. | |
| 2480 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300), | |
| 2481 occlusion.UnoccludedLayerContentRect( | |
| 2482 surface_child, gfx::Rect(0, 0, 200, 300))); | |
| 2483 EXPECT_FALSE( | |
| 2484 occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300))); | |
| 2485 | 2447 |
| 2486 this->LeaveLayer(surface_child, &occlusion); | 2448 this->LeaveLayer(surface_child, &occlusion); |
| 2487 this->EnterLayer(surface, &occlusion); | 2449 // surface_child is moving relative to its target, so it does not add |
| 2488 // The surface_child is moving in screen space but not relative to its | 2450 // occlusion. |
| 2489 // target, so occlusion should happen from within the target only. | |
| 2490 EXPECT_EQ(gfx::Rect().ToString(), | 2451 EXPECT_EQ(gfx::Rect().ToString(), |
| 2491 occlusion.occlusion_from_outside_target().ToString()); | 2452 occlusion.occlusion_from_outside_target().ToString()); |
| 2492 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), | 2453 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), |
| 2493 occlusion.occlusion_from_inside_target().ToString()); | 2454 occlusion.occlusion_from_inside_target().ToString()); |
| 2494 EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), | 2455 |
| 2495 occlusion.UnoccludedLayerContentRect( | 2456 this->EnterLayer(surface, &occlusion); |
| 2496 surface, gfx::Rect(0, 0, 300, 300))); | 2457 EXPECT_EQ(gfx::Rect().ToString(), |
| 2458 occlusion.occlusion_from_outside_target().ToString()); |
| 2459 EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), |
| 2460 occlusion.occlusion_from_inside_target().ToString()); |
| 2497 | 2461 |
| 2498 this->LeaveLayer(surface, &occlusion); | 2462 this->LeaveLayer(surface, &occlusion); |
| 2499 // The surface's owning layer is moving in screen space but not relative to | 2463 // The surface's owning layer is moving in screen space but not relative to |
| 2500 // its target, so occlusion should happen within the target only. | 2464 // its target, so it adds to the occlusion. |
| 2501 EXPECT_EQ(gfx::Rect().ToString(), | 2465 EXPECT_EQ(gfx::Rect().ToString(), |
| 2502 occlusion.occlusion_from_outside_target().ToString()); | 2466 occlusion.occlusion_from_outside_target().ToString()); |
| 2503 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), | 2467 EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), |
| 2504 occlusion.occlusion_from_inside_target().ToString()); | 2468 occlusion.occlusion_from_inside_target().ToString()); |
| 2505 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), | |
| 2506 occlusion.UnoccludedLayerContentRect( | |
| 2507 surface, gfx::Rect(0, 0, 300, 300))); | |
| 2508 | 2469 |
| 2509 this->EnterContributingSurface(surface, &occlusion); | 2470 this->EnterContributingSurface(surface, &occlusion); |
| 2510 // The contributing |surface| is animating so it can't be occluded. | |
| 2511 EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300), | |
| 2512 occlusion.UnoccludedContributingSurfaceContentRect( | |
| 2513 surface, false, gfx::Rect(0, 0, 300, 300))); | |
| 2514 this->LeaveContributingSurface(surface, &occlusion); | 2471 this->LeaveContributingSurface(surface, &occlusion); |
| 2472 // The |surface| is moving in the screen and in its target, so all occlusion |
| 2473 // within the surface is lost when leaving it. Only the |surface2| occlusion |
| 2474 // is left. |
| 2475 EXPECT_EQ(gfx::Rect().ToString(), |
| 2476 occlusion.occlusion_from_outside_target().ToString()); |
| 2477 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), |
| 2478 occlusion.occlusion_from_inside_target().ToString()); |
| 2515 | 2479 |
| 2516 this->EnterLayer(layer, &occlusion); | 2480 this->VisitLayer(layer, &occlusion); |
| 2517 // The |surface| is moving in the screen and in its target, so all occlusion | |
| 2518 // within the surface is lost when leaving it. | |
| 2519 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), | |
| 2520 occlusion.UnoccludedLayerContentRect( | |
| 2521 parent, gfx::Rect(0, 0, 300, 300))); | |
| 2522 this->LeaveLayer(layer, &occlusion); | |
| 2523 | |
| 2524 this->EnterLayer(parent, &occlusion); | |
| 2525 // The |layer| is animating in the screen and in its target, so no occlusion | 2481 // The |layer| is animating in the screen and in its target, so no occlusion |
| 2526 // is added. | 2482 // is added. |
| 2527 EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300), | 2483 EXPECT_EQ(gfx::Rect().ToString(), |
| 2528 occlusion.UnoccludedLayerContentRect( | 2484 occlusion.occlusion_from_outside_target().ToString()); |
| 2529 parent, gfx::Rect(0, 0, 300, 300))); | 2485 EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), |
| 2486 occlusion.occlusion_from_inside_target().ToString()); |
| 2530 } | 2487 } |
| 2531 }; | 2488 }; |
| 2532 | 2489 |
| 2533 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread); | 2490 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread); |
| 2534 | 2491 |
| 2535 template <class Types> | 2492 template <class Types> |
| 2536 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent | 2493 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent |
| 2537 : public OcclusionTrackerTest<Types> { | 2494 : public OcclusionTrackerTest<Types> { |
| 2538 protected: | 2495 protected: |
| 2539 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent( | 2496 explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent( |
| (...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3766 occlusion.occlusion_from_outside_target().ToString()); | 3723 occlusion.occlusion_from_outside_target().ToString()); |
| 3767 EXPECT_EQ(gfx::Rect().ToString(), | 3724 EXPECT_EQ(gfx::Rect().ToString(), |
| 3768 occlusion.occlusion_from_inside_target().ToString()); | 3725 occlusion.occlusion_from_inside_target().ToString()); |
| 3769 } | 3726 } |
| 3770 }; | 3727 }; |
| 3771 | 3728 |
| 3772 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude) | 3729 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude) |
| 3773 | 3730 |
| 3774 } // namespace | 3731 } // namespace |
| 3775 } // namespace cc | 3732 } // namespace cc |
| OLD | NEW |