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