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/json/json_reader.h"
      9 #include "base/strings/stringprintf.h"
     10 #include "cc/animation/animation_registrar.h"
     11 #include "cc/animation/scrollbar_animation_controller.h"
     12 #include "cc/animation/scrollbar_animation_controller_linear_fade.h"
     13 #include "cc/animation/scrollbar_animation_controller_thinning.h"
     14 #include "cc/base/math_util.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/painted_scrollbar_layer_impl.h"
     21 #include "cc/layers/quad_sink.h"
     22 #include "cc/output/copy_output_request.h"
     23 #include "cc/quads/debug_border_draw_quad.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/point_conversions.h"
     29 #include "ui/gfx/quad_f.h"
     30 #include "ui/gfx/rect_conversions.h"
     31 
     32 namespace cc {
     33 LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id)
     34     : parent_(NULL),
     35       scroll_parent_(NULL),
     36       clip_parent_(NULL),
     37       mask_layer_id_(-1),
     38       replica_layer_id_(-1),
     39       layer_id_(id),
     40       layer_tree_impl_(tree_impl),
     41       anchor_point_(0.5f, 0.5f),
     42       anchor_point_z_(0.f),
     43       scroll_offset_delegate_(NULL),
     44       scrollable_(false),
     45       should_scroll_on_main_thread_(false),
     46       have_wheel_event_handlers_(false),
     47       user_scrollable_horizontal_(true),
     48       user_scrollable_vertical_(true),
     49       stacking_order_changed_(false),
     50       double_sided_(true),
     51       layer_property_changed_(false),
     52       masks_to_bounds_(false),
     53       contents_opaque_(false),
     54       is_root_for_isolated_group_(false),
     55       preserves_3d_(false),
     56       use_parent_backface_visibility_(false),
     57       draw_checkerboard_for_missing_tiles_(false),
     58       draws_content_(false),
     59       hide_layer_and_subtree_(false),
     60       force_render_surface_(false),
     61       is_container_for_fixed_position_layers_(false),
     62       background_color_(0),
     63       opacity_(1.0),
     64       blend_mode_(SkXfermode::kSrcOver_Mode),
     65       draw_depth_(0.f),
     66       compositing_reasons_(kCompositingReasonUnknown),
     67       current_draw_mode_(DRAW_MODE_NONE),
     68       horizontal_scrollbar_layer_(NULL),
     69       vertical_scrollbar_layer_(NULL) {
     70   DCHECK_GT(layer_id_, 0);
     71   DCHECK(layer_tree_impl_);
     72   layer_tree_impl_->RegisterLayer(this);
     73   AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar();
     74   layer_animation_controller_ =
     75       registrar->GetAnimationControllerForId(layer_id_);
     76   layer_animation_controller_->AddValueObserver(this);
     77   if (IsActive())
     78     layer_animation_controller_->set_value_provider(this);
     79 }
     80 
     81 LayerImpl::~LayerImpl() {
     82   DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_);
     83 
     84   layer_animation_controller_->RemoveValueObserver(this);
     85   layer_animation_controller_->remove_value_provider(this);
     86 
     87   if (!copy_requests_.empty() && layer_tree_impl_->IsActiveTree())
     88     layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
     89   layer_tree_impl_->UnregisterLayer(this);
     90 
     91   if (scroll_children_) {
     92     for (std::set<LayerImpl*>::iterator it = scroll_children_->begin();
     93         it != scroll_children_->end(); ++it)
     94       (*it)->scroll_parent_ = NULL;
     95   }
     96 
     97   if (scroll_parent_)
     98     scroll_parent_->RemoveScrollChild(this);
     99 
    100   if (clip_children_) {
    101     for (std::set<LayerImpl*>::iterator it = clip_children_->begin();
    102         it != clip_children_->end(); ++it)
    103       (*it)->clip_parent_ = NULL;
    104   }
    105 
    106   if (clip_parent_)
    107     clip_parent_->RemoveClipChild(this);
    108 }
    109 
    110 void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) {
    111   child->set_parent(this);
    112   DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl());
    113   children_.push_back(child.Pass());
    114   layer_tree_impl()->set_needs_update_draw_properties();
    115 }
    116 
    117 scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) {
    118   for (OwnedLayerImplList::iterator it = children_.begin();
    119        it != children_.end();
    120        ++it) {
    121     if (*it == child) {
    122       scoped_ptr<LayerImpl> ret = children_.take(it);
    123       children_.erase(it);
    124       layer_tree_impl()->set_needs_update_draw_properties();
    125       return ret.Pass();
    126     }
    127   }
    128   return scoped_ptr<LayerImpl>();
    129 }
    130 
    131 void LayerImpl::ClearChildList() {
    132   if (children_.empty())
    133     return;
    134 
    135   children_.clear();
    136   layer_tree_impl()->set_needs_update_draw_properties();
    137 }
    138 
    139 bool LayerImpl::HasAncestor(const LayerImpl* ancestor) const {
    140   if (!ancestor)
    141     return false;
    142 
    143   for (const LayerImpl* layer = this; layer; layer = layer->parent()) {
    144     if (layer == ancestor)
    145       return true;
    146   }
    147 
    148   return false;
    149 }
    150 
    151 void LayerImpl::SetScrollParent(LayerImpl* parent) {
    152   if (scroll_parent_ == parent)
    153     return;
    154 
    155   // Having both a scroll parent and a scroll offset delegate is unsupported.
    156   DCHECK(!scroll_offset_delegate_);
    157 
    158   if (scroll_parent_)
    159     scroll_parent_->RemoveScrollChild(this);
    160 
    161   scroll_parent_ = parent;
    162 }
    163 
    164 void LayerImpl::SetDebugInfo(
    165     scoped_refptr<base::debug::ConvertableToTraceFormat> other) {
    166   debug_info_ = other;
    167 }
    168 
    169 void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) {
    170   if (scroll_children_.get() == children)
    171     return;
    172   scroll_children_.reset(children);
    173 }
    174 
    175 void LayerImpl::RemoveScrollChild(LayerImpl* child) {
    176   DCHECK(scroll_children_);
    177   scroll_children_->erase(child);
    178   if (scroll_children_->empty())
    179     scroll_children_.reset();
    180 }
    181 
    182 void LayerImpl::SetClipParent(LayerImpl* ancestor) {
    183   if (clip_parent_ == ancestor)
    184     return;
    185 
    186   if (clip_parent_)
    187     clip_parent_->RemoveClipChild(this);
    188 
    189   clip_parent_ = ancestor;
    190 }
    191 
    192 void LayerImpl::SetClipChildren(std::set<LayerImpl*>* children) {
    193   if (clip_children_.get() == children)
    194     return;
    195   clip_children_.reset(children);
    196 }
    197 
    198 void LayerImpl::RemoveClipChild(LayerImpl* child) {
    199   DCHECK(clip_children_);
    200   clip_children_->erase(child);
    201   if (clip_children_->empty())
    202     clip_children_.reset();
    203 }
    204 
    205 void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) {
    206   if (requests->empty())
    207     return;
    208 
    209   bool was_empty = copy_requests_.empty();
    210   copy_requests_.insert_and_take(copy_requests_.end(), *requests);
    211   requests->clear();
    212 
    213   if (was_empty && layer_tree_impl()->IsActiveTree())
    214     layer_tree_impl()->AddLayerWithCopyOutputRequest(this);
    215   NoteLayerPropertyChangedForSubtree();
    216 }
    217 
    218 void LayerImpl::TakeCopyRequestsAndTransformToTarget(
    219     ScopedPtrVector<CopyOutputRequest>* requests) {
    220   if (copy_requests_.empty())
    221     return;
    222 
    223   size_t first_inserted_request = requests->size();
    224   requests->insert_and_take(requests->end(), copy_requests_);
    225   copy_requests_.clear();
    226 
    227   for (size_t i = first_inserted_request; i < requests->size(); ++i) {
    228     CopyOutputRequest* request = requests->at(i);
    229     if (!request->has_area())
    230       continue;
    231 
    232     gfx::Rect request_in_layer_space = request->area();
    233     gfx::Rect request_in_content_space =
    234         LayerRectToContentRect(request_in_layer_space);
    235     request->set_area(
    236         MathUtil::MapClippedRect(draw_properties_.target_space_transform,
    237                                  request_in_content_space));
    238   }
    239 
    240   if (layer_tree_impl()->IsActiveTree())
    241     layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
    242 }
    243 
    244 void LayerImpl::CreateRenderSurface() {
    245   DCHECK(!draw_properties_.render_surface);
    246   draw_properties_.render_surface =
    247       make_scoped_ptr(new RenderSurfaceImpl(this));
    248   draw_properties_.render_target = this;
    249 }
    250 
    251 void LayerImpl::ClearRenderSurface() {
    252   draw_properties_.render_surface.reset();
    253 }
    254 
    255 scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const {
    256   scoped_ptr<SharedQuadState> state = SharedQuadState::Create();
    257   state->SetAll(draw_properties_.target_space_transform,
    258                 draw_properties_.content_bounds,
    259                 draw_properties_.visible_content_rect,
    260                 draw_properties_.clip_rect,
    261                 draw_properties_.is_clipped,
    262                 draw_properties_.opacity,
    263                 blend_mode_);
    264   return state.Pass();
    265 }
    266 
    267 bool LayerImpl::WillDraw(DrawMode draw_mode,
    268                          ResourceProvider* resource_provider) {
    269   // WillDraw/DidDraw must be matched.
    270   DCHECK_NE(DRAW_MODE_NONE, draw_mode);
    271   DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_);
    272   current_draw_mode_ = draw_mode;
    273   return true;
    274 }
    275 
    276 void LayerImpl::DidDraw(ResourceProvider* resource_provider) {
    277   DCHECK_NE(DRAW_MODE_NONE, current_draw_mode_);
    278   current_draw_mode_ = DRAW_MODE_NONE;
    279 }
    280 
    281 bool LayerImpl::ShowDebugBorders() const {
    282   return layer_tree_impl()->debug_state().show_debug_borders;
    283 }
    284 
    285 void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const {
    286   if (draws_content_) {
    287     *color = DebugColors::ContentLayerBorderColor();
    288     *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl());
    289     return;
    290   }
    291 
    292   if (masks_to_bounds_) {
    293     *color = DebugColors::MaskingLayerBorderColor();
    294     *width = DebugColors::MaskingLayerBorderWidth(layer_tree_impl());
    295     return;
    296   }
    297 
    298   *color = DebugColors::ContainerLayerBorderColor();
    299   *width = DebugColors::ContainerLayerBorderWidth(layer_tree_impl());
    300 }
    301 
    302 void LayerImpl::AppendDebugBorderQuad(
    303     QuadSink* quad_sink,
    304     const SharedQuadState* shared_quad_state,
    305     AppendQuadsData* append_quads_data) const {
    306   SkColor color;
    307   float width;
    308   GetDebugBorderProperties(&color, &width);
    309   AppendDebugBorderQuad(
    310       quad_sink, shared_quad_state, append_quads_data, color, width);
    311 }
    312 
    313 void LayerImpl::AppendDebugBorderQuad(QuadSink* quad_sink,
    314                                       const SharedQuadState* shared_quad_state,
    315                                       AppendQuadsData* append_quads_data,
    316                                       SkColor color,
    317                                       float width) const {
    318   if (!ShowDebugBorders())
    319     return;
    320 
    321   gfx::Rect content_rect(content_bounds());
    322   scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
    323       DebugBorderDrawQuad::Create();
    324   debug_border_quad->SetNew(shared_quad_state, content_rect, color, width);
    325   quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(), append_quads_data);
    326 }
    327 
    328 bool LayerImpl::HasDelegatedContent() const {
    329   return false;
    330 }
    331 
    332 bool LayerImpl::HasContributingDelegatedRenderPasses() const {
    333   return false;
    334 }
    335 
    336 RenderPass::Id LayerImpl::FirstContributingRenderPassId() const {
    337   return RenderPass::Id(0, 0);
    338 }
    339 
    340 RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id)
    341     const {
    342   return RenderPass::Id(0, 0);
    343 }
    344 
    345 ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const {
    346   NOTREACHED();
    347   return 0;
    348 }
    349 
    350 void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) {
    351   // Pending tree never has sent scroll deltas
    352   DCHECK(layer_tree_impl()->IsActiveTree());
    353 
    354   if (sent_scroll_delta_ == sent_scroll_delta)
    355     return;
    356 
    357   sent_scroll_delta_ = sent_scroll_delta;
    358 }
    359 
    360 gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) {
    361   DCHECK(scrollable());
    362   gfx::Vector2dF min_delta = -scroll_offset_;
    363   gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_;
    364   // Clamp new_delta so that position + delta stays within scroll bounds.
    365   gfx::Vector2dF new_delta = (ScrollDelta() + scroll);
    366   new_delta.SetToMax(min_delta);
    367   new_delta.SetToMin(max_delta);
    368   gfx::Vector2dF unscrolled =
    369       ScrollDelta() + scroll - new_delta;
    370   SetScrollDelta(new_delta);
    371   return unscrolled;
    372 }
    373 
    374 void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() {
    375   // Pending tree never has sent scroll deltas
    376   DCHECK(layer_tree_impl()->IsActiveTree());
    377 
    378   // Apply sent scroll deltas to scroll position / scroll delta as if the
    379   // main thread had applied them and then committed those values.
    380   //
    381   // This function should not change the total scroll offset; it just shifts
    382   // some of the scroll delta to the scroll offset.  Therefore, adjust these
    383   // variables directly rather than calling the scroll offset delegate to
    384   // avoid sending it multiple spurious calls.
    385   //
    386   // Because of the way scroll delta is calculated with a delegate, this will
    387   // leave the total scroll offset unchanged on this layer regardless of
    388   // whether a delegate is being used.
    389   scroll_offset_ += sent_scroll_delta_;
    390   scroll_delta_ -= sent_scroll_delta_;
    391   sent_scroll_delta_ = gfx::Vector2d();
    392 }
    393 
    394 void LayerImpl::ApplyScrollDeltasSinceBeginMainFrame() {
    395   // Only the pending tree can have missing scrolls.
    396   DCHECK(layer_tree_impl()->IsPendingTree());
    397   if (!scrollable())
    398     return;
    399 
    400   // Pending tree should never have sent scroll deltas.
    401   DCHECK(sent_scroll_delta().IsZero());
    402 
    403   LayerImpl* active_twin = layer_tree_impl()->FindActiveTreeLayerById(id());
    404   if (active_twin) {
    405     // Scrolls that happens after begin frame (where the sent scroll delta
    406     // comes from) and commit need to be applied to the pending tree
    407     // so that it is up to date with the total scroll.
    408     SetScrollDelta(active_twin->ScrollDelta() -
    409                    active_twin->sent_scroll_delta());
    410   }
    411 }
    412 
    413 InputHandler::ScrollStatus LayerImpl::TryScroll(
    414     gfx::PointF screen_space_point,
    415     InputHandler::ScrollInputType type) const {
    416   if (should_scroll_on_main_thread()) {
    417     TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread");
    418     return InputHandler::ScrollOnMainThread;
    419   }
    420 
    421   if (!screen_space_transform().IsInvertible()) {
    422     TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform");
    423     return InputHandler::ScrollIgnored;
    424   }
    425 
    426   if (!non_fast_scrollable_region().IsEmpty()) {
    427     bool clipped = false;
    428     gfx::Transform inverse_screen_space_transform(
    429         gfx::Transform::kSkipInitialization);
    430     if (!screen_space_transform().GetInverse(&inverse_screen_space_transform)) {
    431       // TODO(shawnsingh): We shouldn't be applying a projection if screen space
    432       // transform is uninvertible here. Perhaps we should be returning
    433       // ScrollOnMainThread in this case?
    434     }
    435 
    436     gfx::PointF hit_test_point_in_content_space =
    437         MathUtil::ProjectPoint(inverse_screen_space_transform,
    438                                screen_space_point,
    439                                &clipped);
    440     gfx::PointF hit_test_point_in_layer_space =
    441         gfx::ScalePoint(hit_test_point_in_content_space,
    442                         1.f / contents_scale_x(),
    443                         1.f / contents_scale_y());
    444     if (!clipped &&
    445         non_fast_scrollable_region().Contains(
    446             gfx::ToRoundedPoint(hit_test_point_in_layer_space))) {
    447       TRACE_EVENT0("cc",
    448                    "LayerImpl::tryScroll: Failed NonFastScrollableRegion");
    449       return InputHandler::ScrollOnMainThread;
    450     }
    451   }
    452 
    453   if (type == InputHandler::Wheel && have_wheel_event_handlers()) {
    454     TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers");
    455     return InputHandler::ScrollOnMainThread;
    456   }
    457 
    458   if (!scrollable()) {
    459     TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable");
    460     return InputHandler::ScrollIgnored;
    461   }
    462 
    463   if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) {
    464     TRACE_EVENT0("cc",
    465                  "LayerImpl::tryScroll: Ignored. Technically scrollable,"
    466                  " but has no affordance in either direction.");
    467     return InputHandler::ScrollIgnored;
    468   }
    469 
    470   return InputHandler::ScrollStarted;
    471 }
    472 
    473 bool LayerImpl::DrawCheckerboardForMissingTiles() const {
    474   return draw_checkerboard_for_missing_tiles_ &&
    475       !layer_tree_impl()->settings().background_color_instead_of_checkerboard;
    476 }
    477 
    478 gfx::Rect LayerImpl::LayerRectToContentRect(
    479     const gfx::RectF& layer_rect) const {
    480   gfx::RectF content_rect =
    481       gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y());
    482   // Intersect with content rect to avoid the extra pixel because for some
    483   // values x and y, ceil((x / y) * y) may be x + 1.
    484   content_rect.Intersect(gfx::Rect(content_bounds()));
    485   return gfx::ToEnclosingRect(content_rect);
    486 }
    487 
    488 skia::RefPtr<SkPicture> LayerImpl::GetPicture() {
    489   return skia::RefPtr<SkPicture>();
    490 }
    491 
    492 bool LayerImpl::AreVisibleResourcesReady() const {
    493   return true;
    494 }
    495 
    496 scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) {
    497   return LayerImpl::Create(tree_impl, layer_id_);
    498 }
    499 
    500 void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
    501   layer->SetAnchorPoint(anchor_point_);
    502   layer->SetAnchorPointZ(anchor_point_z_);
    503   layer->SetBackgroundColor(background_color_);
    504   layer->SetBounds(bounds_);
    505   layer->SetContentBounds(content_bounds());
    506   layer->SetContentsScale(contents_scale_x(), contents_scale_y());
    507   layer->SetDebugName(debug_name_);
    508   layer->SetCompositingReasons(compositing_reasons_);
    509   layer->SetDoubleSided(double_sided_);
    510   layer->SetDrawCheckerboardForMissingTiles(
    511       draw_checkerboard_for_missing_tiles_);
    512   layer->SetForceRenderSurface(force_render_surface_);
    513   layer->SetDrawsContent(DrawsContent());
    514   layer->SetHideLayerAndSubtree(hide_layer_and_subtree_);
    515   layer->SetFilters(filters());
    516   layer->SetBackgroundFilters(background_filters());
    517   layer->SetMasksToBounds(masks_to_bounds_);
    518   layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_);
    519   layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_);
    520   layer->SetNonFastScrollableRegion(non_fast_scrollable_region_);
    521   layer->SetTouchEventHandlerRegion(touch_event_handler_region_);
    522   layer->SetContentsOpaque(contents_opaque_);
    523   layer->SetOpacity(opacity_);
    524   layer->SetBlendMode(blend_mode_);
    525   layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_);
    526   layer->SetPosition(position_);
    527   layer->SetIsContainerForFixedPositionLayers(
    528       is_container_for_fixed_position_layers_);
    529   layer->SetFixedContainerSizeDelta(fixed_container_size_delta_);
    530   layer->SetPositionConstraint(position_constraint_);
    531   layer->SetPreserves3d(preserves_3d());
    532   layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_);
    533   layer->SetSublayerTransform(sublayer_transform_);
    534   layer->SetTransform(transform_);
    535 
    536   layer->SetScrollable(scrollable_);
    537   layer->set_user_scrollable_horizontal(user_scrollable_horizontal_);
    538   layer->set_user_scrollable_vertical(user_scrollable_vertical_);
    539   layer->SetScrollOffsetAndDelta(
    540       scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta());
    541   layer->SetSentScrollDelta(gfx::Vector2d());
    542 
    543   layer->SetMaxScrollOffset(max_scroll_offset_);
    544 
    545   LayerImpl* scroll_parent = NULL;
    546   if (scroll_parent_)
    547     scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id());
    548 
    549   layer->SetScrollParent(scroll_parent);
    550   if (scroll_children_) {
    551     std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>;
    552     for (std::set<LayerImpl*>::iterator it = scroll_children_->begin();
    553         it != scroll_children_->end(); ++it)
    554       scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id()));
    555     layer->SetScrollChildren(scroll_children);
    556   }
    557 
    558   LayerImpl* clip_parent = NULL;
    559   if (clip_parent_) {
    560     clip_parent = layer->layer_tree_impl()->LayerById(
    561         clip_parent_->id());
    562   }
    563 
    564   layer->SetClipParent(clip_parent);
    565   if (clip_children_) {
    566     std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>;
    567     for (std::set<LayerImpl*>::iterator it = clip_children_->begin();
    568         it != clip_children_->end(); ++it)
    569       clip_children->insert(layer->layer_tree_impl()->LayerById((*it)->id()));
    570     layer->SetClipChildren(clip_children);
    571   }
    572 
    573   layer->PassCopyRequests(&copy_requests_);
    574 
    575   // If the main thread commits multiple times before the impl thread actually
    576   // draws, then damage tracking will become incorrect if we simply clobber the
    577   // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
    578   // union) any update changes that have occurred on the main thread.
    579   update_rect_.Union(layer->update_rect());
    580   layer->set_update_rect(update_rect_);
    581 
    582   layer->SetStackingOrderChanged(stacking_order_changed_);
    583 
    584   // Reset any state that should be cleared for the next update.
    585   stacking_order_changed_ = false;
    586   update_rect_ = gfx::RectF();
    587 
    588   layer->SetDebugInfo(debug_info_);
    589 }
    590 
    591 base::DictionaryValue* LayerImpl::LayerTreeAsJson() const {
    592   base::DictionaryValue* result = new base::DictionaryValue;
    593   result->SetString("LayerType", LayerTypeAsString());
    594 
    595   base::ListValue* list = new base::ListValue;
    596   list->AppendInteger(bounds().width());
    597   list->AppendInteger(bounds().height());
    598   result->Set("Bounds", list);
    599 
    600   list = new base::ListValue;
    601   list->AppendDouble(position_.x());
    602   list->AppendDouble(position_.y());
    603   result->Set("Position", list);
    604 
    605   const gfx::Transform& gfx_transform = draw_properties_.target_space_transform;
    606   double transform[16];
    607   gfx_transform.matrix().asColMajord(transform);
    608   list = new base::ListValue;
    609   for (int i = 0; i < 16; ++i)
    610     list->AppendDouble(transform[i]);
    611   result->Set("DrawTransform", list);
    612 
    613   result->SetBoolean("DrawsContent", draws_content_);
    614   result->SetDouble("Opacity", opacity());
    615   result->SetBoolean("ContentsOpaque", contents_opaque_);
    616 
    617   if (scrollable_)
    618     result->SetBoolean("Scrollable", scrollable_);
    619 
    620   if (have_wheel_event_handlers_)
    621     result->SetBoolean("WheelHandler", have_wheel_event_handlers_);
    622   if (!touch_event_handler_region_.IsEmpty()) {
    623     scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue();
    624     result->Set("TouchRegion", region.release());
    625   }
    626 
    627   list = new base::ListValue;
    628   for (size_t i = 0; i < children_.size(); ++i)
    629     list->Append(children_[i]->LayerTreeAsJson());
    630   result->Set("Children", list);
    631 
    632   return result;
    633 }
    634 
    635 void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) {
    636   if (stacking_order_changed) {
    637     stacking_order_changed_ = true;
    638     NoteLayerPropertyChangedForSubtree();
    639   }
    640 }
    641 
    642 void LayerImpl::NoteLayerPropertyChanged() {
    643   layer_property_changed_ = true;
    644   layer_tree_impl()->set_needs_update_draw_properties();
    645 }
    646 
    647 void LayerImpl::NoteLayerPropertyChangedForSubtree() {
    648   NoteLayerPropertyChanged();
    649   NoteLayerPropertyChangedForDescendants();
    650 }
    651 
    652 void LayerImpl::NoteLayerPropertyChangedForDescendants() {
    653   layer_tree_impl()->set_needs_update_draw_properties();
    654   for (size_t i = 0; i < children_.size(); ++i)
    655     children_[i]->NoteLayerPropertyChangedForSubtree();
    656 }
    657 
    658 const char* LayerImpl::LayerTypeAsString() const {
    659   return "cc::LayerImpl";
    660 }
    661 
    662 void LayerImpl::ResetAllChangeTrackingForSubtree() {
    663   layer_property_changed_ = false;
    664 
    665   update_rect_ = gfx::RectF();
    666 
    667   if (draw_properties_.render_surface)
    668     draw_properties_.render_surface->ResetPropertyChangedFlag();
    669 
    670   if (mask_layer_)
    671     mask_layer_->ResetAllChangeTrackingForSubtree();
    672 
    673   if (replica_layer_) {
    674     // This also resets the replica mask, if it exists.
    675     replica_layer_->ResetAllChangeTrackingForSubtree();
    676   }
    677 
    678   for (size_t i = 0; i < children_.size(); ++i)
    679     children_[i]->ResetAllChangeTrackingForSubtree();
    680 }
    681 
    682 bool LayerImpl::LayerIsAlwaysDamaged() const {
    683   return false;
    684 }
    685 
    686 gfx::Vector2dF LayerImpl::ScrollOffsetForAnimation() const {
    687   return TotalScrollOffset();
    688 }
    689 
    690 void LayerImpl::OnFilterAnimated(const FilterOperations& filters) {
    691   SetFilters(filters);
    692 }
    693 
    694 void LayerImpl::OnOpacityAnimated(float opacity) {
    695   SetOpacity(opacity);
    696 }
    697 
    698 void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) {
    699   SetTransform(transform);
    700 }
    701 
    702 void LayerImpl::OnScrollOffsetAnimated(gfx::Vector2dF scroll_offset) {
    703   // Only layers in the active tree should need to do anything here, since
    704   // layers in the pending tree will find out about these changes as a
    705   // result of the call to SetScrollDelta.
    706   if (!IsActive())
    707     return;
    708 
    709   SetScrollDelta(scroll_offset - scroll_offset_);
    710 
    711   layer_tree_impl_->DidAnimateScrollOffset();
    712 }
    713 
    714 void LayerImpl::OnAnimationWaitingForDeletion() {}
    715 
    716 bool LayerImpl::IsActive() const {
    717   return layer_tree_impl_->IsActiveTree();
    718 }
    719 
    720 void LayerImpl::SetBounds(gfx::Size bounds) {
    721   if (bounds_ == bounds)
    722     return;
    723 
    724   bounds_ = bounds;
    725 
    726   if (masks_to_bounds())
    727     NoteLayerPropertyChangedForSubtree();
    728   else
    729     NoteLayerPropertyChanged();
    730 }
    731 
    732 void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) {
    733   int new_layer_id = mask_layer ? mask_layer->id() : -1;
    734 
    735   if (mask_layer) {
    736     DCHECK_EQ(layer_tree_impl(), mask_layer->layer_tree_impl());
    737     DCHECK_NE(new_layer_id, mask_layer_id_);
    738   } else if (new_layer_id == mask_layer_id_) {
    739     return;
    740   }
    741 
    742   mask_layer_ = mask_layer.Pass();
    743   mask_layer_id_ = new_layer_id;
    744   if (mask_layer_)
    745     mask_layer_->set_parent(this);
    746   NoteLayerPropertyChangedForSubtree();
    747 }
    748 
    749 scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() {
    750   mask_layer_id_ = -1;
    751   return mask_layer_.Pass();
    752 }
    753 
    754 void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) {
    755   int new_layer_id = replica_layer ? replica_layer->id() : -1;
    756 
    757   if (replica_layer) {
    758     DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl());
    759     DCHECK_NE(new_layer_id, replica_layer_id_);
    760   } else if (new_layer_id == replica_layer_id_) {
    761     return;
    762   }
    763 
    764   replica_layer_ = replica_layer.Pass();
    765   replica_layer_id_ = new_layer_id;
    766   if (replica_layer_)
    767     replica_layer_->set_parent(this);
    768   NoteLayerPropertyChangedForSubtree();
    769 }
    770 
    771 scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() {
    772   replica_layer_id_ = -1;
    773   return replica_layer_.Pass();
    774 }
    775 
    776 ScrollbarLayerImplBase* LayerImpl::ToScrollbarLayer() {
    777   return NULL;
    778 }
    779 
    780 void LayerImpl::SetDrawsContent(bool draws_content) {
    781   if (draws_content_ == draws_content)
    782     return;
    783 
    784   draws_content_ = draws_content;
    785   NoteLayerPropertyChanged();
    786 }
    787 
    788 void LayerImpl::SetHideLayerAndSubtree(bool hide) {
    789   if (hide_layer_and_subtree_ == hide)
    790     return;
    791 
    792   hide_layer_and_subtree_ = hide;
    793   NoteLayerPropertyChangedForSubtree();
    794 }
    795 
    796 void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) {
    797   if (anchor_point_ == anchor_point)
    798     return;
    799 
    800   anchor_point_ = anchor_point;
    801   NoteLayerPropertyChangedForSubtree();
    802 }
    803 
    804 void LayerImpl::SetAnchorPointZ(float anchor_point_z) {
    805   if (anchor_point_z_ == anchor_point_z)
    806     return;
    807 
    808   anchor_point_z_ = anchor_point_z;
    809   NoteLayerPropertyChangedForSubtree();
    810 }
    811 
    812 void LayerImpl::SetBackgroundColor(SkColor background_color) {
    813   if (background_color_ == background_color)
    814     return;
    815 
    816   background_color_ = background_color;
    817   NoteLayerPropertyChanged();
    818 }
    819 
    820 SkColor LayerImpl::SafeOpaqueBackgroundColor() const {
    821   SkColor color = background_color();
    822   if (SkColorGetA(color) == 255 && !contents_opaque()) {
    823     color = SK_ColorTRANSPARENT;
    824   } else if (SkColorGetA(color) != 255 && contents_opaque()) {
    825     for (const LayerImpl* layer = parent(); layer;
    826          layer = layer->parent()) {
    827       color = layer->background_color();
    828       if (SkColorGetA(color) == 255)
    829         break;
    830     }
    831     if (SkColorGetA(color) != 255)
    832       color = layer_tree_impl()->background_color();
    833     if (SkColorGetA(color) != 255)
    834       color = SkColorSetA(color, 255);
    835   }
    836   return color;
    837 }
    838 
    839 void LayerImpl::SetFilters(const FilterOperations& filters) {
    840   if (filters_ == filters)
    841     return;
    842 
    843   filters_ = filters;
    844   NoteLayerPropertyChangedForSubtree();
    845 }
    846 
    847 bool LayerImpl::FilterIsAnimating() const {
    848   return layer_animation_controller_->IsAnimatingProperty(Animation::Filter);
    849 }
    850 
    851 bool LayerImpl::FilterIsAnimatingOnImplOnly() const {
    852   Animation* filter_animation =
    853       layer_animation_controller_->GetAnimation(Animation::Filter);
    854   return filter_animation && filter_animation->is_impl_only();
    855 }
    856 
    857 void LayerImpl::SetBackgroundFilters(
    858     const FilterOperations& filters) {
    859   if (background_filters_ == filters)
    860     return;
    861 
    862   background_filters_ = filters;
    863   NoteLayerPropertyChanged();
    864 }
    865 
    866 void LayerImpl::SetMasksToBounds(bool masks_to_bounds) {
    867   if (masks_to_bounds_ == masks_to_bounds)
    868     return;
    869 
    870   masks_to_bounds_ = masks_to_bounds;
    871   NoteLayerPropertyChangedForSubtree();
    872 }
    873 
    874 void LayerImpl::SetContentsOpaque(bool opaque) {
    875   if (contents_opaque_ == opaque)
    876     return;
    877 
    878   contents_opaque_ = opaque;
    879   NoteLayerPropertyChangedForSubtree();
    880 }
    881 
    882 void LayerImpl::SetOpacity(float opacity) {
    883   if (opacity_ == opacity)
    884     return;
    885 
    886   opacity_ = opacity;
    887   NoteLayerPropertyChangedForSubtree();
    888 }
    889 
    890 bool LayerImpl::OpacityIsAnimating() const {
    891   return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity);
    892 }
    893 
    894 bool LayerImpl::OpacityIsAnimatingOnImplOnly() const {
    895   Animation* opacity_animation =
    896       layer_animation_controller_->GetAnimation(Animation::Opacity);
    897   return opacity_animation && opacity_animation->is_impl_only();
    898 }
    899 
    900 void LayerImpl::SetBlendMode(SkXfermode::Mode blend_mode) {
    901   if (blend_mode_ == blend_mode)
    902     return;
    903 
    904   blend_mode_ = blend_mode;
    905   NoteLayerPropertyChangedForSubtree();
    906 }
    907 
    908 void LayerImpl::SetIsRootForIsolatedGroup(bool root) {
    909   if (is_root_for_isolated_group_ == root)
    910     return;
    911 
    912   is_root_for_isolated_group_ = root;
    913 }
    914 
    915 void LayerImpl::SetPosition(gfx::PointF position) {
    916   if (position_ == position)
    917     return;
    918 
    919   position_ = position;
    920   NoteLayerPropertyChangedForSubtree();
    921 }
    922 
    923 void LayerImpl::SetPreserves3d(bool preserves3_d) {
    924   if (preserves_3d_ == preserves3_d)
    925     return;
    926 
    927   preserves_3d_ = preserves3_d;
    928   NoteLayerPropertyChangedForSubtree();
    929 }
    930 
    931 void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) {
    932   if (sublayer_transform_ == sublayer_transform)
    933     return;
    934 
    935   sublayer_transform_ = sublayer_transform;
    936   // Sublayer transform does not affect the current layer; it affects only its
    937   // children.
    938   NoteLayerPropertyChangedForDescendants();
    939 }
    940 
    941 void LayerImpl::SetTransform(const gfx::Transform& transform) {
    942   if (transform_ == transform)
    943     return;
    944 
    945   transform_ = transform;
    946   NoteLayerPropertyChangedForSubtree();
    947 }
    948 
    949 bool LayerImpl::TransformIsAnimating() const {
    950   return layer_animation_controller_->IsAnimatingProperty(Animation::Transform);
    951 }
    952 
    953 bool LayerImpl::TransformIsAnimatingOnImplOnly() const {
    954   Animation* transform_animation =
    955       layer_animation_controller_->GetAnimation(Animation::Transform);
    956   return transform_animation && transform_animation->is_impl_only();
    957 }
    958 
    959 void LayerImpl::SetContentBounds(gfx::Size content_bounds) {
    960   if (this->content_bounds() == content_bounds)
    961     return;
    962 
    963   draw_properties_.content_bounds = content_bounds;
    964   NoteLayerPropertyChanged();
    965 }
    966 
    967 void LayerImpl::SetContentsScale(float contents_scale_x,
    968                                  float contents_scale_y) {
    969   if (this->contents_scale_x() == contents_scale_x &&
    970       this->contents_scale_y() == contents_scale_y)
    971     return;
    972 
    973   draw_properties_.contents_scale_x = contents_scale_x;
    974   draw_properties_.contents_scale_y = contents_scale_y;
    975   NoteLayerPropertyChanged();
    976 }
    977 
    978 void LayerImpl::CalculateContentsScale(
    979     float ideal_contents_scale,
    980     float device_scale_factor,
    981     float page_scale_factor,
    982     bool animating_transform_to_screen,
    983     float* contents_scale_x,
    984     float* contents_scale_y,
    985     gfx::Size* content_bounds) {
    986   // Base LayerImpl has all of its content scales and content bounds pushed
    987   // from its Layer during commit and just reuses those values as-is.
    988   *contents_scale_x = this->contents_scale_x();
    989   *contents_scale_y = this->contents_scale_y();
    990   *content_bounds = this->content_bounds();
    991 }
    992 
    993 void LayerImpl::UpdateScrollbarPositions() {
    994   gfx::Vector2dF current_offset = scroll_offset_ + ScrollDelta();
    995 
    996   gfx::RectF viewport(PointAtOffsetFromOrigin(current_offset), bounds_);
    997   gfx::SizeF scrollable_size(max_scroll_offset_.x() + bounds_.width(),
    998                              max_scroll_offset_.y() + bounds_.height());
    999   if (horizontal_scrollbar_layer_) {
   1000     horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x());
   1001     horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x());
   1002     horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio(
   1003         viewport.width() / scrollable_size.width());
   1004   }
   1005   if (vertical_scrollbar_layer_) {
   1006     vertical_scrollbar_layer_->SetCurrentPos(current_offset.y());
   1007     vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y());
   1008     vertical_scrollbar_layer_->SetVisibleToTotalLengthRatio(
   1009         viewport.height() / scrollable_size.height());
   1010   }
   1011 
   1012   if (current_offset == last_scroll_offset_)
   1013     return;
   1014   last_scroll_offset_ = current_offset;
   1015 
   1016   if (scrollbar_animation_controller_) {
   1017     bool should_animate = scrollbar_animation_controller_->DidScrollUpdate(
   1018         layer_tree_impl_->CurrentPhysicalTimeTicks());
   1019     if (should_animate)
   1020       layer_tree_impl_->StartScrollbarAnimation();
   1021   }
   1022 
   1023   // Get the current_offset_.y() value for a sanity-check on scrolling
   1024   // benchmark metrics. Specifically, we want to make sure
   1025   // BasicMouseWheelSmoothScrollGesture has proper scroll curves.
   1026   if (layer_tree_impl()->IsActiveTree()) {
   1027     TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y());
   1028   }
   1029 }
   1030 
   1031 void LayerImpl::SetScrollOffsetDelegate(
   1032     LayerScrollOffsetDelegate* scroll_offset_delegate) {
   1033   // Having both a scroll parent and a scroll offset delegate is unsupported.
   1034   DCHECK(!scroll_parent_);
   1035   if (!scroll_offset_delegate && scroll_offset_delegate_) {
   1036     scroll_delta_ =
   1037         scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_;
   1038   }
   1039   gfx::Vector2dF total_offset = TotalScrollOffset();
   1040   scroll_offset_delegate_ = scroll_offset_delegate;
   1041   if (scroll_offset_delegate_) {
   1042     scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_);
   1043     scroll_offset_delegate_->SetTotalScrollOffset(total_offset);
   1044   }
   1045 }
   1046 
   1047 bool LayerImpl::IsExternalFlingActive() const {
   1048   return scroll_offset_delegate_ &&
   1049          scroll_offset_delegate_->IsExternalFlingActive();
   1050 }
   1051 
   1052 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) {
   1053   SetScrollOffsetAndDelta(scroll_offset, ScrollDelta());
   1054 }
   1055 
   1056 void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset,
   1057                                         gfx::Vector2dF scroll_delta) {
   1058   bool changed = false;
   1059 
   1060   if (scroll_offset_ != scroll_offset) {
   1061     changed = true;
   1062     scroll_offset_ = scroll_offset;
   1063 
   1064     if (scroll_offset_delegate_)
   1065       scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset());
   1066   }
   1067 
   1068   if (ScrollDelta() != scroll_delta) {
   1069     changed = true;
   1070     if (layer_tree_impl()->IsActiveTree()) {
   1071       LayerImpl* pending_twin =
   1072           layer_tree_impl()->FindPendingTreeLayerById(id());
   1073       if (pending_twin) {
   1074         // The pending twin can't mirror the scroll delta of the active
   1075         // layer.  Although the delta - sent scroll delta difference is
   1076         // identical for both twins, the sent scroll delta for the pending
   1077         // layer is zero, as anything that has been sent has been baked
   1078         // into the layer's position/scroll offset as a part of commit.
   1079         DCHECK(pending_twin->sent_scroll_delta().IsZero());
   1080         pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta());
   1081       }
   1082     }
   1083 
   1084     if (scroll_offset_delegate_) {
   1085       scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ +
   1086                                                     scroll_delta);
   1087     } else {
   1088       scroll_delta_ = scroll_delta;
   1089     }
   1090   }
   1091 
   1092   if (changed) {
   1093     NoteLayerPropertyChangedForSubtree();
   1094     UpdateScrollbarPositions();
   1095   }
   1096 }
   1097 
   1098 gfx::Vector2dF LayerImpl::ScrollDelta() const {
   1099   if (scroll_offset_delegate_)
   1100     return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_;
   1101   return scroll_delta_;
   1102 }
   1103 
   1104 void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) {
   1105   SetScrollOffsetAndDelta(scroll_offset_, scroll_delta);
   1106 }
   1107 
   1108 gfx::Vector2dF LayerImpl::TotalScrollOffset() const {
   1109   return scroll_offset_ + ScrollDelta();
   1110 }
   1111 
   1112 void LayerImpl::SetDoubleSided(bool double_sided) {
   1113   if (double_sided_ == double_sided)
   1114     return;
   1115 
   1116   double_sided_ = double_sided;
   1117   NoteLayerPropertyChangedForSubtree();
   1118 }
   1119 
   1120 Region LayerImpl::VisibleContentOpaqueRegion() const {
   1121   if (contents_opaque())
   1122     return visible_content_rect();
   1123   return Region();
   1124 }
   1125 
   1126 void LayerImpl::DidBeginTracing() {}
   1127 
   1128 void LayerImpl::DidLoseOutputSurface() {}
   1129 
   1130 void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) {
   1131   if (max_scroll_offset_ == max_scroll_offset)
   1132     return;
   1133   max_scroll_offset_ = max_scroll_offset;
   1134 
   1135   if (scroll_offset_delegate_)
   1136     scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_);
   1137 
   1138   layer_tree_impl()->set_needs_update_draw_properties();
   1139   UpdateScrollbarPositions();
   1140 }
   1141 
   1142 void LayerImpl::DidBecomeActive() {
   1143   if (layer_tree_impl_->settings().scrollbar_animator ==
   1144       LayerTreeSettings::NoAnimator) {
   1145     return;
   1146   }
   1147 
   1148   bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ ||
   1149                                              vertical_scrollbar_layer_;
   1150   if (!need_scrollbar_animation_controller) {
   1151     scrollbar_animation_controller_.reset();
   1152     return;
   1153   }
   1154 
   1155   if (scrollbar_animation_controller_)
   1156     return;
   1157 
   1158   switch (layer_tree_impl_->settings().scrollbar_animator) {
   1159   case LayerTreeSettings::LinearFade: {
   1160     base::TimeDelta fadeout_delay = base::TimeDelta::FromMilliseconds(
   1161         layer_tree_impl_->settings().scrollbar_linear_fade_delay_ms);
   1162     base::TimeDelta fadeout_length = base::TimeDelta::FromMilliseconds(
   1163         layer_tree_impl_->settings().scrollbar_linear_fade_length_ms);
   1164 
   1165     scrollbar_animation_controller_ =
   1166         ScrollbarAnimationControllerLinearFade::Create(
   1167             this, fadeout_delay, fadeout_length)
   1168             .PassAs<ScrollbarAnimationController>();
   1169     break;
   1170   }
   1171   case LayerTreeSettings::Thinning: {
   1172     scrollbar_animation_controller_ =
   1173         ScrollbarAnimationControllerThinning::Create(this)
   1174             .PassAs<ScrollbarAnimationController>();
   1175     break;
   1176   }
   1177   case LayerTreeSettings::NoAnimator:
   1178     NOTREACHED();
   1179     break;
   1180   }
   1181 }
   1182 void LayerImpl::SetHorizontalScrollbarLayer(
   1183     ScrollbarLayerImplBase* scrollbar_layer) {
   1184   horizontal_scrollbar_layer_ = scrollbar_layer;
   1185   if (horizontal_scrollbar_layer_)
   1186     horizontal_scrollbar_layer_->set_scroll_layer_id(id());
   1187 }
   1188 
   1189 void LayerImpl::SetVerticalScrollbarLayer(
   1190     ScrollbarLayerImplBase* scrollbar_layer) {
   1191   vertical_scrollbar_layer_ = scrollbar_layer;
   1192   if (vertical_scrollbar_layer_)
   1193     vertical_scrollbar_layer_->set_scroll_layer_id(id());
   1194 }
   1195 
   1196 static scoped_ptr<base::Value>
   1197 CompositingReasonsAsValue(CompositingReasons reasons) {
   1198   scoped_ptr<base::ListValue> reason_list(new base::ListValue());
   1199 
   1200   if (reasons == kCompositingReasonUnknown) {
   1201     reason_list->AppendString("No reasons given");
   1202     return reason_list.PassAs<base::Value>();
   1203   }
   1204 
   1205   if (reasons & kCompositingReason3DTransform)
   1206     reason_list->AppendString("Has a 3d Transform");
   1207 
   1208   if (reasons & kCompositingReasonVideo)
   1209     reason_list->AppendString("Is accelerated video");
   1210 
   1211   if (reasons & kCompositingReasonCanvas)
   1212     reason_list->AppendString("Is accelerated canvas");
   1213 
   1214   if (reasons & kCompositingReasonPlugin)
   1215     reason_list->AppendString("Is accelerated plugin");
   1216 
   1217   if (reasons & kCompositingReasonIFrame)
   1218     reason_list->AppendString("Is accelerated iframe");
   1219 
   1220   if (reasons & kCompositingReasonBackfaceVisibilityHidden)
   1221     reason_list->AppendString("Has backface-visibility: hidden");
   1222 
   1223   if (reasons & kCompositingReasonAnimation)
   1224     reason_list->AppendString("Has accelerated animation or transition");
   1225 
   1226   if (reasons & kCompositingReasonFilters)
   1227     reason_list->AppendString("Has accelerated filters");
   1228 
   1229   if (reasons & kCompositingReasonPositionFixed)
   1230     reason_list->AppendString("Is fixed position");
   1231 
   1232   if (reasons & kCompositingReasonPositionSticky)
   1233     reason_list->AppendString("Is sticky position");
   1234 
   1235   if (reasons & kCompositingReasonOverflowScrollingTouch)
   1236     reason_list->AppendString("Is a scrollable overflow element");
   1237 
   1238   if (reasons & kCompositingReasonAssumedOverlap)
   1239     reason_list->AppendString("Might overlap a composited animation");
   1240 
   1241   if (reasons & kCompositingReasonOverlap)
   1242     reason_list->AppendString("Overlaps other composited content");
   1243 
   1244   if (reasons & kCompositingReasonNegativeZIndexChildren) {
   1245     reason_list->AppendString("Might overlap negative z-index "
   1246                               "composited content");
   1247   }
   1248 
   1249   if (reasons & kCompositingReasonTransformWithCompositedDescendants) {
   1250     reason_list->AppendString("Has transform needed by a "
   1251                               "composited descendant");
   1252   }
   1253 
   1254   if (reasons & kCompositingReasonOpacityWithCompositedDescendants)
   1255     reason_list->AppendString("Has opacity needed by a composited descendant");
   1256 
   1257   if (reasons & kCompositingReasonMaskWithCompositedDescendants)
   1258     reason_list->AppendString("Has a mask needed by a composited descendant");
   1259 
   1260   if (reasons & kCompositingReasonReflectionWithCompositedDescendants)
   1261     reason_list->AppendString("Has a reflection with a composited descendant");
   1262 
   1263   if (reasons & kCompositingReasonFilterWithCompositedDescendants)
   1264     reason_list->AppendString("Has filter effect with a composited descendant");
   1265 
   1266   if (reasons & kCompositingReasonBlendingWithCompositedDescendants)
   1267     reason_list->AppendString("Has a blend mode with a composited descendant");
   1268 
   1269   if (reasons & kCompositingReasonClipsCompositingDescendants)
   1270     reason_list->AppendString("Clips a composited descendant");
   1271 
   1272   if (reasons & kCompositingReasonPerspective) {
   1273     reason_list->AppendString("Has a perspective transform needed by a "
   1274                               "composited 3d descendant");
   1275   }
   1276 
   1277   if (reasons & kCompositingReasonPreserve3D) {
   1278     reason_list->AppendString("Has preserves-3d style with composited "
   1279                               "3d descendant");
   1280   }
   1281 
   1282   if (reasons & kCompositingReasonReflectionOfCompositedParent)
   1283     reason_list->AppendString("Is the reflection of a composited layer");
   1284 
   1285   if (reasons & kCompositingReasonRoot)
   1286     reason_list->AppendString("Is the root");
   1287 
   1288   if (reasons & kCompositingReasonLayerForClip)
   1289     reason_list->AppendString("Convenience layer, to clip subtree");
   1290 
   1291   if (reasons & kCompositingReasonLayerForScrollbar)
   1292     reason_list->AppendString("Convenience layer for rendering scrollbar");
   1293 
   1294   if (reasons & kCompositingReasonLayerForScrollingContainer)
   1295     reason_list->AppendString("Convenience layer, the scrolling container");
   1296 
   1297   if (reasons & kCompositingReasonLayerForForeground) {
   1298     reason_list->AppendString("Convenience layer, foreground when main layer "
   1299                               "has negative z-index composited content");
   1300   }
   1301 
   1302   if (reasons & kCompositingReasonLayerForBackground) {
   1303     reason_list->AppendString("Convenience layer, background when main layer "
   1304                               "has a composited background");
   1305   }
   1306 
   1307   if (reasons & kCompositingReasonLayerForMask)
   1308     reason_list->AppendString("Is a mask layer");
   1309 
   1310   if (reasons & kCompositingReasonOverflowScrollingParent)
   1311     reason_list->AppendString("Scroll parent is not an ancestor");
   1312 
   1313   if (reasons & kCompositingReasonOutOfFlowClipping)
   1314     reason_list->AppendString("Has clipping ancestor");
   1315 
   1316   if (reasons & kCompositingReasonIsolateCompositedDescendants)
   1317     reason_list->AppendString("Should isolate composited descendants");
   1318 
   1319   return reason_list.PassAs<base::Value>();
   1320 }
   1321 
   1322 void LayerImpl::AsValueInto(base::DictionaryValue* state) const {
   1323   TracedValue::MakeDictIntoImplicitSnapshot(state, LayerTypeAsString(), this);
   1324   state->SetInteger("layer_id", id());
   1325   state->SetString("layer_name", debug_name());
   1326   state->Set("bounds", MathUtil::AsValue(bounds()).release());
   1327   state->SetInteger("draws_content", DrawsContent());
   1328   state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes());
   1329   state->Set("compositing_reasons",
   1330              CompositingReasonsAsValue(compositing_reasons_).release());
   1331 
   1332   bool clipped;
   1333   gfx::QuadF layer_quad = MathUtil::MapQuad(
   1334       screen_space_transform(),
   1335       gfx::QuadF(gfx::Rect(content_bounds())),
   1336       &clipped);
   1337   state->Set("layer_quad", MathUtil::AsValue(layer_quad).release());
   1338 
   1339   if (!touch_event_handler_region_.IsEmpty()) {
   1340     state->Set("touch_event_handler_region",
   1341                touch_event_handler_region_.AsValue().release());
   1342   }
   1343   if (have_wheel_event_handlers_) {
   1344     gfx::Rect wheel_rect(content_bounds());
   1345     Region wheel_region(wheel_rect);
   1346     state->Set("wheel_event_handler_region",
   1347                wheel_region.AsValue().release());
   1348   }
   1349   if (!non_fast_scrollable_region_.IsEmpty()) {
   1350     state->Set("non_fast_scrollable_region",
   1351                non_fast_scrollable_region_.AsValue().release());
   1352   }
   1353 
   1354   scoped_ptr<base::ListValue> children_list(new base::ListValue());
   1355   for (size_t i = 0; i < children_.size(); ++i)
   1356     children_list->Append(children_[i]->AsValue().release());
   1357   state->Set("children", children_list.release());
   1358   if (mask_layer_)
   1359     state->Set("mask_layer", mask_layer_->AsValue().release());
   1360   if (replica_layer_)
   1361     state->Set("replica_layer", replica_layer_->AsValue().release());
   1362 
   1363   if (scroll_parent_)
   1364     state->SetInteger("scroll_parent", scroll_parent_->id());
   1365 
   1366   if (clip_parent_)
   1367     state->SetInteger("clip_parent", clip_parent_->id());
   1368 
   1369   state->SetBoolean("can_use_lcd_text", can_use_lcd_text());
   1370   state->SetBoolean("contents_opaque", contents_opaque());
   1371 
   1372   if (layer_animation_controller_->IsAnimatingProperty(Animation::Transform) ||
   1373       layer_animation_controller_->IsAnimatingProperty(Animation::Filter)) {
   1374     gfx::BoxF box(bounds().width(), bounds().height(), 0.f);
   1375     gfx::BoxF inflated;
   1376     if (layer_animation_controller_->AnimatedBoundsForBox(box, &inflated))
   1377       state->Set("animated_bounds", MathUtil::AsValue(inflated).release());
   1378   }
   1379 
   1380   if (debug_info_.get()) {
   1381     std::string str;
   1382     debug_info_->AppendAsTraceFormat(&str);
   1383     base::JSONReader json_reader;
   1384     // Parsing the JSON and re-encoding it is not very efficient,
   1385     // but it's the simplest way to achieve the desired effect, which
   1386     // is to output:
   1387     // {..., layout_rects: [{geometry_rect: ...}, ...], ...}
   1388     // rather than:
   1389     // {layout_rects: "[{geometry_rect: ...}, ...]", ...}
   1390     state->Set("layout_rects", json_reader.ReadToValue(str));
   1391   }
   1392 }
   1393 
   1394 size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
   1395 
   1396 scoped_ptr<base::Value> LayerImpl::AsValue() const {
   1397   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
   1398   AsValueInto(state.get());
   1399   return state.PassAs<base::Value>();
   1400 }
   1401 
   1402 void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
   1403   benchmark->RunOnLayer(this);
   1404 }
   1405 
   1406 }  // namespace cc
   1407