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