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