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