Home | History | Annotate | Download | only in trees
      1 // Copyright 2011 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.
      4 
      5 #include "cc/trees/damage_tracker.h"
      6 
      7 #include "cc/base/math_util.h"
      8 #include "cc/layers/layer_impl.h"
      9 #include "cc/output/filter_operation.h"
     10 #include "cc/output/filter_operations.h"
     11 #include "cc/test/fake_impl_proxy.h"
     12 #include "cc/test/fake_layer_tree_host_impl.h"
     13 #include "cc/test/geometry_test_utils.h"
     14 #include "cc/test/test_shared_bitmap_manager.h"
     15 #include "cc/trees/layer_tree_host_common.h"
     16 #include "cc/trees/single_thread_proxy.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 #include "third_party/skia/include/effects/SkBlurImageFilter.h"
     19 #include "ui/gfx/geometry/quad_f.h"
     20 #include "ui/gfx/geometry/rect_conversions.h"
     21 
     22 namespace cc {
     23 namespace {
     24 
     25 void ExecuteCalculateDrawProperties(LayerImpl* root,
     26                                     LayerImplList* render_surface_layer_list) {
     27   // Sanity check: The test itself should create the root layer's render
     28   //               surface, so that the surface (and its damage tracker) can
     29   //               persist across multiple calls to this function.
     30   ASSERT_TRUE(root->render_surface());
     31   ASSERT_FALSE(render_surface_layer_list->size());
     32 
     33   FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root);
     34   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
     35       root, root->bounds(), render_surface_layer_list);
     36   LayerTreeHostCommon::CalculateDrawProperties(&inputs);
     37 }
     38 
     39 void ClearDamageForAllSurfaces(LayerImpl* layer) {
     40   if (layer->render_surface())
     41     layer->render_surface()->damage_tracker()->DidDrawDamagedArea();
     42 
     43   // Recursively clear damage for any existing surface.
     44   for (size_t i = 0; i < layer->children().size(); ++i)
     45     ClearDamageForAllSurfaces(layer->children()[i]);
     46 }
     47 
     48 void EmulateDrawingOneFrame(LayerImpl* root) {
     49   // This emulates only steps that are relevant to testing the damage tracker:
     50   //   1. computing the render passes and layerlists
     51   //   2. updating all damage trackers in the correct order
     52   //   3. resetting all update_rects and property_changed flags for all layers
     53   //      and surfaces.
     54 
     55   LayerImplList render_surface_layer_list;
     56   ExecuteCalculateDrawProperties(root, &render_surface_layer_list);
     57 
     58   // Iterate back-to-front, so that damage correctly propagates from descendant
     59   // surfaces to ancestors.
     60   for (int i = render_surface_layer_list.size() - 1; i >= 0; --i) {
     61     RenderSurfaceImpl* target_surface =
     62             render_surface_layer_list[i]->render_surface();
     63     target_surface->damage_tracker()->UpdateDamageTrackingState(
     64         target_surface->layer_list(),
     65         target_surface->OwningLayerId(),
     66         target_surface->SurfacePropertyChangedOnlyFromDescendant(),
     67         target_surface->content_rect(),
     68         render_surface_layer_list[i]->mask_layer(),
     69         render_surface_layer_list[i]->filters());
     70   }
     71 
     72   root->ResetAllChangeTrackingForSubtree();
     73 }
     74 
     75 class DamageTrackerTest : public testing::Test {
     76  public:
     77   DamageTrackerTest() : host_impl_(&proxy_, &shared_bitmap_manager_) {}
     78 
     79   scoped_ptr<LayerImpl> CreateTestTreeWithOneSurface() {
     80     scoped_ptr<LayerImpl> root =
     81             LayerImpl::Create(host_impl_.active_tree(), 1);
     82     scoped_ptr<LayerImpl> child =
     83             LayerImpl::Create(host_impl_.active_tree(), 2);
     84 
     85     root->SetPosition(gfx::PointF());
     86     root->SetBounds(gfx::Size(500, 500));
     87     root->SetContentBounds(gfx::Size(500, 500));
     88     root->SetDrawsContent(true);
     89     root->CreateRenderSurface();
     90     root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500));
     91 
     92     child->SetPosition(gfx::PointF(100.f, 100.f));
     93     child->SetBounds(gfx::Size(30, 30));
     94     child->SetContentBounds(gfx::Size(30, 30));
     95     child->SetDrawsContent(true);
     96     root->AddChild(child.Pass());
     97 
     98     return root.Pass();
     99   }
    100 
    101   scoped_ptr<LayerImpl> CreateTestTreeWithTwoSurfaces() {
    102     // This test tree has two render surfaces: one for the root, and one for
    103     // child1. Additionally, the root has a second child layer, and child1 has
    104     // two children of its own.
    105 
    106     scoped_ptr<LayerImpl> root =
    107             LayerImpl::Create(host_impl_.active_tree(), 1);
    108     scoped_ptr<LayerImpl> child1 =
    109             LayerImpl::Create(host_impl_.active_tree(), 2);
    110     scoped_ptr<LayerImpl> child2 =
    111             LayerImpl::Create(host_impl_.active_tree(), 3);
    112     scoped_ptr<LayerImpl> grand_child1 =
    113             LayerImpl::Create(host_impl_.active_tree(), 4);
    114     scoped_ptr<LayerImpl> grand_child2 =
    115             LayerImpl::Create(host_impl_.active_tree(), 5);
    116 
    117     root->SetPosition(gfx::PointF());
    118     root->SetBounds(gfx::Size(500, 500));
    119     root->SetContentBounds(gfx::Size(500, 500));
    120     root->SetDrawsContent(true);
    121     root->CreateRenderSurface();
    122     root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500));
    123 
    124     child1->SetPosition(gfx::PointF(100.f, 100.f));
    125     child1->SetBounds(gfx::Size(30, 30));
    126     child1->SetContentBounds(gfx::Size(30, 30));
    127     // With a child that draws_content, opacity will cause the layer to create
    128     // its own RenderSurface. This layer does not draw, but is intended to
    129     // create its own RenderSurface. TODO: setting opacity and
    130     // ForceRenderSurface may be redundant here.
    131     child1->SetOpacity(0.5f);
    132     child1->SetDrawsContent(false);
    133     child1->SetForceRenderSurface(true);
    134 
    135     child2->SetPosition(gfx::PointF(11.f, 11.f));
    136     child2->SetBounds(gfx::Size(18, 18));
    137     child2->SetContentBounds(gfx::Size(18, 18));
    138     child2->SetDrawsContent(true);
    139 
    140     grand_child1->SetPosition(gfx::PointF(200.f, 200.f));
    141     grand_child1->SetBounds(gfx::Size(6, 8));
    142     grand_child1->SetContentBounds(gfx::Size(6, 8));
    143     grand_child1->SetDrawsContent(true);
    144 
    145     grand_child2->SetPosition(gfx::PointF(190.f, 190.f));
    146     grand_child2->SetBounds(gfx::Size(6, 8));
    147     grand_child2->SetContentBounds(gfx::Size(6, 8));
    148     grand_child2->SetDrawsContent(true);
    149 
    150     child1->AddChild(grand_child1.Pass());
    151     child1->AddChild(grand_child2.Pass());
    152     root->AddChild(child1.Pass());
    153     root->AddChild(child2.Pass());
    154 
    155     return root.Pass();
    156   }
    157 
    158   scoped_ptr<LayerImpl> CreateAndSetUpTestTreeWithOneSurface() {
    159     scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface();
    160 
    161     // Setup includes going past the first frame which always damages
    162     // everything, so that we can actually perform specific tests.
    163     EmulateDrawingOneFrame(root.get());
    164 
    165     return root.Pass();
    166   }
    167 
    168   scoped_ptr<LayerImpl> CreateAndSetUpTestTreeWithTwoSurfaces() {
    169     scoped_ptr<LayerImpl> root = CreateTestTreeWithTwoSurfaces();
    170 
    171     // Setup includes going past the first frame which always damages
    172     // everything, so that we can actually perform specific tests.
    173     EmulateDrawingOneFrame(root.get());
    174 
    175     return root.Pass();
    176   }
    177 
    178  protected:
    179   FakeImplProxy proxy_;
    180   TestSharedBitmapManager shared_bitmap_manager_;
    181   FakeLayerTreeHostImpl host_impl_;
    182 };
    183 
    184 TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) {
    185   // Sanity check that the simple test tree will actually produce the expected
    186   // render surfaces and layer lists.
    187 
    188   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    189 
    190   EXPECT_EQ(2u, root->render_surface()->layer_list().size());
    191   EXPECT_EQ(1, root->render_surface()->layer_list()[0]->id());
    192   EXPECT_EQ(2, root->render_surface()->layer_list()[1]->id());
    193 
    194   gfx::Rect root_damage_rect =
    195       root->render_surface()->damage_tracker()->current_damage_rect();
    196 
    197   EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString());
    198 }
    199 
    200 TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) {
    201   // Sanity check that the complex test tree will actually produce the expected
    202   // render surfaces and layer lists.
    203 
    204   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
    205 
    206   LayerImpl* child1 = root->children()[0];
    207   LayerImpl* child2 = root->children()[1];
    208   gfx::Rect child_damage_rect =
    209       child1->render_surface()->damage_tracker()->current_damage_rect();
    210   gfx::Rect root_damage_rect =
    211       root->render_surface()->damage_tracker()->current_damage_rect();
    212 
    213   ASSERT_TRUE(child1->render_surface());
    214   EXPECT_FALSE(child2->render_surface());
    215   EXPECT_EQ(3u, root->render_surface()->layer_list().size());
    216   EXPECT_EQ(2u, child1->render_surface()->layer_list().size());
    217 
    218   // The render surface for child1 only has a content_rect that encloses
    219   // grand_child1 and grand_child2, because child1 does not draw content.
    220   EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
    221             child_damage_rect.ToString());
    222   EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString());
    223 }
    224 
    225 TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) {
    226   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    227   LayerImpl* child = root->children()[0];
    228 
    229   // CASE 1: Setting the update rect should cause the corresponding damage to
    230   //         the surface.
    231   ClearDamageForAllSurfaces(root.get());
    232   child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
    233   EmulateDrawingOneFrame(root.get());
    234 
    235   // Damage position on the surface should be: position of update_rect (10, 11)
    236   // relative to the child (100, 100).
    237   gfx::Rect root_damage_rect =
    238       root->render_surface()->damage_tracker()->current_damage_rect();
    239   EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(),
    240             root_damage_rect.ToString());
    241 
    242   // CASE 2: The same update rect twice in a row still produces the same
    243   //         damage.
    244   ClearDamageForAllSurfaces(root.get());
    245   child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
    246   EmulateDrawingOneFrame(root.get());
    247   root_damage_rect =
    248           root->render_surface()->damage_tracker()->current_damage_rect();
    249   EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(),
    250             root_damage_rect.ToString());
    251 
    252   // CASE 3: Setting a different update rect should cause damage on the new
    253   //         update region, but no additional exposed old region.
    254   ClearDamageForAllSurfaces(root.get());
    255   child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
    256   EmulateDrawingOneFrame(root.get());
    257 
    258   // Damage position on the surface should be: position of update_rect (20, 25)
    259   // relative to the child (100, 100).
    260   root_damage_rect =
    261           root->render_surface()->damage_tracker()->current_damage_rect();
    262   EXPECT_EQ(gfx::Rect(120, 125, 1, 2).ToString(), root_damage_rect.ToString());
    263 }
    264 
    265 TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) {
    266   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    267   LayerImpl* child = root->children()[0];
    268 
    269   // CASE 1: Adding the layer damage rect should cause the corresponding damage
    270   // to the surface.
    271   ClearDamageForAllSurfaces(root.get());
    272   child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
    273   EmulateDrawingOneFrame(root.get());
    274 
    275   // Damage position on the surface should be: position of layer damage_rect
    276   // (10, 11) relative to the child (100, 100).
    277   gfx::Rect root_damage_rect =
    278       root->render_surface()->damage_tracker()->current_damage_rect();
    279   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13)));
    280 
    281   // CASE 2: The same layer damage rect twice in a row still produces the same
    282   // damage.
    283   ClearDamageForAllSurfaces(root.get());
    284   child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
    285   EmulateDrawingOneFrame(root.get());
    286   root_damage_rect =
    287       root->render_surface()->damage_tracker()->current_damage_rect();
    288   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13)));
    289 
    290   // CASE 3: Adding a different layer damage rect should cause damage on the
    291   // new damaged region, but no additional exposed old region.
    292   ClearDamageForAllSurfaces(root.get());
    293   child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
    294   EmulateDrawingOneFrame(root.get());
    295 
    296   // Damage position on the surface should be: position of layer damage_rect
    297   // (20, 25) relative to the child (100, 100).
    298   root_damage_rect =
    299       root->render_surface()->damage_tracker()->current_damage_rect();
    300   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2)));
    301 
    302   // CASE 4: Adding multiple layer damage rects should cause a unified
    303   // damage on root damage rect.
    304   ClearDamageForAllSurfaces(root.get());
    305   child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
    306   child->AddDamageRect(gfx::RectF(10.f, 15.f, 3.f, 4.f));
    307   EmulateDrawingOneFrame(root.get());
    308 
    309   // Damage position on the surface should be: position of layer damage_rect
    310   // (20, 25) relative to the child (100, 100).
    311   root_damage_rect =
    312       root->render_surface()->damage_tracker()->current_damage_rect();
    313   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2)));
    314   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 115, 3, 4)));
    315 }
    316 
    317 TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) {
    318   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    319   LayerImpl* child = root->children()[0];
    320 
    321   // CASE 1: Adding the layer damage rect and update rect should cause the
    322   // corresponding damage to the surface.
    323   ClearDamageForAllSurfaces(root.get());
    324   child->AddDamageRect(gfx::RectF(5.f, 6.f, 12.f, 13.f));
    325   child->SetUpdateRect(gfx::RectF(15.f, 16.f, 14.f, 10.f));
    326   EmulateDrawingOneFrame(root.get());
    327 
    328   // Damage position on the surface should be: position of unified layer
    329   // damage_rect and update rect (5, 6)
    330   // relative to the child (100, 100).
    331   gfx::Rect root_damage_rect =
    332       root->render_surface()->damage_tracker()->current_damage_rect();
    333   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 106, 24, 20)));
    334 
    335   // CASE 2: The same layer damage rect and update rect twice in a row still
    336   // produces the same damage.
    337   ClearDamageForAllSurfaces(root.get());
    338   child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
    339   child->SetUpdateRect(gfx::RectF(10.f, 11.f, 14.f, 15.f));
    340   EmulateDrawingOneFrame(root.get());
    341   root_damage_rect =
    342       root->render_surface()->damage_tracker()->current_damage_rect();
    343   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 14, 15)));
    344 
    345   // CASE 3: Adding a different layer damage rect and update rect should cause
    346   // damage on the new damaged region, but no additional exposed old region.
    347   ClearDamageForAllSurfaces(root.get());
    348   child->AddDamageRect(gfx::RectF(20.f, 25.f, 2.f, 3.f));
    349   child->SetUpdateRect(gfx::RectF(5.f, 10.f, 7.f, 8.f));
    350   EmulateDrawingOneFrame(root.get());
    351 
    352   // Damage position on the surface should be: position of unified layer damage
    353   // rect and update rect (5, 10) relative to the child (100, 100).
    354   root_damage_rect =
    355       root->render_surface()->damage_tracker()->current_damage_rect();
    356   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 110, 17, 18)));
    357 }
    358 
    359 TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) {
    360   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    361   LayerImpl* child = root->children()[0];
    362 
    363   // CASE 1: The layer's property changed flag takes priority over update rect.
    364   //
    365   ClearDamageForAllSurfaces(root.get());
    366   child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
    367   child->SetOpacity(0.5f);
    368   EmulateDrawingOneFrame(root.get());
    369 
    370   // Sanity check - we should not have accidentally created a separate render
    371   // surface for the translucent layer.
    372   ASSERT_FALSE(child->render_surface());
    373   ASSERT_EQ(2u, root->render_surface()->layer_list().size());
    374 
    375   // Damage should be the entire child layer in target_surface space.
    376   gfx::Rect expected_rect = gfx::Rect(100, 100, 30, 30);
    377   gfx::Rect root_damage_rect =
    378       root->render_surface()->damage_tracker()->current_damage_rect();
    379   EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString());
    380 
    381   // CASE 2: If a layer moves due to property change, it damages both the new
    382   //         location and the old (exposed) location. The old location is the
    383   //         entire old layer, not just the update_rect.
    384 
    385   // Cycle one frame of no change, just to sanity check that the next rect is
    386   // not because of the old damage state.
    387   ClearDamageForAllSurfaces(root.get());
    388   EmulateDrawingOneFrame(root.get());
    389   root_damage_rect =
    390           root->render_surface()->damage_tracker()->current_damage_rect();
    391   EXPECT_TRUE(root_damage_rect.IsEmpty());
    392 
    393   // Then, test the actual layer movement.
    394   ClearDamageForAllSurfaces(root.get());
    395   child->SetPosition(gfx::PointF(200.f, 230.f));
    396   EmulateDrawingOneFrame(root.get());
    397 
    398   // Expect damage to be the combination of the previous one and the new one.
    399   expected_rect.Union(gfx::Rect(200, 230, 30, 30));
    400   root_damage_rect =
    401           root->render_surface()->damage_tracker()->current_damage_rect();
    402   EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect);
    403 }
    404 
    405 TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) {
    406   // If a layer is transformed, the damage rect should still enclose the entire
    407   // transformed layer.
    408 
    409   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    410   LayerImpl* child = root->children()[0];
    411 
    412   gfx::Transform rotation;
    413   rotation.Rotate(45.0);
    414 
    415   ClearDamageForAllSurfaces(root.get());
    416   child->SetTransformOrigin(gfx::Point3F(
    417       child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f));
    418   child->SetPosition(gfx::PointF(85.f, 85.f));
    419   EmulateDrawingOneFrame(root.get());
    420 
    421   // Sanity check that the layer actually moved to (85, 85), damaging its old
    422   // location and new location.
    423   gfx::Rect root_damage_rect =
    424       root->render_surface()->damage_tracker()->current_damage_rect();
    425   EXPECT_EQ(gfx::Rect(85, 85, 45, 45).ToString(), root_damage_rect.ToString());
    426 
    427   // With the anchor on the layer's center, now we can test the rotation more
    428   // intuitively, since it applies about the layer's anchor.
    429   ClearDamageForAllSurfaces(root.get());
    430   child->SetTransform(rotation);
    431   EmulateDrawingOneFrame(root.get());
    432 
    433   // Since the child layer is square, rotation by 45 degrees about the center
    434   // should increase the size of the expected rect by sqrt(2), centered around
    435   // (100, 100). The old exposed region should be fully contained in the new
    436   // region.
    437   float expected_width = 30.f * sqrt(2.f);
    438   float expected_position = 100.f - 0.5f * expected_width;
    439   gfx::Rect expected_rect = gfx::ToEnclosingRect(gfx::RectF(
    440       expected_position, expected_position, expected_width, expected_width));
    441   root_damage_rect =
    442       root->render_surface()->damage_tracker()->current_damage_rect();
    443   EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString());
    444 }
    445 
    446 TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) {
    447   // If a layer has a perspective transform that causes w < 0, then not
    448   // clipping the layer can cause an invalid damage rect. This test checks that
    449   // the w < 0 case is tracked properly.
    450   //
    451   // The transform is constructed so that if w < 0 clipping is not performed,
    452   // the incorrect rect will be very small, specifically: position (500.972504,
    453   // 498.544617) and size 0.056610 x 2.910767.  Instead, the correctly
    454   // transformed rect should actually be very huge (i.e. in theory, -infinity
    455   // on the left), and positioned so that the right-most bound rect will be
    456   // approximately 501 units in root surface space.
    457   //
    458 
    459   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    460   LayerImpl* child = root->children()[0];
    461 
    462   gfx::Transform transform;
    463   transform.Translate3d(500.0, 500.0, 0.0);
    464   transform.ApplyPerspectiveDepth(1.0);
    465   transform.RotateAboutYAxis(45.0);
    466   transform.Translate3d(-50.0, -50.0, 0.0);
    467 
    468   // Set up the child
    469   child->SetPosition(gfx::PointF(0.f, 0.f));
    470   child->SetBounds(gfx::Size(100, 100));
    471   child->SetContentBounds(gfx::Size(100, 100));
    472   child->SetTransform(transform);
    473   EmulateDrawingOneFrame(root.get());
    474 
    475   // Sanity check that the child layer's bounds would actually get clipped by
    476   // w < 0, otherwise this test is not actually testing the intended scenario.
    477   gfx::QuadF test_quad(gfx::RectF(gfx::PointF(), gfx::SizeF(100.f, 100.f)));
    478   bool clipped = false;
    479   MathUtil::MapQuad(transform, test_quad, &clipped);
    480   EXPECT_TRUE(clipped);
    481 
    482   // Damage the child without moving it.
    483   ClearDamageForAllSurfaces(root.get());
    484   child->SetOpacity(0.5f);
    485   EmulateDrawingOneFrame(root.get());
    486 
    487   // The expected damage should cover the entire root surface (500x500), but we
    488   // don't care whether the damage rect was clamped or is larger than the
    489   // surface for this test.
    490   gfx::Rect root_damage_rect =
    491       root->render_surface()->damage_tracker()->current_damage_rect();
    492   gfx::Rect damage_we_care_about = gfx::Rect(gfx::Size(500, 500));
    493   EXPECT_TRUE(root_damage_rect.Contains(damage_we_care_about));
    494 }
    495 
    496 TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) {
    497   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
    498   LayerImpl* surface = root->children()[0];
    499   LayerImpl* child = surface->children()[0];
    500 
    501   FilterOperations filters;
    502   filters.Append(FilterOperation::CreateBlurFilter(5.f));
    503   int outset_top, outset_right, outset_bottom, outset_left;
    504   filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left);
    505 
    506   // Setting the filter will damage the whole surface.
    507   ClearDamageForAllSurfaces(root.get());
    508   surface->SetFilters(filters);
    509   EmulateDrawingOneFrame(root.get());
    510 
    511   // Setting the update rect should cause the corresponding damage to the
    512   // surface, blurred based on the size of the blur filter.
    513   ClearDamageForAllSurfaces(root.get());
    514   child->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f));
    515   EmulateDrawingOneFrame(root.get());
    516 
    517   // Damage position on the surface should be: position of update_rect (1, 2)
    518   // relative to the child (300, 300), but expanded by the blur outsets.
    519   gfx::Rect root_damage_rect =
    520       root->render_surface()->damage_tracker()->current_damage_rect();
    521   gfx::Rect expected_damage_rect = gfx::Rect(301, 302, 3, 4);
    522 
    523   expected_damage_rect.Inset(-outset_left,
    524                              -outset_top,
    525                              -outset_right,
    526                              -outset_bottom);
    527   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
    528 }
    529 
    530 TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) {
    531   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    532   LayerImpl* child = root->children()[0];
    533   gfx::Rect root_damage_rect, child_damage_rect;
    534 
    535   // Allow us to set damage on child too.
    536   child->SetDrawsContent(true);
    537 
    538   skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
    539       SkBlurImageFilter::Create(SkIntToScalar(2), SkIntToScalar(2)));
    540   FilterOperations filters;
    541   filters.Append(FilterOperation::CreateReferenceFilter(filter));
    542 
    543   // Setting the filter will damage the whole surface.
    544   ClearDamageForAllSurfaces(root.get());
    545   child->SetFilters(filters);
    546   EmulateDrawingOneFrame(root.get());
    547   root_damage_rect =
    548           root->render_surface()->damage_tracker()->current_damage_rect();
    549   child_damage_rect =
    550           child->render_surface()->damage_tracker()->current_damage_rect();
    551   EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
    552             root_damage_rect.ToString());
    553   EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
    554 
    555   // CASE 1: Setting the update rect should damage the whole surface (for now)
    556   ClearDamageForAllSurfaces(root.get());
    557   child->SetUpdateRect(gfx::RectF(1.f, 1.f));
    558   EmulateDrawingOneFrame(root.get());
    559 
    560   root_damage_rect =
    561           root->render_surface()->damage_tracker()->current_damage_rect();
    562   child_damage_rect =
    563           child->render_surface()->damage_tracker()->current_damage_rect();
    564   EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
    565             root_damage_rect.ToString());
    566   EXPECT_EQ(gfx::Rect(30.f, 30.f).ToString(), child_damage_rect.ToString());
    567 }
    568 
    569 TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) {
    570   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
    571   LayerImpl* child1 = root->children()[0];
    572   LayerImpl* child2 = root->children()[1];
    573 
    574   // Allow us to set damage on child1 too.
    575   child1->SetDrawsContent(true);
    576 
    577   FilterOperations filters;
    578   filters.Append(FilterOperation::CreateBlurFilter(2.f));
    579   int outset_top, outset_right, outset_bottom, outset_left;
    580   filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left);
    581 
    582   // Setting the filter will damage the whole surface.
    583   ClearDamageForAllSurfaces(root.get());
    584   child1->SetBackgroundFilters(filters);
    585   EmulateDrawingOneFrame(root.get());
    586 
    587   // CASE 1: Setting the update rect should cause the corresponding damage to
    588   //         the surface, blurred based on the size of the child's background
    589   //         blur filter.
    590   ClearDamageForAllSurfaces(root.get());
    591   root->SetUpdateRect(gfx::RectF(297.f, 297.f, 2.f, 2.f));
    592   EmulateDrawingOneFrame(root.get());
    593 
    594   gfx::Rect root_damage_rect =
    595       root->render_surface()->damage_tracker()->current_damage_rect();
    596   // Damage position on the surface should be a composition of the damage on
    597   // the root and on child2.  Damage on the root should be: position of
    598   // update_rect (297, 297), but expanded by the blur outsets.
    599   gfx::Rect expected_damage_rect = gfx::Rect(297, 297, 2, 2);
    600 
    601   expected_damage_rect.Inset(-outset_left,
    602                              -outset_top,
    603                              -outset_right,
    604                              -outset_bottom);
    605   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
    606 
    607   // CASE 2: Setting the update rect should cause the corresponding damage to
    608   //         the surface, blurred based on the size of the child's background
    609   //         blur filter. Since the damage extends to the right/bottom outside
    610   //         of the blurred layer, only the left/top should end up expanded.
    611   ClearDamageForAllSurfaces(root.get());
    612   root->SetUpdateRect(gfx::RectF(297.f, 297.f, 30.f, 30.f));
    613   EmulateDrawingOneFrame(root.get());
    614 
    615   root_damage_rect =
    616           root->render_surface()->damage_tracker()->current_damage_rect();
    617   // Damage position on the surface should be a composition of the damage on
    618   // the root and on child2.  Damage on the root should be: position of
    619   // update_rect (297, 297), but expanded on the left/top by the blur outsets.
    620   expected_damage_rect = gfx::Rect(297, 297, 30, 30);
    621 
    622   expected_damage_rect.Inset(-outset_left,
    623                              -outset_top,
    624                              0,
    625                              0);
    626   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
    627 
    628   // CASE 3: Setting this update rect outside the blurred content_bounds of the
    629   //         blurred child1 will not cause it to be expanded.
    630   ClearDamageForAllSurfaces(root.get());
    631   root->SetUpdateRect(gfx::RectF(30.f, 30.f, 2.f, 2.f));
    632   EmulateDrawingOneFrame(root.get());
    633 
    634   root_damage_rect =
    635           root->render_surface()->damage_tracker()->current_damage_rect();
    636   // Damage on the root should be: position of update_rect (30, 30), not
    637   // expanded.
    638   expected_damage_rect = gfx::Rect(30, 30, 2, 2);
    639 
    640   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
    641 
    642   // CASE 4: Setting this update rect inside the blurred content_bounds but
    643   //         outside the original content_bounds of the blurred child1 will
    644   //         cause it to be expanded.
    645   ClearDamageForAllSurfaces(root.get());
    646   root->SetUpdateRect(gfx::RectF(99.f, 99.f, 1.f, 1.f));
    647   EmulateDrawingOneFrame(root.get());
    648 
    649   root_damage_rect =
    650           root->render_surface()->damage_tracker()->current_damage_rect();
    651   // Damage on the root should be: position of update_rect (99, 99), expanded by
    652   // the blurring on child1, but since it is 1 pixel outside the layer, the
    653   // expanding should be reduced by 1.
    654   expected_damage_rect = gfx::Rect(99, 99, 1, 1);
    655 
    656   expected_damage_rect.Inset(-outset_left + 1,
    657                              -outset_top + 1,
    658                              -outset_right,
    659                              -outset_bottom);
    660   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
    661 
    662   // CASE 5: Setting the update rect on child2, which is above child1, will
    663   // not get blurred by child1, so it does not need to get expanded.
    664   ClearDamageForAllSurfaces(root.get());
    665   child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f));
    666   EmulateDrawingOneFrame(root.get());
    667 
    668   root_damage_rect =
    669           root->render_surface()->damage_tracker()->current_damage_rect();
    670   // Damage on child2 should be: position of update_rect offset by the child's
    671   // position (11, 11), and not expanded by anything.
    672   expected_damage_rect = gfx::Rect(11, 11, 1, 1);
    673 
    674   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
    675 
    676   // CASE 6: Setting the update rect on child1 will also blur the damage, so
    677   //         that any pixels needed for the blur are redrawn in the current
    678   //         frame.
    679   ClearDamageForAllSurfaces(root.get());
    680   child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f));
    681   EmulateDrawingOneFrame(root.get());
    682 
    683   root_damage_rect =
    684           root->render_surface()->damage_tracker()->current_damage_rect();
    685   // Damage on child1 should be: position of update_rect offset by the child's
    686   // position (100, 100), and expanded by the damage.
    687   expected_damage_rect = gfx::Rect(100, 100, 1, 1);
    688 
    689   expected_damage_rect.Inset(-outset_left,
    690                              -outset_top,
    691                              -outset_right,
    692                              -outset_bottom);
    693   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
    694 }
    695 
    696 TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) {
    697   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    698   LayerImpl* child1 = root->children()[0];
    699 
    700   // CASE 1: Adding a new layer should cause the appropriate damage.
    701   //
    702   ClearDamageForAllSurfaces(root.get());
    703   {
    704     scoped_ptr<LayerImpl> child2 =
    705             LayerImpl::Create(host_impl_.active_tree(), 3);
    706     child2->SetPosition(gfx::PointF(400.f, 380.f));
    707     child2->SetBounds(gfx::Size(6, 8));
    708     child2->SetContentBounds(gfx::Size(6, 8));
    709     child2->SetDrawsContent(true);
    710     root->AddChild(child2.Pass());
    711   }
    712   EmulateDrawingOneFrame(root.get());
    713 
    714   // Sanity check - all 3 layers should be on the same render surface; render
    715   // surfaces are tested elsewhere.
    716   ASSERT_EQ(3u, root->render_surface()->layer_list().size());
    717 
    718   gfx::Rect root_damage_rect =
    719       root->render_surface()->damage_tracker()->current_damage_rect();
    720   EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString());
    721 
    722   // CASE 2: If the layer is removed, its entire old layer becomes exposed, not
    723   //         just the last update rect.
    724 
    725   // Advance one frame without damage so that we know the damage rect is not
    726   // leftover from the previous case.
    727   ClearDamageForAllSurfaces(root.get());
    728   EmulateDrawingOneFrame(root.get());
    729 
    730   root_damage_rect =
    731           root->render_surface()->damage_tracker()->current_damage_rect();
    732   EXPECT_TRUE(root_damage_rect.IsEmpty());
    733 
    734   // Then, test removing child1.
    735   root->RemoveChild(child1);
    736   child1 = NULL;
    737   EmulateDrawingOneFrame(root.get());
    738 
    739   root_damage_rect =
    740           root->render_surface()->damage_tracker()->current_damage_rect();
    741   EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
    742             root_damage_rect.ToString());
    743 }
    744 
    745 TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) {
    746   // If child2 is added to the layer tree, but it doesn't have any explicit
    747   // damage of its own, it should still indeed damage the target surface.
    748 
    749   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    750 
    751   ClearDamageForAllSurfaces(root.get());
    752   {
    753     scoped_ptr<LayerImpl> child2 =
    754             LayerImpl::Create(host_impl_.active_tree(), 3);
    755     child2->SetPosition(gfx::PointF(400.f, 380.f));
    756     child2->SetBounds(gfx::Size(6, 8));
    757     child2->SetContentBounds(gfx::Size(6, 8));
    758     child2->SetDrawsContent(true);
    759     child2->ResetAllChangeTrackingForSubtree();
    760     // Sanity check the initial conditions of the test, if these asserts
    761     // trigger, it means the test no longer actually covers the intended
    762     // scenario.
    763     ASSERT_FALSE(child2->LayerPropertyChanged());
    764     ASSERT_TRUE(child2->update_rect().IsEmpty());
    765     root->AddChild(child2.Pass());
    766   }
    767   EmulateDrawingOneFrame(root.get());
    768 
    769   // Sanity check - all 3 layers should be on the same render surface; render
    770   // surfaces are tested elsewhere.
    771   ASSERT_EQ(3u, root->render_surface()->layer_list().size());
    772 
    773   gfx::Rect root_damage_rect =
    774       root->render_surface()->damage_tracker()->current_damage_rect();
    775   EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString());
    776 }
    777 
    778 TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) {
    779   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
    780   LayerImpl* child1 = root->children()[0];
    781 
    782   // In this test we don't want the above tree manipulation to be considered
    783   // part of the same frame.
    784   ClearDamageForAllSurfaces(root.get());
    785   {
    786     scoped_ptr<LayerImpl> child2 =
    787             LayerImpl::Create(host_impl_.active_tree(), 3);
    788     child2->SetPosition(gfx::PointF(400.f, 380.f));
    789     child2->SetBounds(gfx::Size(6, 8));
    790     child2->SetContentBounds(gfx::Size(6, 8));
    791     child2->SetDrawsContent(true);
    792     root->AddChild(child2.Pass());
    793   }
    794   LayerImpl* child2 = root->children()[1];
    795   EmulateDrawingOneFrame(root.get());
    796 
    797   // Damaging two layers simultaneously should cause combined damage.
    798   // - child1 update rect in surface space: gfx::Rect(100, 100, 1, 2);
    799   // - child2 update rect in surface space: gfx::Rect(400, 380, 3, 4);
    800   ClearDamageForAllSurfaces(root.get());
    801   child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f));
    802   child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 3.f, 4.f));
    803   EmulateDrawingOneFrame(root.get());
    804   gfx::Rect root_damage_rect =
    805       root->render_surface()->damage_tracker()->current_damage_rect();
    806   EXPECT_EQ(gfx::Rect(100, 100, 303, 284).ToString(),
    807             root_damage_rect.ToString());
    808 }
    809 
    810 TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) {
    811   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
    812   LayerImpl* child1 = root->children()[0];
    813   LayerImpl* child2 = root->children()[1];
    814   LayerImpl* grand_child1 = root->children()[0]->children()[0];
    815   gfx::Rect child_damage_rect;
    816   gfx::Rect root_damage_rect;
    817 
    818   // CASE 1: Damage to a descendant surface should propagate properly to
    819   //         ancestor surface.
    820   ClearDamageForAllSurfaces(root.get());
    821   grand_child1->SetOpacity(0.5f);
    822   EmulateDrawingOneFrame(root.get());
    823   child_damage_rect =
    824           child1->render_surface()->damage_tracker()->current_damage_rect();
    825   root_damage_rect =
    826           root->render_surface()->damage_tracker()->current_damage_rect();
    827   EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString());
    828   EXPECT_EQ(gfx::Rect(300, 300, 6, 8).ToString(), root_damage_rect.ToString());
    829 
    830   // CASE 2: Same as previous case, but with additional damage elsewhere that
    831   //         should be properly unioned.
    832   // - child1 surface damage in root surface space:
    833   //   gfx::Rect(300, 300, 6, 8);
    834   // - child2 damage in root surface space:
    835   //   gfx::Rect(11, 11, 18, 18);
    836   ClearDamageForAllSurfaces(root.get());
    837   grand_child1->SetOpacity(0.7f);
    838   child2->SetOpacity(0.7f);
    839   EmulateDrawingOneFrame(root.get());
    840   child_damage_rect =
    841           child1->render_surface()->damage_tracker()->current_damage_rect();
    842   root_damage_rect =
    843           root->render_surface()->damage_tracker()->current_damage_rect();
    844   EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString());
    845   EXPECT_EQ(gfx::Rect(11, 11, 295, 297).ToString(),
    846             root_damage_rect.ToString());
    847 }
    848 
    849 TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) {
    850   // If descendant layer changes and affects the content bounds of the render
    851   // surface, then the entire descendant surface should be damaged, and it
    852   // should damage its ancestor surface with the old and new surface regions.
    853 
    854   // This is a tricky case, since only the first grand_child changes, but the
    855   // entire surface should be marked dirty.
    856 
    857   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
    858   LayerImpl* child1 = root->children()[0];
    859   LayerImpl* grand_child1 = root->children()[0]->children()[0];
    860   gfx::Rect child_damage_rect;
    861   gfx::Rect root_damage_rect;
    862 
    863   ClearDamageForAllSurfaces(root.get());
    864   grand_child1->SetPosition(gfx::PointF(195.f, 205.f));
    865   EmulateDrawingOneFrame(root.get());
    866   child_damage_rect =
    867           child1->render_surface()->damage_tracker()->current_damage_rect();
    868   root_damage_rect =
    869           root->render_surface()->damage_tracker()->current_damage_rect();
    870 
    871   // The new surface bounds should be damaged entirely, even though only one of
    872   // the layers changed.
    873   EXPECT_EQ(gfx::Rect(190, 190, 11, 23).ToString(),
    874             child_damage_rect.ToString());
    875 
    876   // Damage to the root surface should be the union of child1's *entire* render
    877   // surface (in target space), and its old exposed area (also in target
    878   // space).
    879   EXPECT_EQ(gfx::Rect(290, 290, 16, 23).ToString(),
    880             root_damage_rect.ToString());
    881 }
    882 
    883 TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) {
    884   // An ancestor/owning layer changes that affects the position/transform of
    885   // the render surface. Note that in this case, the layer_property_changed flag
    886   // already propagates to the subtree (tested in LayerImpltest), which damages
    887   // the entire child1 surface, but the damage tracker still needs the correct
    888   // logic to compute the exposed region on the root surface.
    889 
    890   // TODO(shawnsingh): the expectations of this test case should change when we
    891   // add support for a unique scissor_rect per RenderSurface. In that case, the
    892   // child1 surface should be completely unchanged, since we are only
    893   // transforming it, while the root surface would be damaged appropriately.
    894 
    895   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
    896   LayerImpl* child1 = root->children()[0];
    897   gfx::Rect child_damage_rect;
    898   gfx::Rect root_damage_rect;
    899 
    900   ClearDamageForAllSurfaces(root.get());
    901   child1->SetPosition(gfx::PointF(50.f, 50.f));
    902   EmulateDrawingOneFrame(root.get());
    903   child_damage_rect =
    904           child1->render_surface()->damage_tracker()->current_damage_rect();
    905   root_damage_rect =
    906           root->render_surface()->damage_tracker()->current_damage_rect();
    907 
    908   // The new surface bounds should be damaged entirely.
    909   EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
    910             child_damage_rect.ToString());
    911 
    912   // The entire child1 surface and the old exposed child1 surface should damage
    913   // the root surface.
    914   //  - old child1 surface in target space: gfx::Rect(290, 290, 16, 18)
    915   //  - new child1 surface in target space: gfx::Rect(240, 240, 16, 18)
    916   EXPECT_EQ(gfx::Rect(240, 240, 66, 68).ToString(),
    917             root_damage_rect.ToString());
    918 }
    919 
    920 TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) {
    921   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
    922   LayerImpl* child1 = root->children()[0];
    923   gfx::Rect child_damage_rect;
    924   gfx::Rect root_damage_rect;
    925 
    926   // CASE 1: If a descendant surface disappears, its entire old area becomes
    927   //         exposed.
    928   ClearDamageForAllSurfaces(root.get());
    929   child1->SetOpacity(1.f);
    930   child1->SetForceRenderSurface(false);
    931   EmulateDrawingOneFrame(root.get());
    932 
    933   // Sanity check that there is only one surface now.
    934   ASSERT_FALSE(child1->render_surface());
    935   ASSERT_EQ(4u, root->render_surface()->layer_list().size());
    936 
    937   root_damage_rect =
    938           root->render_surface()->damage_tracker()->current_damage_rect();
    939   EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(),
    940             root_damage_rect.ToString());
    941 
    942   // CASE 2: If a descendant surface appears, its entire old area becomes
    943   //         exposed.
    944 
    945   // Cycle one frame of no change, just to sanity check that the next rect is
    946   // not because of the old damage state.
    947   ClearDamageForAllSurfaces(root.get());
    948   EmulateDrawingOneFrame(root.get());
    949   root_damage_rect =
    950           root->render_surface()->damage_tracker()->current_damage_rect();
    951   EXPECT_TRUE(root_damage_rect.IsEmpty());
    952 
    953   // Then change the tree so that the render surface is added back.
    954   ClearDamageForAllSurfaces(root.get());
    955   child1->SetOpacity(0.5f);
    956   child1->SetForceRenderSurface(true);
    957   EmulateDrawingOneFrame(root.get());
    958 
    959   // Sanity check that there is a new surface now.
    960   ASSERT_TRUE(child1->render_surface());
    961   EXPECT_EQ(3u, root->render_surface()->layer_list().size());
    962   EXPECT_EQ(2u, child1->render_surface()->layer_list().size());
    963 
    964   child_damage_rect =
    965           child1->render_surface()->damage_tracker()->current_damage_rect();
    966   root_damage_rect =
    967           root->render_surface()->damage_tracker()->current_damage_rect();
    968   EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
    969             child_damage_rect.ToString());
    970   EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(),
    971             root_damage_rect.ToString());
    972 }
    973 
    974 TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) {
    975   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
    976   LayerImpl* child1 = root->children()[0];
    977   gfx::Rect child_damage_rect;
    978   gfx::Rect root_damage_rect;
    979 
    980   // CASE 1: If nothing changes, the damage rect should be empty.
    981   //
    982   ClearDamageForAllSurfaces(root.get());
    983   EmulateDrawingOneFrame(root.get());
    984   child_damage_rect =
    985           child1->render_surface()->damage_tracker()->current_damage_rect();
    986   root_damage_rect =
    987           root->render_surface()->damage_tracker()->current_damage_rect();
    988   EXPECT_TRUE(child_damage_rect.IsEmpty());
    989   EXPECT_TRUE(root_damage_rect.IsEmpty());
    990 
    991   // CASE 2: If nothing changes twice in a row, the damage rect should still be
    992   //         empty.
    993   //
    994   ClearDamageForAllSurfaces(root.get());
    995   EmulateDrawingOneFrame(root.get());
    996   child_damage_rect =
    997           child1->render_surface()->damage_tracker()->current_damage_rect();
    998   root_damage_rect =
    999           root->render_surface()->damage_tracker()->current_damage_rect();
   1000   EXPECT_TRUE(child_damage_rect.IsEmpty());
   1001   EXPECT_TRUE(root_damage_rect.IsEmpty());
   1002 }
   1003 
   1004 TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) {
   1005   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
   1006   LayerImpl* child1 = root->children()[0];
   1007   gfx::Rect child_damage_rect;
   1008   gfx::Rect root_damage_rect;
   1009 
   1010   // In our specific tree, the update rect of child1 should not cause any
   1011   // damage to any surface because it does not actually draw content.
   1012   ClearDamageForAllSurfaces(root.get());
   1013   child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f));
   1014   EmulateDrawingOneFrame(root.get());
   1015   child_damage_rect =
   1016           child1->render_surface()->damage_tracker()->current_damage_rect();
   1017   root_damage_rect =
   1018           root->render_surface()->damage_tracker()->current_damage_rect();
   1019   EXPECT_TRUE(child_damage_rect.IsEmpty());
   1020   EXPECT_TRUE(root_damage_rect.IsEmpty());
   1021 }
   1022 
   1023 TEST_F(DamageTrackerTest, VerifyDamageForReplica) {
   1024   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
   1025   LayerImpl* child1 = root->children()[0];
   1026   LayerImpl* grand_child1 = child1->children()[0];
   1027   LayerImpl* grand_child2 = child1->children()[1];
   1028 
   1029   // Damage on a surface that has a reflection should cause the target surface
   1030   // to receive the surface's damage and the surface's reflected damage.
   1031 
   1032   // For this test case, we modify grand_child2, and add grand_child3 to extend
   1033   // the bounds of child1's surface. This way, we can test reflection changes
   1034   // without changing content_bounds of the surface.
   1035   grand_child2->SetPosition(gfx::PointF(180.f, 180.f));
   1036   {
   1037     scoped_ptr<LayerImpl> grand_child3 =
   1038             LayerImpl::Create(host_impl_.active_tree(), 6);
   1039     grand_child3->SetPosition(gfx::PointF(240.f, 240.f));
   1040     grand_child3->SetBounds(gfx::Size(10, 10));
   1041     grand_child3->SetContentBounds(gfx::Size(10, 10));
   1042     grand_child3->SetDrawsContent(true);
   1043     child1->AddChild(grand_child3.Pass());
   1044   }
   1045   child1->SetOpacity(0.5f);
   1046   EmulateDrawingOneFrame(root.get());
   1047 
   1048   // CASE 1: adding a reflection about the left edge of grand_child1.
   1049   //
   1050   ClearDamageForAllSurfaces(root.get());
   1051   {
   1052     scoped_ptr<LayerImpl> grand_child1_replica =
   1053             LayerImpl::Create(host_impl_.active_tree(), 7);
   1054     grand_child1_replica->SetPosition(gfx::PointF());
   1055     gfx::Transform reflection;
   1056     reflection.Scale3d(-1.0, 1.0, 1.0);
   1057     grand_child1_replica->SetTransform(reflection);
   1058     grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
   1059   }
   1060   EmulateDrawingOneFrame(root.get());
   1061 
   1062   gfx::Rect grand_child_damage_rect =
   1063       grand_child1->render_surface()->damage_tracker()->current_damage_rect();
   1064   gfx::Rect child_damage_rect =
   1065       child1->render_surface()->damage_tracker()->current_damage_rect();
   1066   gfx::Rect root_damage_rect =
   1067       root->render_surface()->damage_tracker()->current_damage_rect();
   1068 
   1069   // The grand_child surface damage should not include its own replica. The
   1070   // child surface damage should include the normal and replica surfaces.
   1071   EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString());
   1072   EXPECT_EQ(gfx::Rect(194, 200, 12, 8).ToString(),
   1073             child_damage_rect.ToString());
   1074   EXPECT_EQ(gfx::Rect(294, 300, 12, 8).ToString(), root_damage_rect.ToString());
   1075 
   1076   // CASE 2: moving the descendant surface should cause both the original and
   1077   //         reflected areas to be damaged on the target.
   1078   ClearDamageForAllSurfaces(root.get());
   1079   gfx::Rect old_content_rect = child1->render_surface()->content_rect();
   1080   grand_child1->SetPosition(gfx::PointF(195.f, 205.f));
   1081   EmulateDrawingOneFrame(root.get());
   1082   ASSERT_EQ(old_content_rect.width(),
   1083             child1->render_surface()->content_rect().width());
   1084   ASSERT_EQ(old_content_rect.height(),
   1085             child1->render_surface()->content_rect().height());
   1086 
   1087   grand_child_damage_rect =
   1088           grand_child1->render_surface()->
   1089               damage_tracker()->current_damage_rect();
   1090   child_damage_rect =
   1091           child1->render_surface()->damage_tracker()->current_damage_rect();
   1092   root_damage_rect =
   1093           root->render_surface()->damage_tracker()->current_damage_rect();
   1094 
   1095   // The child surface damage should include normal and replica surfaces for
   1096   // both old and new locations.
   1097   //  - old location in target space: gfx::Rect(194, 200, 12, 8)
   1098   //  - new location in target space: gfx::Rect(189, 205, 12, 8)
   1099   EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString());
   1100   EXPECT_EQ(gfx::Rect(189, 200, 17, 13).ToString(),
   1101             child_damage_rect.ToString());
   1102   EXPECT_EQ(gfx::Rect(289, 300, 17, 13).ToString(),
   1103             root_damage_rect.ToString());
   1104 
   1105   // CASE 3: removing the reflection should cause the entire region including
   1106   //         reflection to damage the target surface.
   1107   ClearDamageForAllSurfaces(root.get());
   1108   grand_child1->SetReplicaLayer(scoped_ptr<LayerImpl>());
   1109   EmulateDrawingOneFrame(root.get());
   1110   ASSERT_EQ(old_content_rect.width(),
   1111             child1->render_surface()->content_rect().width());
   1112   ASSERT_EQ(old_content_rect.height(),
   1113             child1->render_surface()->content_rect().height());
   1114 
   1115   EXPECT_FALSE(grand_child1->render_surface());
   1116   child_damage_rect =
   1117           child1->render_surface()->damage_tracker()->current_damage_rect();
   1118   root_damage_rect =
   1119           root->render_surface()->damage_tracker()->current_damage_rect();
   1120 
   1121   EXPECT_EQ(gfx::Rect(189, 205, 12, 8).ToString(),
   1122             child_damage_rect.ToString());
   1123   EXPECT_EQ(gfx::Rect(289, 305, 12, 8).ToString(), root_damage_rect.ToString());
   1124 }
   1125 
   1126 TEST_F(DamageTrackerTest, VerifyDamageForMask) {
   1127   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
   1128   LayerImpl* child = root->children()[0];
   1129 
   1130   // In the current implementation of the damage tracker, changes to mask
   1131   // layers should damage the entire corresponding surface.
   1132 
   1133   ClearDamageForAllSurfaces(root.get());
   1134 
   1135   // Set up the mask layer.
   1136   {
   1137     scoped_ptr<LayerImpl> mask_layer =
   1138             LayerImpl::Create(host_impl_.active_tree(), 3);
   1139     mask_layer->SetPosition(child->position());
   1140     mask_layer->SetBounds(child->bounds());
   1141     mask_layer->SetContentBounds(child->bounds());
   1142     child->SetMaskLayer(mask_layer.Pass());
   1143   }
   1144   LayerImpl* mask_layer = child->mask_layer();
   1145 
   1146   // Add opacity and a grand_child so that the render surface persists even
   1147   // after we remove the mask.
   1148   child->SetOpacity(0.5f);
   1149   {
   1150     scoped_ptr<LayerImpl> grand_child =
   1151             LayerImpl::Create(host_impl_.active_tree(), 4);
   1152     grand_child->SetPosition(gfx::PointF(2.f, 2.f));
   1153     grand_child->SetBounds(gfx::Size(2, 2));
   1154     grand_child->SetContentBounds(gfx::Size(2, 2));
   1155     grand_child->SetDrawsContent(true);
   1156     child->AddChild(grand_child.Pass());
   1157   }
   1158   EmulateDrawingOneFrame(root.get());
   1159 
   1160   // Sanity check that a new surface was created for the child.
   1161   ASSERT_TRUE(child->render_surface());
   1162 
   1163   // CASE 1: the update_rect on a mask layer should damage the entire target
   1164   //         surface.
   1165   ClearDamageForAllSurfaces(root.get());
   1166   mask_layer->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f));
   1167   EmulateDrawingOneFrame(root.get());
   1168   gfx::Rect child_damage_rect =
   1169       child->render_surface()->damage_tracker()->current_damage_rect();
   1170   EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
   1171 
   1172   // CASE 2: a property change on the mask layer should damage the entire
   1173   //         target surface.
   1174 
   1175   // Advance one frame without damage so that we know the damage rect is not
   1176   // leftover from the previous case.
   1177   ClearDamageForAllSurfaces(root.get());
   1178   EmulateDrawingOneFrame(root.get());
   1179   child_damage_rect =
   1180           child->render_surface()->damage_tracker()->current_damage_rect();
   1181   EXPECT_TRUE(child_damage_rect.IsEmpty());
   1182 
   1183   // Then test the property change.
   1184   ClearDamageForAllSurfaces(root.get());
   1185   mask_layer->SetStackingOrderChanged(true);
   1186 
   1187   EmulateDrawingOneFrame(root.get());
   1188   child_damage_rect =
   1189           child->render_surface()->damage_tracker()->current_damage_rect();
   1190   EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
   1191 
   1192   // CASE 3: removing the mask also damages the entire target surface.
   1193   //
   1194 
   1195   // Advance one frame without damage so that we know the damage rect is not
   1196   // leftover from the previous case.
   1197   ClearDamageForAllSurfaces(root.get());
   1198   EmulateDrawingOneFrame(root.get());
   1199   child_damage_rect =
   1200           child->render_surface()->damage_tracker()->current_damage_rect();
   1201   EXPECT_TRUE(child_damage_rect.IsEmpty());
   1202 
   1203   // Then test mask removal.
   1204   ClearDamageForAllSurfaces(root.get());
   1205   child->SetMaskLayer(scoped_ptr<LayerImpl>());
   1206   ASSERT_TRUE(child->LayerPropertyChanged());
   1207   EmulateDrawingOneFrame(root.get());
   1208 
   1209   // Sanity check that a render surface still exists.
   1210   ASSERT_TRUE(child->render_surface());
   1211 
   1212   child_damage_rect =
   1213           child->render_surface()->damage_tracker()->current_damage_rect();
   1214   EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
   1215 }
   1216 
   1217 TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) {
   1218   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
   1219   LayerImpl* child1 = root->children()[0];
   1220   LayerImpl* grand_child1 = child1->children()[0];
   1221 
   1222   // Changes to a replica's mask should not damage the original surface,
   1223   // because it is not masked. But it does damage the ancestor target surface.
   1224 
   1225   ClearDamageForAllSurfaces(root.get());
   1226 
   1227   // Create a reflection about the left edge of grand_child1.
   1228   {
   1229     scoped_ptr<LayerImpl> grand_child1_replica =
   1230             LayerImpl::Create(host_impl_.active_tree(), 6);
   1231     grand_child1_replica->SetPosition(gfx::PointF());
   1232     gfx::Transform reflection;
   1233     reflection.Scale3d(-1.0, 1.0, 1.0);
   1234     grand_child1_replica->SetTransform(reflection);
   1235     grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
   1236   }
   1237   LayerImpl* grand_child1_replica = grand_child1->replica_layer();
   1238 
   1239   // Set up the mask layer on the replica layer
   1240   {
   1241     scoped_ptr<LayerImpl> replica_mask_layer =
   1242             LayerImpl::Create(host_impl_.active_tree(), 7);
   1243     replica_mask_layer->SetPosition(gfx::PointF());
   1244     replica_mask_layer->SetBounds(grand_child1->bounds());
   1245     replica_mask_layer->SetContentBounds(grand_child1->bounds());
   1246     grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass());
   1247   }
   1248   LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer();
   1249 
   1250   EmulateDrawingOneFrame(root.get());
   1251 
   1252   // Sanity check that the appropriate render surfaces were created
   1253   ASSERT_TRUE(grand_child1->render_surface());
   1254 
   1255   // CASE 1: a property change on the mask should damage only the reflected
   1256   //         region on the target surface.
   1257   ClearDamageForAllSurfaces(root.get());
   1258   replica_mask_layer->SetStackingOrderChanged(true);
   1259   EmulateDrawingOneFrame(root.get());
   1260 
   1261   gfx::Rect grand_child_damage_rect =
   1262       grand_child1->render_surface()->damage_tracker()->current_damage_rect();
   1263   gfx::Rect child_damage_rect =
   1264       child1->render_surface()->damage_tracker()->current_damage_rect();
   1265 
   1266   EXPECT_TRUE(grand_child_damage_rect.IsEmpty());
   1267   EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString());
   1268 
   1269   // CASE 2: removing the replica mask damages only the reflected region on the
   1270   //         target surface.
   1271   //
   1272   ClearDamageForAllSurfaces(root.get());
   1273   grand_child1_replica->SetMaskLayer(scoped_ptr<LayerImpl>());
   1274   EmulateDrawingOneFrame(root.get());
   1275 
   1276   grand_child_damage_rect =
   1277           grand_child1->render_surface()->damage_tracker()->
   1278               current_damage_rect();
   1279   child_damage_rect =
   1280           child1->render_surface()->damage_tracker()->current_damage_rect();
   1281 
   1282   EXPECT_TRUE(grand_child_damage_rect.IsEmpty());
   1283   EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString());
   1284 }
   1285 
   1286 TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithTransformOrigin) {
   1287   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
   1288   LayerImpl* child1 = root->children()[0];
   1289   LayerImpl* grand_child1 = child1->children()[0];
   1290 
   1291   // Verify that the correct replica_origin_transform is used for the
   1292   // replica_mask.
   1293   ClearDamageForAllSurfaces(root.get());
   1294 
   1295   // This is not actually the transform origin point being tested, but by
   1296   // convention its
   1297   // expected to be the same as the replica's anchor point.
   1298   grand_child1->SetTransformOrigin(
   1299       gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f));
   1300 
   1301   {
   1302     scoped_ptr<LayerImpl> grand_child1_replica =
   1303             LayerImpl::Create(host_impl_.active_tree(), 6);
   1304     grand_child1_replica->SetPosition(gfx::PointF());
   1305 
   1306     // This is the anchor being tested.
   1307     grand_child1_replica->SetTransformOrigin(
   1308         gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f));
   1309     gfx::Transform reflection;
   1310     reflection.Scale3d(-1.0, 1.0, 1.0);
   1311     grand_child1_replica->SetTransform(reflection);
   1312     grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
   1313   }
   1314   LayerImpl* grand_child1_replica = grand_child1->replica_layer();
   1315 
   1316   // Set up the mask layer on the replica layer
   1317   {
   1318     scoped_ptr<LayerImpl> replica_mask_layer =
   1319             LayerImpl::Create(host_impl_.active_tree(), 7);
   1320     replica_mask_layer->SetPosition(gfx::PointF());
   1321     // Note: this is not the transform origin being tested.
   1322     replica_mask_layer->SetBounds(grand_child1->bounds());
   1323     replica_mask_layer->SetContentBounds(grand_child1->bounds());
   1324     grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass());
   1325   }
   1326   LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer();
   1327 
   1328   EmulateDrawingOneFrame(root.get());
   1329 
   1330   // Sanity check that the appropriate render surfaces were created
   1331   ASSERT_TRUE(grand_child1->render_surface());
   1332 
   1333   // A property change on the replica_mask should damage the reflected region on
   1334   // the target surface.
   1335   ClearDamageForAllSurfaces(root.get());
   1336   replica_mask_layer->SetStackingOrderChanged(true);
   1337 
   1338   EmulateDrawingOneFrame(root.get());
   1339 
   1340   gfx::Rect child_damage_rect =
   1341       child1->render_surface()->damage_tracker()->current_damage_rect();
   1342   EXPECT_EQ(gfx::Rect(206, 200, 6, 8).ToString(), child_damage_rect.ToString());
   1343 }
   1344 
   1345 TEST_F(DamageTrackerTest, DamageWhenAddedExternally) {
   1346   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
   1347   LayerImpl* child = root->children()[0];
   1348 
   1349   // Case 1: This test ensures that when the tracker is given damage, that
   1350   //         it is included with any other partial damage.
   1351   //
   1352   ClearDamageForAllSurfaces(root.get());
   1353   child->SetUpdateRect(gfx::RectF(10, 11, 12, 13));
   1354   root->render_surface()->damage_tracker()->AddDamageNextUpdate(
   1355       gfx::Rect(15, 16, 32, 33));
   1356   EmulateDrawingOneFrame(root.get());
   1357   gfx::Rect root_damage_rect =
   1358       root->render_surface()->damage_tracker()->current_damage_rect();
   1359   EXPECT_EQ(gfx::UnionRects(gfx::Rect(15, 16, 32, 33),
   1360                             gfx::Rect(100 + 10, 100 + 11, 12, 13)).ToString(),
   1361             root_damage_rect.ToString());
   1362 
   1363   // Case 2: An additional sanity check that adding damage works even when
   1364   //         nothing on the layer tree changed.
   1365   //
   1366   ClearDamageForAllSurfaces(root.get());
   1367   root->render_surface()->damage_tracker()->AddDamageNextUpdate(
   1368       gfx::Rect(30, 31, 14, 15));
   1369   EmulateDrawingOneFrame(root.get());
   1370   root_damage_rect =
   1371       root->render_surface()->damage_tracker()->current_damage_rect();
   1372   EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString());
   1373 }
   1374 
   1375 TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) {
   1376   // Though it should never happen, its a good idea to verify that the damage
   1377   // tracker does not crash when it receives an empty layer_list.
   1378 
   1379   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_.active_tree(), 1);
   1380   root->CreateRenderSurface();
   1381 
   1382   ASSERT_TRUE(root == root->render_target());
   1383   RenderSurfaceImpl* target_surface = root->render_surface();
   1384 
   1385   LayerImplList empty_list;
   1386   target_surface->damage_tracker()->UpdateDamageTrackingState(
   1387       empty_list,
   1388       target_surface->OwningLayerId(),
   1389       false,
   1390       gfx::Rect(),
   1391       NULL,
   1392       FilterOperations());
   1393 
   1394   gfx::Rect damage_rect =
   1395       target_surface->damage_tracker()->current_damage_rect();
   1396   EXPECT_TRUE(damage_rect.IsEmpty());
   1397 }
   1398 
   1399 TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) {
   1400   // If damage is not cleared, it should accumulate.
   1401 
   1402   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
   1403   LayerImpl* child = root->children()[0];
   1404 
   1405   ClearDamageForAllSurfaces(root.get());
   1406   child->SetUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f));
   1407   EmulateDrawingOneFrame(root.get());
   1408 
   1409   // Sanity check damage after the first frame; this isnt the actual test yet.
   1410   gfx::Rect root_damage_rect =
   1411       root->render_surface()->damage_tracker()->current_damage_rect();
   1412   EXPECT_EQ(gfx::Rect(110, 111, 1, 2).ToString(), root_damage_rect.ToString());
   1413 
   1414   // New damage, without having cleared the previous damage, should be unioned
   1415   // to the previous one.
   1416   child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
   1417   EmulateDrawingOneFrame(root.get());
   1418   root_damage_rect =
   1419           root->render_surface()->damage_tracker()->current_damage_rect();
   1420   EXPECT_EQ(gfx::Rect(110, 111, 11, 16).ToString(),
   1421             root_damage_rect.ToString());
   1422 
   1423   // If we notify the damage tracker that we drew the damaged area, then damage
   1424   // should be emptied.
   1425   root->render_surface()->damage_tracker()->DidDrawDamagedArea();
   1426   root_damage_rect =
   1427           root->render_surface()->damage_tracker()->current_damage_rect();
   1428   EXPECT_TRUE(root_damage_rect.IsEmpty());
   1429 
   1430   // Damage should remain empty even after one frame, since there's yet no new
   1431   // damage.
   1432   EmulateDrawingOneFrame(root.get());
   1433   root_damage_rect =
   1434           root->render_surface()->damage_tracker()->current_damage_rect();
   1435   EXPECT_TRUE(root_damage_rect.IsEmpty());
   1436 }
   1437 
   1438 TEST_F(DamageTrackerTest, HugeDamageRect) {
   1439   // This number is so large that we start losting floating point accuracy.
   1440   const int kBigNumber = 900000000;
   1441   // Walk over a range to find floating point inaccuracy boundaries that move
   1442   // toward the wrong direction.
   1443   const int kRange = 5000;
   1444 
   1445   for (int i = 0; i < kRange; ++i) {
   1446     scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface();
   1447     LayerImpl* child = root->children()[0];
   1448 
   1449     gfx::Transform transform;
   1450     transform.Translate(-kBigNumber, -kBigNumber);
   1451 
   1452     // The child layer covers (0, 0, i, i) of the viewport,
   1453     // but has a huge negative position.
   1454     child->SetPosition(gfx::PointF());
   1455     child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
   1456     child->SetContentBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
   1457     child->SetTransform(transform);
   1458     EmulateDrawingOneFrame(root.get());
   1459 
   1460     // The expected damage should cover the visible part of the child layer,
   1461     // which is (0, 0, i, i) in the viewport.
   1462     gfx::Rect root_damage_rect =
   1463         root->render_surface()->damage_tracker()->current_damage_rect();
   1464     gfx::Rect damage_we_care_about = gfx::Rect(i, i);
   1465     EXPECT_LE(damage_we_care_about.right(), root_damage_rect.right());
   1466     EXPECT_LE(damage_we_care_about.bottom(), root_damage_rect.bottom());
   1467   }
   1468 }
   1469 
   1470 }  // namespace
   1471 }  // namespace cc
   1472