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.
5 #include "ui/compositor/layer.h"
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"
40 const ui::Layer* GetRoot(const ui::Layer* layer) {
41 while (layer->parent())
42 layer = layer->parent();
46 struct UIImplSidePaintingStatus {
47 UIImplSidePaintingStatus()
48 : enabled(ui::IsUIImplSidePaintingEnabled()) {
52 base::LazyInstance<UIImplSidePaintingStatus> g_ui_impl_side_painting_status =
53 LAZY_INSTANCE_INITIALIZER;
60 : type_(LAYER_TEXTURED),
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),
73 layer_mask_back_link_(NULL),
79 device_scale_factor_(1.0f) {
83 Layer::Layer(LayerType type)
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),
97 layer_mask_back_link_(NULL),
103 device_scale_factor_(1.0f) {
108 // Destroying the animator may cause observers to use the layer (and
109 // indirectly the WebLayer). Destroy the animator first so that the WebLayer
112 animator_->SetDelegate(NULL);
115 compositor_->SetRootLayer(NULL);
117 parent_->Remove(this);
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();
129 bool Layer::UsingPictureLayer() {
130 return g_ui_impl_side_painting_status.Get().enabled;
133 const Compositor* Layer::GetCompositor() const {
134 return GetRoot(this)->compositor_;
137 float Layer::opacity() const {
138 return cc_layer_->opacity();
141 void Layer::SetCompositor(Compositor* compositor) {
142 // This function must only be called to set the compositor on the root layer,
144 DCHECK(!compositor || !compositor_);
145 DCHECK(!compositor || compositor->root_layer() == this);
148 RemoveAnimatorsInTreeFromCollection(
149 compositor_->layer_animator_collection());
151 compositor_ = compositor;
153 OnDeviceScaleFactorChanged(compositor->device_scale_factor());
154 SendPendingThreadedAnimations();
155 AddAnimatorsInTreeToCollection(compositor_->layer_animator_collection());
159 void Layer::Add(Layer* child) {
160 DCHECK(!child->compositor_);
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_);
168 child->SendPendingThreadedAnimations();
169 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
171 child->AddAnimatorsInTreeToCollection(collection);
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();
179 child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS);
180 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
182 child->RemoveAnimatorsInTreeFromCollection(collection);
184 std::vector<Layer*>::iterator i =
185 std::find(children_.begin(), children_.end(), child);
186 DCHECK(i != children_.end());
188 child->parent_ = NULL;
189 child->cc_layer_->RemoveFromParent();
192 void Layer::StackAtTop(Layer* child) {
193 if (children_.size() <= 1 || child == children_.back())
194 return; // Already in front.
195 StackAbove(child, children_.back());
198 void Layer::StackAbove(Layer* child, Layer* other) {
199 StackRelativeTo(child, other, true);
202 void Layer::StackAtBottom(Layer* child) {
203 if (children_.size() <= 1 || child == children_.front())
204 return; // Already on bottom.
205 StackBelow(child, children_.front());
208 void Layer::StackBelow(Layer* child, Layer* other) {
209 StackRelativeTo(child, other, false);
212 bool Layer::Contains(const Layer* other) const {
213 for (const Layer* parent = other; parent; parent = parent->parent()) {
220 void Layer::SetAnimator(LayerAnimator* animator) {
222 animator->SetDelegate(this);
223 animator_ = animator;
226 LayerAnimator* Layer::GetAnimator() {
227 if (!animator_.get())
228 SetAnimator(LayerAnimator::CreateDefaultAnimator());
229 return animator_.get();
232 void Layer::SetTransform(const gfx::Transform& transform) {
233 GetAnimator()->SetTransform(transform);
236 gfx::Transform Layer::GetTargetTransform() const {
237 if (animator_.get() && animator_->IsAnimatingProperty(
238 LayerAnimationElement::TRANSFORM)) {
239 return animator_->GetTargetTransform();
244 void Layer::SetBounds(const gfx::Rect& bounds) {
245 GetAnimator()->SetBounds(bounds);
248 void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF offset) {
249 subpixel_position_offset_ = offset;
253 gfx::Rect Layer::GetTargetBounds() const {
254 if (animator_.get() && animator_->IsAnimatingProperty(
255 LayerAnimationElement::BOUNDS)) {
256 return animator_->GetTargetBounds();
261 void Layer::SetMasksToBounds(bool masks_to_bounds) {
262 cc_layer_->SetMasksToBounds(masks_to_bounds);
265 bool Layer::GetMasksToBounds() const {
266 return cc_layer_->masks_to_bounds();
269 void Layer::SetOpacity(float opacity) {
270 GetAnimator()->SetOpacity(opacity);
273 float Layer::GetCombinedOpacity() const {
274 float opacity = this->opacity();
275 Layer* current = this->parent_;
277 opacity *= current->opacity();
278 current = current->parent_;
283 void Layer::SetBackgroundBlur(int blur_radius) {
284 background_blur_radius_ = blur_radius;
286 SetLayerBackgroundFilters();
289 void Layer::SetLayerSaturation(float saturation) {
290 layer_saturation_ = saturation;
294 void Layer::SetLayerBrightness(float brightness) {
295 GetAnimator()->SetBrightness(brightness);
298 float Layer::GetTargetBrightness() const {
299 if (animator_.get() && animator_->IsAnimatingProperty(
300 LayerAnimationElement::BRIGHTNESS)) {
301 return animator_->GetTargetBrightness();
303 return layer_brightness();
306 void Layer::SetLayerGrayscale(float grayscale) {
307 GetAnimator()->SetGrayscale(grayscale);
310 float Layer::GetTargetGrayscale() const {
311 if (animator_.get() && animator_->IsAnimatingProperty(
312 LayerAnimationElement::GRAYSCALE)) {
313 return animator_->GetTargetGrayscale();
315 return layer_grayscale();
318 void Layer::SetLayerInverted(bool inverted) {
319 layer_inverted_ = inverted;
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)
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.
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.
342 layer_mask->layer_mask_back_link_ = this;
343 layer_mask->OnDeviceScaleFactorChanged(device_scale_factor_);
347 void Layer::SetBackgroundZoom(float zoom, int inset) {
351 SetLayerBackgroundFilters();
354 void Layer::SetAlphaShape(scoped_ptr<SkRegion> region) {
355 alpha_shape_ = region.Pass();
360 void Layer::SetLayerFilters() {
361 cc::FilterOperations filters;
362 if (layer_saturation_) {
363 filters.Append(cc::FilterOperation::CreateSaturateFilter(
366 if (layer_grayscale_) {
367 filters.Append(cc::FilterOperation::CreateGrayscaleFilter(
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(
380 filters.Append(cc::FilterOperation::CreateAlphaThresholdFilter(
381 *alpha_shape_, 0.f, 0.f));
384 cc_layer_->SetFilters(filters);
387 void Layer::SetLayerBackgroundFilters() {
388 cc::FilterOperations filters;
390 filters.Append(cc::FilterOperation::CreateZoomFilter(zoom_, zoom_inset_));
392 if (background_blur_radius_) {
393 filters.Append(cc::FilterOperation::CreateBlurFilter(
394 background_blur_radius_));
397 cc_layer_->SetBackgroundFilters(filters);
400 float Layer::GetTargetOpacity() const {
401 if (animator_.get() && animator_->IsAnimatingProperty(
402 LayerAnimationElement::OPACITY))
403 return animator_->GetTargetOpacity();
407 void Layer::SetVisible(bool visible) {
408 GetAnimator()->SetVisibility(visible);
411 bool Layer::GetTargetVisibility() const {
412 if (animator_.get() && animator_->IsAnimatingProperty(
413 LayerAnimationElement::VISIBILITY))
414 return animator_->GetTargetVisibility();
418 bool Layer::IsDrawn() const {
419 const Layer* layer = this;
420 while (layer && layer->visible_)
421 layer = layer->parent_;
422 return layer == NULL;
425 bool Layer::ShouldDraw() const {
426 return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f;
430 void Layer::ConvertPointToLayer(const Layer* source,
433 if (source == target)
436 const Layer* root_layer = GetRoot(source);
437 CHECK_EQ(root_layer, GetRoot(target));
439 if (source != root_layer)
440 source->ConvertPointForAncestor(root_layer, point);
441 if (target != root_layer)
442 target->ConvertPointFromAncestor(root_layer, point);
445 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
454 if (!p->GetTargetTransform().IsIdentity())
455 transform->ConcatTransform(p->GetTargetTransform());
456 transform->ConcatTransform(translation);
458 return p == ancestor;
461 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
462 if (fills_bounds_opaquely_ == fills_bounds_opaquely)
465 fills_bounds_opaquely_ = fills_bounds_opaquely;
467 cc_layer_->SetContentsOpaque(fills_bounds_opaquely);
470 void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely) {
471 fills_bounds_completely_ = fills_bounds_completely;
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);
481 if (texture_layer_.get())
482 texture_layer_->ClearClient();
483 // TODO(piman): delegated_renderer_layer_ cleanup.
485 cc_layer_->RemoveAllChildren();
486 if (cc_layer_->parent()) {
487 cc_layer_->parent()->ReplaceChild(cc_layer_, new_layer);
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 new_layer->SetBackgroundColor(cc_layer_->background_color());
496 cc_layer_ = new_layer.get();
497 content_layer_ = NULL;
498 solid_color_layer_ = NULL;
499 texture_layer_ = NULL;
500 delegated_renderer_layer_ = NULL;
501 surface_layer_ = NULL;
503 cc_layer_->AddLayerAnimationEventObserver(this);
504 for (size_t i = 0; i < children_.size(); ++i) {
505 DCHECK(children_[i]->cc_layer_);
506 cc_layer_->AddChild(children_[i]->cc_layer_);
508 cc_layer_->SetLayerClient(this);
509 cc_layer_->SetTransformOrigin(gfx::Point3F());
510 cc_layer_->SetContentsOpaque(fills_bounds_opaquely_);
511 cc_layer_->SetForceRenderSurface(force_render_surface_);
512 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
513 cc_layer_->SetHideLayerAndSubtree(!visible_);
516 SetLayerBackgroundFilters();
519 void Layer::SwitchCCLayerForTest() {
520 scoped_refptr<cc::Layer> new_layer;
521 if (Layer::UsingPictureLayer())
522 new_layer = cc::PictureLayer::Create(this);
524 new_layer = cc::ContentLayer::Create(this);
525 SwitchToLayer(new_layer);
526 content_layer_ = new_layer;
529 void Layer::SetTextureMailbox(
530 const cc::TextureMailbox& mailbox,
531 scoped_ptr<cc::SingleReleaseCallback> release_callback,
532 gfx::Size texture_size_in_dip) {
533 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
534 DCHECK(mailbox.IsValid());
535 DCHECK(release_callback);
536 if (!texture_layer_.get()) {
537 scoped_refptr<cc::TextureLayer> new_layer =
538 cc::TextureLayer::CreateForMailbox(this);
539 new_layer->SetFlipped(true);
540 SwitchToLayer(new_layer);
541 texture_layer_ = new_layer;
543 if (mailbox_release_callback_)
544 mailbox_release_callback_->Run(0, false);
545 mailbox_release_callback_ = release_callback.Pass();
547 SetTextureSize(texture_size_in_dip);
550 void Layer::SetTextureSize(gfx::Size texture_size_in_dip) {
551 DCHECK(texture_layer_.get());
552 if (frame_size_in_dip_ == texture_size_in_dip)
554 frame_size_in_dip_ = texture_size_in_dip;
555 RecomputeDrawsContentAndUVRect();
556 texture_layer_->SetNeedsDisplay();
559 void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
560 gfx::Size frame_size_in_dip) {
561 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
563 scoped_refptr<cc::DelegatedRendererLayer> new_layer =
564 cc::DelegatedRendererLayer::Create(frame_provider);
565 SwitchToLayer(new_layer);
566 delegated_renderer_layer_ = new_layer;
568 frame_size_in_dip_ = frame_size_in_dip;
569 RecomputeDrawsContentAndUVRect();
572 void Layer::SetShowSurface(
573 cc::SurfaceId surface_id,
574 const cc::SurfaceLayer::SatisfyCallback& satisfy_callback,
575 const cc::SurfaceLayer::RequireCallback& require_callback,
576 gfx::Size surface_size,
577 gfx::Size frame_size_in_dip) {
578 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
580 scoped_refptr<cc::SurfaceLayer> new_layer =
581 cc::SurfaceLayer::Create(satisfy_callback, require_callback);
582 new_layer->SetSurfaceId(surface_id, surface_size);
583 SwitchToLayer(new_layer);
584 surface_layer_ = new_layer;
586 frame_size_in_dip_ = frame_size_in_dip;
587 RecomputeDrawsContentAndUVRect();
590 void Layer::SetShowSolidColorContent() {
591 DCHECK_EQ(type_, LAYER_SOLID_COLOR);
593 if (solid_color_layer_.get())
596 scoped_refptr<cc::SolidColorLayer> new_layer = cc::SolidColorLayer::Create();
597 SwitchToLayer(new_layer);
598 solid_color_layer_ = new_layer;
600 mailbox_ = cc::TextureMailbox();
601 if (mailbox_release_callback_) {
602 mailbox_release_callback_->Run(0, false);
603 mailbox_release_callback_.reset();
605 RecomputeDrawsContentAndUVRect();
608 void Layer::UpdateNinePatchLayerBitmap(const SkBitmap& bitmap) {
609 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
610 SkBitmap bitmap_copy;
611 if (bitmap.isImmutable()) {
612 bitmap_copy = bitmap;
614 // UIResourceBitmap requires an immutable copy of the input |bitmap|.
615 bitmap.copyTo(&bitmap_copy);
616 bitmap_copy.setImmutable();
618 nine_patch_layer_->SetBitmap(bitmap_copy);
621 void Layer::UpdateNinePatchLayerAperture(const gfx::Rect& aperture) {
622 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
623 nine_patch_layer_->SetAperture(aperture);
626 void Layer::UpdateNinePatchLayerBorder(const gfx::Rect& border) {
627 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
628 nine_patch_layer_->SetBorder(border);
631 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
633 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
634 if ((type_ == LAYER_SOLID_COLOR && !texture_layer_.get()) ||
635 type_ == LAYER_NINE_PATCH || (!delegate_ && !mailbox_.IsValid()))
638 damaged_region_.op(invalid_rect.x(),
640 invalid_rect.right(),
641 invalid_rect.bottom(),
642 SkRegion::kUnion_Op);
647 void Layer::ScheduleDraw() {
648 Compositor* compositor = GetCompositor();
650 compositor->ScheduleDraw();
653 void Layer::SendDamagedRects() {
654 if ((delegate_ || mailbox_.IsValid()) && !damaged_region_.isEmpty()) {
655 for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) {
656 const SkIRect& sk_damaged = iter.rect();
661 sk_damaged.height());
662 cc_layer_->SetNeedsDisplayRect(damaged);
664 damaged_region_.setEmpty();
666 for (size_t i = 0; i < children_.size(); ++i)
667 children_[i]->SendDamagedRects();
670 void Layer::CompleteAllAnimations() {
671 typedef std::vector<scoped_refptr<LayerAnimator> > LayerAnimatorVector;
672 LayerAnimatorVector animators;
673 CollectAnimators(&animators);
674 for (LayerAnimatorVector::const_iterator it = animators.begin();
675 it != animators.end();
677 (*it)->StopAnimating();
681 void Layer::SuppressPaint() {
685 for (size_t i = 0; i < children_.size(); ++i)
686 children_[i]->SuppressPaint();
689 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) {
690 if (device_scale_factor_ == device_scale_factor)
693 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
694 device_scale_factor_ = device_scale_factor;
695 RecomputeDrawsContentAndUVRect();
697 SchedulePaint(gfx::Rect(bounds_.size()));
699 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
700 for (size_t i = 0; i < children_.size(); ++i)
701 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
703 layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor);
706 void Layer::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) {
707 DCHECK(delegated_renderer_layer_.get() || surface_layer_.get());
710 delegate_->OnDelegatedFrameDamage(damage_rect_in_dip);
713 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
714 cc_layer_->RequestCopyOfOutput(request.Pass());
717 void Layer::PaintContents(SkCanvas* sk_canvas,
718 const gfx::Rect& clip,
719 ContentLayerClient::GraphicsContextStatus gc_status) {
720 TRACE_EVENT0("ui", "Layer::PaintContents");
721 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
722 sk_canvas, device_scale_factor_));
724 delegate_->OnPaintLayer(canvas.get());
727 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_; }
729 bool Layer::PrepareTextureMailbox(
730 cc::TextureMailbox* mailbox,
731 scoped_ptr<cc::SingleReleaseCallback>* release_callback,
732 bool use_shared_memory) {
733 if (!mailbox_release_callback_)
736 *release_callback = mailbox_release_callback_.Pass();
740 void Layer::SetForceRenderSurface(bool force) {
741 if (force_render_surface_ == force)
744 force_render_surface_ = force;
745 cc_layer_->SetForceRenderSurface(force_render_surface_);
748 class LayerDebugInfo : public base::debug::ConvertableToTraceFormat {
750 explicit LayerDebugInfo(std::string name) : name_(name) { }
751 void AppendAsTraceFormat(std::string* out) const override {
752 base::DictionaryValue dictionary;
753 dictionary.SetString("layer_name", name_);
754 base::JSONWriter::Write(&dictionary, out);
758 ~LayerDebugInfo() override {}
762 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
763 return new LayerDebugInfo(name_);
766 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
768 animator_->OnThreadedAnimationStarted(event);
771 void Layer::CollectAnimators(
772 std::vector<scoped_refptr<LayerAnimator> >* animators) {
774 animators->push_back(animator_);
775 std::for_each(children_.begin(), children_.end(),
776 std::bind2nd(std::mem_fun(&Layer::CollectAnimators),
780 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
781 DCHECK_NE(child, other);
782 DCHECK_EQ(this, child->parent());
783 DCHECK_EQ(this, other->parent());
785 const size_t child_i =
786 std::find(children_.begin(), children_.end(), child) - children_.begin();
787 const size_t other_i =
788 std::find(children_.begin(), children_.end(), other) - children_.begin();
789 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
792 const size_t dest_i =
794 (child_i < other_i ? other_i : other_i + 1) :
795 (child_i < other_i ? other_i - 1 : other_i);
796 children_.erase(children_.begin() + child_i);
797 children_.insert(children_.begin() + dest_i, child);
799 child->cc_layer_->RemoveFromParent();
800 cc_layer_->InsertChild(child->cc_layer_, dest_i);
803 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
804 gfx::Point* point) const {
805 gfx::Transform transform;
806 bool result = GetTargetTransformRelativeTo(ancestor, &transform);
807 gfx::Point3F p(*point);
808 transform.TransformPoint(&p);
809 *point = gfx::ToFlooredPoint(p.AsPointF());
813 bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
814 gfx::Point* point) const {
815 gfx::Transform transform;
816 bool result = GetTargetTransformRelativeTo(ancestor, &transform);
817 gfx::Point3F p(*point);
818 transform.TransformPointReverse(&p);
819 *point = gfx::ToFlooredPoint(p.AsPointF());
823 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
824 if (bounds == bounds_)
827 base::Closure closure;
829 closure = delegate_->PrepareForLayerBoundsChange();
830 bool was_move = bounds_.size() == bounds.size();
833 RecomputeDrawsContentAndUVRect();
836 if (!closure.is_null())
840 // Don't schedule a draw if we're invisible. We'll schedule one
841 // automatically when we get visible.
845 // Always schedule a paint, even if we're invisible.
846 SchedulePaint(gfx::Rect(bounds.size()));
850 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
851 cc_layer_->SetTransform(transform);
854 void Layer::SetOpacityFromAnimation(float opacity) {
855 cc_layer_->SetOpacity(opacity);
859 void Layer::SetVisibilityFromAnimation(bool visible) {
860 if (visible_ == visible)
864 cc_layer_->SetHideLayerAndSubtree(!visible_);
867 void Layer::SetBrightnessFromAnimation(float brightness) {
868 layer_brightness_ = brightness;
872 void Layer::SetGrayscaleFromAnimation(float grayscale) {
873 layer_grayscale_ = grayscale;
877 void Layer::SetColorFromAnimation(SkColor color) {
878 DCHECK_EQ(type_, LAYER_SOLID_COLOR);
879 cc_layer_->SetBackgroundColor(color);
880 SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
883 void Layer::ScheduleDrawForAnimation() {
887 const gfx::Rect& Layer::GetBoundsForAnimation() const {
891 gfx::Transform Layer::GetTransformForAnimation() const {
895 float Layer::GetOpacityForAnimation() const {
899 bool Layer::GetVisibilityForAnimation() const {
903 float Layer::GetBrightnessForAnimation() const {
904 return layer_brightness();
907 float Layer::GetGrayscaleForAnimation() const {
908 return layer_grayscale();
911 SkColor Layer::GetColorForAnimation() const {
912 // WebColor is equivalent to SkColor, per WebColor.h.
913 // The NULL check is here since this is invoked regardless of whether we have
914 // been configured as LAYER_SOLID_COLOR.
915 return solid_color_layer_.get() ?
916 solid_color_layer_->background_color() : SK_ColorBLACK;
919 float Layer::GetDeviceScaleFactor() const {
920 return device_scale_factor_;
923 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
925 // Until this layer has a compositor (and hence cc_layer_ has a
926 // LayerTreeHost), addAnimation will fail.
928 cc_layer_->AddAnimation(animation.Pass());
930 pending_threaded_animations_.push_back(animation.Pass());
935 struct HasAnimationId {
936 HasAnimationId(int id): id_(id) {
939 bool operator()(cc::Animation* animation) const {
940 return animation->id() == id_;
949 void Layer::RemoveThreadedAnimation(int animation_id) {
951 if (pending_threaded_animations_.size() == 0) {
952 cc_layer_->RemoveAnimation(animation_id);
956 pending_threaded_animations_.erase(
957 cc::remove_if(&pending_threaded_animations_,
958 pending_threaded_animations_.begin(),
959 pending_threaded_animations_.end(),
960 HasAnimationId(animation_id)),
961 pending_threaded_animations_.end());
964 LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() {
965 Compositor* compositor = GetCompositor();
966 return compositor ? compositor->layer_animator_collection() : NULL;
969 void Layer::SendPendingThreadedAnimations() {
970 for (cc::ScopedPtrVector<cc::Animation>::iterator it =
971 pending_threaded_animations_.begin();
972 it != pending_threaded_animations_.end();
974 cc_layer_->AddAnimation(pending_threaded_animations_.take(it));
976 pending_threaded_animations_.clear();
978 for (size_t i = 0; i < children_.size(); ++i)
979 children_[i]->SendPendingThreadedAnimations();
982 void Layer::CreateCcLayer() {
983 if (type_ == LAYER_SOLID_COLOR) {
984 solid_color_layer_ = cc::SolidColorLayer::Create();
985 cc_layer_ = solid_color_layer_.get();
986 } else if (type_ == LAYER_NINE_PATCH) {
987 nine_patch_layer_ = cc::NinePatchLayer::Create();
988 cc_layer_ = nine_patch_layer_.get();
990 if (Layer::UsingPictureLayer())
991 content_layer_ = cc::PictureLayer::Create(this);
993 content_layer_ = cc::ContentLayer::Create(this);
994 cc_layer_ = content_layer_.get();
996 cc_layer_->SetTransformOrigin(gfx::Point3F());
997 cc_layer_->SetContentsOpaque(true);
998 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
999 cc_layer_->AddLayerAnimationEventObserver(this);
1000 cc_layer_->SetLayerClient(this);
1001 RecomputePosition();
1004 gfx::Transform Layer::transform() const {
1005 return cc_layer_->transform();
1008 void Layer::RecomputeDrawsContentAndUVRect() {
1010 gfx::Size size(bounds_.size());
1011 if (texture_layer_.get()) {
1012 size.SetToMin(frame_size_in_dip_);
1013 gfx::PointF uv_top_left(0.f, 0.f);
1014 gfx::PointF uv_bottom_right(
1015 static_cast<float>(size.width()) / frame_size_in_dip_.width(),
1016 static_cast<float>(size.height()) / frame_size_in_dip_.height());
1017 texture_layer_->SetUV(uv_top_left, uv_bottom_right);
1018 } else if (delegated_renderer_layer_.get() || surface_layer_.get()) {
1019 size.SetToMin(frame_size_in_dip_);
1021 cc_layer_->SetBounds(size);
1024 void Layer::RecomputePosition() {
1025 cc_layer_->SetPosition(bounds_.origin() + subpixel_position_offset_);
1028 void Layer::AddAnimatorsInTreeToCollection(
1029 LayerAnimatorCollection* collection) {
1032 animator_->AddToCollection(collection);
1036 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection),
1040 void Layer::RemoveAnimatorsInTreeFromCollection(
1041 LayerAnimatorCollection* collection) {
1044 animator_->RemoveFromCollection(collection);
1048 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection),
1052 bool Layer::IsAnimating() const {
1053 return animator_.get() && animator_->is_animating();