layer_impl.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/layers/layer_impl.h"
6
7#include "base/debug/trace_event.h"
8#include "base/debug/trace_event_argument.h"
9#include "base/json/json_reader.h"
10#include "base/strings/stringprintf.h"
11#include "cc/animation/animation_registrar.h"
12#include "cc/animation/scrollbar_animation_controller.h"
13#include "cc/base/math_util.h"
14#include "cc/debug/debug_colors.h"
15#include "cc/debug/layer_tree_debug_state.h"
16#include "cc/debug/micro_benchmark_impl.h"
17#include "cc/debug/traced_value.h"
18#include "cc/input/layer_scroll_offset_delegate.h"
19#include "cc/layers/layer_utils.h"
20#include "cc/layers/painted_scrollbar_layer_impl.h"
21#include "cc/output/copy_output_request.h"
22#include "cc/quads/debug_border_draw_quad.h"
23#include "cc/trees/layer_tree_host_common.h"
24#include "cc/trees/layer_tree_impl.h"
25#include "cc/trees/layer_tree_settings.h"
26#include "cc/trees/proxy.h"
27#include "ui/gfx/box_f.h"
28#include "ui/gfx/geometry/vector2d_conversions.h"
29#include "ui/gfx/point_conversions.h"
30#include "ui/gfx/quad_f.h"
31#include "ui/gfx/rect_conversions.h"
32#include "ui/gfx/size_conversions.h"
33
34namespace cc {
35LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id)
36    : parent_(NULL),
37      scroll_parent_(NULL),
38      clip_parent_(NULL),
39      mask_layer_id_(-1),
40      replica_layer_id_(-1),
41      layer_id_(id),
42      layer_tree_impl_(tree_impl),
43      scroll_offset_delegate_(NULL),
44      scroll_clip_layer_(NULL),
45      should_scroll_on_main_thread_(false),
46      have_wheel_event_handlers_(false),
47      have_scroll_event_handlers_(false),
48      user_scrollable_horizontal_(true),
49      user_scrollable_vertical_(true),
50      stacking_order_changed_(false),
51      double_sided_(true),
52      should_flatten_transform_(true),
53      layer_property_changed_(false),
54      masks_to_bounds_(false),
55      contents_opaque_(false),
56      is_root_for_isolated_group_(false),
57      use_parent_backface_visibility_(false),
58      draw_checkerboard_for_missing_tiles_(false),
59      draws_content_(false),
60      hide_layer_and_subtree_(false),
61      force_render_surface_(false),
62      transform_is_invertible_(true),
63      is_container_for_fixed_position_layers_(false),
64      background_color_(0),
65      opacity_(1.0),
66      blend_mode_(SkXfermode::kSrcOver_Mode),
67      draw_depth_(0.f),
68      needs_push_properties_(false),
69      num_dependents_need_push_properties_(0),
70      sorting_context_id_(0),
71      current_draw_mode_(DRAW_MODE_NONE) {
72  DCHECK_GT(layer_id_, 0);
73  DCHECK(layer_tree_impl_);
74  layer_tree_impl_->RegisterLayer(this);
75  AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar();
76  layer_animation_controller_ =
77      registrar->GetAnimationControllerForId(layer_id_);
78  layer_animation_controller_->AddValueObserver(this);
79  if (IsActive()) {
80    layer_animation_controller_->set_value_provider(this);
81    layer_animation_controller_->set_layer_animation_delegate(this);
82  }
83  SetNeedsPushProperties();
84}
85
86LayerImpl::~LayerImpl() {
87  DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_);
88
89  layer_animation_controller_->RemoveValueObserver(this);
90  layer_animation_controller_->remove_value_provider(this);
91  layer_animation_controller_->remove_layer_animation_delegate(this);
92
93  if (!copy_requests_.empty() && layer_tree_impl_->IsActiveTree())
94    layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
95  layer_tree_impl_->UnregisterLayer(this);
96
97  TRACE_EVENT_OBJECT_DELETED_WITH_ID(
98      TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerImpl", this);
99}
100
101void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) {
102  child->SetParent(this);
103  DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl());
104  children_.push_back(child.Pass());
105  layer_tree_impl()->set_needs_update_draw_properties();
106}
107
108scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) {
109  for (OwnedLayerImplList::iterator it = children_.begin();
110       it != children_.end();
111       ++it) {
112    if (*it == child) {
113      scoped_ptr<LayerImpl> ret = children_.take(it);
114      children_.erase(it);
115      layer_tree_impl()->set_needs_update_draw_properties();
116      return ret.Pass();
117    }
118  }
119  return scoped_ptr<LayerImpl>();
120}
121
122void LayerImpl::SetParent(LayerImpl* parent) {
123  if (parent_should_know_need_push_properties()) {
124    if (parent_)
125      parent_->RemoveDependentNeedsPushProperties();
126    if (parent)
127      parent->AddDependentNeedsPushProperties();
128  }
129  parent_ = parent;
130}
131
132void LayerImpl::ClearChildList() {
133  if (children_.empty())
134    return;
135
136  children_.clear();
137  layer_tree_impl()->set_needs_update_draw_properties();
138}
139
140bool LayerImpl::HasAncestor(const LayerImpl* ancestor) const {
141  if (!ancestor)
142    return false;
143
144  for (const LayerImpl* layer = this; layer; layer = layer->parent()) {
145    if (layer == ancestor)
146      return true;
147  }
148
149  return false;
150}
151
152void LayerImpl::SetScrollParent(LayerImpl* parent) {
153  if (scroll_parent_ == parent)
154    return;
155
156  // Having both a scroll parent and a scroll offset delegate is unsupported.
157  DCHECK(!scroll_offset_delegate_);
158
159  if (parent)
160    DCHECK_EQ(layer_tree_impl()->LayerById(parent->id()), parent);
161
162  scroll_parent_ = parent;
163  SetNeedsPushProperties();
164}
165
166void LayerImpl::SetDebugInfo(
167    scoped_refptr<base::debug::ConvertableToTraceFormat> other) {
168  debug_info_ = other;
169  SetNeedsPushProperties();
170}
171
172void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) {
173  if (scroll_children_.get() == children)
174    return;
175  scroll_children_.reset(children);
176  SetNeedsPushProperties();
177}
178
179void LayerImpl::SetClipParent(LayerImpl* ancestor) {
180  if (clip_parent_ == ancestor)
181    return;
182
183  clip_parent_ = ancestor;
184  SetNeedsPushProperties();
185}
186
187void LayerImpl::SetClipChildren(std::set<LayerImpl*>* children) {
188  if (clip_children_.get() == children)
189    return;
190  clip_children_.reset(children);
191  SetNeedsPushProperties();
192}
193
194void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) {
195  if (requests->empty())
196    return;
197
198  bool was_empty = copy_requests_.empty();
199  copy_requests_.insert_and_take(copy_requests_.end(), *requests);
200  requests->clear();
201
202  if (was_empty && layer_tree_impl()->IsActiveTree())
203    layer_tree_impl()->AddLayerWithCopyOutputRequest(this);
204  NoteLayerPropertyChangedForSubtree();
205}
206
207void LayerImpl::TakeCopyRequestsAndTransformToTarget(
208    ScopedPtrVector<CopyOutputRequest>* requests) {
209  DCHECK(!copy_requests_.empty());
210  DCHECK(layer_tree_impl()->IsActiveTree());
211
212  size_t first_inserted_request = requests->size();
213  requests->insert_and_take(requests->end(), copy_requests_);
214  copy_requests_.clear();
215
216  for (size_t i = first_inserted_request; i < requests->size(); ++i) {
217    CopyOutputRequest* request = requests->at(i);
218    if (!request->has_area())
219      continue;
220
221    gfx::Rect request_in_layer_space = request->area();
222    gfx::Rect request_in_content_space =
223        LayerRectToContentRect(request_in_layer_space);
224    request->set_area(MathUtil::MapEnclosingClippedRect(
225        draw_properties_.target_space_transform, request_in_content_space));
226  }
227
228  layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
229}
230
231void LayerImpl::CreateRenderSurface() {
232  DCHECK(!draw_properties_.render_surface);
233  draw_properties_.render_surface =
234      make_scoped_ptr(new RenderSurfaceImpl(this));
235  draw_properties_.render_target = this;
236}
237
238void LayerImpl::ClearRenderSurface() {
239  draw_properties_.render_surface.reset();
240}
241
242void LayerImpl::ClearRenderSurfaceLayerList() {
243  if (draw_properties_.render_surface)
244    draw_properties_.render_surface->layer_list().clear();
245}
246
247void LayerImpl::PopulateSharedQuadState(SharedQuadState* state) const {
248  state->SetAll(draw_properties_.target_space_transform,
249                draw_properties_.content_bounds,
250                draw_properties_.visible_content_rect,
251                draw_properties_.clip_rect,
252                draw_properties_.is_clipped,
253                draw_properties_.opacity,
254                blend_mode_,
255                sorting_context_id_);
256}
257
258bool LayerImpl::WillDraw(DrawMode draw_mode,
259                         ResourceProvider* resource_provider) {
260  // WillDraw/DidDraw must be matched.
261  DCHECK_NE(DRAW_MODE_NONE, draw_mode);
262  DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_);
263  current_draw_mode_ = draw_mode;
264  return true;
265}
266
267void LayerImpl::DidDraw(ResourceProvider* resource_provider) {
268  DCHECK_NE(DRAW_MODE_NONE, current_draw_mode_);
269  current_draw_mode_ = DRAW_MODE_NONE;
270}
271
272bool LayerImpl::ShowDebugBorders() const {
273  return layer_tree_impl()->debug_state().show_debug_borders;
274}
275
276void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const {
277  if (draws_content_) {
278    *color = DebugColors::ContentLayerBorderColor();
279    *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl());
280    return;
281  }
282
283  if (masks_to_bounds_) {
284    *color = DebugColors::MaskingLayerBorderColor();
285    *width = DebugColors::MaskingLayerBorderWidth(layer_tree_impl());
286    return;
287  }
288
289  *color = DebugColors::ContainerLayerBorderColor();
290  *width = DebugColors::ContainerLayerBorderWidth(layer_tree_impl());
291}
292
293void LayerImpl::AppendDebugBorderQuad(
294    RenderPass* render_pass,
295    const gfx::Size& content_bounds,
296    const SharedQuadState* shared_quad_state,
297    AppendQuadsData* append_quads_data) const {
298  SkColor color;
299  float width;
300  GetDebugBorderProperties(&color, &width);
301  AppendDebugBorderQuad(render_pass,
302                        content_bounds,
303                        shared_quad_state,
304                        append_quads_data,
305                        color,
306                        width);
307}
308
309void LayerImpl::AppendDebugBorderQuad(RenderPass* render_pass,
310                                      const gfx::Size& content_bounds,
311                                      const SharedQuadState* shared_quad_state,
312                                      AppendQuadsData* append_quads_data,
313                                      SkColor color,
314                                      float width) const {
315  if (!ShowDebugBorders())
316    return;
317
318  gfx::Rect quad_rect(content_bounds);
319  gfx::Rect visible_quad_rect(quad_rect);
320  DebugBorderDrawQuad* debug_border_quad =
321      render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
322  debug_border_quad->SetNew(
323      shared_quad_state, quad_rect, visible_quad_rect, color, width);
324}
325
326bool LayerImpl::HasDelegatedContent() const {
327  return false;
328}
329
330bool LayerImpl::HasContributingDelegatedRenderPasses() const {
331  return false;
332}
333
334RenderPass::Id LayerImpl::FirstContributingRenderPassId() const {
335  return RenderPass::Id(0, 0);
336}
337
338RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id)
339    const {
340  return RenderPass::Id(0, 0);
341}
342
343ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const {
344  NOTREACHED();
345  return 0;
346}
347
348void LayerImpl::SetSentScrollDelta(const gfx::Vector2d& sent_scroll_delta) {
349  // Pending tree never has sent scroll deltas
350  DCHECK(layer_tree_impl()->IsActiveTree());
351
352  if (sent_scroll_delta_ == sent_scroll_delta)
353    return;
354
355  sent_scroll_delta_ = sent_scroll_delta;
356}
357
358gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) {
359  DCHECK(scrollable());
360  gfx::Vector2dF min_delta = -scroll_offset_;
361  gfx::Vector2dF max_delta = MaxScrollOffset() - scroll_offset_;
362  // Clamp new_delta so that position + delta stays within scroll bounds.
363  gfx::Vector2dF new_delta = (ScrollDelta() + scroll);
364  new_delta.SetToMax(min_delta);
365  new_delta.SetToMin(max_delta);
366  gfx::Vector2dF unscrolled =
367      ScrollDelta() + scroll - new_delta;
368  SetScrollDelta(new_delta);
369
370  return unscrolled;
371}
372
373void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) {
374  scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id);
375}
376
377void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() {
378  // Pending tree never has sent scroll deltas
379  DCHECK(layer_tree_impl()->IsActiveTree());
380
381  // Apply sent scroll deltas to scroll position / scroll delta as if the
382  // main thread had applied them and then committed those values.
383  //
384  // This function should not change the total scroll offset; it just shifts
385  // some of the scroll delta to the scroll offset.  Therefore, adjust these
386  // variables directly rather than calling the scroll offset delegate to
387  // avoid sending it multiple spurious calls.
388  //
389  // Because of the way scroll delta is calculated with a delegate, this will
390  // leave the total scroll offset unchanged on this layer regardless of
391  // whether a delegate is being used.
392  scroll_offset_ += sent_scroll_delta_;
393  scroll_delta_ -= sent_scroll_delta_;
394  sent_scroll_delta_ = gfx::Vector2d();
395}
396
397void LayerImpl::ApplyScrollDeltasSinceBeginMainFrame() {
398  // Only the pending tree can have missing scrolls.
399  DCHECK(layer_tree_impl()->IsPendingTree());
400  if (!scrollable())
401    return;
402
403  // Pending tree should never have sent scroll deltas.
404  DCHECK(sent_scroll_delta().IsZero());
405
406  LayerImpl* active_twin = layer_tree_impl()->FindActiveTreeLayerById(id());
407  if (active_twin) {
408    // Scrolls that happens after begin frame (where the sent scroll delta
409    // comes from) and commit need to be applied to the pending tree
410    // so that it is up to date with the total scroll.
411    SetScrollDelta(active_twin->ScrollDelta() -
412                   active_twin->sent_scroll_delta());
413  }
414}
415
416InputHandler::ScrollStatus LayerImpl::TryScroll(
417    const gfx::PointF& screen_space_point,
418    InputHandler::ScrollInputType type) const {
419  if (should_scroll_on_main_thread()) {
420    TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread");
421    return InputHandler::ScrollOnMainThread;
422  }
423
424  if (!screen_space_transform().IsInvertible()) {
425    TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform");
426    return InputHandler::ScrollIgnored;
427  }
428
429  if (!non_fast_scrollable_region().IsEmpty()) {
430    bool clipped = false;
431    gfx::Transform inverse_screen_space_transform(
432        gfx::Transform::kSkipInitialization);
433    if (!screen_space_transform().GetInverse(&inverse_screen_space_transform)) {
434      // TODO(shawnsingh): We shouldn't be applying a projection if screen space
435      // transform is uninvertible here. Perhaps we should be returning
436      // ScrollOnMainThread in this case?
437    }
438
439    gfx::PointF hit_test_point_in_content_space =
440        MathUtil::ProjectPoint(inverse_screen_space_transform,
441                               screen_space_point,
442                               &clipped);
443    gfx::PointF hit_test_point_in_layer_space =
444        gfx::ScalePoint(hit_test_point_in_content_space,
445                        1.f / contents_scale_x(),
446                        1.f / contents_scale_y());
447    if (!clipped &&
448        non_fast_scrollable_region().Contains(
449            gfx::ToRoundedPoint(hit_test_point_in_layer_space))) {
450      TRACE_EVENT0("cc",
451                   "LayerImpl::tryScroll: Failed NonFastScrollableRegion");
452      return InputHandler::ScrollOnMainThread;
453    }
454  }
455
456  if (type == InputHandler::Wheel && have_wheel_event_handlers()) {
457    TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers");
458    return InputHandler::ScrollOnMainThread;
459  }
460
461  if (!scrollable()) {
462    TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable");
463    return InputHandler::ScrollIgnored;
464  }
465
466  gfx::Vector2d max_scroll_offset = MaxScrollOffset();
467  if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0) {
468    TRACE_EVENT0("cc",
469                 "LayerImpl::tryScroll: Ignored. Technically scrollable,"
470                 " but has no affordance in either direction.");
471    return InputHandler::ScrollIgnored;
472  }
473
474  return InputHandler::ScrollStarted;
475}
476
477gfx::Rect LayerImpl::LayerRectToContentRect(
478    const gfx::RectF& layer_rect) const {
479  gfx::RectF content_rect =
480      gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y());
481  // Intersect with content rect to avoid the extra pixel because for some
482  // values x and y, ceil((x / y) * y) may be x + 1.
483  content_rect.Intersect(gfx::Rect(content_bounds()));
484  return gfx::ToEnclosingRect(content_rect);
485}
486
487skia::RefPtr<SkPicture> LayerImpl::GetPicture() {
488  return skia::RefPtr<SkPicture>();
489}
490
491scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) {
492  return LayerImpl::Create(tree_impl, layer_id_);
493}
494
495void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
496  layer->SetTransformOrigin(transform_origin_);
497  layer->SetBackgroundColor(background_color_);
498  layer->SetBounds(bounds_);
499  layer->SetContentBounds(content_bounds());
500  layer->SetContentsScale(contents_scale_x(), contents_scale_y());
501  layer->SetDoubleSided(double_sided_);
502  layer->SetDrawCheckerboardForMissingTiles(
503      draw_checkerboard_for_missing_tiles_);
504  layer->SetForceRenderSurface(force_render_surface_);
505  layer->SetDrawsContent(DrawsContent());
506  layer->SetHideLayerAndSubtree(hide_layer_and_subtree_);
507  layer->SetFilters(filters());
508  layer->SetBackgroundFilters(background_filters());
509  layer->SetMasksToBounds(masks_to_bounds_);
510  layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_);
511  layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_);
512  layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_);
513  layer->SetNonFastScrollableRegion(non_fast_scrollable_region_);
514  layer->SetTouchEventHandlerRegion(touch_event_handler_region_);
515  layer->SetContentsOpaque(contents_opaque_);
516  layer->SetOpacity(opacity_);
517  layer->SetBlendMode(blend_mode_);
518  layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_);
519  layer->SetPosition(position_);
520  layer->SetIsContainerForFixedPositionLayers(
521      is_container_for_fixed_position_layers_);
522  layer->SetPositionConstraint(position_constraint_);
523  layer->SetShouldFlattenTransform(should_flatten_transform_);
524  layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_);
525  layer->SetTransformAndInvertibility(transform_, transform_is_invertible_);
526
527  layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id()
528                                               : Layer::INVALID_ID);
529  layer->set_user_scrollable_horizontal(user_scrollable_horizontal_);
530  layer->set_user_scrollable_vertical(user_scrollable_vertical_);
531  layer->SetScrollOffsetAndDelta(
532      scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta());
533  layer->SetSentScrollDelta(gfx::Vector2d());
534  layer->Set3dSortingContextId(sorting_context_id_);
535
536  LayerImpl* scroll_parent = NULL;
537  if (scroll_parent_) {
538    scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id());
539    DCHECK(scroll_parent);
540  }
541
542  layer->SetScrollParent(scroll_parent);
543  if (scroll_children_) {
544    std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>;
545    for (std::set<LayerImpl*>::iterator it = scroll_children_->begin();
546         it != scroll_children_->end();
547         ++it) {
548      DCHECK_EQ((*it)->scroll_parent(), this);
549      LayerImpl* scroll_child =
550          layer->layer_tree_impl()->LayerById((*it)->id());
551      DCHECK(scroll_child);
552      scroll_children->insert(scroll_child);
553    }
554    layer->SetScrollChildren(scroll_children);
555  } else {
556    layer->SetScrollChildren(NULL);
557  }
558
559  LayerImpl* clip_parent = NULL;
560  if (clip_parent_) {
561    clip_parent = layer->layer_tree_impl()->LayerById(
562        clip_parent_->id());
563    DCHECK(clip_parent);
564  }
565
566  layer->SetClipParent(clip_parent);
567  if (clip_children_) {
568    std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>;
569    for (std::set<LayerImpl*>::iterator it = clip_children_->begin();
570        it != clip_children_->end(); ++it)
571      clip_children->insert(layer->layer_tree_impl()->LayerById((*it)->id()));
572    layer->SetClipChildren(clip_children);
573  } else {
574    layer->SetClipChildren(NULL);
575  }
576
577  layer->PassCopyRequests(&copy_requests_);
578
579  // If the main thread commits multiple times before the impl thread actually
580  // draws, then damage tracking will become incorrect if we simply clobber the
581  // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
582  // union) any update changes that have occurred on the main thread.
583  update_rect_.Union(layer->update_rect());
584  layer->SetUpdateRect(update_rect_);
585
586  layer->SetStackingOrderChanged(stacking_order_changed_);
587  layer->SetDebugInfo(debug_info_);
588
589  // Reset any state that should be cleared for the next update.
590  stacking_order_changed_ = false;
591  update_rect_ = gfx::RectF();
592  needs_push_properties_ = false;
593  num_dependents_need_push_properties_ = 0;
594}
595
596gfx::Vector2dF LayerImpl::FixedContainerSizeDelta() const {
597  if (!scroll_clip_layer_)
598    return gfx::Vector2dF();
599
600  float scale_delta = layer_tree_impl()->page_scale_delta();
601  float scale = layer_tree_impl()->page_scale_factor();
602
603  gfx::Vector2dF delta_from_scroll = scroll_clip_layer_->BoundsDelta();
604  delta_from_scroll.Scale(1.f / scale);
605
606  // The delta-from-pinch component requires some explanation: A viewport of
607  // size (w,h) will appear to be size (w/s,h/s) under scale s in the content
608  // space. If s -> s' on the impl thread, where s' = s * ds, then the apparent
609  // viewport size change in the content space due to ds is:
610  //
611  // (w/s',h/s') - (w/s,h/s) = (w,h)(1/s' - 1/s) = (w,h)(1 - ds)/(s ds)
612  //
613  gfx::Vector2dF delta_from_pinch =
614      gfx::Rect(scroll_clip_layer_->bounds()).bottom_right() - gfx::PointF();
615  delta_from_pinch.Scale((1.f - scale_delta) / (scale * scale_delta));
616
617  return delta_from_scroll + delta_from_pinch;
618}
619
620base::DictionaryValue* LayerImpl::LayerTreeAsJson() const {
621  base::DictionaryValue* result = new base::DictionaryValue;
622  result->SetString("LayerType", LayerTypeAsString());
623
624  base::ListValue* list = new base::ListValue;
625  list->AppendInteger(bounds().width());
626  list->AppendInteger(bounds().height());
627  result->Set("Bounds", list);
628
629  list = new base::ListValue;
630  list->AppendDouble(position_.x());
631  list->AppendDouble(position_.y());
632  result->Set("Position", list);
633
634  const gfx::Transform& gfx_transform = draw_properties_.target_space_transform;
635  double transform[16];
636  gfx_transform.matrix().asColMajord(transform);
637  list = new base::ListValue;
638  for (int i = 0; i < 16; ++i)
639    list->AppendDouble(transform[i]);
640  result->Set("DrawTransform", list);
641
642  result->SetBoolean("DrawsContent", draws_content_);
643  result->SetBoolean("Is3dSorted", Is3dSorted());
644  result->SetDouble("Opacity", opacity());
645  result->SetBoolean("ContentsOpaque", contents_opaque_);
646
647  if (scrollable())
648    result->SetBoolean("Scrollable", true);
649
650  if (have_wheel_event_handlers_)
651    result->SetBoolean("WheelHandler", have_wheel_event_handlers_);
652  if (have_scroll_event_handlers_)
653    result->SetBoolean("ScrollHandler", have_scroll_event_handlers_);
654  if (!touch_event_handler_region_.IsEmpty()) {
655    scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue();
656    result->Set("TouchRegion", region.release());
657  }
658
659  list = new base::ListValue;
660  for (size_t i = 0; i < children_.size(); ++i)
661    list->Append(children_[i]->LayerTreeAsJson());
662  result->Set("Children", list);
663
664  return result;
665}
666
667void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) {
668  if (stacking_order_changed) {
669    stacking_order_changed_ = true;
670    NoteLayerPropertyChangedForSubtree();
671  }
672}
673
674void LayerImpl::NoteLayerPropertyChanged() {
675  layer_property_changed_ = true;
676  layer_tree_impl()->set_needs_update_draw_properties();
677  SetNeedsPushProperties();
678}
679
680void LayerImpl::NoteLayerPropertyChangedForSubtree() {
681  layer_property_changed_ = true;
682  layer_tree_impl()->set_needs_update_draw_properties();
683  for (size_t i = 0; i < children_.size(); ++i)
684    children_[i]->NoteLayerPropertyChangedForDescendantsInternal();
685  SetNeedsPushProperties();
686}
687
688void LayerImpl::NoteLayerPropertyChangedForDescendantsInternal() {
689  layer_property_changed_ = true;
690  for (size_t i = 0; i < children_.size(); ++i)
691    children_[i]->NoteLayerPropertyChangedForDescendantsInternal();
692}
693
694void LayerImpl::NoteLayerPropertyChangedForDescendants() {
695  layer_tree_impl()->set_needs_update_draw_properties();
696  for (size_t i = 0; i < children_.size(); ++i)
697    children_[i]->NoteLayerPropertyChangedForDescendantsInternal();
698  SetNeedsPushProperties();
699}
700
701const char* LayerImpl::LayerTypeAsString() const {
702  return "cc::LayerImpl";
703}
704
705void LayerImpl::ResetAllChangeTrackingForSubtree() {
706  layer_property_changed_ = false;
707
708  update_rect_ = gfx::RectF();
709  damage_rect_ = gfx::RectF();
710
711  if (draw_properties_.render_surface)
712    draw_properties_.render_surface->ResetPropertyChangedFlag();
713
714  if (mask_layer_)
715    mask_layer_->ResetAllChangeTrackingForSubtree();
716
717  if (replica_layer_) {
718    // This also resets the replica mask, if it exists.
719    replica_layer_->ResetAllChangeTrackingForSubtree();
720  }
721
722  for (size_t i = 0; i < children_.size(); ++i)
723    children_[i]->ResetAllChangeTrackingForSubtree();
724
725  needs_push_properties_ = false;
726  num_dependents_need_push_properties_ = 0;
727}
728
729gfx::Vector2dF LayerImpl::ScrollOffsetForAnimation() const {
730  return TotalScrollOffset();
731}
732
733void LayerImpl::OnFilterAnimated(const FilterOperations& filters) {
734  SetFilters(filters);
735}
736
737void LayerImpl::OnOpacityAnimated(float opacity) {
738  SetOpacity(opacity);
739}
740
741void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) {
742  SetTransform(transform);
743}
744
745void LayerImpl::OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset) {
746  // Only layers in the active tree should need to do anything here, since
747  // layers in the pending tree will find out about these changes as a
748  // result of the call to SetScrollDelta.
749  if (!IsActive())
750    return;
751
752  SetScrollDelta(scroll_offset - scroll_offset_);
753
754  layer_tree_impl_->DidAnimateScrollOffset();
755}
756
757void LayerImpl::OnAnimationWaitingForDeletion() {}
758
759bool LayerImpl::IsActive() const {
760  return layer_tree_impl_->IsActiveTree();
761}
762
763// TODO(wjmaclean) Convert so that bounds returns SizeF.
764gfx::Size LayerImpl::bounds() const {
765  return ToFlooredSize(temporary_impl_bounds_);
766}
767
768void LayerImpl::SetBounds(const gfx::Size& bounds) {
769  if (bounds_ == bounds)
770    return;
771
772  bounds_ = bounds;
773  temporary_impl_bounds_ = bounds;
774
775  ScrollbarParametersDidChange();
776  if (masks_to_bounds())
777    NoteLayerPropertyChangedForSubtree();
778  else
779    NoteLayerPropertyChanged();
780}
781
782void LayerImpl::SetTemporaryImplBounds(const gfx::SizeF& bounds) {
783  if (temporary_impl_bounds_ == bounds)
784    return;
785
786  temporary_impl_bounds_ = bounds;
787
788  ScrollbarParametersDidChange();
789  if (masks_to_bounds())
790    NoteLayerPropertyChangedForSubtree();
791  else
792    NoteLayerPropertyChanged();
793}
794
795void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) {
796  int new_layer_id = mask_layer ? mask_layer->id() : -1;
797
798  if (mask_layer) {
799    DCHECK_EQ(layer_tree_impl(), mask_layer->layer_tree_impl());
800    DCHECK_NE(new_layer_id, mask_layer_id_);
801  } else if (new_layer_id == mask_layer_id_) {
802    return;
803  }
804
805  mask_layer_ = mask_layer.Pass();
806  mask_layer_id_ = new_layer_id;
807  if (mask_layer_)
808    mask_layer_->SetParent(this);
809  NoteLayerPropertyChangedForSubtree();
810}
811
812scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() {
813  mask_layer_id_ = -1;
814  return mask_layer_.Pass();
815}
816
817void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) {
818  int new_layer_id = replica_layer ? replica_layer->id() : -1;
819
820  if (replica_layer) {
821    DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl());
822    DCHECK_NE(new_layer_id, replica_layer_id_);
823  } else if (new_layer_id == replica_layer_id_) {
824    return;
825  }
826
827  replica_layer_ = replica_layer.Pass();
828  replica_layer_id_ = new_layer_id;
829  if (replica_layer_)
830    replica_layer_->SetParent(this);
831  NoteLayerPropertyChangedForSubtree();
832}
833
834scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() {
835  replica_layer_id_ = -1;
836  return replica_layer_.Pass();
837}
838
839ScrollbarLayerImplBase* LayerImpl::ToScrollbarLayer() {
840  return NULL;
841}
842
843void LayerImpl::SetDrawsContent(bool draws_content) {
844  if (draws_content_ == draws_content)
845    return;
846
847  draws_content_ = draws_content;
848  NoteLayerPropertyChanged();
849}
850
851void LayerImpl::SetHideLayerAndSubtree(bool hide) {
852  if (hide_layer_and_subtree_ == hide)
853    return;
854
855  hide_layer_and_subtree_ = hide;
856  NoteLayerPropertyChangedForSubtree();
857}
858
859void LayerImpl::SetTransformOrigin(const gfx::Point3F& transform_origin) {
860  if (transform_origin_ == transform_origin)
861    return;
862  transform_origin_ = transform_origin;
863  NoteLayerPropertyChangedForSubtree();
864}
865
866void LayerImpl::SetBackgroundColor(SkColor background_color) {
867  if (background_color_ == background_color)
868    return;
869
870  background_color_ = background_color;
871  NoteLayerPropertyChanged();
872}
873
874SkColor LayerImpl::SafeOpaqueBackgroundColor() const {
875  SkColor color = background_color();
876  if (SkColorGetA(color) == 255 && !contents_opaque()) {
877    color = SK_ColorTRANSPARENT;
878  } else if (SkColorGetA(color) != 255 && contents_opaque()) {
879    for (const LayerImpl* layer = parent(); layer;
880         layer = layer->parent()) {
881      color = layer->background_color();
882      if (SkColorGetA(color) == 255)
883        break;
884    }
885    if (SkColorGetA(color) != 255)
886      color = layer_tree_impl()->background_color();
887    if (SkColorGetA(color) != 255)
888      color = SkColorSetA(color, 255);
889  }
890  return color;
891}
892
893void LayerImpl::SetFilters(const FilterOperations& filters) {
894  if (filters_ == filters)
895    return;
896
897  filters_ = filters;
898  NoteLayerPropertyChangedForSubtree();
899}
900
901bool LayerImpl::FilterIsAnimating() const {
902  return layer_animation_controller_->IsAnimatingProperty(Animation::Filter);
903}
904
905bool LayerImpl::FilterIsAnimatingOnImplOnly() const {
906  Animation* filter_animation =
907      layer_animation_controller_->GetAnimation(Animation::Filter);
908  return filter_animation && filter_animation->is_impl_only();
909}
910
911void LayerImpl::SetBackgroundFilters(
912    const FilterOperations& filters) {
913  if (background_filters_ == filters)
914    return;
915
916  background_filters_ = filters;
917  NoteLayerPropertyChanged();
918}
919
920void LayerImpl::SetMasksToBounds(bool masks_to_bounds) {
921  if (masks_to_bounds_ == masks_to_bounds)
922    return;
923
924  masks_to_bounds_ = masks_to_bounds;
925  NoteLayerPropertyChangedForSubtree();
926}
927
928void LayerImpl::SetContentsOpaque(bool opaque) {
929  if (contents_opaque_ == opaque)
930    return;
931
932  contents_opaque_ = opaque;
933  NoteLayerPropertyChangedForSubtree();
934}
935
936void LayerImpl::SetOpacity(float opacity) {
937  if (opacity_ == opacity)
938    return;
939
940  opacity_ = opacity;
941  NoteLayerPropertyChangedForSubtree();
942}
943
944bool LayerImpl::OpacityIsAnimating() const {
945  return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity);
946}
947
948bool LayerImpl::OpacityIsAnimatingOnImplOnly() const {
949  Animation* opacity_animation =
950      layer_animation_controller_->GetAnimation(Animation::Opacity);
951  return opacity_animation && opacity_animation->is_impl_only();
952}
953
954void LayerImpl::SetBlendMode(SkXfermode::Mode blend_mode) {
955  if (blend_mode_ == blend_mode)
956    return;
957
958  blend_mode_ = blend_mode;
959  NoteLayerPropertyChangedForSubtree();
960}
961
962void LayerImpl::SetIsRootForIsolatedGroup(bool root) {
963  if (is_root_for_isolated_group_ == root)
964    return;
965
966  is_root_for_isolated_group_ = root;
967  SetNeedsPushProperties();
968}
969
970void LayerImpl::SetPosition(const gfx::PointF& position) {
971  if (position_ == position)
972    return;
973
974  position_ = position;
975  NoteLayerPropertyChangedForSubtree();
976}
977
978void LayerImpl::SetShouldFlattenTransform(bool flatten) {
979  if (should_flatten_transform_ == flatten)
980    return;
981
982  should_flatten_transform_ = flatten;
983  NoteLayerPropertyChangedForSubtree();
984}
985
986void LayerImpl::Set3dSortingContextId(int id) {
987  if (id == sorting_context_id_)
988    return;
989  sorting_context_id_ = id;
990  NoteLayerPropertyChangedForSubtree();
991}
992
993void LayerImpl::SetTransform(const gfx::Transform& transform) {
994  if (transform_ == transform)
995    return;
996
997  transform_ = transform;
998  transform_is_invertible_ = transform_.IsInvertible();
999  NoteLayerPropertyChangedForSubtree();
1000}
1001
1002void LayerImpl::SetTransformAndInvertibility(const gfx::Transform& transform,
1003                                             bool transform_is_invertible) {
1004  if (transform_ == transform) {
1005    DCHECK(transform_is_invertible_ == transform_is_invertible)
1006        << "Can't change invertibility if transform is unchanged";
1007    return;
1008  }
1009  transform_ = transform;
1010  transform_is_invertible_ = transform_is_invertible;
1011  NoteLayerPropertyChangedForSubtree();
1012}
1013
1014bool LayerImpl::TransformIsAnimating() const {
1015  return layer_animation_controller_->IsAnimatingProperty(Animation::Transform);
1016}
1017
1018bool LayerImpl::TransformIsAnimatingOnImplOnly() const {
1019  Animation* transform_animation =
1020      layer_animation_controller_->GetAnimation(Animation::Transform);
1021  return transform_animation && transform_animation->is_impl_only();
1022}
1023
1024void LayerImpl::SetUpdateRect(const gfx::RectF& update_rect) {
1025  update_rect_ = update_rect;
1026  SetNeedsPushProperties();
1027}
1028
1029void LayerImpl::AddDamageRect(const gfx::RectF& damage_rect) {
1030  damage_rect_ = gfx::UnionRects(damage_rect_, damage_rect);
1031}
1032
1033void LayerImpl::SetContentBounds(const gfx::Size& content_bounds) {
1034  if (this->content_bounds() == content_bounds)
1035    return;
1036
1037  draw_properties_.content_bounds = content_bounds;
1038  NoteLayerPropertyChanged();
1039}
1040
1041void LayerImpl::SetContentsScale(float contents_scale_x,
1042                                 float contents_scale_y) {
1043  if (this->contents_scale_x() == contents_scale_x &&
1044      this->contents_scale_y() == contents_scale_y)
1045    return;
1046
1047  draw_properties_.contents_scale_x = contents_scale_x;
1048  draw_properties_.contents_scale_y = contents_scale_y;
1049  NoteLayerPropertyChanged();
1050}
1051
1052void LayerImpl::SetScrollOffsetDelegate(
1053    ScrollOffsetDelegate* scroll_offset_delegate) {
1054  // Having both a scroll parent and a scroll offset delegate is unsupported.
1055  DCHECK(!scroll_parent_);
1056  if (!scroll_offset_delegate && scroll_offset_delegate_) {
1057    scroll_delta_ =
1058        scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_;
1059  }
1060  gfx::Vector2dF total_offset = TotalScrollOffset();
1061  scroll_offset_delegate_ = scroll_offset_delegate;
1062  if (scroll_offset_delegate_)
1063    scroll_offset_delegate_->SetTotalScrollOffset(total_offset);
1064}
1065
1066bool LayerImpl::IsExternalFlingActive() const {
1067  return scroll_offset_delegate_ &&
1068         scroll_offset_delegate_->IsExternalFlingActive();
1069}
1070
1071void LayerImpl::SetScrollOffset(const gfx::Vector2d& scroll_offset) {
1072  SetScrollOffsetAndDelta(scroll_offset, ScrollDelta());
1073}
1074
1075void LayerImpl::SetScrollOffsetAndDelta(const gfx::Vector2d& scroll_offset,
1076                                        const gfx::Vector2dF& scroll_delta) {
1077  bool changed = false;
1078
1079  last_scroll_offset_ = scroll_offset;
1080
1081  if (scroll_offset_ != scroll_offset) {
1082    changed = true;
1083    scroll_offset_ = scroll_offset;
1084
1085    if (scroll_offset_delegate_)
1086      scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset());
1087  }
1088
1089  if (ScrollDelta() != scroll_delta) {
1090    changed = true;
1091    if (layer_tree_impl()->IsActiveTree()) {
1092      LayerImpl* pending_twin =
1093          layer_tree_impl()->FindPendingTreeLayerById(id());
1094      if (pending_twin) {
1095        // The pending twin can't mirror the scroll delta of the active
1096        // layer.  Although the delta - sent scroll delta difference is
1097        // identical for both twins, the sent scroll delta for the pending
1098        // layer is zero, as anything that has been sent has been baked
1099        // into the layer's position/scroll offset as a part of commit.
1100        DCHECK(pending_twin->sent_scroll_delta().IsZero());
1101        pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta());
1102      }
1103    }
1104
1105    if (scroll_offset_delegate_) {
1106      scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ +
1107                                                    scroll_delta);
1108    } else {
1109      scroll_delta_ = scroll_delta;
1110    }
1111  }
1112
1113  if (changed) {
1114    NoteLayerPropertyChangedForSubtree();
1115    ScrollbarParametersDidChange();
1116  }
1117}
1118
1119gfx::Vector2dF LayerImpl::ScrollDelta() const {
1120  if (scroll_offset_delegate_)
1121    return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_;
1122  return scroll_delta_;
1123}
1124
1125void LayerImpl::SetScrollDelta(const gfx::Vector2dF& scroll_delta) {
1126  SetScrollOffsetAndDelta(scroll_offset_, scroll_delta);
1127}
1128
1129gfx::Vector2dF LayerImpl::TotalScrollOffset() const {
1130  return scroll_offset_ + ScrollDelta();
1131}
1132
1133void LayerImpl::SetDoubleSided(bool double_sided) {
1134  if (double_sided_ == double_sided)
1135    return;
1136
1137  double_sided_ = double_sided;
1138  NoteLayerPropertyChangedForSubtree();
1139}
1140
1141Region LayerImpl::VisibleContentOpaqueRegion() const {
1142  if (contents_opaque())
1143    return visible_content_rect();
1144  return Region();
1145}
1146
1147void LayerImpl::DidBeginTracing() {}
1148
1149void LayerImpl::ReleaseResources() {}
1150
1151gfx::Vector2d LayerImpl::MaxScrollOffset() const {
1152  if (!scroll_clip_layer_ || bounds().IsEmpty())
1153    return gfx::Vector2d();
1154
1155  LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer();
1156  DCHECK(this != page_scale_layer);
1157  DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() ||
1158         IsContainerForFixedPositionLayers());
1159
1160  gfx::SizeF scaled_scroll_bounds(bounds());
1161
1162  float scale_factor = 1.f;
1163  for (LayerImpl const* current_layer = this;
1164       current_layer != scroll_clip_layer_;
1165       current_layer = current_layer->parent()) {
1166    DCHECK(current_layer);
1167    float current_layer_scale = 1.f;
1168
1169    const gfx::Transform& layer_transform = current_layer->transform();
1170    if (current_layer == page_scale_layer) {
1171      DCHECK(layer_transform.IsIdentity());
1172      current_layer_scale = layer_tree_impl()->total_page_scale_factor();
1173    } else {
1174      // TODO(wjmaclean) Should we allow for translation too?
1175      DCHECK(layer_transform.IsScale2d());
1176      gfx::Vector2dF layer_scale = layer_transform.Scale2d();
1177      // TODO(wjmaclean) Allow for non-isotropic scales.
1178      DCHECK(layer_scale.x() == layer_scale.y());
1179      current_layer_scale = layer_scale.x();
1180    }
1181
1182    scale_factor *= current_layer_scale;
1183  }
1184  // TODO(wjmaclean) Once we move to a model where the two-viewport model is
1185  // turned on in all builds, remove the next two lines. For now however, the
1186  // page scale layer may coincide with the clip layer, and so this is
1187  // necessary.
1188  if (page_scale_layer == scroll_clip_layer_)
1189    scale_factor *= layer_tree_impl()->total_page_scale_factor();
1190
1191  scaled_scroll_bounds.SetSize(scale_factor * scaled_scroll_bounds.width(),
1192                               scale_factor * scaled_scroll_bounds.height());
1193  scaled_scroll_bounds = gfx::ToFlooredSize(scaled_scroll_bounds);
1194
1195  gfx::Vector2dF max_offset(
1196      scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(),
1197      scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height());
1198  // We need the final scroll offset to be in CSS coords.
1199  max_offset.Scale(1 / scale_factor);
1200  max_offset.SetToMax(gfx::Vector2dF());
1201  return gfx::ToFlooredVector2d(max_offset);
1202}
1203
1204gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() {
1205  gfx::Vector2dF max_offset = MaxScrollOffset();
1206  gfx::Vector2dF old_offset = TotalScrollOffset();
1207  gfx::Vector2dF clamped_offset = old_offset;
1208
1209  clamped_offset.SetToMin(max_offset);
1210  clamped_offset.SetToMax(gfx::Vector2d());
1211  gfx::Vector2dF delta = clamped_offset - old_offset;
1212  if (!delta.IsZero())
1213    ScrollBy(delta);
1214
1215  return delta;
1216}
1217
1218void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer,
1219                                     LayerImpl* scrollbar_clip_layer) const {
1220  DCHECK(scrollbar_layer);
1221  LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer();
1222
1223  DCHECK(this != page_scale_layer);
1224  DCHECK(scrollbar_clip_layer);
1225  DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() ||
1226         IsContainerForFixedPositionLayers());
1227  gfx::RectF clip_rect(gfx::PointF(), scrollbar_clip_layer->bounds());
1228
1229  // See comment in MaxScrollOffset() regarding the use of the content layer
1230  // bounds here.
1231  gfx::RectF scroll_rect(gfx::PointF(), bounds());
1232
1233  if (scroll_rect.size().IsEmpty())
1234    return;
1235
1236  // TODO(wjmaclean) This computation is nearly identical to the one in
1237  // MaxScrollOffset. Find some way to combine these.
1238  gfx::Vector2dF current_offset;
1239  for (LayerImpl const* current_layer = this;
1240       current_layer != scrollbar_clip_layer;
1241       current_layer = current_layer->parent()) {
1242    DCHECK(current_layer);
1243    const gfx::Transform& layer_transform = current_layer->transform();
1244    if (current_layer == page_scale_layer) {
1245      DCHECK(layer_transform.IsIdentity());
1246      float scale_factor = layer_tree_impl()->total_page_scale_factor();
1247      current_offset.Scale(scale_factor);
1248      scroll_rect.Scale(scale_factor);
1249    } else {
1250      DCHECK(layer_transform.IsScale2d());
1251      gfx::Vector2dF layer_scale = layer_transform.Scale2d();
1252      DCHECK(layer_scale.x() == layer_scale.y());
1253      gfx::Vector2dF new_offset =
1254          current_layer->scroll_offset() + current_layer->ScrollDelta();
1255      new_offset.Scale(layer_scale.x(), layer_scale.y());
1256      current_offset += new_offset;
1257    }
1258  }
1259  // TODO(wjmaclean) Once we move to a model where the two-viewport model is
1260  // turned on in all builds, remove the next two lines. For now however, the
1261  // page scale layer may coincide with the clip layer, and so this is
1262  // necessary.
1263  if (page_scale_layer == scrollbar_clip_layer) {
1264    scroll_rect.Scale(layer_tree_impl()->total_page_scale_factor());
1265    current_offset.Scale(layer_tree_impl()->total_page_scale_factor());
1266  }
1267
1268  scrollbar_layer->SetVerticalAdjust(
1269      layer_tree_impl()->VerticalAdjust(scrollbar_clip_layer->id()));
1270  if (scrollbar_layer->orientation() == HORIZONTAL) {
1271    float visible_ratio = clip_rect.width() / scroll_rect.width();
1272    scrollbar_layer->SetCurrentPos(current_offset.x());
1273    scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width());
1274    scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio);
1275  } else {
1276    float visible_ratio = clip_rect.height() / scroll_rect.height();
1277    scrollbar_layer->SetCurrentPos(current_offset.y());
1278    scrollbar_layer->SetMaximum(scroll_rect.height() - clip_rect.height());
1279    scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio);
1280  }
1281
1282  layer_tree_impl()->set_needs_update_draw_properties();
1283  // TODO(wjmaclean) The scrollbar animator for the pinch-zoom scrollbars should
1284  // activate for every scroll on the main frame, not just the scrolls that move
1285  // the pinch virtual viewport (i.e. trigger from either inner or outer
1286  // viewport).
1287  if (scrollbar_animation_controller_) {
1288    // When both non-overlay and overlay scrollbars are both present, don't
1289    // animate the overlay scrollbars when page scale factor is at the min.
1290    // Non-overlay scrollbars also shouldn't trigger animations.
1291    bool is_animatable_scrollbar =
1292        scrollbar_layer->is_overlay_scrollbar() &&
1293        ((layer_tree_impl()->total_page_scale_factor() >
1294          layer_tree_impl()->min_page_scale_factor()) ||
1295         !layer_tree_impl()->settings().use_pinch_zoom_scrollbars);
1296    if (is_animatable_scrollbar)
1297      scrollbar_animation_controller_->DidScrollUpdate();
1298  }
1299}
1300
1301void LayerImpl::DidBecomeActive() {
1302  if (layer_tree_impl_->settings().scrollbar_animator ==
1303      LayerTreeSettings::NoAnimator) {
1304    return;
1305  }
1306
1307  bool need_scrollbar_animation_controller = scrollable() && scrollbars_;
1308  if (!need_scrollbar_animation_controller) {
1309    scrollbar_animation_controller_.reset();
1310    return;
1311  }
1312
1313  if (scrollbar_animation_controller_)
1314    return;
1315
1316  scrollbar_animation_controller_ =
1317      layer_tree_impl_->CreateScrollbarAnimationController(this);
1318}
1319
1320void LayerImpl::ClearScrollbars() {
1321  if (!scrollbars_)
1322    return;
1323
1324  scrollbars_.reset(NULL);
1325}
1326
1327void LayerImpl::AddScrollbar(ScrollbarLayerImplBase* layer) {
1328  DCHECK(layer);
1329  DCHECK(!scrollbars_ || scrollbars_->find(layer) == scrollbars_->end());
1330  if (!scrollbars_)
1331    scrollbars_.reset(new ScrollbarSet());
1332
1333  scrollbars_->insert(layer);
1334}
1335
1336void LayerImpl::RemoveScrollbar(ScrollbarLayerImplBase* layer) {
1337  DCHECK(scrollbars_);
1338  DCHECK(layer);
1339  DCHECK(scrollbars_->find(layer) != scrollbars_->end());
1340
1341  scrollbars_->erase(layer);
1342  if (scrollbars_->empty())
1343    scrollbars_.reset();
1344}
1345
1346bool LayerImpl::HasScrollbar(ScrollbarOrientation orientation) const {
1347  if (!scrollbars_)
1348    return false;
1349
1350  for (ScrollbarSet::iterator it = scrollbars_->begin();
1351       it != scrollbars_->end();
1352       ++it)
1353    if ((*it)->orientation() == orientation)
1354      return true;
1355
1356  return false;
1357}
1358
1359void LayerImpl::ScrollbarParametersDidChange() {
1360  if (!scrollbars_)
1361    return;
1362
1363  for (ScrollbarSet::iterator it = scrollbars_->begin();
1364       it != scrollbars_->end();
1365       ++it)
1366    (*it)->ScrollbarParametersDidChange();
1367}
1368
1369void LayerImpl::SetNeedsPushProperties() {
1370  if (needs_push_properties_)
1371    return;
1372  if (!parent_should_know_need_push_properties() && parent_)
1373    parent_->AddDependentNeedsPushProperties();
1374  needs_push_properties_ = true;
1375}
1376
1377void LayerImpl::AddDependentNeedsPushProperties() {
1378  DCHECK_GE(num_dependents_need_push_properties_, 0);
1379
1380  if (!parent_should_know_need_push_properties() && parent_)
1381    parent_->AddDependentNeedsPushProperties();
1382
1383  num_dependents_need_push_properties_++;
1384}
1385
1386void LayerImpl::RemoveDependentNeedsPushProperties() {
1387  num_dependents_need_push_properties_--;
1388  DCHECK_GE(num_dependents_need_push_properties_, 0);
1389
1390  if (!parent_should_know_need_push_properties() && parent_)
1391      parent_->RemoveDependentNeedsPushProperties();
1392}
1393
1394void LayerImpl::AsValueInto(base::debug::TracedValue* state) const {
1395  TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
1396      TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1397      state,
1398      "cc::LayerImpl",
1399      LayerTypeAsString(),
1400      this);
1401  state->SetInteger("layer_id", id());
1402  state->BeginDictionary("bounds");
1403  MathUtil::AddToTracedValue(bounds_, state);
1404  state->EndDictionary();
1405
1406  state->BeginArray("position");
1407  MathUtil::AddToTracedValue(position_, state);
1408  state->EndArray();
1409
1410  state->SetInteger("draws_content", DrawsContent());
1411  state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes());
1412
1413  state->BeginArray("scroll_offset");
1414  MathUtil::AddToTracedValue(scroll_offset_, state);
1415  state->EndArray();
1416
1417  state->BeginArray("transform_origin");
1418  MathUtil::AddToTracedValue(transform_origin_, state);
1419  state->EndArray();
1420
1421  bool clipped;
1422  gfx::QuadF layer_quad = MathUtil::MapQuad(
1423      screen_space_transform(),
1424      gfx::QuadF(gfx::Rect(content_bounds())),
1425      &clipped);
1426  state->BeginArray("layer_quad");
1427  MathUtil::AddToTracedValue(layer_quad, state);
1428  state->EndArray();
1429  if (!touch_event_handler_region_.IsEmpty()) {
1430    state->BeginArray("touch_event_handler_region");
1431    touch_event_handler_region_.AsValueInto(state);
1432    state->EndArray();
1433  }
1434  if (have_wheel_event_handlers_) {
1435    gfx::Rect wheel_rect(content_bounds());
1436    Region wheel_region(wheel_rect);
1437    state->BeginArray("wheel_event_handler_region");
1438    wheel_region.AsValueInto(state);
1439    state->EndArray();
1440  }
1441  if (have_scroll_event_handlers_) {
1442    gfx::Rect scroll_rect(content_bounds());
1443    Region scroll_region(scroll_rect);
1444    state->BeginArray("scroll_event_handler_region");
1445    scroll_region.AsValueInto(state);
1446    state->EndArray();
1447  }
1448  if (!non_fast_scrollable_region_.IsEmpty()) {
1449    state->BeginArray("non_fast_scrollable_region");
1450    non_fast_scrollable_region_.AsValueInto(state);
1451    state->EndArray();
1452  }
1453
1454  state->BeginArray("children");
1455  for (size_t i = 0; i < children_.size(); ++i) {
1456    state->BeginDictionary();
1457    children_[i]->AsValueInto(state);
1458    state->EndDictionary();
1459  }
1460  state->EndArray();
1461  if (mask_layer_) {
1462    state->BeginDictionary("mask_layer");
1463    mask_layer_->AsValueInto(state);
1464    state->EndDictionary();
1465  }
1466  if (replica_layer_) {
1467    state->BeginDictionary("replica_layer");
1468    replica_layer_->AsValueInto(state);
1469    state->EndDictionary();
1470  }
1471
1472  if (scroll_parent_)
1473    state->SetInteger("scroll_parent", scroll_parent_->id());
1474
1475  if (clip_parent_)
1476    state->SetInteger("clip_parent", clip_parent_->id());
1477
1478  state->SetBoolean("can_use_lcd_text", can_use_lcd_text());
1479  state->SetBoolean("contents_opaque", contents_opaque());
1480
1481  state->SetBoolean(
1482      "has_animation_bounds",
1483      layer_animation_controller()->HasAnimationThatInflatesBounds());
1484
1485  gfx::BoxF box;
1486  if (LayerUtils::GetAnimationBounds(*this, &box)) {
1487    state->BeginArray("animation_bounds");
1488    MathUtil::AddToTracedValue(box, state);
1489    state->EndArray();
1490  }
1491
1492  if (debug_info_.get()) {
1493    std::string str;
1494    debug_info_->AppendAsTraceFormat(&str);
1495    base::JSONReader json_reader;
1496    scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(str));
1497
1498    if (debug_info_value->IsType(base::Value::TYPE_DICTIONARY)) {
1499      base::DictionaryValue* dictionary_value = NULL;
1500      bool converted_to_dictionary =
1501          debug_info_value->GetAsDictionary(&dictionary_value);
1502      DCHECK(converted_to_dictionary);
1503      for (base::DictionaryValue::Iterator it(*dictionary_value); !it.IsAtEnd();
1504           it.Advance()) {
1505        state->SetValue(it.key().data(), it.value().DeepCopy());
1506      }
1507    } else {
1508      NOTREACHED();
1509    }
1510  }
1511}
1512
1513bool LayerImpl::IsDrawnRenderSurfaceLayerListMember() const {
1514  return draw_properties_.last_drawn_render_surface_layer_list_id ==
1515         layer_tree_impl_->current_render_surface_list_id();
1516}
1517
1518size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
1519
1520void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
1521  benchmark->RunOnLayer(this);
1522}
1523
1524void LayerImpl::NotifyAnimationFinished(
1525    base::TimeTicks monotonic_time,
1526    Animation::TargetProperty target_property) {
1527  if (target_property == Animation::ScrollOffset)
1528    layer_tree_impl_->InputScrollAnimationFinished();
1529}
1530
1531}  // namespace cc
1532