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