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