Home | History | Annotate | Download | only in compositor
      1 // Copyright (c) 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 "ui/compositor/layer.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/command_line.h"
     10 #include "base/debug/trace_event.h"
     11 #include "base/json/json_writer.h"
     12 #include "base/logging.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "cc/base/scoped_ptr_algorithm.h"
     15 #include "cc/layers/content_layer.h"
     16 #include "cc/layers/delegated_renderer_layer.h"
     17 #include "cc/layers/picture_layer.h"
     18 #include "cc/layers/solid_color_layer.h"
     19 #include "cc/layers/texture_layer.h"
     20 #include "cc/output/copy_output_request.h"
     21 #include "cc/output/delegated_frame_data.h"
     22 #include "cc/output/filter_operation.h"
     23 #include "cc/output/filter_operations.h"
     24 #include "cc/resources/transferable_resource.h"
     25 #include "ui/compositor/compositor_switches.h"
     26 #include "ui/compositor/dip_util.h"
     27 #include "ui/compositor/layer_animator.h"
     28 #include "ui/gfx/animation/animation.h"
     29 #include "ui/gfx/canvas.h"
     30 #include "ui/gfx/display.h"
     31 #include "ui/gfx/interpolated_transform.h"
     32 #include "ui/gfx/point3_f.h"
     33 #include "ui/gfx/point_conversions.h"
     34 #include "ui/gfx/size_conversions.h"
     35 
     36 namespace {
     37 
     38 const ui::Layer* GetRoot(const ui::Layer* layer) {
     39   while (layer->parent())
     40     layer = layer->parent();
     41   return layer;
     42 }
     43 
     44 struct UIImplSidePaintingStatus {
     45   UIImplSidePaintingStatus()
     46       : enabled(ui::IsUIImplSidePaintingEnabled()) {
     47   }
     48   bool enabled;
     49 };
     50 base::LazyInstance<UIImplSidePaintingStatus> g_ui_impl_side_painting_status =
     51     LAZY_INSTANCE_INITIALIZER;
     52 
     53 }  // namespace
     54 
     55 namespace ui {
     56 
     57 Layer::Layer()
     58     : type_(LAYER_TEXTURED),
     59       compositor_(NULL),
     60       parent_(NULL),
     61       visible_(true),
     62       force_render_surface_(false),
     63       fills_bounds_opaquely_(true),
     64       fills_bounds_completely_(false),
     65       background_blur_radius_(0),
     66       layer_saturation_(0.0f),
     67       layer_brightness_(0.0f),
     68       layer_grayscale_(0.0f),
     69       layer_inverted_(false),
     70       layer_mask_(NULL),
     71       layer_mask_back_link_(NULL),
     72       zoom_(1),
     73       zoom_inset_(0),
     74       delegate_(NULL),
     75       owner_(NULL),
     76       cc_layer_(NULL),
     77       device_scale_factor_(1.0f) {
     78   CreateWebLayer();
     79 }
     80 
     81 Layer::Layer(LayerType type)
     82     : type_(type),
     83       compositor_(NULL),
     84       parent_(NULL),
     85       visible_(true),
     86       force_render_surface_(false),
     87       fills_bounds_opaquely_(true),
     88       fills_bounds_completely_(false),
     89       background_blur_radius_(0),
     90       layer_saturation_(0.0f),
     91       layer_brightness_(0.0f),
     92       layer_grayscale_(0.0f),
     93       layer_inverted_(false),
     94       layer_mask_(NULL),
     95       layer_mask_back_link_(NULL),
     96       zoom_(1),
     97       zoom_inset_(0),
     98       delegate_(NULL),
     99       owner_(NULL),
    100       cc_layer_(NULL),
    101       device_scale_factor_(1.0f) {
    102   CreateWebLayer();
    103 }
    104 
    105 Layer::~Layer() {
    106   // Destroying the animator may cause observers to use the layer (and
    107   // indirectly the WebLayer). Destroy the animator first so that the WebLayer
    108   // is still around.
    109   if (animator_.get())
    110     animator_->SetDelegate(NULL);
    111   animator_ = NULL;
    112   if (compositor_)
    113     compositor_->SetRootLayer(NULL);
    114   if (parent_)
    115     parent_->Remove(this);
    116   if (layer_mask_)
    117     SetMaskLayer(NULL);
    118   if (layer_mask_back_link_)
    119     layer_mask_back_link_->SetMaskLayer(NULL);
    120   for (size_t i = 0; i < children_.size(); ++i)
    121     children_[i]->parent_ = NULL;
    122   cc_layer_->RemoveLayerAnimationEventObserver(this);
    123   cc_layer_->RemoveFromParent();
    124 }
    125 
    126 // static
    127 bool Layer::UsingPictureLayer() {
    128   return g_ui_impl_side_painting_status.Get().enabled;
    129 }
    130 
    131 Compositor* Layer::GetCompositor() {
    132   return GetRoot(this)->compositor_;
    133 }
    134 
    135 float Layer::opacity() const {
    136   return cc_layer_->opacity();
    137 }
    138 
    139 void Layer::SetCompositor(Compositor* compositor) {
    140   // This function must only be called to set the compositor on the root layer,
    141   // or to reset it.
    142   DCHECK(!compositor || !compositor_);
    143   DCHECK(!compositor || compositor->root_layer() == this);
    144   DCHECK(!parent_);
    145   if (compositor_) {
    146     RemoveAnimatorsInTreeFromCollection(
    147         compositor_->layer_animator_collection());
    148   }
    149   compositor_ = compositor;
    150   if (compositor) {
    151     OnDeviceScaleFactorChanged(compositor->device_scale_factor());
    152     SendPendingThreadedAnimations();
    153     AddAnimatorsInTreeToCollection(compositor_->layer_animator_collection());
    154   }
    155 }
    156 
    157 void Layer::Add(Layer* child) {
    158   DCHECK(!child->compositor_);
    159   if (child->parent_)
    160     child->parent_->Remove(child);
    161   child->parent_ = this;
    162   children_.push_back(child);
    163   cc_layer_->AddChild(child->cc_layer_);
    164   child->OnDeviceScaleFactorChanged(device_scale_factor_);
    165   if (GetCompositor())
    166     child->SendPendingThreadedAnimations();
    167   LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
    168   if (collection)
    169     child->AddAnimatorsInTreeToCollection(collection);
    170 }
    171 
    172 void Layer::Remove(Layer* child) {
    173   // Current bounds are used to calculate offsets when layers are reparented.
    174   // Stop (and complete) an ongoing animation to update the bounds immediately.
    175   LayerAnimator* child_animator = child->animator_;
    176   if (child_animator)
    177     child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS);
    178   LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
    179   if (collection)
    180     child->RemoveAnimatorsInTreeFromCollection(collection);
    181 
    182   std::vector<Layer*>::iterator i =
    183       std::find(children_.begin(), children_.end(), child);
    184   DCHECK(i != children_.end());
    185   children_.erase(i);
    186   child->parent_ = NULL;
    187   child->cc_layer_->RemoveFromParent();
    188 }
    189 
    190 void Layer::StackAtTop(Layer* child) {
    191   if (children_.size() <= 1 || child == children_.back())
    192     return;  // Already in front.
    193   StackAbove(child, children_.back());
    194 }
    195 
    196 void Layer::StackAbove(Layer* child, Layer* other) {
    197   StackRelativeTo(child, other, true);
    198 }
    199 
    200 void Layer::StackAtBottom(Layer* child) {
    201   if (children_.size() <= 1 || child == children_.front())
    202     return;  // Already on bottom.
    203   StackBelow(child, children_.front());
    204 }
    205 
    206 void Layer::StackBelow(Layer* child, Layer* other) {
    207   StackRelativeTo(child, other, false);
    208 }
    209 
    210 bool Layer::Contains(const Layer* other) const {
    211   for (const Layer* parent = other; parent; parent = parent->parent()) {
    212     if (parent == this)
    213       return true;
    214   }
    215   return false;
    216 }
    217 
    218 void Layer::SetAnimator(LayerAnimator* animator) {
    219   if (animator)
    220     animator->SetDelegate(this);
    221   animator_ = animator;
    222 }
    223 
    224 LayerAnimator* Layer::GetAnimator() {
    225   if (!animator_.get())
    226     SetAnimator(LayerAnimator::CreateDefaultAnimator());
    227   return animator_.get();
    228 }
    229 
    230 void Layer::SetTransform(const gfx::Transform& transform) {
    231   GetAnimator()->SetTransform(transform);
    232 }
    233 
    234 gfx::Transform Layer::GetTargetTransform() const {
    235   if (animator_.get() && animator_->IsAnimatingProperty(
    236       LayerAnimationElement::TRANSFORM)) {
    237     return animator_->GetTargetTransform();
    238   }
    239   return transform();
    240 }
    241 
    242 void Layer::SetBounds(const gfx::Rect& bounds) {
    243   GetAnimator()->SetBounds(bounds);
    244 }
    245 
    246 void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF offset) {
    247   subpixel_position_offset_ = offset;
    248   RecomputePosition();
    249 }
    250 
    251 gfx::Rect Layer::GetTargetBounds() const {
    252   if (animator_.get() && animator_->IsAnimatingProperty(
    253       LayerAnimationElement::BOUNDS)) {
    254     return animator_->GetTargetBounds();
    255   }
    256   return bounds_;
    257 }
    258 
    259 void Layer::SetMasksToBounds(bool masks_to_bounds) {
    260   cc_layer_->SetMasksToBounds(masks_to_bounds);
    261 }
    262 
    263 bool Layer::GetMasksToBounds() const {
    264   return cc_layer_->masks_to_bounds();
    265 }
    266 
    267 void Layer::SetOpacity(float opacity) {
    268   GetAnimator()->SetOpacity(opacity);
    269 }
    270 
    271 float Layer::GetCombinedOpacity() const {
    272   float opacity = this->opacity();
    273   Layer* current = this->parent_;
    274   while (current) {
    275     opacity *= current->opacity();
    276     current = current->parent_;
    277   }
    278   return opacity;
    279 }
    280 
    281 void Layer::SetBackgroundBlur(int blur_radius) {
    282   background_blur_radius_ = blur_radius;
    283 
    284   SetLayerBackgroundFilters();
    285 }
    286 
    287 void Layer::SetLayerSaturation(float saturation) {
    288   layer_saturation_ = saturation;
    289   SetLayerFilters();
    290 }
    291 
    292 void Layer::SetLayerBrightness(float brightness) {
    293   GetAnimator()->SetBrightness(brightness);
    294 }
    295 
    296 float Layer::GetTargetBrightness() const {
    297   if (animator_.get() && animator_->IsAnimatingProperty(
    298       LayerAnimationElement::BRIGHTNESS)) {
    299     return animator_->GetTargetBrightness();
    300   }
    301   return layer_brightness();
    302 }
    303 
    304 void Layer::SetLayerGrayscale(float grayscale) {
    305   GetAnimator()->SetGrayscale(grayscale);
    306 }
    307 
    308 float Layer::GetTargetGrayscale() const {
    309   if (animator_.get() && animator_->IsAnimatingProperty(
    310       LayerAnimationElement::GRAYSCALE)) {
    311     return animator_->GetTargetGrayscale();
    312   }
    313   return layer_grayscale();
    314 }
    315 
    316 void Layer::SetLayerInverted(bool inverted) {
    317   layer_inverted_ = inverted;
    318   SetLayerFilters();
    319 }
    320 
    321 void Layer::SetMaskLayer(Layer* layer_mask) {
    322   // The provided mask should not have a layer mask itself.
    323   DCHECK(!layer_mask ||
    324          (!layer_mask->layer_mask_layer() &&
    325           layer_mask->children().empty() &&
    326           !layer_mask->layer_mask_back_link_));
    327   DCHECK(!layer_mask_back_link_);
    328   if (layer_mask_ == layer_mask)
    329     return;
    330   // We need to de-reference the currently linked object so that no problem
    331   // arises if the mask layer gets deleted before this object.
    332   if (layer_mask_)
    333     layer_mask_->layer_mask_back_link_ = NULL;
    334   layer_mask_ = layer_mask;
    335   cc_layer_->SetMaskLayer(
    336       layer_mask ? layer_mask->cc_layer() : NULL);
    337   // We need to reference the linked object so that it can properly break the
    338   // link to us when it gets deleted.
    339   if (layer_mask) {
    340     layer_mask->layer_mask_back_link_ = this;
    341     layer_mask->OnDeviceScaleFactorChanged(device_scale_factor_);
    342   }
    343 }
    344 
    345 void Layer::SetBackgroundZoom(float zoom, int inset) {
    346   zoom_ = zoom;
    347   zoom_inset_ = inset;
    348 
    349   SetLayerBackgroundFilters();
    350 }
    351 
    352 void Layer::SetAlphaShape(scoped_ptr<SkRegion> region) {
    353   alpha_shape_ = region.Pass();
    354 
    355   SetLayerFilters();
    356 }
    357 
    358 void Layer::SetLayerFilters() {
    359   cc::FilterOperations filters;
    360   if (layer_saturation_) {
    361     filters.Append(cc::FilterOperation::CreateSaturateFilter(
    362         layer_saturation_));
    363   }
    364   if (layer_grayscale_) {
    365     filters.Append(cc::FilterOperation::CreateGrayscaleFilter(
    366         layer_grayscale_));
    367   }
    368   if (layer_inverted_)
    369     filters.Append(cc::FilterOperation::CreateInvertFilter(1.0));
    370   // Brightness goes last, because the resulting colors neeed clamping, which
    371   // cause further color matrix filters to be applied separately. In this order,
    372   // they all can be combined in a single pass.
    373   if (layer_brightness_) {
    374     filters.Append(cc::FilterOperation::CreateSaturatingBrightnessFilter(
    375         layer_brightness_));
    376   }
    377   if (alpha_shape_) {
    378     filters.Append(cc::FilterOperation::CreateAlphaThresholdFilter(
    379             *alpha_shape_, 1.f, 0.f));
    380   }
    381 
    382   cc_layer_->SetFilters(filters);
    383 }
    384 
    385 void Layer::SetLayerBackgroundFilters() {
    386   cc::FilterOperations filters;
    387   if (zoom_ != 1)
    388     filters.Append(cc::FilterOperation::CreateZoomFilter(zoom_, zoom_inset_));
    389 
    390   if (background_blur_radius_) {
    391     filters.Append(cc::FilterOperation::CreateBlurFilter(
    392         background_blur_radius_));
    393   }
    394 
    395   cc_layer_->SetBackgroundFilters(filters);
    396 }
    397 
    398 float Layer::GetTargetOpacity() const {
    399   if (animator_.get() && animator_->IsAnimatingProperty(
    400       LayerAnimationElement::OPACITY))
    401     return animator_->GetTargetOpacity();
    402   return opacity();
    403 }
    404 
    405 void Layer::SetVisible(bool visible) {
    406   GetAnimator()->SetVisibility(visible);
    407 }
    408 
    409 bool Layer::GetTargetVisibility() const {
    410   if (animator_.get() && animator_->IsAnimatingProperty(
    411       LayerAnimationElement::VISIBILITY))
    412     return animator_->GetTargetVisibility();
    413   return visible_;
    414 }
    415 
    416 bool Layer::IsDrawn() const {
    417   const Layer* layer = this;
    418   while (layer && layer->visible_)
    419     layer = layer->parent_;
    420   return layer == NULL;
    421 }
    422 
    423 bool Layer::ShouldDraw() const {
    424   return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f;
    425 }
    426 
    427 // static
    428 void Layer::ConvertPointToLayer(const Layer* source,
    429                                 const Layer* target,
    430                                 gfx::Point* point) {
    431   if (source == target)
    432     return;
    433 
    434   const Layer* root_layer = GetRoot(source);
    435   CHECK_EQ(root_layer, GetRoot(target));
    436 
    437   if (source != root_layer)
    438     source->ConvertPointForAncestor(root_layer, point);
    439   if (target != root_layer)
    440     target->ConvertPointFromAncestor(root_layer, point);
    441 }
    442 
    443 bool Layer::GetTargetTransformRelativeTo(const Layer* ancestor,
    444                                          gfx::Transform* transform) const {
    445   const Layer* p = this;
    446   for (; p && p != ancestor; p = p->parent()) {
    447     gfx::Transform translation;
    448     translation.Translate(static_cast<float>(p->bounds().x()),
    449                           static_cast<float>(p->bounds().y()));
    450     // Use target transform so that result will be correct once animation is
    451     // finished.
    452     if (!p->GetTargetTransform().IsIdentity())
    453       transform->ConcatTransform(p->GetTargetTransform());
    454     transform->ConcatTransform(translation);
    455   }
    456   return p == ancestor;
    457 }
    458 
    459 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
    460   if (fills_bounds_opaquely_ == fills_bounds_opaquely)
    461     return;
    462 
    463   fills_bounds_opaquely_ = fills_bounds_opaquely;
    464 
    465   cc_layer_->SetContentsOpaque(fills_bounds_opaquely);
    466 }
    467 
    468 void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely) {
    469   fills_bounds_completely_ = fills_bounds_completely;
    470 }
    471 
    472 void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
    473   // Finish animations being handled by cc_layer_.
    474   if (animator_.get()) {
    475     animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
    476     animator_->StopAnimatingProperty(LayerAnimationElement::OPACITY);
    477   }
    478 
    479   if (texture_layer_.get())
    480     texture_layer_->ClearClient();
    481   // TODO(piman): delegated_renderer_layer_ cleanup.
    482 
    483   cc_layer_->RemoveAllChildren();
    484   if (cc_layer_->parent()) {
    485     cc_layer_->parent()->ReplaceChild(cc_layer_, new_layer);
    486   }
    487   cc_layer_->SetLayerClient(NULL);
    488   cc_layer_->RemoveLayerAnimationEventObserver(this);
    489   new_layer->SetOpacity(cc_layer_->opacity());
    490   new_layer->SetTransform(cc_layer_->transform());
    491   new_layer->SetPosition(cc_layer_->position());
    492 
    493   cc_layer_ = new_layer.get();
    494   content_layer_ = NULL;
    495   solid_color_layer_ = NULL;
    496   texture_layer_ = NULL;
    497   delegated_renderer_layer_ = NULL;
    498 
    499   cc_layer_->AddLayerAnimationEventObserver(this);
    500   for (size_t i = 0; i < children_.size(); ++i) {
    501     DCHECK(children_[i]->cc_layer_);
    502     cc_layer_->AddChild(children_[i]->cc_layer_);
    503   }
    504   cc_layer_->SetLayerClient(this);
    505   cc_layer_->SetTransformOrigin(gfx::Point3F());
    506   cc_layer_->SetContentsOpaque(fills_bounds_opaquely_);
    507   cc_layer_->SetForceRenderSurface(force_render_surface_);
    508   cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
    509   cc_layer_->SetHideLayerAndSubtree(!visible_);
    510 }
    511 
    512 void Layer::SwitchCCLayerForTest() {
    513   scoped_refptr<cc::Layer> new_layer;
    514   if (Layer::UsingPictureLayer())
    515     new_layer = cc::PictureLayer::Create(this);
    516   else
    517     new_layer = cc::ContentLayer::Create(this);
    518   SwitchToLayer(new_layer);
    519   content_layer_ = new_layer;
    520 }
    521 
    522 void Layer::SetTextureMailbox(
    523     const cc::TextureMailbox& mailbox,
    524     scoped_ptr<cc::SingleReleaseCallback> release_callback,
    525     gfx::Size texture_size_in_dip) {
    526   DCHECK_EQ(type_, LAYER_TEXTURED);
    527   DCHECK(!solid_color_layer_.get());
    528   DCHECK(mailbox.IsValid());
    529   DCHECK(release_callback);
    530   if (!texture_layer_) {
    531     scoped_refptr<cc::TextureLayer> new_layer =
    532         cc::TextureLayer::CreateForMailbox(this);
    533     new_layer->SetFlipped(true);
    534     SwitchToLayer(new_layer);
    535     texture_layer_ = new_layer;
    536   }
    537   if (mailbox_release_callback_)
    538     mailbox_release_callback_->Run(0, false);
    539   mailbox_release_callback_ = release_callback.Pass();
    540   mailbox_ = mailbox;
    541   SetTextureSize(texture_size_in_dip);
    542 }
    543 
    544 void Layer::SetTextureSize(gfx::Size texture_size_in_dip) {
    545   DCHECK(texture_layer_.get());
    546   if (frame_size_in_dip_ == texture_size_in_dip)
    547     return;
    548   frame_size_in_dip_ = texture_size_in_dip;
    549   RecomputeDrawsContentAndUVRect();
    550   texture_layer_->SetNeedsDisplay();
    551 }
    552 
    553 void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
    554                                     gfx::Size frame_size_in_dip) {
    555   DCHECK_EQ(type_, LAYER_TEXTURED);
    556 
    557   scoped_refptr<cc::DelegatedRendererLayer> new_layer =
    558       cc::DelegatedRendererLayer::Create(frame_provider);
    559   SwitchToLayer(new_layer);
    560   delegated_renderer_layer_ = new_layer;
    561 
    562   frame_size_in_dip_ = frame_size_in_dip;
    563   RecomputeDrawsContentAndUVRect();
    564 }
    565 
    566 void Layer::SetShowPaintedContent() {
    567   if (content_layer_.get())
    568     return;
    569 
    570   scoped_refptr<cc::Layer> new_layer;
    571   if (Layer::UsingPictureLayer())
    572     new_layer = cc::PictureLayer::Create(this);
    573   else
    574     new_layer = cc::ContentLayer::Create(this);
    575   SwitchToLayer(new_layer);
    576   content_layer_ = new_layer;
    577 
    578   mailbox_ = cc::TextureMailbox();
    579   if (mailbox_release_callback_) {
    580     mailbox_release_callback_->Run(0, false);
    581     mailbox_release_callback_.reset();
    582   }
    583   RecomputeDrawsContentAndUVRect();
    584 }
    585 
    586 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
    587 
    588 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
    589   if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !mailbox_.IsValid()))
    590     return false;
    591 
    592   damaged_region_.op(invalid_rect.x(),
    593                      invalid_rect.y(),
    594                      invalid_rect.right(),
    595                      invalid_rect.bottom(),
    596                      SkRegion::kUnion_Op);
    597   ScheduleDraw();
    598   return true;
    599 }
    600 
    601 void Layer::ScheduleDraw() {
    602   Compositor* compositor = GetCompositor();
    603   if (compositor)
    604     compositor->ScheduleDraw();
    605 }
    606 
    607 void Layer::SendDamagedRects() {
    608   if ((delegate_ || mailbox_.IsValid()) && !damaged_region_.isEmpty()) {
    609     for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) {
    610       const SkIRect& sk_damaged = iter.rect();
    611       gfx::Rect damaged(
    612           sk_damaged.x(),
    613           sk_damaged.y(),
    614           sk_damaged.width(),
    615           sk_damaged.height());
    616       cc_layer_->SetNeedsDisplayRect(damaged);
    617     }
    618     damaged_region_.setEmpty();
    619   }
    620   for (size_t i = 0; i < children_.size(); ++i)
    621     children_[i]->SendDamagedRects();
    622 }
    623 
    624 void Layer::CompleteAllAnimations() {
    625   std::vector<scoped_refptr<LayerAnimator> > animators;
    626   CollectAnimators(&animators);
    627   std::for_each(animators.begin(), animators.end(),
    628                 std::mem_fun(&LayerAnimator::StopAnimating));
    629 }
    630 
    631 void Layer::SuppressPaint() {
    632   if (!delegate_)
    633     return;
    634   delegate_ = NULL;
    635   for (size_t i = 0; i < children_.size(); ++i)
    636     children_[i]->SuppressPaint();
    637 }
    638 
    639 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) {
    640   if (device_scale_factor_ == device_scale_factor)
    641     return;
    642   if (animator_.get())
    643     animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
    644   device_scale_factor_ = device_scale_factor;
    645   RecomputeDrawsContentAndUVRect();
    646   RecomputePosition();
    647   SchedulePaint(gfx::Rect(bounds_.size()));
    648   if (delegate_)
    649     delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
    650   for (size_t i = 0; i < children_.size(); ++i)
    651     children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
    652   if (layer_mask_)
    653     layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor);
    654 }
    655 
    656 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
    657   cc_layer_->RequestCopyOfOutput(request.Pass());
    658 }
    659 
    660 void Layer::PaintContents(SkCanvas* sk_canvas,
    661                           const gfx::Rect& clip,
    662                           gfx::RectF* opaque,
    663                           ContentLayerClient::GraphicsContextStatus gc_status) {
    664   TRACE_EVENT0("ui", "Layer::PaintContents");
    665   scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
    666       sk_canvas, device_scale_factor_));
    667   if (delegate_)
    668     delegate_->OnPaintLayer(canvas.get());
    669 }
    670 
    671 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_; }
    672 
    673 bool Layer::PrepareTextureMailbox(
    674     cc::TextureMailbox* mailbox,
    675     scoped_ptr<cc::SingleReleaseCallback>* release_callback,
    676     bool use_shared_memory) {
    677   if (!mailbox_release_callback_)
    678     return false;
    679   *mailbox = mailbox_;
    680   *release_callback = mailbox_release_callback_.Pass();
    681   return true;
    682 }
    683 
    684 void Layer::SetForceRenderSurface(bool force) {
    685   if (force_render_surface_ == force)
    686     return;
    687 
    688   force_render_surface_ = force;
    689   cc_layer_->SetForceRenderSurface(force_render_surface_);
    690 }
    691 
    692 class LayerDebugInfo : public base::debug::ConvertableToTraceFormat {
    693  public:
    694   explicit LayerDebugInfo(std::string name) : name_(name) { }
    695   virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
    696     base::DictionaryValue dictionary;
    697     dictionary.SetString("layer_name", name_);
    698     base::JSONWriter::Write(&dictionary, out);
    699   }
    700 
    701  private:
    702   virtual ~LayerDebugInfo() { }
    703   std::string name_;
    704 };
    705 
    706 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
    707   return new LayerDebugInfo(name_);
    708 }
    709 
    710 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
    711   if (animator_.get())
    712     animator_->OnThreadedAnimationStarted(event);
    713 }
    714 
    715 void Layer::CollectAnimators(
    716     std::vector<scoped_refptr<LayerAnimator> >* animators) {
    717   if (IsAnimating())
    718     animators->push_back(animator_);
    719   std::for_each(children_.begin(), children_.end(),
    720                 std::bind2nd(std::mem_fun(&Layer::CollectAnimators),
    721                              animators));
    722 }
    723 
    724 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
    725   DCHECK_NE(child, other);
    726   DCHECK_EQ(this, child->parent());
    727   DCHECK_EQ(this, other->parent());
    728 
    729   const size_t child_i =
    730       std::find(children_.begin(), children_.end(), child) - children_.begin();
    731   const size_t other_i =
    732       std::find(children_.begin(), children_.end(), other) - children_.begin();
    733   if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
    734     return;
    735 
    736   const size_t dest_i =
    737       above ?
    738       (child_i < other_i ? other_i : other_i + 1) :
    739       (child_i < other_i ? other_i - 1 : other_i);
    740   children_.erase(children_.begin() + child_i);
    741   children_.insert(children_.begin() + dest_i, child);
    742 
    743   child->cc_layer_->RemoveFromParent();
    744   cc_layer_->InsertChild(child->cc_layer_, dest_i);
    745 }
    746 
    747 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
    748                                     gfx::Point* point) const {
    749   gfx::Transform transform;
    750   bool result = GetTargetTransformRelativeTo(ancestor, &transform);
    751   gfx::Point3F p(*point);
    752   transform.TransformPoint(&p);
    753   *point = gfx::ToFlooredPoint(p.AsPointF());
    754   return result;
    755 }
    756 
    757 bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
    758                                      gfx::Point* point) const {
    759   gfx::Transform transform;
    760   bool result = GetTargetTransformRelativeTo(ancestor, &transform);
    761   gfx::Point3F p(*point);
    762   transform.TransformPointReverse(&p);
    763   *point = gfx::ToFlooredPoint(p.AsPointF());
    764   return result;
    765 }
    766 
    767 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
    768   if (bounds == bounds_)
    769     return;
    770 
    771   base::Closure closure;
    772   if (delegate_)
    773     closure = delegate_->PrepareForLayerBoundsChange();
    774   bool was_move = bounds_.size() == bounds.size();
    775   bounds_ = bounds;
    776 
    777   RecomputeDrawsContentAndUVRect();
    778   RecomputePosition();
    779 
    780   if (!closure.is_null())
    781     closure.Run();
    782 
    783   if (was_move) {
    784     // Don't schedule a draw if we're invisible. We'll schedule one
    785     // automatically when we get visible.
    786     if (IsDrawn())
    787       ScheduleDraw();
    788   } else {
    789     // Always schedule a paint, even if we're invisible.
    790     SchedulePaint(gfx::Rect(bounds.size()));
    791   }
    792 }
    793 
    794 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
    795   cc_layer_->SetTransform(transform);
    796 }
    797 
    798 void Layer::SetOpacityFromAnimation(float opacity) {
    799   cc_layer_->SetOpacity(opacity);
    800   ScheduleDraw();
    801 }
    802 
    803 void Layer::SetVisibilityFromAnimation(bool visible) {
    804   if (visible_ == visible)
    805     return;
    806 
    807   visible_ = visible;
    808   cc_layer_->SetHideLayerAndSubtree(!visible_);
    809 }
    810 
    811 void Layer::SetBrightnessFromAnimation(float brightness) {
    812   layer_brightness_ = brightness;
    813   SetLayerFilters();
    814 }
    815 
    816 void Layer::SetGrayscaleFromAnimation(float grayscale) {
    817   layer_grayscale_ = grayscale;
    818   SetLayerFilters();
    819 }
    820 
    821 void Layer::SetColorFromAnimation(SkColor color) {
    822   DCHECK_EQ(type_, LAYER_SOLID_COLOR);
    823   solid_color_layer_->SetBackgroundColor(color);
    824   SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
    825 }
    826 
    827 void Layer::ScheduleDrawForAnimation() {
    828   ScheduleDraw();
    829 }
    830 
    831 const gfx::Rect& Layer::GetBoundsForAnimation() const {
    832   return bounds();
    833 }
    834 
    835 gfx::Transform Layer::GetTransformForAnimation() const {
    836   return transform();
    837 }
    838 
    839 float Layer::GetOpacityForAnimation() const {
    840   return opacity();
    841 }
    842 
    843 bool Layer::GetVisibilityForAnimation() const {
    844   return visible();
    845 }
    846 
    847 float Layer::GetBrightnessForAnimation() const {
    848   return layer_brightness();
    849 }
    850 
    851 float Layer::GetGrayscaleForAnimation() const {
    852   return layer_grayscale();
    853 }
    854 
    855 SkColor Layer::GetColorForAnimation() const {
    856   // WebColor is equivalent to SkColor, per WebColor.h.
    857   // The NULL check is here since this is invoked regardless of whether we have
    858   // been configured as LAYER_SOLID_COLOR.
    859   return solid_color_layer_.get() ?
    860       solid_color_layer_->background_color() : SK_ColorBLACK;
    861 }
    862 
    863 float Layer::GetDeviceScaleFactor() const {
    864   return device_scale_factor_;
    865 }
    866 
    867 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
    868   DCHECK(cc_layer_);
    869   // Until this layer has a compositor (and hence cc_layer_ has a
    870   // LayerTreeHost), addAnimation will fail.
    871   if (GetCompositor())
    872     cc_layer_->AddAnimation(animation.Pass());
    873   else
    874     pending_threaded_animations_.push_back(animation.Pass());
    875 }
    876 
    877 namespace{
    878 
    879 struct HasAnimationId {
    880   HasAnimationId(int id): id_(id) {
    881   }
    882 
    883   bool operator()(cc::Animation* animation) const {
    884     return animation->id() == id_;
    885   }
    886 
    887  private:
    888   int id_;
    889 };
    890 
    891 }
    892 
    893 void Layer::RemoveThreadedAnimation(int animation_id) {
    894   DCHECK(cc_layer_);
    895   if (pending_threaded_animations_.size() == 0) {
    896     cc_layer_->RemoveAnimation(animation_id);
    897     return;
    898   }
    899 
    900   pending_threaded_animations_.erase(
    901       cc::remove_if(&pending_threaded_animations_,
    902                     pending_threaded_animations_.begin(),
    903                     pending_threaded_animations_.end(),
    904                     HasAnimationId(animation_id)),
    905       pending_threaded_animations_.end());
    906 }
    907 
    908 LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() {
    909   Compositor* compositor = GetCompositor();
    910   return compositor ? compositor->layer_animator_collection() : NULL;
    911 }
    912 
    913 void Layer::SendPendingThreadedAnimations() {
    914   for (cc::ScopedPtrVector<cc::Animation>::iterator it =
    915            pending_threaded_animations_.begin();
    916        it != pending_threaded_animations_.end();
    917        ++it)
    918     cc_layer_->AddAnimation(pending_threaded_animations_.take(it));
    919 
    920   pending_threaded_animations_.clear();
    921 
    922   for (size_t i = 0; i < children_.size(); ++i)
    923     children_[i]->SendPendingThreadedAnimations();
    924 }
    925 
    926 void Layer::CreateWebLayer() {
    927   if (type_ == LAYER_SOLID_COLOR) {
    928     solid_color_layer_ = cc::SolidColorLayer::Create();
    929     cc_layer_ = solid_color_layer_.get();
    930   } else {
    931     if (Layer::UsingPictureLayer())
    932       content_layer_ = cc::PictureLayer::Create(this);
    933     else
    934       content_layer_ = cc::ContentLayer::Create(this);
    935     cc_layer_ = content_layer_.get();
    936   }
    937   cc_layer_->SetTransformOrigin(gfx::Point3F());
    938   cc_layer_->SetContentsOpaque(true);
    939   cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
    940   cc_layer_->AddLayerAnimationEventObserver(this);
    941   cc_layer_->SetLayerClient(this);
    942   RecomputePosition();
    943 }
    944 
    945 gfx::Transform Layer::transform() const {
    946   return cc_layer_->transform();
    947 }
    948 
    949 void Layer::RecomputeDrawsContentAndUVRect() {
    950   DCHECK(cc_layer_);
    951   gfx::Size size(bounds_.size());
    952   if (texture_layer_.get()) {
    953     size.SetToMin(frame_size_in_dip_);
    954     gfx::PointF uv_top_left(0.f, 0.f);
    955     gfx::PointF uv_bottom_right(
    956         static_cast<float>(size.width()) / frame_size_in_dip_.width(),
    957         static_cast<float>(size.height()) / frame_size_in_dip_.height());
    958     texture_layer_->SetUV(uv_top_left, uv_bottom_right);
    959   } else if (delegated_renderer_layer_.get()) {
    960     size.SetToMin(frame_size_in_dip_);
    961   }
    962   cc_layer_->SetBounds(size);
    963 }
    964 
    965 void Layer::RecomputePosition() {
    966   cc_layer_->SetPosition(bounds_.origin() + subpixel_position_offset_);
    967 }
    968 
    969 void Layer::AddAnimatorsInTreeToCollection(
    970     LayerAnimatorCollection* collection) {
    971   DCHECK(collection);
    972   if (IsAnimating())
    973     animator_->AddToCollection(collection);
    974   std::for_each(
    975       children_.begin(),
    976       children_.end(),
    977       std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection),
    978                    collection));
    979 }
    980 
    981 void Layer::RemoveAnimatorsInTreeFromCollection(
    982     LayerAnimatorCollection* collection) {
    983   DCHECK(collection);
    984   if (IsAnimating())
    985     animator_->RemoveFromCollection(collection);
    986   std::for_each(
    987       children_.begin(),
    988       children_.end(),
    989       std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection),
    990                    collection));
    991 }
    992 
    993 bool Layer::IsAnimating() const {
    994   return animator_ && animator_->is_animating();
    995 }
    996 
    997 }  // namespace ui
    998