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
38namespace {
39
40const ui::Layer* GetRoot(const ui::Layer* layer) {
41  while (layer->parent())
42    layer = layer->parent();
43  return layer;
44}
45
46struct UIImplSidePaintingStatus {
47  UIImplSidePaintingStatus()
48      : enabled(ui::IsUIImplSidePaintingEnabled()) {
49  }
50  bool enabled;
51};
52base::LazyInstance<UIImplSidePaintingStatus> g_ui_impl_side_painting_status =
53    LAZY_INSTANCE_INITIALIZER;
54
55}  // namespace
56
57namespace ui {
58
59Layer::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
83Layer::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
107Layer::~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
129bool Layer::UsingPictureLayer() {
130  return g_ui_impl_side_painting_status.Get().enabled;
131}
132
133Compositor* Layer::GetCompositor() {
134  return GetRoot(this)->compositor_;
135}
136
137float Layer::opacity() const {
138  return cc_layer_->opacity();
139}
140
141void 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
159void 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
174void 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
192void Layer::StackAtTop(Layer* child) {
193  if (children_.size() <= 1 || child == children_.back())
194    return;  // Already in front.
195  StackAbove(child, children_.back());
196}
197
198void Layer::StackAbove(Layer* child, Layer* other) {
199  StackRelativeTo(child, other, true);
200}
201
202void Layer::StackAtBottom(Layer* child) {
203  if (children_.size() <= 1 || child == children_.front())
204    return;  // Already on bottom.
205  StackBelow(child, children_.front());
206}
207
208void Layer::StackBelow(Layer* child, Layer* other) {
209  StackRelativeTo(child, other, false);
210}
211
212bool 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
220void Layer::SetAnimator(LayerAnimator* animator) {
221  if (animator)
222    animator->SetDelegate(this);
223  animator_ = animator;
224}
225
226LayerAnimator* Layer::GetAnimator() {
227  if (!animator_.get())
228    SetAnimator(LayerAnimator::CreateDefaultAnimator());
229  return animator_.get();
230}
231
232void Layer::SetTransform(const gfx::Transform& transform) {
233  GetAnimator()->SetTransform(transform);
234}
235
236gfx::Transform Layer::GetTargetTransform() const {
237  if (animator_.get() && animator_->IsAnimatingProperty(
238      LayerAnimationElement::TRANSFORM)) {
239    return animator_->GetTargetTransform();
240  }
241  return transform();
242}
243
244void Layer::SetBounds(const gfx::Rect& bounds) {
245  GetAnimator()->SetBounds(bounds);
246}
247
248void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF offset) {
249  subpixel_position_offset_ = offset;
250  RecomputePosition();
251}
252
253gfx::Rect Layer::GetTargetBounds() const {
254  if (animator_.get() && animator_->IsAnimatingProperty(
255      LayerAnimationElement::BOUNDS)) {
256    return animator_->GetTargetBounds();
257  }
258  return bounds_;
259}
260
261void Layer::SetMasksToBounds(bool masks_to_bounds) {
262  cc_layer_->SetMasksToBounds(masks_to_bounds);
263}
264
265bool Layer::GetMasksToBounds() const {
266  return cc_layer_->masks_to_bounds();
267}
268
269void Layer::SetOpacity(float opacity) {
270  GetAnimator()->SetOpacity(opacity);
271}
272
273float 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
283void Layer::SetBackgroundBlur(int blur_radius) {
284  background_blur_radius_ = blur_radius;
285
286  SetLayerBackgroundFilters();
287}
288
289void Layer::SetLayerSaturation(float saturation) {
290  layer_saturation_ = saturation;
291  SetLayerFilters();
292}
293
294void Layer::SetLayerBrightness(float brightness) {
295  GetAnimator()->SetBrightness(brightness);
296}
297
298float Layer::GetTargetBrightness() const {
299  if (animator_.get() && animator_->IsAnimatingProperty(
300      LayerAnimationElement::BRIGHTNESS)) {
301    return animator_->GetTargetBrightness();
302  }
303  return layer_brightness();
304}
305
306void Layer::SetLayerGrayscale(float grayscale) {
307  GetAnimator()->SetGrayscale(grayscale);
308}
309
310float Layer::GetTargetGrayscale() const {
311  if (animator_.get() && animator_->IsAnimatingProperty(
312      LayerAnimationElement::GRAYSCALE)) {
313    return animator_->GetTargetGrayscale();
314  }
315  return layer_grayscale();
316}
317
318void Layer::SetLayerInverted(bool inverted) {
319  layer_inverted_ = inverted;
320  SetLayerFilters();
321}
322
323void 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
347void Layer::SetBackgroundZoom(float zoom, int inset) {
348  zoom_ = zoom;
349  zoom_inset_ = inset;
350
351  SetLayerBackgroundFilters();
352}
353
354void Layer::SetAlphaShape(scoped_ptr<SkRegion> region) {
355  alpha_shape_ = region.Pass();
356
357  SetLayerFilters();
358}
359
360void 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
387void 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
400float Layer::GetTargetOpacity() const {
401  if (animator_.get() && animator_->IsAnimatingProperty(
402      LayerAnimationElement::OPACITY))
403    return animator_->GetTargetOpacity();
404  return opacity();
405}
406
407void Layer::SetVisible(bool visible) {
408  GetAnimator()->SetVisibility(visible);
409}
410
411bool Layer::GetTargetVisibility() const {
412  if (animator_.get() && animator_->IsAnimatingProperty(
413      LayerAnimationElement::VISIBILITY))
414    return animator_->GetTargetVisibility();
415  return visible_;
416}
417
418bool Layer::IsDrawn() const {
419  const Layer* layer = this;
420  while (layer && layer->visible_)
421    layer = layer->parent_;
422  return layer == NULL;
423}
424
425bool Layer::ShouldDraw() const {
426  return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f;
427}
428
429// static
430void 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
445bool 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
461void 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
470void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely) {
471  fills_bounds_completely_ = fills_bounds_completely;
472}
473
474void 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
515void 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
525void 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
547void 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
556void 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
569void 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
581void 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
601void 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
614void Layer::UpdateNinePatchLayerAperture(const gfx::Rect& aperture) {
615  DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
616  nine_patch_layer_->SetAperture(aperture);
617}
618
619void Layer::UpdateNinePatchLayerBorder(const gfx::Rect& border) {
620  DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
621  nine_patch_layer_->SetBorder(border);
622}
623
624void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
625
626bool 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
641void Layer::ScheduleDraw() {
642  Compositor* compositor = GetCompositor();
643  if (compositor)
644    compositor->ScheduleDraw();
645}
646
647void 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
664void 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
675void 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
683void 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
700void 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
707void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
708  cc_layer_->RequestCopyOfOutput(request.Pass());
709}
710
711void 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
721bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_; }
722
723bool 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
734void 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
742class 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
756scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
757  return new LayerDebugInfo(name_);
758}
759
760void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
761  if (animator_.get())
762    animator_->OnThreadedAnimationStarted(event);
763}
764
765void 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
774void 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
797bool 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
807bool 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
817void 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
844void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
845  cc_layer_->SetTransform(transform);
846}
847
848void Layer::SetOpacityFromAnimation(float opacity) {
849  cc_layer_->SetOpacity(opacity);
850  ScheduleDraw();
851}
852
853void Layer::SetVisibilityFromAnimation(bool visible) {
854  if (visible_ == visible)
855    return;
856
857  visible_ = visible;
858  cc_layer_->SetHideLayerAndSubtree(!visible_);
859}
860
861void Layer::SetBrightnessFromAnimation(float brightness) {
862  layer_brightness_ = brightness;
863  SetLayerFilters();
864}
865
866void Layer::SetGrayscaleFromAnimation(float grayscale) {
867  layer_grayscale_ = grayscale;
868  SetLayerFilters();
869}
870
871void Layer::SetColorFromAnimation(SkColor color) {
872  DCHECK_EQ(type_, LAYER_SOLID_COLOR);
873  solid_color_layer_->SetBackgroundColor(color);
874  SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
875}
876
877void Layer::ScheduleDrawForAnimation() {
878  ScheduleDraw();
879}
880
881const gfx::Rect& Layer::GetBoundsForAnimation() const {
882  return bounds();
883}
884
885gfx::Transform Layer::GetTransformForAnimation() const {
886  return transform();
887}
888
889float Layer::GetOpacityForAnimation() const {
890  return opacity();
891}
892
893bool Layer::GetVisibilityForAnimation() const {
894  return visible();
895}
896
897float Layer::GetBrightnessForAnimation() const {
898  return layer_brightness();
899}
900
901float Layer::GetGrayscaleForAnimation() const {
902  return layer_grayscale();
903}
904
905SkColor 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
913float Layer::GetDeviceScaleFactor() const {
914  return device_scale_factor_;
915}
916
917void 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
927namespace{
928
929struct 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
943void 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
958LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() {
959  Compositor* compositor = GetCompositor();
960  return compositor ? compositor->layer_animator_collection() : NULL;
961}
962
963void 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
976void 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
998gfx::Transform Layer::transform() const {
999  return cc_layer_->transform();
1000}
1001
1002void 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
1018void Layer::RecomputePosition() {
1019  cc_layer_->SetPosition(bounds_.origin() + subpixel_position_offset_);
1020}
1021
1022void 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
1034void 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
1046bool Layer::IsAnimating() const {
1047  return animator_.get() && animator_->is_animating();
1048}
1049
1050}  // namespace ui
1051