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/base/animation/animation.h"
     24 #include "ui/compositor/compositor_switches.h"
     25 #include "ui/compositor/dip_util.h"
     26 #include "ui/compositor/layer_animator.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_->RemoveLayerAnimationEventObserver(this);
    448   new_layer->SetOpacity(cc_layer_->opacity());
    449   new_layer->SetTransform(cc_layer_->transform());
    450   new_layer->SetPosition(cc_layer_->position());
    451 
    452   cc_layer_ = new_layer.get();
    453   content_layer_ = NULL;
    454   solid_color_layer_ = NULL;
    455   texture_layer_ = NULL;
    456   delegated_renderer_layer_ = NULL;
    457 
    458   cc_layer_->AddLayerAnimationEventObserver(this);
    459   for (size_t i = 0; i < children_.size(); ++i) {
    460     DCHECK(children_[i]->cc_layer_);
    461     cc_layer_->AddChild(children_[i]->cc_layer_);
    462   }
    463   cc_layer_->SetAnchorPoint(gfx::PointF());
    464   cc_layer_->SetContentsOpaque(fills_bounds_opaquely_);
    465   cc_layer_->SetForceRenderSurface(force_render_surface_);
    466   cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
    467   cc_layer_->SetHideLayerAndSubtree(!visible_);
    468 }
    469 
    470 void Layer::SwitchCCLayerForTest() {
    471   scoped_refptr<cc::ContentLayer> new_layer = cc::ContentLayer::Create(this);
    472   SwitchToLayer(new_layer);
    473   content_layer_ = new_layer;
    474 }
    475 
    476 void Layer::SetExternalTexture(Texture* texture) {
    477   // Hold a ref to the old |Texture| until we have updated all
    478   // compositor references to the texture id that it holds.
    479   scoped_refptr<ui::Texture> old_texture = texture_;
    480 
    481   DCHECK_EQ(type_, LAYER_TEXTURED);
    482   DCHECK(!solid_color_layer_.get());
    483   bool has_texture = !!texture;
    484   layer_updated_externally_ = has_texture;
    485   texture_ = texture;
    486   if (!!texture_layer_.get() != has_texture) {
    487     // Switch to a different type of layer.
    488     if (has_texture) {
    489       scoped_refptr<cc::TextureLayer> new_layer =
    490           cc::TextureLayer::Create(this);
    491       new_layer->SetFlipped(texture_->flipped());
    492       SwitchToLayer(new_layer);
    493       texture_layer_ = new_layer;
    494     } else {
    495       scoped_refptr<cc::ContentLayer> new_layer =
    496           cc::ContentLayer::Create(this);
    497       SwitchToLayer(new_layer);
    498       content_layer_ = new_layer;
    499     }
    500   }
    501   RecomputeDrawsContentAndUVRect();
    502 }
    503 
    504 void Layer::SetTextureMailbox(const cc::TextureMailbox& mailbox,
    505                               float scale_factor) {
    506   DCHECK_EQ(type_, LAYER_TEXTURED);
    507   DCHECK(!solid_color_layer_.get());
    508   layer_updated_externally_ = true;
    509   texture_ = NULL;
    510   if (!texture_layer_.get() || !texture_layer_->uses_mailbox()) {
    511     scoped_refptr<cc::TextureLayer> new_layer =
    512         cc::TextureLayer::CreateForMailbox(this);
    513     new_layer->SetFlipped(false);
    514     SwitchToLayer(new_layer);
    515     texture_layer_ = new_layer;
    516   }
    517   texture_layer_->SetTextureMailbox(mailbox);
    518   mailbox_ = mailbox;
    519   mailbox_scale_factor_ = scale_factor;
    520   RecomputeDrawsContentAndUVRect();
    521 }
    522 
    523 cc::TextureMailbox Layer::GetTextureMailbox(float* scale_factor) {
    524   if (scale_factor)
    525     *scale_factor = mailbox_scale_factor_;
    526   cc::TextureMailbox::ReleaseCallback callback;
    527   return mailbox_.CopyWithNewCallback(callback);
    528 }
    529 
    530 void Layer::SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame,
    531                               gfx::Size frame_size_in_dip) {
    532   DCHECK_EQ(type_, LAYER_TEXTURED);
    533   bool has_frame = frame.get() && !frame->render_pass_list.empty();
    534   layer_updated_externally_ = has_frame;
    535   delegated_frame_size_in_dip_ = frame_size_in_dip;
    536   if (!!delegated_renderer_layer_.get() != has_frame) {
    537     if (has_frame) {
    538       scoped_refptr<cc::DelegatedRendererLayer> new_layer =
    539           cc::DelegatedRendererLayer::Create(NULL);
    540       SwitchToLayer(new_layer);
    541       delegated_renderer_layer_ = new_layer;
    542     } else {
    543       scoped_refptr<cc::ContentLayer> new_layer =
    544           cc::ContentLayer::Create(this);
    545       SwitchToLayer(new_layer);
    546       content_layer_ = new_layer;
    547     }
    548   }
    549   if (has_frame)
    550     delegated_renderer_layer_->SetFrameData(frame.Pass());
    551   RecomputeDrawsContentAndUVRect();
    552 }
    553 
    554 void Layer::TakeUnusedResourcesForChildCompositor(
    555     cc::TransferableResourceArray* list) {
    556   if (delegated_renderer_layer_.get())
    557     delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor(list);
    558 }
    559 
    560 void Layer::SetColor(SkColor color) {
    561   GetAnimator()->SetColor(color);
    562 }
    563 
    564 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
    565   if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !texture_.get()))
    566     return false;
    567 
    568   damaged_region_.op(invalid_rect.x(),
    569                      invalid_rect.y(),
    570                      invalid_rect.right(),
    571                      invalid_rect.bottom(),
    572                      SkRegion::kUnion_Op);
    573   ScheduleDraw();
    574   return true;
    575 }
    576 
    577 void Layer::ScheduleDraw() {
    578   Compositor* compositor = GetCompositor();
    579   if (compositor)
    580     compositor->ScheduleDraw();
    581 }
    582 
    583 void Layer::SendDamagedRects() {
    584   if ((delegate_ || texture_.get()) && !damaged_region_.isEmpty()) {
    585     for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) {
    586       const SkIRect& sk_damaged = iter.rect();
    587       gfx::Rect damaged(
    588           sk_damaged.x(),
    589           sk_damaged.y(),
    590           sk_damaged.width(),
    591           sk_damaged.height());
    592 
    593       gfx::Rect damaged_in_pixel = ConvertRectToPixel(this, damaged);
    594       cc_layer_->SetNeedsDisplayRect(damaged_in_pixel);
    595     }
    596     damaged_region_.setEmpty();
    597   }
    598   for (size_t i = 0; i < children_.size(); ++i)
    599     children_[i]->SendDamagedRects();
    600 }
    601 
    602 void Layer::SuppressPaint() {
    603   if (!delegate_)
    604     return;
    605   delegate_ = NULL;
    606   for (size_t i = 0; i < children_.size(); ++i)
    607     children_[i]->SuppressPaint();
    608 }
    609 
    610 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) {
    611   if (device_scale_factor_ == device_scale_factor)
    612     return;
    613   if (animator_.get())
    614     animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
    615   gfx::Transform transform = this->transform();
    616   device_scale_factor_ = device_scale_factor;
    617   RecomputeCCTransformFromTransform(transform);
    618   RecomputeDrawsContentAndUVRect();
    619   RecomputePosition();
    620   SchedulePaint(gfx::Rect(bounds_.size()));
    621   if (delegate_)
    622     delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
    623   for (size_t i = 0; i < children_.size(); ++i)
    624     children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
    625   if (layer_mask_)
    626     layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor);
    627 }
    628 
    629 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
    630   cc_layer_->RequestCopyOfOutput(request.Pass());
    631 }
    632 
    633 void Layer::PaintContents(SkCanvas* sk_canvas,
    634                           gfx::Rect clip,
    635                           gfx::RectF* opaque) {
    636   TRACE_EVENT0("ui", "Layer::PaintContents");
    637   scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
    638       sk_canvas, ui::GetScaleFactorFromScale(device_scale_factor_)));
    639 
    640   bool scale_content = scale_content_;
    641   if (scale_content) {
    642     canvas->Save();
    643     canvas->sk_canvas()->scale(SkFloatToScalar(device_scale_factor_),
    644                                SkFloatToScalar(device_scale_factor_));
    645   }
    646 
    647   if (delegate_)
    648     delegate_->OnPaintLayer(canvas.get());
    649   if (scale_content)
    650     canvas->Restore();
    651 }
    652 
    653 unsigned Layer::PrepareTexture() {
    654   DCHECK(texture_layer_.get());
    655   return texture_->PrepareTexture();
    656 }
    657 
    658 WebKit::WebGraphicsContext3D* Layer::Context3d() {
    659   DCHECK(texture_layer_.get());
    660   if (texture_.get())
    661     return texture_->HostContext3D();
    662   return NULL;
    663 }
    664 
    665 bool Layer::PrepareTextureMailbox(cc::TextureMailbox* mailbox,
    666                                   bool use_shared_memory) {
    667   return false;
    668 }
    669 
    670 void Layer::SetForceRenderSurface(bool force) {
    671   if (force_render_surface_ == force)
    672     return;
    673 
    674   force_render_surface_ = force;
    675   cc_layer_->SetForceRenderSurface(force_render_surface_);
    676 }
    677 
    678 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
    679   if (animator_.get())
    680     animator_->OnThreadedAnimationStarted(event);
    681 }
    682 
    683 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
    684   DCHECK_NE(child, other);
    685   DCHECK_EQ(this, child->parent());
    686   DCHECK_EQ(this, other->parent());
    687 
    688   const size_t child_i =
    689       std::find(children_.begin(), children_.end(), child) - children_.begin();
    690   const size_t other_i =
    691       std::find(children_.begin(), children_.end(), other) - children_.begin();
    692   if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
    693     return;
    694 
    695   const size_t dest_i =
    696       above ?
    697       (child_i < other_i ? other_i : other_i + 1) :
    698       (child_i < other_i ? other_i - 1 : other_i);
    699   children_.erase(children_.begin() + child_i);
    700   children_.insert(children_.begin() + dest_i, child);
    701 
    702   child->cc_layer_->RemoveFromParent();
    703   cc_layer_->InsertChild(child->cc_layer_, dest_i);
    704 }
    705 
    706 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
    707                                     gfx::Point* point) const {
    708   gfx::Transform transform;
    709   bool result = GetTargetTransformRelativeTo(ancestor, &transform);
    710   gfx::Point3F p(*point);
    711   transform.TransformPoint(p);
    712   *point = gfx::ToFlooredPoint(p.AsPointF());
    713   return result;
    714 }
    715 
    716 bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
    717                                      gfx::Point* point) const {
    718   gfx::Transform transform;
    719   bool result = GetTargetTransformRelativeTo(ancestor, &transform);
    720   gfx::Point3F p(*point);
    721   transform.TransformPointReverse(p);
    722   *point = gfx::ToFlooredPoint(p.AsPointF());
    723   return result;
    724 }
    725 
    726 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) {
    727   if (bounds == bounds_)
    728     return;
    729 
    730   base::Closure closure;
    731   if (delegate_)
    732     closure = delegate_->PrepareForLayerBoundsChange();
    733   bool was_move = bounds_.size() == bounds.size();
    734   bounds_ = bounds;
    735 
    736   RecomputeDrawsContentAndUVRect();
    737   RecomputePosition();
    738 
    739   if (!closure.is_null())
    740     closure.Run();
    741 
    742   if (was_move) {
    743     // Don't schedule a draw if we're invisible. We'll schedule one
    744     // automatically when we get visible.
    745     if (IsDrawn())
    746       ScheduleDraw();
    747   } else {
    748     // Always schedule a paint, even if we're invisible.
    749     SchedulePaint(gfx::Rect(bounds.size()));
    750   }
    751 }
    752 
    753 void Layer::SetTransformImmediately(const gfx::Transform& transform) {
    754   RecomputeCCTransformFromTransform(transform);
    755 }
    756 
    757 void Layer::SetOpacityImmediately(float opacity) {
    758   cc_layer_->SetOpacity(opacity);
    759   ScheduleDraw();
    760 }
    761 
    762 void Layer::SetVisibilityImmediately(bool visible) {
    763   if (visible_ == visible)
    764     return;
    765 
    766   visible_ = visible;
    767   cc_layer_->SetHideLayerAndSubtree(!visible_);
    768 }
    769 
    770 void Layer::SetBrightnessImmediately(float brightness) {
    771   layer_brightness_ = brightness;
    772   SetLayerFilters();
    773 }
    774 
    775 void Layer::SetGrayscaleImmediately(float grayscale) {
    776   layer_grayscale_ = grayscale;
    777   SetLayerFilters();
    778 }
    779 
    780 void Layer::SetColorImmediately(SkColor color) {
    781   DCHECK_EQ(type_, LAYER_SOLID_COLOR);
    782   solid_color_layer_->SetBackgroundColor(color);
    783   SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
    784 }
    785 
    786 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
    787   SetBoundsImmediately(bounds);
    788 }
    789 
    790 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
    791   SetTransformImmediately(transform);
    792 }
    793 
    794 void Layer::SetOpacityFromAnimation(float opacity) {
    795   SetOpacityImmediately(opacity);
    796 }
    797 
    798 void Layer::SetVisibilityFromAnimation(bool visibility) {
    799   SetVisibilityImmediately(visibility);
    800 }
    801 
    802 void Layer::SetBrightnessFromAnimation(float brightness) {
    803   SetBrightnessImmediately(brightness);
    804 }
    805 
    806 void Layer::SetGrayscaleFromAnimation(float grayscale) {
    807   SetGrayscaleImmediately(grayscale);
    808 }
    809 
    810 void Layer::SetColorFromAnimation(SkColor color) {
    811   SetColorImmediately(color);
    812 }
    813 
    814 void Layer::ScheduleDrawForAnimation() {
    815   ScheduleDraw();
    816 }
    817 
    818 const gfx::Rect& Layer::GetBoundsForAnimation() const {
    819   return bounds();
    820 }
    821 
    822 gfx::Transform Layer::GetTransformForAnimation() const {
    823   return transform();
    824 }
    825 
    826 float Layer::GetOpacityForAnimation() const {
    827   return opacity();
    828 }
    829 
    830 bool Layer::GetVisibilityForAnimation() const {
    831   return visible();
    832 }
    833 
    834 float Layer::GetBrightnessForAnimation() const {
    835   return layer_brightness();
    836 }
    837 
    838 float Layer::GetGrayscaleForAnimation() const {
    839   return layer_grayscale();
    840 }
    841 
    842 SkColor Layer::GetColorForAnimation() const {
    843   // WebColor is equivalent to SkColor, per WebColor.h.
    844   // The NULL check is here since this is invoked regardless of whether we have
    845   // been configured as LAYER_SOLID_COLOR.
    846   return solid_color_layer_.get() ?
    847       solid_color_layer_->background_color() : SK_ColorBLACK;
    848 }
    849 
    850 float Layer::GetDeviceScaleFactor() const {
    851   return device_scale_factor_;
    852 }
    853 
    854 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
    855   DCHECK(cc_layer_);
    856   // Until this layer has a compositor (and hence cc_layer_ has a
    857   // LayerTreeHost), addAnimation will fail.
    858   if (GetCompositor())
    859     cc_layer_->AddAnimation(animation.Pass());
    860   else
    861     pending_threaded_animations_.push_back(animation.Pass());
    862 }
    863 
    864 namespace{
    865 
    866 struct HasAnimationId {
    867   HasAnimationId(int id): id_(id) {
    868   }
    869 
    870   bool operator()(cc::Animation* animation) const {
    871     return animation->id() == id_;
    872   }
    873 
    874  private:
    875   int id_;
    876 };
    877 
    878 }
    879 
    880 void Layer::RemoveThreadedAnimation(int animation_id) {
    881   DCHECK(cc_layer_);
    882   if (pending_threaded_animations_.size() == 0) {
    883     cc_layer_->RemoveAnimation(animation_id);
    884     return;
    885   }
    886 
    887   pending_threaded_animations_.erase(
    888       cc::remove_if(&pending_threaded_animations_,
    889                     pending_threaded_animations_.begin(),
    890                     pending_threaded_animations_.end(),
    891                     HasAnimationId(animation_id)),
    892       pending_threaded_animations_.end());
    893 }
    894 
    895 void Layer::SendPendingThreadedAnimations() {
    896   for (cc::ScopedPtrVector<cc::Animation>::iterator it =
    897            pending_threaded_animations_.begin();
    898        it != pending_threaded_animations_.end();
    899        ++it)
    900     cc_layer_->AddAnimation(pending_threaded_animations_.take(it));
    901 
    902   pending_threaded_animations_.clear();
    903 
    904   for (size_t i = 0; i < children_.size(); ++i)
    905     children_[i]->SendPendingThreadedAnimations();
    906 }
    907 
    908 void Layer::CreateWebLayer() {
    909   if (type_ == LAYER_SOLID_COLOR) {
    910     solid_color_layer_ = cc::SolidColorLayer::Create();
    911     cc_layer_ = solid_color_layer_.get();
    912   } else {
    913     content_layer_ = cc::ContentLayer::Create(this);
    914     cc_layer_ = content_layer_.get();
    915   }
    916   cc_layer_->SetAnchorPoint(gfx::PointF());
    917   cc_layer_->SetContentsOpaque(true);
    918   cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
    919   cc_layer_->AddLayerAnimationEventObserver(this);
    920   RecomputePosition();
    921 }
    922 
    923 void Layer::RecomputeCCTransformFromTransform(const gfx::Transform& transform) {
    924   cc_layer_->SetTransform(ConvertTransformToCCTransform(transform,
    925                                                         device_scale_factor_));
    926 }
    927 
    928 gfx::Transform Layer::transform() const {
    929   gfx::Transform transform;
    930   transform.Scale(1.0f / device_scale_factor_, 1.0f / device_scale_factor_);
    931   transform.PreconcatTransform(cc_layer_->transform());
    932   transform.Scale(device_scale_factor_, device_scale_factor_);
    933   return transform;
    934 }
    935 
    936 void Layer::RecomputeDrawsContentAndUVRect() {
    937   DCHECK(cc_layer_);
    938   gfx::Size size(bounds_.size());
    939   if (texture_layer_.get()) {
    940     gfx::Size texture_size;
    941     if (!texture_layer_->uses_mailbox()) {
    942       DCHECK(texture_.get());
    943       float texture_scale_factor = 1.0f / texture_->device_scale_factor();
    944       texture_size = gfx::ToFlooredSize(
    945           gfx::ScaleSize(texture_->size(), texture_scale_factor));
    946     } else {
    947       DCHECK(mailbox_.IsSharedMemory());
    948       float texture_scale_factor = 1.0f / mailbox_scale_factor_;
    949       texture_size = gfx::ToFlooredSize(
    950           gfx::ScaleSize(mailbox_.shared_memory_size(), texture_scale_factor));
    951     }
    952     size.SetToMin(texture_size);
    953 
    954     gfx::PointF uv_top_left(0.f, 0.f);
    955     gfx::PointF uv_bottom_right(
    956         static_cast<float>(size.width())/texture_size.width(),
    957         static_cast<float>(size.height())/texture_size.height());
    958     texture_layer_->SetUV(uv_top_left, uv_bottom_right);
    959   } else if (delegated_renderer_layer_.get()) {
    960     delegated_renderer_layer_->SetDisplaySize(
    961         ConvertSizeToPixel(this, delegated_frame_size_in_dip_));
    962     size.SetToMin(delegated_frame_size_in_dip_);
    963   }
    964   cc_layer_->SetBounds(ConvertSizeToPixel(this, size));
    965 }
    966 
    967 void Layer::RecomputePosition() {
    968   cc_layer_->SetPosition(gfx::ScalePoint(
    969         gfx::PointF(bounds_.x(), bounds_.y()),
    970         device_scale_factor_));
    971 }
    972 
    973 }  // namespace ui
    974