// Copyright 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/trees/damage_tracker.h"

#include "cc/base/math_util.h"
#include "cc/layers/layer_impl.h"
#include "cc/output/filter_operation.h"
#include "cc/output/filter_operations.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"
#include "ui/gfx/geometry/quad_f.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace cc {
namespace {

void ExecuteCalculateDrawProperties(LayerImpl* root,
                                    LayerImplList* render_surface_layer_list) {
  // Sanity check: The test itself should create the root layer's render
  //               surface, so that the surface (and its damage tracker) can
  //               persist across multiple calls to this function.
  ASSERT_TRUE(root->render_surface());
  ASSERT_FALSE(render_surface_layer_list->size());

  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root, root->bounds(), render_surface_layer_list);
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}

void ClearDamageForAllSurfaces(LayerImpl* layer) {
  if (layer->render_surface())
    layer->render_surface()->damage_tracker()->DidDrawDamagedArea();

  // Recursively clear damage for any existing surface.
  for (size_t i = 0; i < layer->children().size(); ++i)
    ClearDamageForAllSurfaces(layer->children()[i]);
}

void EmulateDrawingOneFrame(LayerImpl* root) {
  // This emulates only steps that are relevant to testing the damage tracker:
  //   1. computing the render passes and layerlists
  //   2. updating all damage trackers in the correct order
  //   3. resetting all update_rects and property_changed flags for all layers
  //      and surfaces.

  LayerImplList render_surface_layer_list;
  ExecuteCalculateDrawProperties(root, &render_surface_layer_list);

  // Iterate back-to-front, so that damage correctly propagates from descendant
  // surfaces to ancestors.
  for (int i = render_surface_layer_list.size() - 1; i >= 0; --i) {
    RenderSurfaceImpl* target_surface =
            render_surface_layer_list[i]->render_surface();
    target_surface->damage_tracker()->UpdateDamageTrackingState(
        target_surface->layer_list(),
        target_surface->OwningLayerId(),
        target_surface->SurfacePropertyChangedOnlyFromDescendant(),
        target_surface->content_rect(),
        render_surface_layer_list[i]->mask_layer(),
        render_surface_layer_list[i]->filters());
  }

  root->ResetAllChangeTrackingForSubtree();
}

class DamageTrackerTest : public testing::Test {
 public:
  DamageTrackerTest() : host_impl_(&proxy_, &shared_bitmap_manager_) {}

  scoped_ptr<LayerImpl> CreateTestTreeWithOneSurface() {
    scoped_ptr<LayerImpl> root =
            LayerImpl::Create(host_impl_.active_tree(), 1);
    scoped_ptr<LayerImpl> child =
            LayerImpl::Create(host_impl_.active_tree(), 2);

    root->SetPosition(gfx::PointF());
    root->SetBounds(gfx::Size(500, 500));
    root->SetContentBounds(gfx::Size(500, 500));
    root->SetDrawsContent(true);
    root->CreateRenderSurface();
    root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500));

    child->SetPosition(gfx::PointF(100.f, 100.f));
    child->SetBounds(gfx::Size(30, 30));
    child->SetContentBounds(gfx::Size(30, 30));
    child->SetDrawsContent(true);
    root->AddChild(child.Pass());

    return root.Pass();
  }

  scoped_ptr<LayerImpl> CreateTestTreeWithTwoSurfaces() {
    // This test tree has two render surfaces: one for the root, and one for
    // child1. Additionally, the root has a second child layer, and child1 has
    // two children of its own.

    scoped_ptr<LayerImpl> root =
            LayerImpl::Create(host_impl_.active_tree(), 1);
    scoped_ptr<LayerImpl> child1 =
            LayerImpl::Create(host_impl_.active_tree(), 2);
    scoped_ptr<LayerImpl> child2 =
            LayerImpl::Create(host_impl_.active_tree(), 3);
    scoped_ptr<LayerImpl> grand_child1 =
            LayerImpl::Create(host_impl_.active_tree(), 4);
    scoped_ptr<LayerImpl> grand_child2 =
            LayerImpl::Create(host_impl_.active_tree(), 5);

    root->SetPosition(gfx::PointF());
    root->SetBounds(gfx::Size(500, 500));
    root->SetContentBounds(gfx::Size(500, 500));
    root->SetDrawsContent(true);
    root->CreateRenderSurface();
    root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500));

    child1->SetPosition(gfx::PointF(100.f, 100.f));
    child1->SetBounds(gfx::Size(30, 30));
    child1->SetContentBounds(gfx::Size(30, 30));
    // With a child that draws_content, opacity will cause the layer to create
    // its own RenderSurface. This layer does not draw, but is intended to
    // create its own RenderSurface. TODO: setting opacity and
    // ForceRenderSurface may be redundant here.
    child1->SetOpacity(0.5f);
    child1->SetDrawsContent(false);
    child1->SetForceRenderSurface(true);

    child2->SetPosition(gfx::PointF(11.f, 11.f));
    child2->SetBounds(gfx::Size(18, 18));
    child2->SetContentBounds(gfx::Size(18, 18));
    child2->SetDrawsContent(true);

    grand_child1->SetPosition(gfx::PointF(200.f, 200.f));
    grand_child1->SetBounds(gfx::Size(6, 8));
    grand_child1->SetContentBounds(gfx::Size(6, 8));
    grand_child1->SetDrawsContent(true);

    grand_child2->SetPosition(gfx::PointF(190.f, 190.f));
    grand_child2->SetBounds(gfx::Size(6, 8));
    grand_child2->SetContentBounds(gfx::Size(6, 8));
    grand_child2->SetDrawsContent(true);

    child1->AddChild(grand_child1.Pass());
    child1->AddChild(grand_child2.Pass());
    root->AddChild(child1.Pass());
    root->AddChild(child2.Pass());

    return root.Pass();
  }

  scoped_ptr<LayerImpl> CreateAndSetUpTestTreeWithOneSurface() {
    scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface();

    // Setup includes going past the first frame which always damages
    // everything, so that we can actually perform specific tests.
    EmulateDrawingOneFrame(root.get());

    return root.Pass();
  }

  scoped_ptr<LayerImpl> CreateAndSetUpTestTreeWithTwoSurfaces() {
    scoped_ptr<LayerImpl> root = CreateTestTreeWithTwoSurfaces();

    // Setup includes going past the first frame which always damages
    // everything, so that we can actually perform specific tests.
    EmulateDrawingOneFrame(root.get());

    return root.Pass();
  }

 protected:
  FakeImplProxy proxy_;
  TestSharedBitmapManager shared_bitmap_manager_;
  FakeLayerTreeHostImpl host_impl_;
};

TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) {
  // Sanity check that the simple test tree will actually produce the expected
  // render surfaces and layer lists.

  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();

  EXPECT_EQ(2u, root->render_surface()->layer_list().size());
  EXPECT_EQ(1, root->render_surface()->layer_list()[0]->id());
  EXPECT_EQ(2, root->render_surface()->layer_list()[1]->id());

  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();

  EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) {
  // Sanity check that the complex test tree will actually produce the expected
  // render surfaces and layer lists.

  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();

  LayerImpl* child1 = root->children()[0];
  LayerImpl* child2 = root->children()[1];
  gfx::Rect child_damage_rect =
      child1->render_surface()->damage_tracker()->current_damage_rect();
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();

  ASSERT_TRUE(child1->render_surface());
  EXPECT_FALSE(child2->render_surface());
  EXPECT_EQ(3u, root->render_surface()->layer_list().size());
  EXPECT_EQ(2u, child1->render_surface()->layer_list().size());

  // The render surface for child1 only has a content_rect that encloses
  // grand_child1 and grand_child2, because child1 does not draw content.
  EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
            child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  // CASE 1: Setting the update rect should cause the corresponding damage to
  //         the surface.
  ClearDamageForAllSurfaces(root.get());
  child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
  EmulateDrawingOneFrame(root.get());

  // Damage position on the surface should be: position of update_rect (10, 11)
  // relative to the child (100, 100).
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(),
            root_damage_rect.ToString());

  // CASE 2: The same update rect twice in a row still produces the same
  //         damage.
  ClearDamageForAllSurfaces(root.get());
  child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(),
            root_damage_rect.ToString());

  // CASE 3: Setting a different update rect should cause damage on the new
  //         update region, but no additional exposed old region.
  ClearDamageForAllSurfaces(root.get());
  child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
  EmulateDrawingOneFrame(root.get());

  // Damage position on the surface should be: position of update_rect (20, 25)
  // relative to the child (100, 100).
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(120, 125, 1, 2).ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  // CASE 1: Adding the layer damage rect should cause the corresponding damage
  // to the surface.
  ClearDamageForAllSurfaces(root.get());
  child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
  EmulateDrawingOneFrame(root.get());

  // Damage position on the surface should be: position of layer damage_rect
  // (10, 11) relative to the child (100, 100).
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13)));

  // CASE 2: The same layer damage rect twice in a row still produces the same
  // damage.
  ClearDamageForAllSurfaces(root.get());
  child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13)));

  // CASE 3: Adding a different layer damage rect should cause damage on the
  // new damaged region, but no additional exposed old region.
  ClearDamageForAllSurfaces(root.get());
  child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
  EmulateDrawingOneFrame(root.get());

  // Damage position on the surface should be: position of layer damage_rect
  // (20, 25) relative to the child (100, 100).
  root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2)));

  // CASE 4: Adding multiple layer damage rects should cause a unified
  // damage on root damage rect.
  ClearDamageForAllSurfaces(root.get());
  child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
  child->AddDamageRect(gfx::RectF(10.f, 15.f, 3.f, 4.f));
  EmulateDrawingOneFrame(root.get());

  // Damage position on the surface should be: position of layer damage_rect
  // (20, 25) relative to the child (100, 100).
  root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2)));
  EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 115, 3, 4)));
}

TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  // CASE 1: Adding the layer damage rect and update rect should cause the
  // corresponding damage to the surface.
  ClearDamageForAllSurfaces(root.get());
  child->AddDamageRect(gfx::RectF(5.f, 6.f, 12.f, 13.f));
  child->SetUpdateRect(gfx::RectF(15.f, 16.f, 14.f, 10.f));
  EmulateDrawingOneFrame(root.get());

  // Damage position on the surface should be: position of unified layer
  // damage_rect and update rect (5, 6)
  // relative to the child (100, 100).
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 106, 24, 20)));

  // CASE 2: The same layer damage rect and update rect twice in a row still
  // produces the same damage.
  ClearDamageForAllSurfaces(root.get());
  child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
  child->SetUpdateRect(gfx::RectF(10.f, 11.f, 14.f, 15.f));
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 14, 15)));

  // CASE 3: Adding a different layer damage rect and update rect should cause
  // damage on the new damaged region, but no additional exposed old region.
  ClearDamageForAllSurfaces(root.get());
  child->AddDamageRect(gfx::RectF(20.f, 25.f, 2.f, 3.f));
  child->SetUpdateRect(gfx::RectF(5.f, 10.f, 7.f, 8.f));
  EmulateDrawingOneFrame(root.get());

  // Damage position on the surface should be: position of unified layer damage
  // rect and update rect (5, 10) relative to the child (100, 100).
  root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 110, 17, 18)));
}

TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  // CASE 1: The layer's property changed flag takes priority over update rect.
  //
  ClearDamageForAllSurfaces(root.get());
  child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
  child->SetOpacity(0.5f);
  EmulateDrawingOneFrame(root.get());

  // Sanity check - we should not have accidentally created a separate render
  // surface for the translucent layer.
  ASSERT_FALSE(child->render_surface());
  ASSERT_EQ(2u, root->render_surface()->layer_list().size());

  // Damage should be the entire child layer in target_surface space.
  gfx::Rect expected_rect = gfx::Rect(100, 100, 30, 30);
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString());

  // CASE 2: If a layer moves due to property change, it damages both the new
  //         location and the old (exposed) location. The old location is the
  //         entire old layer, not just the update_rect.

  // Cycle one frame of no change, just to sanity check that the next rect is
  // not because of the old damage state.
  ClearDamageForAllSurfaces(root.get());
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(root_damage_rect.IsEmpty());

  // Then, test the actual layer movement.
  ClearDamageForAllSurfaces(root.get());
  child->SetPosition(gfx::PointF(200.f, 230.f));
  EmulateDrawingOneFrame(root.get());

  // Expect damage to be the combination of the previous one and the new one.
  expected_rect.Union(gfx::Rect(200, 230, 30, 30));
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect);
}

TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) {
  // If a layer is transformed, the damage rect should still enclose the entire
  // transformed layer.

  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  gfx::Transform rotation;
  rotation.Rotate(45.0);

  ClearDamageForAllSurfaces(root.get());
  child->SetTransformOrigin(gfx::Point3F(
      child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f));
  child->SetPosition(gfx::PointF(85.f, 85.f));
  EmulateDrawingOneFrame(root.get());

  // Sanity check that the layer actually moved to (85, 85), damaging its old
  // location and new location.
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(85, 85, 45, 45).ToString(), root_damage_rect.ToString());

  // With the anchor on the layer's center, now we can test the rotation more
  // intuitively, since it applies about the layer's anchor.
  ClearDamageForAllSurfaces(root.get());
  child->SetTransform(rotation);
  EmulateDrawingOneFrame(root.get());

  // Since the child layer is square, rotation by 45 degrees about the center
  // should increase the size of the expected rect by sqrt(2), centered around
  // (100, 100). The old exposed region should be fully contained in the new
  // region.
  float expected_width = 30.f * sqrt(2.f);
  float expected_position = 100.f - 0.5f * expected_width;
  gfx::Rect expected_rect = gfx::ToEnclosingRect(gfx::RectF(
      expected_position, expected_position, expected_width, expected_width));
  root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) {
  // If a layer has a perspective transform that causes w < 0, then not
  // clipping the layer can cause an invalid damage rect. This test checks that
  // the w < 0 case is tracked properly.
  //
  // The transform is constructed so that if w < 0 clipping is not performed,
  // the incorrect rect will be very small, specifically: position (500.972504,
  // 498.544617) and size 0.056610 x 2.910767.  Instead, the correctly
  // transformed rect should actually be very huge (i.e. in theory, -infinity
  // on the left), and positioned so that the right-most bound rect will be
  // approximately 501 units in root surface space.
  //

  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  gfx::Transform transform;
  transform.Translate3d(500.0, 500.0, 0.0);
  transform.ApplyPerspectiveDepth(1.0);
  transform.RotateAboutYAxis(45.0);
  transform.Translate3d(-50.0, -50.0, 0.0);

  // Set up the child
  child->SetPosition(gfx::PointF(0.f, 0.f));
  child->SetBounds(gfx::Size(100, 100));
  child->SetContentBounds(gfx::Size(100, 100));
  child->SetTransform(transform);
  EmulateDrawingOneFrame(root.get());

  // Sanity check that the child layer's bounds would actually get clipped by
  // w < 0, otherwise this test is not actually testing the intended scenario.
  gfx::QuadF test_quad(gfx::RectF(gfx::PointF(), gfx::SizeF(100.f, 100.f)));
  bool clipped = false;
  MathUtil::MapQuad(transform, test_quad, &clipped);
  EXPECT_TRUE(clipped);

  // Damage the child without moving it.
  ClearDamageForAllSurfaces(root.get());
  child->SetOpacity(0.5f);
  EmulateDrawingOneFrame(root.get());

  // The expected damage should cover the entire root surface (500x500), but we
  // don't care whether the damage rect was clamped or is larger than the
  // surface for this test.
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  gfx::Rect damage_we_care_about = gfx::Rect(gfx::Size(500, 500));
  EXPECT_TRUE(root_damage_rect.Contains(damage_we_care_about));
}

TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* surface = root->children()[0];
  LayerImpl* child = surface->children()[0];

  FilterOperations filters;
  filters.Append(FilterOperation::CreateBlurFilter(5.f));
  int outset_top, outset_right, outset_bottom, outset_left;
  filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left);

  // Setting the filter will damage the whole surface.
  ClearDamageForAllSurfaces(root.get());
  surface->SetFilters(filters);
  EmulateDrawingOneFrame(root.get());

  // Setting the update rect should cause the corresponding damage to the
  // surface, blurred based on the size of the blur filter.
  ClearDamageForAllSurfaces(root.get());
  child->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f));
  EmulateDrawingOneFrame(root.get());

  // Damage position on the surface should be: position of update_rect (1, 2)
  // relative to the child (300, 300), but expanded by the blur outsets.
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  gfx::Rect expected_damage_rect = gfx::Rect(301, 302, 3, 4);

  expected_damage_rect.Inset(-outset_left,
                             -outset_top,
                             -outset_right,
                             -outset_bottom);
  EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];
  gfx::Rect root_damage_rect, child_damage_rect;

  // Allow us to set damage on child too.
  child->SetDrawsContent(true);

  skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
      SkBlurImageFilter::Create(SkIntToScalar(2), SkIntToScalar(2)));
  FilterOperations filters;
  filters.Append(FilterOperation::CreateReferenceFilter(filter));

  // Setting the filter will damage the whole surface.
  ClearDamageForAllSurfaces(root.get());
  child->SetFilters(filters);
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  child_damage_rect =
          child->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
            root_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());

  // CASE 1: Setting the update rect should damage the whole surface (for now)
  ClearDamageForAllSurfaces(root.get());
  child->SetUpdateRect(gfx::RectF(1.f, 1.f));
  EmulateDrawingOneFrame(root.get());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  child_damage_rect =
          child->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
            root_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(30.f, 30.f).ToString(), child_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  LayerImpl* child2 = root->children()[1];

  // Allow us to set damage on child1 too.
  child1->SetDrawsContent(true);

  FilterOperations filters;
  filters.Append(FilterOperation::CreateBlurFilter(2.f));
  int outset_top, outset_right, outset_bottom, outset_left;
  filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left);

  // Setting the filter will damage the whole surface.
  ClearDamageForAllSurfaces(root.get());
  child1->SetBackgroundFilters(filters);
  EmulateDrawingOneFrame(root.get());

  // CASE 1: Setting the update rect should cause the corresponding damage to
  //         the surface, blurred based on the size of the child's background
  //         blur filter.
  ClearDamageForAllSurfaces(root.get());
  root->SetUpdateRect(gfx::RectF(297.f, 297.f, 2.f, 2.f));
  EmulateDrawingOneFrame(root.get());

  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  // Damage position on the surface should be a composition of the damage on
  // the root and on child2.  Damage on the root should be: position of
  // update_rect (297, 297), but expanded by the blur outsets.
  gfx::Rect expected_damage_rect = gfx::Rect(297, 297, 2, 2);

  expected_damage_rect.Inset(-outset_left,
                             -outset_top,
                             -outset_right,
                             -outset_bottom);
  EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());

  // CASE 2: Setting the update rect should cause the corresponding damage to
  //         the surface, blurred based on the size of the child's background
  //         blur filter. Since the damage extends to the right/bottom outside
  //         of the blurred layer, only the left/top should end up expanded.
  ClearDamageForAllSurfaces(root.get());
  root->SetUpdateRect(gfx::RectF(297.f, 297.f, 30.f, 30.f));
  EmulateDrawingOneFrame(root.get());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  // Damage position on the surface should be a composition of the damage on
  // the root and on child2.  Damage on the root should be: position of
  // update_rect (297, 297), but expanded on the left/top by the blur outsets.
  expected_damage_rect = gfx::Rect(297, 297, 30, 30);

  expected_damage_rect.Inset(-outset_left,
                             -outset_top,
                             0,
                             0);
  EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());

  // CASE 3: Setting this update rect outside the blurred content_bounds of the
  //         blurred child1 will not cause it to be expanded.
  ClearDamageForAllSurfaces(root.get());
  root->SetUpdateRect(gfx::RectF(30.f, 30.f, 2.f, 2.f));
  EmulateDrawingOneFrame(root.get());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  // Damage on the root should be: position of update_rect (30, 30), not
  // expanded.
  expected_damage_rect = gfx::Rect(30, 30, 2, 2);

  EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());

  // CASE 4: Setting this update rect inside the blurred content_bounds but
  //         outside the original content_bounds of the blurred child1 will
  //         cause it to be expanded.
  ClearDamageForAllSurfaces(root.get());
  root->SetUpdateRect(gfx::RectF(99.f, 99.f, 1.f, 1.f));
  EmulateDrawingOneFrame(root.get());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  // Damage on the root should be: position of update_rect (99, 99), expanded by
  // the blurring on child1, but since it is 1 pixel outside the layer, the
  // expanding should be reduced by 1.
  expected_damage_rect = gfx::Rect(99, 99, 1, 1);

  expected_damage_rect.Inset(-outset_left + 1,
                             -outset_top + 1,
                             -outset_right,
                             -outset_bottom);
  EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());

  // CASE 5: Setting the update rect on child2, which is above child1, will
  // not get blurred by child1, so it does not need to get expanded.
  ClearDamageForAllSurfaces(root.get());
  child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f));
  EmulateDrawingOneFrame(root.get());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  // Damage on child2 should be: position of update_rect offset by the child's
  // position (11, 11), and not expanded by anything.
  expected_damage_rect = gfx::Rect(11, 11, 1, 1);

  EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());

  // CASE 6: Setting the update rect on child1 will also blur the damage, so
  //         that any pixels needed for the blur are redrawn in the current
  //         frame.
  ClearDamageForAllSurfaces(root.get());
  child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f));
  EmulateDrawingOneFrame(root.get());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  // Damage on child1 should be: position of update_rect offset by the child's
  // position (100, 100), and expanded by the damage.
  expected_damage_rect = gfx::Rect(100, 100, 1, 1);

  expected_damage_rect.Inset(-outset_left,
                             -outset_top,
                             -outset_right,
                             -outset_bottom);
  EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child1 = root->children()[0];

  // CASE 1: Adding a new layer should cause the appropriate damage.
  //
  ClearDamageForAllSurfaces(root.get());
  {
    scoped_ptr<LayerImpl> child2 =
            LayerImpl::Create(host_impl_.active_tree(), 3);
    child2->SetPosition(gfx::PointF(400.f, 380.f));
    child2->SetBounds(gfx::Size(6, 8));
    child2->SetContentBounds(gfx::Size(6, 8));
    child2->SetDrawsContent(true);
    root->AddChild(child2.Pass());
  }
  EmulateDrawingOneFrame(root.get());

  // Sanity check - all 3 layers should be on the same render surface; render
  // surfaces are tested elsewhere.
  ASSERT_EQ(3u, root->render_surface()->layer_list().size());

  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString());

  // CASE 2: If the layer is removed, its entire old layer becomes exposed, not
  //         just the last update rect.

  // Advance one frame without damage so that we know the damage rect is not
  // leftover from the previous case.
  ClearDamageForAllSurfaces(root.get());
  EmulateDrawingOneFrame(root.get());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(root_damage_rect.IsEmpty());

  // Then, test removing child1.
  root->RemoveChild(child1);
  child1 = NULL;
  EmulateDrawingOneFrame(root.get());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
            root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) {
  // If child2 is added to the layer tree, but it doesn't have any explicit
  // damage of its own, it should still indeed damage the target surface.

  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();

  ClearDamageForAllSurfaces(root.get());
  {
    scoped_ptr<LayerImpl> child2 =
            LayerImpl::Create(host_impl_.active_tree(), 3);
    child2->SetPosition(gfx::PointF(400.f, 380.f));
    child2->SetBounds(gfx::Size(6, 8));
    child2->SetContentBounds(gfx::Size(6, 8));
    child2->SetDrawsContent(true);
    child2->ResetAllChangeTrackingForSubtree();
    // Sanity check the initial conditions of the test, if these asserts
    // trigger, it means the test no longer actually covers the intended
    // scenario.
    ASSERT_FALSE(child2->LayerPropertyChanged());
    ASSERT_TRUE(child2->update_rect().IsEmpty());
    root->AddChild(child2.Pass());
  }
  EmulateDrawingOneFrame(root.get());

  // Sanity check - all 3 layers should be on the same render surface; render
  // surfaces are tested elsewhere.
  ASSERT_EQ(3u, root->render_surface()->layer_list().size());

  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child1 = root->children()[0];

  // In this test we don't want the above tree manipulation to be considered
  // part of the same frame.
  ClearDamageForAllSurfaces(root.get());
  {
    scoped_ptr<LayerImpl> child2 =
            LayerImpl::Create(host_impl_.active_tree(), 3);
    child2->SetPosition(gfx::PointF(400.f, 380.f));
    child2->SetBounds(gfx::Size(6, 8));
    child2->SetContentBounds(gfx::Size(6, 8));
    child2->SetDrawsContent(true);
    root->AddChild(child2.Pass());
  }
  LayerImpl* child2 = root->children()[1];
  EmulateDrawingOneFrame(root.get());

  // Damaging two layers simultaneously should cause combined damage.
  // - child1 update rect in surface space: gfx::Rect(100, 100, 1, 2);
  // - child2 update rect in surface space: gfx::Rect(400, 380, 3, 4);
  ClearDamageForAllSurfaces(root.get());
  child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f));
  child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 3.f, 4.f));
  EmulateDrawingOneFrame(root.get());
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(100, 100, 303, 284).ToString(),
            root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  LayerImpl* child2 = root->children()[1];
  LayerImpl* grand_child1 = root->children()[0]->children()[0];
  gfx::Rect child_damage_rect;
  gfx::Rect root_damage_rect;

  // CASE 1: Damage to a descendant surface should propagate properly to
  //         ancestor surface.
  ClearDamageForAllSurfaces(root.get());
  grand_child1->SetOpacity(0.5f);
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(300, 300, 6, 8).ToString(), root_damage_rect.ToString());

  // CASE 2: Same as previous case, but with additional damage elsewhere that
  //         should be properly unioned.
  // - child1 surface damage in root surface space:
  //   gfx::Rect(300, 300, 6, 8);
  // - child2 damage in root surface space:
  //   gfx::Rect(11, 11, 18, 18);
  ClearDamageForAllSurfaces(root.get());
  grand_child1->SetOpacity(0.7f);
  child2->SetOpacity(0.7f);
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(11, 11, 295, 297).ToString(),
            root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) {
  // If descendant layer changes and affects the content bounds of the render
  // surface, then the entire descendant surface should be damaged, and it
  // should damage its ancestor surface with the old and new surface regions.

  // This is a tricky case, since only the first grand_child changes, but the
  // entire surface should be marked dirty.

  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  LayerImpl* grand_child1 = root->children()[0]->children()[0];
  gfx::Rect child_damage_rect;
  gfx::Rect root_damage_rect;

  ClearDamageForAllSurfaces(root.get());
  grand_child1->SetPosition(gfx::PointF(195.f, 205.f));
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();

  // The new surface bounds should be damaged entirely, even though only one of
  // the layers changed.
  EXPECT_EQ(gfx::Rect(190, 190, 11, 23).ToString(),
            child_damage_rect.ToString());

  // Damage to the root surface should be the union of child1's *entire* render
  // surface (in target space), and its old exposed area (also in target
  // space).
  EXPECT_EQ(gfx::Rect(290, 290, 16, 23).ToString(),
            root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) {
  // An ancestor/owning layer changes that affects the position/transform of
  // the render surface. Note that in this case, the layer_property_changed flag
  // already propagates to the subtree (tested in LayerImpltest), which damages
  // the entire child1 surface, but the damage tracker still needs the correct
  // logic to compute the exposed region on the root surface.

  // TODO(shawnsingh): the expectations of this test case should change when we
  // add support for a unique scissor_rect per RenderSurface. In that case, the
  // child1 surface should be completely unchanged, since we are only
  // transforming it, while the root surface would be damaged appropriately.

  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  gfx::Rect child_damage_rect;
  gfx::Rect root_damage_rect;

  ClearDamageForAllSurfaces(root.get());
  child1->SetPosition(gfx::PointF(50.f, 50.f));
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();

  // The new surface bounds should be damaged entirely.
  EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
            child_damage_rect.ToString());

  // The entire child1 surface and the old exposed child1 surface should damage
  // the root surface.
  //  - old child1 surface in target space: gfx::Rect(290, 290, 16, 18)
  //  - new child1 surface in target space: gfx::Rect(240, 240, 16, 18)
  EXPECT_EQ(gfx::Rect(240, 240, 66, 68).ToString(),
            root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  gfx::Rect child_damage_rect;
  gfx::Rect root_damage_rect;

  // CASE 1: If a descendant surface disappears, its entire old area becomes
  //         exposed.
  ClearDamageForAllSurfaces(root.get());
  child1->SetOpacity(1.f);
  child1->SetForceRenderSurface(false);
  EmulateDrawingOneFrame(root.get());

  // Sanity check that there is only one surface now.
  ASSERT_FALSE(child1->render_surface());
  ASSERT_EQ(4u, root->render_surface()->layer_list().size());

  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(),
            root_damage_rect.ToString());

  // CASE 2: If a descendant surface appears, its entire old area becomes
  //         exposed.

  // Cycle one frame of no change, just to sanity check that the next rect is
  // not because of the old damage state.
  ClearDamageForAllSurfaces(root.get());
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(root_damage_rect.IsEmpty());

  // Then change the tree so that the render surface is added back.
  ClearDamageForAllSurfaces(root.get());
  child1->SetOpacity(0.5f);
  child1->SetForceRenderSurface(true);
  EmulateDrawingOneFrame(root.get());

  // Sanity check that there is a new surface now.
  ASSERT_TRUE(child1->render_surface());
  EXPECT_EQ(3u, root->render_surface()->layer_list().size());
  EXPECT_EQ(2u, child1->render_surface()->layer_list().size());

  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
            child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(),
            root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  gfx::Rect child_damage_rect;
  gfx::Rect root_damage_rect;

  // CASE 1: If nothing changes, the damage rect should be empty.
  //
  ClearDamageForAllSurfaces(root.get());
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(child_damage_rect.IsEmpty());
  EXPECT_TRUE(root_damage_rect.IsEmpty());

  // CASE 2: If nothing changes twice in a row, the damage rect should still be
  //         empty.
  //
  ClearDamageForAllSurfaces(root.get());
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(child_damage_rect.IsEmpty());
  EXPECT_TRUE(root_damage_rect.IsEmpty());
}

TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  gfx::Rect child_damage_rect;
  gfx::Rect root_damage_rect;

  // In our specific tree, the update rect of child1 should not cause any
  // damage to any surface because it does not actually draw content.
  ClearDamageForAllSurfaces(root.get());
  child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f));
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(child_damage_rect.IsEmpty());
  EXPECT_TRUE(root_damage_rect.IsEmpty());
}

TEST_F(DamageTrackerTest, VerifyDamageForReplica) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  LayerImpl* grand_child1 = child1->children()[0];
  LayerImpl* grand_child2 = child1->children()[1];

  // Damage on a surface that has a reflection should cause the target surface
  // to receive the surface's damage and the surface's reflected damage.

  // For this test case, we modify grand_child2, and add grand_child3 to extend
  // the bounds of child1's surface. This way, we can test reflection changes
  // without changing content_bounds of the surface.
  grand_child2->SetPosition(gfx::PointF(180.f, 180.f));
  {
    scoped_ptr<LayerImpl> grand_child3 =
            LayerImpl::Create(host_impl_.active_tree(), 6);
    grand_child3->SetPosition(gfx::PointF(240.f, 240.f));
    grand_child3->SetBounds(gfx::Size(10, 10));
    grand_child3->SetContentBounds(gfx::Size(10, 10));
    grand_child3->SetDrawsContent(true);
    child1->AddChild(grand_child3.Pass());
  }
  child1->SetOpacity(0.5f);
  EmulateDrawingOneFrame(root.get());

  // CASE 1: adding a reflection about the left edge of grand_child1.
  //
  ClearDamageForAllSurfaces(root.get());
  {
    scoped_ptr<LayerImpl> grand_child1_replica =
            LayerImpl::Create(host_impl_.active_tree(), 7);
    grand_child1_replica->SetPosition(gfx::PointF());
    gfx::Transform reflection;
    reflection.Scale3d(-1.0, 1.0, 1.0);
    grand_child1_replica->SetTransform(reflection);
    grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
  }
  EmulateDrawingOneFrame(root.get());

  gfx::Rect grand_child_damage_rect =
      grand_child1->render_surface()->damage_tracker()->current_damage_rect();
  gfx::Rect child_damage_rect =
      child1->render_surface()->damage_tracker()->current_damage_rect();
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();

  // The grand_child surface damage should not include its own replica. The
  // child surface damage should include the normal and replica surfaces.
  EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(194, 200, 12, 8).ToString(),
            child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(294, 300, 12, 8).ToString(), root_damage_rect.ToString());

  // CASE 2: moving the descendant surface should cause both the original and
  //         reflected areas to be damaged on the target.
  ClearDamageForAllSurfaces(root.get());
  gfx::Rect old_content_rect = child1->render_surface()->content_rect();
  grand_child1->SetPosition(gfx::PointF(195.f, 205.f));
  EmulateDrawingOneFrame(root.get());
  ASSERT_EQ(old_content_rect.width(),
            child1->render_surface()->content_rect().width());
  ASSERT_EQ(old_content_rect.height(),
            child1->render_surface()->content_rect().height());

  grand_child_damage_rect =
          grand_child1->render_surface()->
              damage_tracker()->current_damage_rect();
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();

  // The child surface damage should include normal and replica surfaces for
  // both old and new locations.
  //  - old location in target space: gfx::Rect(194, 200, 12, 8)
  //  - new location in target space: gfx::Rect(189, 205, 12, 8)
  EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(189, 200, 17, 13).ToString(),
            child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(289, 300, 17, 13).ToString(),
            root_damage_rect.ToString());

  // CASE 3: removing the reflection should cause the entire region including
  //         reflection to damage the target surface.
  ClearDamageForAllSurfaces(root.get());
  grand_child1->SetReplicaLayer(scoped_ptr<LayerImpl>());
  EmulateDrawingOneFrame(root.get());
  ASSERT_EQ(old_content_rect.width(),
            child1->render_surface()->content_rect().width());
  ASSERT_EQ(old_content_rect.height(),
            child1->render_surface()->content_rect().height());

  EXPECT_FALSE(grand_child1->render_surface());
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();

  EXPECT_EQ(gfx::Rect(189, 205, 12, 8).ToString(),
            child_damage_rect.ToString());
  EXPECT_EQ(gfx::Rect(289, 305, 12, 8).ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForMask) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  // In the current implementation of the damage tracker, changes to mask
  // layers should damage the entire corresponding surface.

  ClearDamageForAllSurfaces(root.get());

  // Set up the mask layer.
  {
    scoped_ptr<LayerImpl> mask_layer =
            LayerImpl::Create(host_impl_.active_tree(), 3);
    mask_layer->SetPosition(child->position());
    mask_layer->SetBounds(child->bounds());
    mask_layer->SetContentBounds(child->bounds());
    child->SetMaskLayer(mask_layer.Pass());
  }
  LayerImpl* mask_layer = child->mask_layer();

  // Add opacity and a grand_child so that the render surface persists even
  // after we remove the mask.
  child->SetOpacity(0.5f);
  {
    scoped_ptr<LayerImpl> grand_child =
            LayerImpl::Create(host_impl_.active_tree(), 4);
    grand_child->SetPosition(gfx::PointF(2.f, 2.f));
    grand_child->SetBounds(gfx::Size(2, 2));
    grand_child->SetContentBounds(gfx::Size(2, 2));
    grand_child->SetDrawsContent(true);
    child->AddChild(grand_child.Pass());
  }
  EmulateDrawingOneFrame(root.get());

  // Sanity check that a new surface was created for the child.
  ASSERT_TRUE(child->render_surface());

  // CASE 1: the update_rect on a mask layer should damage the entire target
  //         surface.
  ClearDamageForAllSurfaces(root.get());
  mask_layer->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f));
  EmulateDrawingOneFrame(root.get());
  gfx::Rect child_damage_rect =
      child->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());

  // CASE 2: a property change on the mask layer should damage the entire
  //         target surface.

  // Advance one frame without damage so that we know the damage rect is not
  // leftover from the previous case.
  ClearDamageForAllSurfaces(root.get());
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(child_damage_rect.IsEmpty());

  // Then test the property change.
  ClearDamageForAllSurfaces(root.get());
  mask_layer->SetStackingOrderChanged(true);

  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());

  // CASE 3: removing the mask also damages the entire target surface.
  //

  // Advance one frame without damage so that we know the damage rect is not
  // leftover from the previous case.
  ClearDamageForAllSurfaces(root.get());
  EmulateDrawingOneFrame(root.get());
  child_damage_rect =
          child->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(child_damage_rect.IsEmpty());

  // Then test mask removal.
  ClearDamageForAllSurfaces(root.get());
  child->SetMaskLayer(scoped_ptr<LayerImpl>());
  ASSERT_TRUE(child->LayerPropertyChanged());
  EmulateDrawingOneFrame(root.get());

  // Sanity check that a render surface still exists.
  ASSERT_TRUE(child->render_surface());

  child_damage_rect =
          child->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  LayerImpl* grand_child1 = child1->children()[0];

  // Changes to a replica's mask should not damage the original surface,
  // because it is not masked. But it does damage the ancestor target surface.

  ClearDamageForAllSurfaces(root.get());

  // Create a reflection about the left edge of grand_child1.
  {
    scoped_ptr<LayerImpl> grand_child1_replica =
            LayerImpl::Create(host_impl_.active_tree(), 6);
    grand_child1_replica->SetPosition(gfx::PointF());
    gfx::Transform reflection;
    reflection.Scale3d(-1.0, 1.0, 1.0);
    grand_child1_replica->SetTransform(reflection);
    grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
  }
  LayerImpl* grand_child1_replica = grand_child1->replica_layer();

  // Set up the mask layer on the replica layer
  {
    scoped_ptr<LayerImpl> replica_mask_layer =
            LayerImpl::Create(host_impl_.active_tree(), 7);
    replica_mask_layer->SetPosition(gfx::PointF());
    replica_mask_layer->SetBounds(grand_child1->bounds());
    replica_mask_layer->SetContentBounds(grand_child1->bounds());
    grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass());
  }
  LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer();

  EmulateDrawingOneFrame(root.get());

  // Sanity check that the appropriate render surfaces were created
  ASSERT_TRUE(grand_child1->render_surface());

  // CASE 1: a property change on the mask should damage only the reflected
  //         region on the target surface.
  ClearDamageForAllSurfaces(root.get());
  replica_mask_layer->SetStackingOrderChanged(true);
  EmulateDrawingOneFrame(root.get());

  gfx::Rect grand_child_damage_rect =
      grand_child1->render_surface()->damage_tracker()->current_damage_rect();
  gfx::Rect child_damage_rect =
      child1->render_surface()->damage_tracker()->current_damage_rect();

  EXPECT_TRUE(grand_child_damage_rect.IsEmpty());
  EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString());

  // CASE 2: removing the replica mask damages only the reflected region on the
  //         target surface.
  //
  ClearDamageForAllSurfaces(root.get());
  grand_child1_replica->SetMaskLayer(scoped_ptr<LayerImpl>());
  EmulateDrawingOneFrame(root.get());

  grand_child_damage_rect =
          grand_child1->render_surface()->damage_tracker()->
              current_damage_rect();
  child_damage_rect =
          child1->render_surface()->damage_tracker()->current_damage_rect();

  EXPECT_TRUE(grand_child_damage_rect.IsEmpty());
  EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithTransformOrigin) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
  LayerImpl* child1 = root->children()[0];
  LayerImpl* grand_child1 = child1->children()[0];

  // Verify that the correct replica_origin_transform is used for the
  // replica_mask.
  ClearDamageForAllSurfaces(root.get());

  // This is not actually the transform origin point being tested, but by
  // convention its
  // expected to be the same as the replica's anchor point.
  grand_child1->SetTransformOrigin(
      gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f));

  {
    scoped_ptr<LayerImpl> grand_child1_replica =
            LayerImpl::Create(host_impl_.active_tree(), 6);
    grand_child1_replica->SetPosition(gfx::PointF());

    // This is the anchor being tested.
    grand_child1_replica->SetTransformOrigin(
        gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f));
    gfx::Transform reflection;
    reflection.Scale3d(-1.0, 1.0, 1.0);
    grand_child1_replica->SetTransform(reflection);
    grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
  }
  LayerImpl* grand_child1_replica = grand_child1->replica_layer();

  // Set up the mask layer on the replica layer
  {
    scoped_ptr<LayerImpl> replica_mask_layer =
            LayerImpl::Create(host_impl_.active_tree(), 7);
    replica_mask_layer->SetPosition(gfx::PointF());
    // Note: this is not the transform origin being tested.
    replica_mask_layer->SetBounds(grand_child1->bounds());
    replica_mask_layer->SetContentBounds(grand_child1->bounds());
    grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass());
  }
  LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer();

  EmulateDrawingOneFrame(root.get());

  // Sanity check that the appropriate render surfaces were created
  ASSERT_TRUE(grand_child1->render_surface());

  // A property change on the replica_mask should damage the reflected region on
  // the target surface.
  ClearDamageForAllSurfaces(root.get());
  replica_mask_layer->SetStackingOrderChanged(true);

  EmulateDrawingOneFrame(root.get());

  gfx::Rect child_damage_rect =
      child1->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(206, 200, 6, 8).ToString(), child_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, DamageWhenAddedExternally) {
  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  // Case 1: This test ensures that when the tracker is given damage, that
  //         it is included with any other partial damage.
  //
  ClearDamageForAllSurfaces(root.get());
  child->SetUpdateRect(gfx::RectF(10, 11, 12, 13));
  root->render_surface()->damage_tracker()->AddDamageNextUpdate(
      gfx::Rect(15, 16, 32, 33));
  EmulateDrawingOneFrame(root.get());
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::UnionRects(gfx::Rect(15, 16, 32, 33),
                            gfx::Rect(100 + 10, 100 + 11, 12, 13)).ToString(),
            root_damage_rect.ToString());

  // Case 2: An additional sanity check that adding damage works even when
  //         nothing on the layer tree changed.
  //
  ClearDamageForAllSurfaces(root.get());
  root->render_surface()->damage_tracker()->AddDamageNextUpdate(
      gfx::Rect(30, 31, 14, 15));
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString());
}

TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) {
  // Though it should never happen, its a good idea to verify that the damage
  // tracker does not crash when it receives an empty layer_list.

  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_.active_tree(), 1);
  root->CreateRenderSurface();

  ASSERT_TRUE(root == root->render_target());
  RenderSurfaceImpl* target_surface = root->render_surface();

  LayerImplList empty_list;
  target_surface->damage_tracker()->UpdateDamageTrackingState(
      empty_list,
      target_surface->OwningLayerId(),
      false,
      gfx::Rect(),
      NULL,
      FilterOperations());

  gfx::Rect damage_rect =
      target_surface->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(damage_rect.IsEmpty());
}

TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) {
  // If damage is not cleared, it should accumulate.

  scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
  LayerImpl* child = root->children()[0];

  ClearDamageForAllSurfaces(root.get());
  child->SetUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f));
  EmulateDrawingOneFrame(root.get());

  // Sanity check damage after the first frame; this isnt the actual test yet.
  gfx::Rect root_damage_rect =
      root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(110, 111, 1, 2).ToString(), root_damage_rect.ToString());

  // New damage, without having cleared the previous damage, should be unioned
  // to the previous one.
  child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_EQ(gfx::Rect(110, 111, 11, 16).ToString(),
            root_damage_rect.ToString());

  // If we notify the damage tracker that we drew the damaged area, then damage
  // should be emptied.
  root->render_surface()->damage_tracker()->DidDrawDamagedArea();
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(root_damage_rect.IsEmpty());

  // Damage should remain empty even after one frame, since there's yet no new
  // damage.
  EmulateDrawingOneFrame(root.get());
  root_damage_rect =
          root->render_surface()->damage_tracker()->current_damage_rect();
  EXPECT_TRUE(root_damage_rect.IsEmpty());
}

TEST_F(DamageTrackerTest, HugeDamageRect) {
  // This number is so large that we start losting floating point accuracy.
  const int kBigNumber = 900000000;
  // Walk over a range to find floating point inaccuracy boundaries that move
  // toward the wrong direction.
  const int kRange = 5000;

  for (int i = 0; i < kRange; ++i) {
    scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface();
    LayerImpl* child = root->children()[0];

    gfx::Transform transform;
    transform.Translate(-kBigNumber, -kBigNumber);

    // The child layer covers (0, 0, i, i) of the viewport,
    // but has a huge negative position.
    child->SetPosition(gfx::PointF());
    child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
    child->SetContentBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
    child->SetTransform(transform);
    EmulateDrawingOneFrame(root.get());

    // The expected damage should cover the visible part of the child layer,
    // which is (0, 0, i, i) in the viewport.
    gfx::Rect root_damage_rect =
        root->render_surface()->damage_tracker()->current_damage_rect();
    gfx::Rect damage_we_care_about = gfx::Rect(i, i);
    EXPECT_LE(damage_we_care_about.right(), root_damage_rect.right());
    EXPECT_LE(damage_we_care_about.bottom(), root_damage_rect.bottom());
  }
}

}  // namespace
}  // namespace cc
