// 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/layers/layer_impl.h"

#include "cc/layers/painted_scrollbar_layer_impl.h"
#include "cc/layers/solid_color_scrollbar_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/fake_output_surface.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "cc/trees/tree_synchronizer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"

namespace cc {
namespace {

#define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test)                       \
  root->ResetAllChangeTrackingForSubtree();                                    \
  code_to_test;                                                                \
  EXPECT_TRUE(root->needs_push_properties());                                  \
  EXPECT_FALSE(child->needs_push_properties());                                \
  EXPECT_FALSE(grand_child->needs_push_properties());                          \
  EXPECT_TRUE(root->LayerPropertyChanged());                                   \
  EXPECT_TRUE(child->LayerPropertyChanged());                                  \
  EXPECT_TRUE(grand_child->LayerPropertyChanged());

#define EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(code_to_test)                \
  root->ResetAllChangeTrackingForSubtree();                                    \
  code_to_test;                                                                \
  EXPECT_FALSE(root->needs_push_properties());                                 \
  EXPECT_FALSE(child->needs_push_properties());                                \
  EXPECT_FALSE(grand_child->needs_push_properties());                          \
  EXPECT_FALSE(root->LayerPropertyChanged());                                  \
  EXPECT_FALSE(child->LayerPropertyChanged());                                 \
  EXPECT_FALSE(grand_child->LayerPropertyChanged());

#define EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(   \
      code_to_test)                                                            \
  root->ResetAllChangeTrackingForSubtree();                                    \
  code_to_test;                                                                \
  EXPECT_TRUE(root->needs_push_properties());                                  \
  EXPECT_FALSE(child->needs_push_properties());                                \
  EXPECT_FALSE(grand_child->needs_push_properties());                          \
  EXPECT_FALSE(root->LayerPropertyChanged());                                  \
  EXPECT_FALSE(child->LayerPropertyChanged());                                 \
  EXPECT_FALSE(grand_child->LayerPropertyChanged());

#define EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(code_to_test)                    \
  root->ResetAllChangeTrackingForSubtree();                                    \
  code_to_test;                                                                \
  EXPECT_TRUE(root->needs_push_properties());                                  \
  EXPECT_FALSE(child->needs_push_properties());                                \
  EXPECT_FALSE(grand_child->needs_push_properties());                          \
  EXPECT_TRUE(root->LayerPropertyChanged());                                   \
  EXPECT_FALSE(child->LayerPropertyChanged());                                 \
  EXPECT_FALSE(grand_child->LayerPropertyChanged());

#define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test)                      \
  root->ResetAllChangeTrackingForSubtree();                                    \
  host_impl.ForcePrepareToDraw();                                              \
  EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties());       \
  code_to_test;                                                                \
  EXPECT_TRUE(host_impl.active_tree()->needs_update_draw_properties());

#define VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test)                   \
  root->ResetAllChangeTrackingForSubtree();                                    \
  host_impl.ForcePrepareToDraw();                                              \
  EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties());       \
  code_to_test;                                                                \
  EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties());

TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
  //
  // This test checks that layerPropertyChanged() has the correct behavior.
  //

  // The constructor on this will fake that we are on the correct thread.
  // Create a simple LayerImpl tree:
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
  scoped_ptr<LayerImpl> root_clip =
      LayerImpl::Create(host_impl.active_tree(), 1);
  scoped_ptr<LayerImpl> root_ptr =
      LayerImpl::Create(host_impl.active_tree(), 2);
  LayerImpl* root = root_ptr.get();
  root_clip->AddChild(root_ptr.Pass());
  scoped_ptr<LayerImpl> scroll_parent =
      LayerImpl::Create(host_impl.active_tree(), 3);
  LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 4).get();
  std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>();
  scroll_children->insert(scroll_child);
  scroll_children->insert(root);
  root->SetHasRenderSurface(true);

  scoped_ptr<LayerImpl> clip_parent =
      LayerImpl::Create(host_impl.active_tree(), 5);
  LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 6).get();
  std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>();
  clip_children->insert(clip_child);
  clip_children->insert(root);

  root->AddChild(LayerImpl::Create(host_impl.active_tree(), 7));
  LayerImpl* child = root->children()[0];
  child->AddChild(LayerImpl::Create(host_impl.active_tree(), 8));
  LayerImpl* grand_child = child->children()[0];

  root->SetScrollClipLayer(root_clip->id());

  // Adding children is an internal operation and should not mark layers as
  // changed.
  EXPECT_FALSE(root->LayerPropertyChanged());
  EXPECT_FALSE(child->LayerPropertyChanged());
  EXPECT_FALSE(grand_child->LayerPropertyChanged());

  gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
  gfx::Point3F arbitrary_point_3f = gfx::Point3F(0.125f, 0.25f, 0.f);
  float arbitrary_number = 0.352f;
  gfx::Size arbitrary_size = gfx::Size(111, 222);
  gfx::Point arbitrary_point = gfx::Point(333, 444);
  gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222);
  gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size);
  gfx::RectF arbitrary_rect_f =
      gfx::RectF(arbitrary_point_f, gfx::SizeF(1.234f, 5.678f));
  SkColor arbitrary_color = SkColorSetRGB(10, 20, 30);
  gfx::Transform arbitrary_transform;
  arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
  FilterOperations arbitrary_filters;
  arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
  SkXfermode::Mode arbitrary_blend_mode = SkXfermode::kMultiply_Mode;

  // These properties are internal, and should not be considered "change" when
  // they are used.
  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
      root->SetUpdateRect(arbitrary_rect));
  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(arbitrary_size));

  // Changing these properties affects the entire subtree of layers.
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
      root->SetTransformOrigin(arbitrary_point_3f));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(arbitrary_filters));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(FilterOperations()));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
      root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 9)));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMasksToBounds(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetContentsOpaque(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
      root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 10)));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPosition(arbitrary_point_f));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetShouldFlattenTransform(false));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->Set3dSortingContextId(1));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
      root->SetDoubleSided(false));  // constructor initializes it to "true".
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->ScrollBy(arbitrary_vector2d));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetScrollDelta(gfx::Vector2d()));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
      root->SetScrollOffset(gfx::ScrollOffset(arbitrary_vector2d)));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetHideLayerAndSubtree(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetOpacity(arbitrary_number));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBlendMode(arbitrary_blend_mode));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetTransform(arbitrary_transform));

  // Changing these properties only affects the layer itself.
  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetContentBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
      root->SetContentsScale(arbitrary_number, arbitrary_number));
  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetDrawsContent(true));
  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
      root->SetBackgroundColor(arbitrary_color));
  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
      root->SetBackgroundFilters(arbitrary_filters));

  // Special case: check that SetBounds changes behavior depending on
  // masksToBounds.
  root->SetMasksToBounds(false);
  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(gfx::Size(135, 246)));
  root->SetMasksToBounds(true);
  // Should be a different size than previous call, to ensure it marks tree
  // changed.
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBounds(arbitrary_size));

  // Changing this property does not cause the layer to be marked as changed
  // but does cause the layer to need to push properties.
  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
      root->SetIsRootForIsolatedGroup(true));

  // Changing these properties should cause the layer to need to push properties
  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
      root->SetScrollParent(scroll_parent.get()));
  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
      root->SetScrollChildren(scroll_children));
  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
      root->SetClipParent(clip_parent.get()));
  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
      root->SetClipChildren(clip_children));
  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
      root->SetNumDescendantsThatDrawContent(10));

  // After setting all these properties already, setting to the exact same
  // values again should not cause any change.
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetTransformOrigin(arbitrary_point_3f));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetMasksToBounds(true));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetPosition(arbitrary_point_f));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetShouldFlattenTransform(false));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->Set3dSortingContextId(1));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetTransform(arbitrary_transform));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetDoubleSided(false));  // constructor initializes it to "true".
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetScrollDelta(gfx::Vector2d()));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetScrollOffset(gfx::ScrollOffset(arbitrary_vector2d)));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetContentBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetContentsScale(arbitrary_number, arbitrary_number));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetContentsOpaque(true));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetOpacity(arbitrary_number));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetBlendMode(arbitrary_blend_mode));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetIsRootForIsolatedGroup(true));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetDrawsContent(true));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetScrollParent(scroll_parent.get()));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetScrollChildren(scroll_children));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetClipParent(clip_parent.get()));
  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
      root->SetClipChildren(clip_children));
}

TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
  host_impl.active_tree()->SetRootLayer(
      LayerImpl::Create(host_impl.active_tree(), 1));
  LayerImpl* root = host_impl.active_tree()->root_layer();
  root->SetHasRenderSurface(true);
  scoped_ptr<LayerImpl> layer_ptr =
      LayerImpl::Create(host_impl.active_tree(), 2);
  LayerImpl* layer = layer_ptr.get();
  root->AddChild(layer_ptr.Pass());
  layer->SetScrollClipLayer(root->id());
  DCHECK(host_impl.CanDraw());

  gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
  float arbitrary_number = 0.352f;
  gfx::Size arbitrary_size = gfx::Size(111, 222);
  gfx::Point arbitrary_point = gfx::Point(333, 444);
  gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222);
  gfx::Size large_size = gfx::Size(1000, 1000);
  gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size);
  gfx::RectF arbitrary_rect_f =
      gfx::RectF(arbitrary_point_f, gfx::SizeF(1.234f, 5.678f));
  SkColor arbitrary_color = SkColorSetRGB(10, 20, 30);
  gfx::Transform arbitrary_transform;
  arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
  FilterOperations arbitrary_filters;
  arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
  SkXfermode::Mode arbitrary_blend_mode = SkXfermode::kMultiply_Mode;

  // Render surface functions.
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(false));
  // Create a render surface, because we must have a render surface if we have
  // filters.
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true));

  // Related filter functions.
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(FilterOperations()));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));

  // Related scrolling functions.
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(arbitrary_vector2d));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(gfx::Vector2d()));
  layer->SetScrollDelta(gfx::Vector2d(0, 0));
  host_impl.ForcePrepareToDraw();
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetScrollDelta(arbitrary_vector2d));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetScrollDelta(arbitrary_vector2d));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetScrollOffset(gfx::ScrollOffset(arbitrary_vector2d)));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetScrollOffset(gfx::ScrollOffset(arbitrary_vector2d)));

  // Unrelated functions, always set to new values, always set needs update.
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 4)));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 5)));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetPosition(arbitrary_point_f));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetShouldFlattenTransform(false));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->Set3dSortingContextId(1));

  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetDoubleSided(false));  // constructor initializes it to "true".
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentBounds(arbitrary_size));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetContentsScale(arbitrary_number, arbitrary_number));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetBackgroundColor(arbitrary_color));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetBackgroundFilters(arbitrary_filters));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetOpacity(arbitrary_number));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetBlendMode(arbitrary_blend_mode));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetTransform(arbitrary_transform));
  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size));

  // Unrelated functions, set to the same values, no needs update.
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetIsRootForIsolatedGroup(true));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetPosition(arbitrary_point_f));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->Set3dSortingContextId(1));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetDoubleSided(false));  // constructor initializes it to "true".
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetContentBounds(arbitrary_size));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetContentsScale(arbitrary_number, arbitrary_number));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetBackgroundColor(arbitrary_color));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetBackgroundFilters(arbitrary_filters));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetOpacity(arbitrary_number));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetBlendMode(arbitrary_blend_mode));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetIsRootForIsolatedGroup(true));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
      layer->SetTransform(arbitrary_transform));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size));
}

TEST(LayerImplTest, SafeOpaqueBackgroundColor) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
  scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);

  for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) {
    for (int layer_opaque = 0; layer_opaque < 2; ++layer_opaque) {
      for (int host_opaque = 0; host_opaque < 2; ++host_opaque) {
        layer->SetContentsOpaque(!!contents_opaque);
        layer->SetBackgroundColor(layer_opaque ? SK_ColorRED
                                               : SK_ColorTRANSPARENT);
        host_impl.active_tree()->set_background_color(
            host_opaque ? SK_ColorRED : SK_ColorTRANSPARENT);

        SkColor safe_color = layer->SafeOpaqueBackgroundColor();
        if (contents_opaque) {
          EXPECT_EQ(SkColorGetA(safe_color), 255u)
              << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
              << host_opaque << "\n";
        } else {
          EXPECT_NE(SkColorGetA(safe_color), 255u)
              << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
              << host_opaque << "\n";
        }
      }
    }
  }
}

TEST(LayerImplTest, TransformInvertibility) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);

  scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);
  EXPECT_TRUE(layer->transform().IsInvertible());
  EXPECT_TRUE(layer->transform_is_invertible());

  gfx::Transform transform;
  transform.Scale3d(
      SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0));
  layer->SetTransform(transform);
  EXPECT_FALSE(layer->transform().IsInvertible());
  EXPECT_FALSE(layer->transform_is_invertible());

  transform.MakeIdentity();
  transform.ApplyPerspectiveDepth(SkDoubleToMScalar(100.0));
  transform.RotateAboutZAxis(75.0);
  transform.RotateAboutXAxis(32.2);
  transform.RotateAboutZAxis(-75.0);
  transform.Translate3d(SkDoubleToMScalar(50.5),
                        SkDoubleToMScalar(42.42),
                        SkDoubleToMScalar(-100.25));

  layer->SetTransform(transform);
  EXPECT_TRUE(layer->transform().IsInvertible());
  EXPECT_TRUE(layer->transform_is_invertible());
}

class LayerImplScrollTest : public testing::Test {
 public:
  LayerImplScrollTest()
      : host_impl_(settings(), &proxy_, &shared_bitmap_manager_), root_id_(7) {
    host_impl_.active_tree()->SetRootLayer(
        LayerImpl::Create(host_impl_.active_tree(), root_id_));
    host_impl_.active_tree()->root_layer()->AddChild(
        LayerImpl::Create(host_impl_.active_tree(), root_id_ + 1));
    layer()->SetScrollClipLayer(root_id_);
    // Set the max scroll offset by noting that the root layer has bounds (1,1),
    // thus whatever bounds are set for the layer will be the max scroll
    // offset plus 1 in each direction.
    host_impl_.active_tree()->root_layer()->SetBounds(gfx::Size(1, 1));
    gfx::Vector2d max_scroll_offset(51, 81);
    layer()->SetBounds(gfx::Size(max_scroll_offset.x(), max_scroll_offset.y()));
  }

  LayerImpl* layer() {
    return host_impl_.active_tree()->root_layer()->children()[0];
  }

  LayerTreeHostImpl& host_impl() { return host_impl_; }

  LayerTreeImpl* tree() { return host_impl_.active_tree(); }

  LayerTreeSettings settings() {
    LayerTreeSettings settings;
    settings.use_pinch_virtual_viewport = true;
    return settings;
  }

 private:
  FakeImplProxy proxy_;
  TestSharedBitmapManager shared_bitmap_manager_;
  FakeLayerTreeHostImpl host_impl_;
  int root_id_;
};

TEST_F(LayerImplScrollTest, ScrollByWithZeroOffset) {
  // Test that LayerImpl::ScrollBy only affects ScrollDelta and total scroll
  // offset is bounded by the range [0, max scroll offset].

  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->scroll_offset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());

  layer()->ScrollBy(gfx::Vector2dF(-100, 100));
  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->TotalScrollOffset());

  EXPECT_VECTOR_EQ(layer()->ScrollDelta(), layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->scroll_offset());

  layer()->ScrollBy(gfx::Vector2dF(100, -100));
  EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), layer()->TotalScrollOffset());

  EXPECT_VECTOR_EQ(layer()->ScrollDelta(), layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->scroll_offset());
}

TEST_F(LayerImplScrollTest, ScrollByWithNonZeroOffset) {
  gfx::ScrollOffset scroll_offset(10, 5);
  layer()->SetScrollOffset(scroll_offset);

  EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());

  layer()->ScrollBy(gfx::Vector2dF(-100, 100));
  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->TotalScrollOffset());

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset,
                                              layer()->ScrollDelta()),
                   layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());

  layer()->ScrollBy(gfx::Vector2dF(100, -100));
  EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), layer()->TotalScrollOffset());

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset,
                                              layer()->ScrollDelta()),
                   layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
}

class ScrollDelegateIgnore : public LayerImpl::ScrollOffsetDelegate {
 public:
  void SetTotalScrollOffset(const gfx::ScrollOffset& new_value) override {
    last_attempted_set_offset_ = new_value;
  }
  gfx::ScrollOffset last_attempted_set_offset() const {
    return last_attempted_set_offset_;
  }

  gfx::ScrollOffset GetTotalScrollOffset() override {
    return gfx::ScrollOffset(fixed_offset_);
  }
  bool IsExternalFlingActive() const override { return false; }
  void Update() const override { }

  void set_fixed_offset(const gfx::Vector2dF& fixed_offset) {
    fixed_offset_ = fixed_offset;
  }

 private:
  gfx::ScrollOffset last_attempted_set_offset_;
  gfx::Vector2dF fixed_offset_;
};

TEST_F(LayerImplScrollTest, ScrollByWithIgnoringDelegate) {
  gfx::ScrollOffset scroll_offset(10, 5);
  layer()->SetScrollOffset(scroll_offset);

  EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());

  ScrollDelegateIgnore delegate;
  gfx::Vector2dF fixed_offset(32, 12);
  delegate.set_fixed_offset(fixed_offset);
  layer()->SetScrollOffsetDelegate(&delegate);

  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());

  layer()->ScrollBy(gfx::Vector2dF(-100, 100));

  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());

  layer()->SetScrollOffsetDelegate(nullptr);

  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());

  gfx::Vector2dF scroll_delta(1, 1);
  layer()->ScrollBy(scroll_delta);

  EXPECT_VECTOR_EQ(fixed_offset + scroll_delta, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
}

class ScrollDelegateAccept : public LayerImpl::ScrollOffsetDelegate {
 public:
  void SetTotalScrollOffset(const gfx::ScrollOffset& new_value) override {
    current_offset_ = new_value;
  }
  gfx::ScrollOffset GetTotalScrollOffset() override { return current_offset_; }
  bool IsExternalFlingActive() const override { return false; }
  void Update() const override { }

 private:
  gfx::ScrollOffset current_offset_;
};

TEST_F(LayerImplScrollTest, ScrollByWithAcceptingDelegate) {
  gfx::ScrollOffset scroll_offset(10, 5);
  layer()->SetScrollOffset(scroll_offset);

  EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());

  ScrollDelegateAccept delegate;
  layer()->SetScrollOffsetDelegate(&delegate);

  EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());

  layer()->ScrollBy(gfx::Vector2dF(-100, 100));

  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());

  layer()->SetScrollOffsetDelegate(nullptr);

  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());

  gfx::Vector2dF scroll_delta(1, 1);
  layer()->ScrollBy(scroll_delta);

  EXPECT_VECTOR_EQ(gfx::Vector2dF(1, 80), layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
}

TEST_F(LayerImplScrollTest, ApplySentScrollsNoDelegate) {
  gfx::ScrollOffset scroll_offset(10, 5);
  gfx::Vector2dF scroll_delta(20.5f, 8.5f);
  gfx::Vector2d sent_scroll_delta(12, -3);

  layer()->SetScrollOffset(scroll_offset);
  layer()->ScrollBy(scroll_delta);
  layer()->SetSentScrollDelta(sent_scroll_delta);

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                   layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_delta, layer()->ScrollDelta());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
  EXPECT_VECTOR_EQ(sent_scroll_delta, layer()->sent_scroll_delta());

  layer()->ApplySentScrollDeltasFromAbortedCommit();

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                   layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_delta - sent_scroll_delta, layer()->ScrollDelta());
  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta),
                   layer()->scroll_offset());
  EXPECT_VECTOR_EQ(gfx::Vector2d(), layer()->sent_scroll_delta());
}

TEST_F(LayerImplScrollTest, ApplySentScrollsWithIgnoringDelegate) {
  gfx::ScrollOffset scroll_offset(10, 5);
  gfx::Vector2d sent_scroll_delta(12, -3);
  gfx::Vector2dF fixed_offset(32, 12);

  layer()->SetScrollOffset(scroll_offset);
  ScrollDelegateIgnore delegate;
  delegate.set_fixed_offset(fixed_offset);
  layer()->SetScrollOffsetDelegate(&delegate);
  layer()->SetSentScrollDelta(sent_scroll_delta);

  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
  EXPECT_VECTOR_EQ(sent_scroll_delta, layer()->sent_scroll_delta());

  layer()->ApplySentScrollDeltasFromAbortedCommit();

  EXPECT_VECTOR_EQ(fixed_offset, delegate.last_attempted_set_offset());

  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta),
                   layer()->scroll_offset());
  EXPECT_VECTOR_EQ(gfx::Vector2d(), layer()->sent_scroll_delta());
}

TEST_F(LayerImplScrollTest, ApplySentScrollsWithAcceptingDelegate) {
  gfx::ScrollOffset scroll_offset(10, 5);
  gfx::Vector2d sent_scroll_delta(12, -3);
  gfx::Vector2dF scroll_delta(20.5f, 8.5f);

  layer()->SetScrollOffset(scroll_offset);
  ScrollDelegateAccept delegate;
  layer()->SetScrollOffsetDelegate(&delegate);
  layer()->ScrollBy(scroll_delta);
  layer()->SetSentScrollDelta(sent_scroll_delta);

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                   layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
  EXPECT_VECTOR_EQ(sent_scroll_delta, layer()->sent_scroll_delta());

  layer()->ApplySentScrollDeltasFromAbortedCommit();

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                   layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta),
                   layer()->scroll_offset());
  EXPECT_VECTOR_EQ(gfx::Vector2d(), layer()->sent_scroll_delta());
}

TEST_F(LayerImplScrollTest, ScrollUserUnscrollableLayer) {
  gfx::ScrollOffset scroll_offset(10, 5);
  gfx::Vector2dF scroll_delta(20.5f, 8.5f);

  layer()->set_user_scrollable_vertical(false);
  layer()->SetScrollOffset(scroll_offset);
  gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta);

  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 8.5f), unscrolled);
  EXPECT_VECTOR_EQ(gfx::Vector2dF(30.5f, 5), layer()->TotalScrollOffset());
}

TEST_F(LayerImplScrollTest, PushPropertiesToMirrorsTotalScrollOffset) {
  gfx::ScrollOffset scroll_offset(10, 5);
  gfx::Vector2dF scroll_delta(12, 18);

  host_impl().CreatePendingTree();

  layer()->SetScrollOffset(scroll_offset);
  gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta);

  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), unscrolled);
  EXPECT_VECTOR_EQ(gfx::Vector2dF(22, 23), layer()->TotalScrollOffset());

  layer()->SetSentScrollDelta(scroll_delta);

  scoped_ptr<LayerImpl> pending_layer =
      LayerImpl::Create(host_impl().sync_tree(), layer()->id());
  pending_layer->SetScrollOffset(layer()->TotalScrollOffset());

  pending_layer->PushPropertiesTo(layer());

  EXPECT_VECTOR_EQ(gfx::Vector2dF(22, 23), layer()->TotalScrollOffset());
  EXPECT_VECTOR_EQ(layer()->TotalScrollOffset(),
                   pending_layer->TotalScrollOffset());
}

TEST_F(LayerImplScrollTest, SetNewScrollbarParameters) {
  gfx::ScrollOffset scroll_offset(10, 5);
  layer()->SetScrollOffset(scroll_offset);

  scoped_ptr<PaintedScrollbarLayerImpl> vertical_scrollbar(
      PaintedScrollbarLayerImpl::Create(tree(), 100, VERTICAL));
  vertical_scrollbar->SetScrollLayerAndClipLayerByIds(
      layer()->id(), tree()->root_layer()->id());

  int expected_vertical_maximum =
      layer()->bounds().height() - tree()->root_layer()->bounds().height();
  EXPECT_EQ(expected_vertical_maximum, vertical_scrollbar->maximum());
  EXPECT_EQ(scroll_offset.y(), vertical_scrollbar->current_pos());

  scoped_ptr<PaintedScrollbarLayerImpl> horizontal_scrollbar(
      PaintedScrollbarLayerImpl::Create(tree(), 101, HORIZONTAL));
  horizontal_scrollbar->SetScrollLayerAndClipLayerByIds(
      layer()->id(), tree()->root_layer()->id());

  int expected_horizontal_maximum =
      layer()->bounds().width() - tree()->root_layer()->bounds().width();
  EXPECT_EQ(expected_horizontal_maximum, horizontal_scrollbar->maximum());
  EXPECT_EQ(scroll_offset.x(), horizontal_scrollbar->current_pos());
}

class LayerImplScrollbarSyncTest : public testing::Test {
 public:
  enum {
    ROOT = 1,
    IV_CLIP = 2,
    PAGE = 3,
    IV_SCROLL = 4,
    SCROLLBAR = 5,
    OLD_ROOT = 6,
    OV_CLIP = 7,
    OV_SCROLL = 8,
  };
  enum TreeID {
    PENDING,
    ACTIVE
  };

  LayerImplScrollbarSyncTest()
      : host_impl_(settings(), &proxy_, &shared_bitmap_manager_) {
    host_impl_.CreatePendingTree();

    CreateLayers(host_impl_.pending_tree());
    CreateLayers(host_impl_.active_tree());
  }

  void CreateLayers(LayerTreeImpl * tree) {
    tree->SetRootLayer(LayerImpl::Create(tree, ROOT));
    LayerImpl * root = tree->root_layer();
    ASSERT_TRUE(root != nullptr);

    int hierarchy[] = {IV_CLIP, PAGE, IV_SCROLL, OLD_ROOT, OV_CLIP, OV_SCROLL};
    LayerImpl * parent = root;
    for (int child_id : hierarchy) {
      parent->AddChild(LayerImpl::Create(tree, child_id));
      parent = tree->LayerById(child_id);
      ASSERT_TRUE(parent != nullptr);
    }

    root->AddChild(
        SolidColorScrollbarLayerImpl::Create(tree, SCROLLBAR, HORIZONTAL,
                                             5, 5, false, true));
  }

  LayerImpl* layer(int id, TreeID tree_id) {
    LayerTreeImpl* tree =
        ((tree_id == PENDING) ?
         host_impl_.pending_tree() : host_impl_.active_tree());

    assert(tree);
    return tree->LayerById(id);
  }

  bool LayerHasScrollbar(int id, TreeID tree_id) {
    return layer(id, tree_id)->HasScrollbar(HORIZONTAL);
  }

  ScrollbarLayerImplBase* pending_scrollbar() {
    LayerImpl* layer_impl = layer(SCROLLBAR, PENDING);
    assert(layer_impl);
    return layer_impl->ToScrollbarLayer();
  }

  LayerImpl* pending_root() {
    LayerImpl * result = layer(ROOT, PENDING);
    assert(result);
    return result;
  }

  LayerImpl* active_root() {
    LayerImpl * result = layer(ROOT, ACTIVE);
    assert(result);
    return result;
  }

  LayerTreeSettings settings() {
    LayerTreeSettings settings;
    settings.use_pinch_virtual_viewport = true;
    return settings;
  }

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

TEST_F(LayerImplScrollbarSyncTest, LayerImplBecomesScrollable) {
  // In the beginning IV_SCROLL layer is not scrollable.
  ASSERT_FALSE(layer(IV_SCROLL, PENDING)->scrollable());

  // For pinch virtual viewport the clip layer is the inner viewport
  // clip layer (IV_CLIP) and the scroll one is the outer viewport
  // scroll layer (OV_SCROLL).
  pending_scrollbar()->SetScrollLayerAndClipLayerByIds(OV_SCROLL, IV_CLIP);

  ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, PENDING));
  ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, PENDING));

  // Synchronize with the active tree.
  TreeSynchronizer::PushProperties(pending_root(), active_root());

  ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, ACTIVE));
  ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, ACTIVE));

  // Make IV_SCROLL layer scrollable.
  layer(IV_SCROLL, PENDING)->SetScrollClipLayer(IV_CLIP);
  layer(IV_SCROLL, PENDING)->SetNeedsPushProperties();
  ASSERT_TRUE(layer(IV_SCROLL, PENDING)->scrollable());

  pending_scrollbar()->SetScrollLayerAndClipLayerByIds(OV_SCROLL, IV_CLIP);

  // Now IV_CLIP layer should also receive the scrollbar.
  ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, PENDING));
  ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, PENDING));
  ASSERT_TRUE(LayerHasScrollbar(IV_SCROLL, PENDING));

  // Synchronize with the active tree.
  TreeSynchronizer::PushProperties(pending_root(), active_root());

  ASSERT_TRUE(layer(IV_SCROLL, ACTIVE)->scrollable());

  ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, ACTIVE));
  ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, ACTIVE));
  ASSERT_TRUE(LayerHasScrollbar(IV_SCROLL, ACTIVE));
}

}  // namespace
}  // namespace cc
