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