Upstream version 10.38.220.0
[platform/framework/web/crosswalk.git] / src / cc / layers / layer.cc
index 8d07366..9677536 100644 (file)
@@ -6,25 +6,31 @@
 
 #include <algorithm>
 
+#include "base/atomic_sequence_num.h"
 #include "base/debug/trace_event.h"
 #include "base/location.h"
 #include "base/metrics/histogram.h"
 #include "base/single_thread_task_runner.h"
+#include "base/time/time.h"
 #include "cc/animation/animation.h"
 #include "cc/animation/animation_events.h"
+#include "cc/animation/animation_registrar.h"
+#include "cc/animation/keyframed_animation_curve.h"
 #include "cc/animation/layer_animation_controller.h"
 #include "cc/layers/layer_client.h"
 #include "cc/layers/layer_impl.h"
+#include "cc/layers/scrollbar_layer_interface.h"
 #include "cc/output/copy_output_request.h"
 #include "cc/output/copy_output_result.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "third_party/skia/include/core/SkImageFilter.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 #include "ui/gfx/rect_conversions.h"
 
 namespace cc {
 
-static int s_next_layer_id = 1;
+base::StaticAtomicSequenceNumber g_next_layer_id;
 
 scoped_refptr<Layer> Layer::Create() {
   return make_scoped_refptr(new Layer());
@@ -34,42 +40,43 @@ Layer::Layer()
     : needs_push_properties_(false),
       num_dependents_need_push_properties_(false),
       stacking_order_changed_(false),
-      layer_id_(s_next_layer_id++),
+      // Layer IDs start from 1.
+      layer_id_(g_next_layer_id.GetNext() + 1),
       ignore_set_needs_commit_(false),
+      sorting_context_id_(0),
       parent_(NULL),
       layer_tree_host_(NULL),
-      scrollable_(false),
+      scroll_clip_layer_id_(INVALID_ID),
+      num_descendants_that_draw_content_(0),
       should_scroll_on_main_thread_(false),
       have_wheel_event_handlers_(false),
+      have_scroll_event_handlers_(false),
       user_scrollable_horizontal_(true),
       user_scrollable_vertical_(true),
-      anchor_point_(0.5f, 0.5f),
-      background_color_(0),
-      compositing_reasons_(kCompositingReasonUnknown),
-      opacity_(1.f),
-      anchor_point_z_(0.f),
+      is_root_for_isolated_group_(false),
       is_container_for_fixed_position_layers_(false),
       is_drawable_(false),
+      draws_content_(false),
       hide_layer_and_subtree_(false),
       masks_to_bounds_(false),
       contents_opaque_(false),
       double_sided_(true),
-      preserves_3d_(false),
+      should_flatten_transform_(true),
       use_parent_backface_visibility_(false),
       draw_checkerboard_for_missing_tiles_(false),
       force_render_surface_(false),
+      transform_is_invertible_(true),
+      background_color_(0),
+      opacity_(1.f),
+      blend_mode_(SkXfermode::kSrcOver_Mode),
       scroll_parent_(NULL),
       clip_parent_(NULL),
       replica_layer_(NULL),
       raster_scale_(0.f),
       client_(NULL) {
-  if (layer_id_ < 0) {
-    s_next_layer_id = 1;
-    layer_id_ = s_next_layer_id++;
-  }
-
   layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
   layer_animation_controller_->AddValueObserver(this);
+  layer_animation_controller_->set_value_provider(this);
 }
 
 Layer::~Layer() {
@@ -81,6 +88,10 @@ Layer::~Layer() {
   DCHECK(!layer_tree_host());
 
   layer_animation_controller_->RemoveValueObserver(this);
+  layer_animation_controller_->remove_value_provider(this);
+
+  RemoveFromScrollTree();
+  RemoveFromClipTree();
 
   // Remove the parent reference from all children and dependents.
   RemoveAllChildren();
@@ -92,9 +103,6 @@ Layer::~Layer() {
     DCHECK_EQ(this, replica_layer_->parent());
     replica_layer_->RemoveFromParent();
   }
-
-  RemoveFromScrollTree();
-  RemoveFromClipTree();
 }
 
 void Layer::SetLayerTreeHost(LayerTreeHost* host) {
@@ -125,8 +133,6 @@ void Layer::SetLayerTreeHost(LayerTreeHost* host) {
 
   if (host && layer_animation_controller_->has_any_animation())
     host->SetNeedsCommit();
-  if (host && (!filters_.IsEmpty() || !background_filters_.IsEmpty()))
-    layer_tree_host_->set_needs_filter_context();
 }
 
 void Layer::SetNeedsUpdate() {
@@ -241,6 +247,8 @@ void Layer::AddChild(scoped_refptr<Layer> child) {
 void Layer::InsertChild(scoped_refptr<Layer> child, size_t index) {
   DCHECK(IsPropertyChangeAllowed());
   child->RemoveFromParent();
+  AddDrawableDescendants(child->NumDescendantsThatDrawContent() +
+                         (child->DrawsContent() ? 1 : 0));
   child->SetParent(this);
   child->stacking_order_changed_ = true;
 
@@ -276,6 +284,8 @@ void Layer::RemoveChildOrDependent(Layer* child) {
       continue;
 
     child->SetParent(NULL);
+    AddDrawableDescendants(-child->NumDescendantsThatDrawContent() -
+                           (child->DrawsContent() ? 1 : 0));
     children_.erase(iter);
     SetNeedsFullTreeSync();
     return;
@@ -312,7 +322,7 @@ int Layer::IndexOfChild(const Layer* reference) {
   return -1;
 }
 
-void Layer::SetBounds(gfx::Size size) {
+void Layer::SetBounds(const gfx::Size& size) {
   DCHECK(IsPropertyChangeAllowed());
   if (bounds() == size)
     return;
@@ -364,22 +374,6 @@ void Layer::RequestCopyOfOutput(
   SetNeedsCommit();
 }
 
-void Layer::SetAnchorPoint(gfx::PointF anchor_point) {
-  DCHECK(IsPropertyChangeAllowed());
-  if (anchor_point_ == anchor_point)
-    return;
-  anchor_point_ = anchor_point;
-  SetNeedsCommit();
-}
-
-void Layer::SetAnchorPointZ(float anchor_point_z) {
-  DCHECK(IsPropertyChangeAllowed());
-  if (anchor_point_z_ == anchor_point_z)
-    return;
-  anchor_point_z_ = anchor_point_z;
-  SetNeedsCommit();
-}
-
 void Layer::SetBackgroundColor(SkColor background_color) {
   DCHECK(IsPropertyChangeAllowed());
   if (background_color_ == background_color)
@@ -407,14 +401,10 @@ SkColor Layer::SafeOpaqueBackgroundColor() const {
   return color;
 }
 
-void Layer::CalculateContentsScale(
-    float ideal_contents_scale,
-    float device_scale_factor,
-    float page_scale_factor,
-    bool animating_transform_to_screen,
-    float* contents_scale_x,
-    float* contents_scale_y,
-    gfx::Size* content_bounds) {
+void Layer::CalculateContentsScale(float ideal_contents_scale,
+                                   float* contents_scale_x,
+                                   float* contents_scale_y,
+                                   gfx::Size* content_bounds) {
   DCHECK(layer_tree_host_);
 
   *contents_scale_x = 1;
@@ -471,8 +461,6 @@ void Layer::SetFilters(const FilterOperations& filters) {
     return;
   filters_ = filters;
   SetNeedsCommit();
-  if (!filters.IsEmpty() && layer_tree_host_)
-    layer_tree_host_->set_needs_filter_context();
 }
 
 bool Layer::FilterIsAnimating() const {
@@ -485,8 +473,6 @@ void Layer::SetBackgroundFilters(const FilterOperations& filters) {
     return;
   background_filters_ = filters;
   SetNeedsCommit();
-  if (!filters.IsEmpty() && layer_tree_host_)
-    layer_tree_host_->set_needs_filter_context();
 }
 
 void Layer::SetOpacity(float opacity) {
@@ -505,6 +491,63 @@ bool Layer::OpacityCanAnimateOnImplThread() const {
   return false;
 }
 
+void Layer::SetBlendMode(SkXfermode::Mode blend_mode) {
+  DCHECK(IsPropertyChangeAllowed());
+  if (blend_mode_ == blend_mode)
+    return;
+
+  // Allowing only blend modes that are defined in the CSS Compositing standard:
+  // http://dev.w3.org/fxtf/compositing-1/#blending
+  switch (blend_mode) {
+    case SkXfermode::kSrcOver_Mode:
+    case SkXfermode::kScreen_Mode:
+    case SkXfermode::kOverlay_Mode:
+    case SkXfermode::kDarken_Mode:
+    case SkXfermode::kLighten_Mode:
+    case SkXfermode::kColorDodge_Mode:
+    case SkXfermode::kColorBurn_Mode:
+    case SkXfermode::kHardLight_Mode:
+    case SkXfermode::kSoftLight_Mode:
+    case SkXfermode::kDifference_Mode:
+    case SkXfermode::kExclusion_Mode:
+    case SkXfermode::kMultiply_Mode:
+    case SkXfermode::kHue_Mode:
+    case SkXfermode::kSaturation_Mode:
+    case SkXfermode::kColor_Mode:
+    case SkXfermode::kLuminosity_Mode:
+      // supported blend modes
+      break;
+    case SkXfermode::kClear_Mode:
+    case SkXfermode::kSrc_Mode:
+    case SkXfermode::kDst_Mode:
+    case SkXfermode::kDstOver_Mode:
+    case SkXfermode::kSrcIn_Mode:
+    case SkXfermode::kDstIn_Mode:
+    case SkXfermode::kSrcOut_Mode:
+    case SkXfermode::kDstOut_Mode:
+    case SkXfermode::kSrcATop_Mode:
+    case SkXfermode::kDstATop_Mode:
+    case SkXfermode::kXor_Mode:
+    case SkXfermode::kPlus_Mode:
+    case SkXfermode::kModulate_Mode:
+      // Porter Duff Compositing Operators are not yet supported
+      // http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators
+      NOTREACHED();
+      return;
+  }
+
+  blend_mode_ = blend_mode;
+  SetNeedsCommit();
+}
+
+void Layer::SetIsRootForIsolatedGroup(bool root) {
+  DCHECK(IsPropertyChangeAllowed());
+  if (is_root_for_isolated_group_ == root)
+    return;
+  is_root_for_isolated_group_ = root;
+  SetNeedsCommit();
+}
+
 void Layer::SetContentsOpaque(bool opaque) {
   DCHECK(IsPropertyChangeAllowed());
   if (contents_opaque_ == opaque)
@@ -513,7 +556,7 @@ void Layer::SetContentsOpaque(bool opaque) {
   SetNeedsCommit();
 }
 
-void Layer::SetPosition(gfx::PointF position) {
+void Layer::SetPosition(const gfx::PointF& position) {
   DCHECK(IsPropertyChangeAllowed());
   if (position_ == position)
     return;
@@ -524,24 +567,25 @@ void Layer::SetPosition(gfx::PointF position) {
 bool Layer::IsContainerForFixedPositionLayers() const {
   if (!transform_.IsIdentityOrTranslation())
     return true;
-  if (parent_ && !parent_->sublayer_transform_.IsIdentityOrTranslation())
+  if (parent_ && !parent_->transform_.IsIdentityOrTranslation())
     return true;
   return is_container_for_fixed_position_layers_;
 }
 
-void Layer::SetSublayerTransform(const gfx::Transform& sublayer_transform) {
+void Layer::SetTransform(const gfx::Transform& transform) {
   DCHECK(IsPropertyChangeAllowed());
-  if (sublayer_transform_ == sublayer_transform)
+  if (transform_ == transform)
     return;
-  sublayer_transform_ = sublayer_transform;
+  transform_ = transform;
+  transform_is_invertible_ = transform.IsInvertible();
   SetNeedsCommit();
 }
 
-void Layer::SetTransform(const gfx::Transform& transform) {
+void Layer::SetTransformOrigin(const gfx::Point3F& transform_origin) {
   DCHECK(IsPropertyChangeAllowed());
-  if (transform_ == transform)
+  if (transform_origin_ == transform_origin)
     return;
-  transform_ = transform;
+  transform_origin_ = transform_origin;
   SetNeedsCommit();
 }
 
@@ -611,13 +655,14 @@ void Layer::RemoveClipChild(Layer* child) {
 
 void Layer::SetScrollOffset(gfx::Vector2d scroll_offset) {
   DCHECK(IsPropertyChangeAllowed());
+
   if (scroll_offset_ == scroll_offset)
     return;
   scroll_offset_ = scroll_offset;
   SetNeedsCommit();
 }
 
-void Layer::SetScrollOffsetFromImplSide(gfx::Vector2d scroll_offset) {
+void Layer::SetScrollOffsetFromImplSide(const gfx::Vector2d& scroll_offset) {
   DCHECK(IsPropertyChangeAllowed());
   // This function only gets called during a BeginMainFrame, so there
   // is no need to call SetNeedsUpdate here.
@@ -632,19 +677,11 @@ void Layer::SetScrollOffsetFromImplSide(gfx::Vector2d scroll_offset) {
   // "this" may have been destroyed during the process.
 }
 
-void Layer::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) {
+void Layer::SetScrollClipLayerId(int clip_layer_id) {
   DCHECK(IsPropertyChangeAllowed());
-  if (max_scroll_offset_ == max_scroll_offset)
+  if (scroll_clip_layer_id_ == clip_layer_id)
     return;
-  max_scroll_offset_ = max_scroll_offset;
-  SetNeedsCommit();
-}
-
-void Layer::SetScrollable(bool scrollable) {
-  DCHECK(IsPropertyChangeAllowed());
-  if (scrollable_ == scrollable)
-    return;
-  scrollable_ = scrollable;
+  scroll_clip_layer_id_ = clip_layer_id;
   SetNeedsCommit();
 }
 
@@ -674,6 +711,14 @@ void Layer::SetHaveWheelEventHandlers(bool have_wheel_event_handlers) {
   SetNeedsCommit();
 }
 
+void Layer::SetHaveScrollEventHandlers(bool have_scroll_event_handlers) {
+  DCHECK(IsPropertyChangeAllowed());
+  if (have_scroll_event_handlers_ == have_scroll_event_handlers)
+    return;
+  have_scroll_event_handlers_ = have_scroll_event_handlers;
+  SetNeedsCommit();
+}
+
 void Layer::SetNonFastScrollableRegion(const Region& region) {
   DCHECK(IsPropertyChangeAllowed());
   if (non_fast_scrollable_region_ == region)
@@ -714,13 +759,29 @@ void Layer::SetDoubleSided(bool double_sided) {
   SetNeedsCommit();
 }
 
+void Layer::Set3dSortingContextId(int id) {
+  DCHECK(IsPropertyChangeAllowed());
+  if (id == sorting_context_id_)
+    return;
+  sorting_context_id_ = id;
+  SetNeedsCommit();
+}
+
+void Layer::SetShouldFlattenTransform(bool should_flatten) {
+  DCHECK(IsPropertyChangeAllowed());
+  if (should_flatten_transform_ == should_flatten)
+    return;
+  should_flatten_transform_ = should_flatten;
+  SetNeedsCommit();
+}
+
 void Layer::SetIsDrawable(bool is_drawable) {
   DCHECK(IsPropertyChangeAllowed());
   if (is_drawable_ == is_drawable)
     return;
 
   is_drawable_ = is_drawable;
-  SetNeedsCommit();
+  UpdateDrawsContent(HasDrawableContent());
 }
 
 void Layer::SetHideLayerAndSubtree(bool hide) {
@@ -796,8 +857,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
   bool use_paint_properties = paint_properties_.source_frame_number ==
                               layer_tree_host_->source_frame_number();
 
-  layer->SetAnchorPoint(anchor_point_);
-  layer->SetAnchorPointZ(anchor_point_z_);
+  layer->SetTransformOrigin(transform_origin_);
   layer->SetBackgroundColor(background_color_);
   layer->SetBounds(use_paint_properties ? paint_properties_.bounds
                                         : bounds_);
@@ -805,14 +865,13 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
   layer->SetContentsScale(contents_scale_x(), contents_scale_y());
 
   bool is_tracing;
-  TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-                                     &is_tracing);
+  TRACE_EVENT_CATEGORY_GROUP_ENABLED(
+      TRACE_DISABLED_BY_DEFAULT("cc.debug") "," TRACE_DISABLED_BY_DEFAULT(
+          "devtools.timeline.layers"),
+      &is_tracing);
   if (is_tracing)
-      layer->SetDebugName(DebugName());
-  else
-      layer->SetDebugName(std::string());
+    layer->SetDebugInfo(TakeDebugInfo());
 
-  layer->SetCompositingReasons(compositing_reasons_);
   layer->SetDoubleSided(double_sided_);
   layer->SetDrawCheckerboardForMissingTiles(
       draw_checkerboard_for_missing_tiles_);
@@ -826,46 +885,59 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
   layer->SetMasksToBounds(masks_to_bounds_);
   layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_);
   layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_);
+  layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_);
   layer->SetNonFastScrollableRegion(non_fast_scrollable_region_);
   layer->SetTouchEventHandlerRegion(touch_event_handler_region_);
   layer->SetContentsOpaque(contents_opaque_);
   if (!layer->OpacityIsAnimatingOnImplOnly() && !OpacityIsAnimating())
     layer->SetOpacity(opacity_);
   DCHECK(!(OpacityIsAnimating() && layer->OpacityIsAnimatingOnImplOnly()));
+  layer->SetBlendMode(blend_mode_);
+  layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_);
   layer->SetPosition(position_);
   layer->SetIsContainerForFixedPositionLayers(
       IsContainerForFixedPositionLayers());
-  layer->SetFixedContainerSizeDelta(gfx::Vector2dF());
   layer->SetPositionConstraint(position_constraint_);
-  layer->SetPreserves3d(preserves_3d());
+  layer->SetShouldFlattenTransform(should_flatten_transform_);
   layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_);
-  layer->SetSublayerTransform(sublayer_transform_);
   if (!layer->TransformIsAnimatingOnImplOnly() && !TransformIsAnimating())
-    layer->SetTransform(transform_);
+    layer->SetTransformAndInvertibility(transform_, transform_is_invertible_);
   DCHECK(!(TransformIsAnimating() && layer->TransformIsAnimatingOnImplOnly()));
+  layer->Set3dSortingContextId(sorting_context_id_);
+  layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_);
 
-  layer->SetScrollable(scrollable_);
+  layer->SetScrollClipLayer(scroll_clip_layer_id_);
   layer->set_user_scrollable_horizontal(user_scrollable_horizontal_);
   layer->set_user_scrollable_vertical(user_scrollable_vertical_);
-  layer->SetMaxScrollOffset(max_scroll_offset_);
 
   LayerImpl* scroll_parent = NULL;
-  if (scroll_parent_)
+  if (scroll_parent_) {
     scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id());
+    DCHECK(scroll_parent);
+  }
 
   layer->SetScrollParent(scroll_parent);
   if (scroll_children_) {
     std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>;
     for (std::set<Layer*>::iterator it = scroll_children_->begin();
-        it != scroll_children_->end(); ++it)
-      scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id()));
+         it != scroll_children_->end();
+         ++it) {
+      DCHECK_EQ((*it)->scroll_parent(), this);
+      LayerImpl* scroll_child =
+          layer->layer_tree_impl()->LayerById((*it)->id());
+      DCHECK(scroll_child);
+      scroll_children->insert(scroll_child);
+    }
     layer->SetScrollChildren(scroll_children);
+  } else {
+    layer->SetScrollChildren(NULL);
   }
 
   LayerImpl* clip_parent = NULL;
   if (clip_parent_) {
     clip_parent =
         layer->layer_tree_impl()->LayerById(clip_parent_->id());
+    DCHECK(clip_parent);
   }
 
   layer->SetClipParent(clip_parent);
@@ -873,11 +945,14 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
     std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>;
     for (std::set<Layer*>::iterator it = clip_children_->begin();
         it != clip_children_->end(); ++it) {
+      DCHECK_EQ((*it)->clip_parent(), this);
       LayerImpl* clip_child = layer->layer_tree_impl()->LayerById((*it)->id());
       DCHECK(clip_child);
       clip_children->insert(clip_child);
     }
     layer->SetClipChildren(clip_children);
+  } else {
+    layer->SetClipChildren(NULL);
   }
 
   // Adjust the scroll delta to be just the scrolls that have happened since
@@ -916,7 +991,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
   // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
   // union) any update changes that have occurred on the main thread.
   update_rect_.Union(layer->update_rect());
-  layer->set_update_rect(update_rect_);
+  layer->SetUpdateRect(update_rect_);
 
   layer->SetStackingOrderChanged(stacking_order_changed_);
 
@@ -927,9 +1002,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
   stacking_order_changed_ = false;
   update_rect_ = gfx::RectF();
 
-  // Animating layers require further push properties to clean up the animation.
-  // crbug.com/259088
-  needs_push_properties_ = layer_animation_controller_->has_any_animation();
+  needs_push_properties_ = false;
   num_dependents_need_push_properties_ = 0;
 }
 
@@ -938,9 +1011,38 @@ scoped_ptr<LayerImpl> Layer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
 }
 
 bool Layer::DrawsContent() const {
+  return draws_content_;
+}
+
+bool Layer::HasDrawableContent() const {
   return is_drawable_;
 }
 
+void Layer::UpdateDrawsContent(bool has_drawable_content) {
+  bool draws_content = has_drawable_content;
+  DCHECK(is_drawable_ || !has_drawable_content);
+  if (draws_content == draws_content_)
+    return;
+
+  if (HasDelegatedContent()) {
+    // Layers with delegated content need to be treated as if they have as
+    // many children as the number of layers they own delegated quads for.
+    // Since we don't know this number right now, we choose one that acts like
+    // infinity for our purposes.
+    AddDrawableDescendants(draws_content ? 1000 : -1000);
+  }
+
+  if (parent())
+    parent()->AddDrawableDescendants(draws_content ? 1 : -1);
+
+  draws_content_ = draws_content;
+  SetNeedsCommit();
+}
+
+int Layer::NumDescendantsThatDrawContent() const {
+  return num_descendants_that_draw_content_;
+}
+
 void Layer::SavePaintProperties() {
   DCHECK(layer_tree_host_);
 
@@ -952,7 +1054,7 @@ void Layer::SavePaintProperties() {
 }
 
 bool Layer::Update(ResourceUpdateQueue* queue,
-                   const OcclusionTracker* occlusion) {
+                   const OcclusionTracker<Layer>* occlusion) {
   DCHECK(layer_tree_host_);
   DCHECK_EQ(layer_tree_host_->source_frame_number(),
             paint_properties_.source_frame_number) <<
@@ -964,12 +1066,15 @@ bool Layer::NeedMoreUpdates() {
   return false;
 }
 
-std::string Layer::DebugName() {
-  return client_ ? client_->DebugName() : std::string();
+bool Layer::IsSuitableForGpuRasterization() const {
+  return true;
 }
 
-void Layer::SetCompositingReasons(CompositingReasons reasons) {
-  compositing_reasons_ = reasons;
+scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
+  if (client_)
+    return client_->TakeDebugInfo();
+  else
+    return NULL;
 }
 
 void Layer::CreateRenderSurface() {
@@ -982,6 +1087,15 @@ void Layer::ClearRenderSurface() {
   draw_properties_.render_surface.reset();
 }
 
+void Layer::ClearRenderSurfaceLayerList() {
+  if (draw_properties_.render_surface)
+    draw_properties_.render_surface->layer_list().clear();
+}
+
+gfx::Vector2dF Layer::ScrollOffsetForAnimation() const {
+  return TotalScrollOffset();
+}
+
 // On<Property>Animated is called due to an ongoing accelerated animation.
 // Since this animation is also being run on the compositor thread, there
 // is no need to request a commit to push this value over, so the value is
@@ -995,7 +1109,21 @@ void Layer::OnOpacityAnimated(float opacity) {
 }
 
 void Layer::OnTransformAnimated(const gfx::Transform& transform) {
+  if (transform_ == transform)
+    return;
   transform_ = transform;
+  transform_is_invertible_ = transform.IsInvertible();
+}
+
+void Layer::OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset) {
+  // Do nothing. Scroll deltas will be sent from the compositor thread back
+  // to the main thread in the same manner as during non-animated
+  // compositor-driven scrolling.
+}
+
+void Layer::OnAnimationWaitingForDeletion() {
+  // Animations are only deleted during PushProperties.
+  SetNeedsPushProperties();
 }
 
 bool Layer::IsActive() const {
@@ -1006,6 +1134,11 @@ bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
   if (!layer_animation_controller_->animation_registrar())
     return false;
 
+  if (animation->target_property() == Animation::ScrollOffset &&
+      !layer_animation_controller_->animation_registrar()
+           ->supports_scroll_animations())
+    return false;
+
   UMA_HISTOGRAM_BOOLEAN("Renderer.AnimationAddedToOrphanLayer",
                         !layer_tree_host_);
   layer_animation_controller_->AddAnimation(animation.Pass());
@@ -1014,7 +1147,8 @@ bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
 }
 
 void Layer::PauseAnimation(int animation_id, double time_offset) {
-  layer_animation_controller_->PauseAnimation(animation_id, time_offset);
+  layer_animation_controller_->PauseAnimation(
+      animation_id, base::TimeDelta::FromSecondsD(time_offset));
   SetNeedsCommit();
 }
 
@@ -1027,7 +1161,6 @@ void Layer::SetLayerAnimationControllerForTest(
     scoped_refptr<LayerAnimationController> controller) {
   layer_animation_controller_->RemoveValueObserver(this);
   layer_animation_controller_ = controller;
-  layer_animation_controller_->set_force_sync();
   layer_animation_controller_->AddValueObserver(this);
   SetNeedsCommit();
 }
@@ -1066,32 +1199,43 @@ bool Layer::SupportsLCDText() const {
 
 void Layer::RemoveFromScrollTree() {
   if (scroll_children_.get()) {
-    for (std::set<Layer*>::iterator it = scroll_children_->begin();
-        it != scroll_children_->end(); ++it)
-      (*it)->scroll_parent_ = NULL;
+    std::set<Layer*> copy = *scroll_children_;
+    for (std::set<Layer*>::iterator it = copy.begin(); it != copy.end(); ++it)
+      (*it)->SetScrollParent(NULL);
   }
 
-  if (scroll_parent_)
-    scroll_parent_->RemoveScrollChild(this);
-
-  scroll_parent_ = NULL;
+  DCHECK(!scroll_children_);
+  SetScrollParent(NULL);
 }
 
 void Layer::RemoveFromClipTree() {
   if (clip_children_.get()) {
-    for (std::set<Layer*>::iterator it = clip_children_->begin();
-        it != clip_children_->end(); ++it)
-      (*it)->clip_parent_ = NULL;
+    std::set<Layer*> copy = *clip_children_;
+    for (std::set<Layer*>::iterator it = copy.begin(); it != copy.end(); ++it)
+      (*it)->SetClipParent(NULL);
   }
 
-  if (clip_parent_)
-    clip_parent_->RemoveClipChild(this);
+  DCHECK(!clip_children_);
+  SetClipParent(NULL);
+}
 
-  clip_parent_ = NULL;
+void Layer::AddDrawableDescendants(int num) {
+  DCHECK_GE(num_descendants_that_draw_content_, 0);
+  DCHECK_GE(num_descendants_that_draw_content_ + num, 0);
+  if (num == 0)
+    return;
+  num_descendants_that_draw_content_ += num;
+  SetNeedsCommit();
+  if (parent())
+    parent()->AddDrawableDescendants(num);
 }
 
 void Layer::RunMicroBenchmark(MicroBenchmark* benchmark) {
   benchmark->RunOnLayer(this);
 }
 
+bool Layer::HasDelegatedContent() const {
+  return false;
+}
+
 }  // namespace cc