// 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->PushScrollOffsetFromMainThread(
      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->PushScrollOffsetFromMainThread(
          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->PushScrollOffsetFromMainThread(
      gfx::ScrollOffset(arbitrary_vector2d)));
  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->PushScrollOffsetFromMainThread(
      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()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->BaseScrollOffset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());

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

  EXPECT_VECTOR_EQ(layer()->ScrollDelta(), layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->BaseScrollOffset());

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

  EXPECT_VECTOR_EQ(layer()->ScrollDelta(), layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->BaseScrollOffset());
}

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

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

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

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

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

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

class ScrollDelegateIgnore : public LayerImpl::ScrollOffsetDelegate {
 public:
  void SetCurrentScrollOffset(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 GetCurrentScrollOffset() 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()->PushScrollOffsetFromMainThread(scroll_offset);

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

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

  EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset());

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

  EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset());

  layer()->SetScrollOffsetDelegate(nullptr);

  EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset());

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

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

class ScrollDelegateAccept : public LayerImpl::ScrollOffsetDelegate {
 public:
  void SetCurrentScrollOffset(const gfx::ScrollOffset& new_value) override {
    current_offset_ = new_value;
  }
  gfx::ScrollOffset GetCurrentScrollOffset() 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()->PushScrollOffsetFromMainThread(scroll_offset);

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

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

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

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

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

  layer()->SetScrollOffsetDelegate(nullptr);

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

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

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

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()->PushScrollOffsetFromMainThread(scroll_offset);
  layer()->ScrollBy(sent_scroll_delta);
  layer()->PullDeltaForMainThread();
  layer()->SetCurrentScrollOffset(scroll_offset +
                                  gfx::ScrollOffset(scroll_delta));

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                   layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(scroll_delta, layer()->ScrollDelta());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset());

  layer()->ApplySentScrollDeltasFromAbortedCommit();

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

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

  layer()->PushScrollOffsetFromMainThread(scroll_offset);
  layer()->ScrollBy(sent_scroll_delta);
  layer()->PullDeltaForMainThread();
  layer()->SetCurrentScrollOffset(scroll_offset);
  ScrollDelegateIgnore delegate;
  delegate.set_fixed_offset(fixed_offset);
  layer()->SetScrollOffsetDelegate(&delegate);
  layer()->RefreshFromScrollDelegate();

  EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset());

  layer()->ApplySentScrollDeltasFromAbortedCommit();

  EXPECT_VECTOR_EQ(fixed_offset, delegate.last_attempted_set_offset());

  EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta),
                   layer()->BaseScrollOffset());
}

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()->PushScrollOffsetFromMainThread(scroll_offset);
  layer()->ScrollBy(sent_scroll_delta);
  layer()->PullDeltaForMainThread();
  ScrollDelegateAccept delegate;
  layer()->SetScrollOffsetDelegate(&delegate);
  layer()->SetCurrentScrollOffset(scroll_offset +
                                  gfx::ScrollOffset(scroll_delta));

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                   layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset());

  layer()->ApplySentScrollDeltasFromAbortedCommit();

  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                   layer()->CurrentScrollOffset());
  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta),
                   layer()->BaseScrollOffset());
}

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()->PushScrollOffsetFromMainThread(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()->CurrentScrollOffset());
}

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

  host_impl().CreatePendingTree();

  layer()->PushScrollOffsetFromMainThread(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()->CurrentScrollOffset());

  layer()->PullDeltaForMainThread();

  scoped_ptr<LayerImpl> pending_layer = LayerImpl::Create(
      host_impl().sync_tree(), layer()->id(), layer()->synced_scroll_offset());
  pending_layer->PushScrollOffsetFromMainThread(layer()->CurrentScrollOffset());

  pending_layer->PushPropertiesTo(layer());

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

TEST_F(LayerImplScrollTest, SetNewScrollbarParameters) {
  gfx::ScrollOffset scroll_offset(10, 5);
  layer()->PushScrollOffsetFromMainThread(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
