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