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