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