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