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/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "cc/base/scoped_ptr_algorithm.h"
14 #include "cc/layers/content_layer.h"
15 #include "cc/layers/delegated_renderer_layer.h"
16 #include "cc/layers/solid_color_layer.h"
17 #include "cc/layers/texture_layer.h"
18 #include "cc/output/copy_output_request.h"
19 #include "cc/output/delegated_frame_data.h"
20 #include "cc/output/filter_operation.h"
21 #include "cc/output/filter_operations.h"
22 #include "cc/resources/transferable_resource.h"
23 #include "ui/compositor/compositor_switches.h"
24 #include "ui/compositor/dip_util.h"
25 #include "ui/compositor/layer_animator.h"
26 #include "ui/gfx/animation/animation.h"
27 #include "ui/gfx/canvas.h"
28 #include "ui/gfx/display.h"
29 #include "ui/gfx/interpolated_transform.h"
30 #include "ui/gfx/point3_f.h"
31 #include "ui/gfx/point_conversions.h"
32 #include "ui/gfx/size_conversions.h"
36 const ui::Layer* GetRoot(const ui::Layer* layer) {
37 while (layer->parent())
38 layer = layer->parent();
47 : type_(LAYER_TEXTURED),
51 force_render_surface_(false),
52 fills_bounds_opaquely_(true),
53 layer_updated_externally_(false),
54 background_blur_radius_(0),
55 layer_saturation_(0.0f),
56 layer_brightness_(0.0f),
57 layer_grayscale_(0.0f),
58 layer_inverted_(false),
60 layer_mask_back_link_(NULL),
66 device_scale_factor_(1.0f) {
70 Layer::Layer(LayerType type)
75 force_render_surface_(false),
76 fills_bounds_opaquely_(true),
77 layer_updated_externally_(false),
78 background_blur_radius_(0),
79 layer_saturation_(0.0f),
80 layer_brightness_(0.0f),
81 layer_grayscale_(0.0f),
82 layer_inverted_(false),
84 layer_mask_back_link_(NULL),
90 device_scale_factor_(1.0f) {
95 // Destroying the animator may cause observers to use the layer (and
96 // indirectly the WebLayer). Destroy the animator first so that the WebLayer
99 animator_->SetDelegate(NULL);
102 compositor_->SetRootLayer(NULL);
104 parent_->Remove(this);
107 if (layer_mask_back_link_)
108 layer_mask_back_link_->SetMaskLayer(NULL);
109 for (size_t i = 0; i < children_.size(); ++i)
110 children_[i]->parent_ = NULL;
111 cc_layer_->RemoveLayerAnimationEventObserver(this);
112 cc_layer_->RemoveFromParent();
115 Compositor* Layer::GetCompositor() {
116 return GetRoot(this)->compositor_;
119 float Layer::opacity() const {
120 return cc_layer_->opacity();
123 void Layer::SetCompositor(Compositor* compositor) {
124 // This function must only be called to set the compositor on the root layer,
126 DCHECK(!compositor || !compositor_);
127 DCHECK(!compositor || compositor->root_layer() == this);
129 compositor_ = compositor;
131 OnDeviceScaleFactorChanged(compositor->device_scale_factor());
132 SendPendingThreadedAnimations();
136 void Layer::Add(Layer* child) {
137 DCHECK(!child->compositor_);
139 child->parent_->Remove(child);
140 child->parent_ = this;
141 children_.push_back(child);
142 cc_layer_->AddChild(child->cc_layer_);
143 child->OnDeviceScaleFactorChanged(device_scale_factor_);
145 child->SendPendingThreadedAnimations();
148 void Layer::Remove(Layer* child) {
149 std::vector<Layer*>::iterator i =
150 std::find(children_.begin(), children_.end(), child);
151 DCHECK(i != children_.end());
153 child->parent_ = NULL;
154 child->cc_layer_->RemoveFromParent();
157 void Layer::StackAtTop(Layer* child) {
158 if (children_.size() <= 1 || child == children_.back())
159 return; // Already in front.
160 StackAbove(child, children_.back());
163 void Layer::StackAbove(Layer* child, Layer* other) {
164 StackRelativeTo(child, other, true);
167 void Layer::StackAtBottom(Layer* child) {
168 if (children_.size() <= 1 || child == children_.front())
169 return; // Already on bottom.
170 StackBelow(child, children_.front());
173 void Layer::StackBelow(Layer* child, Layer* other) {
174 StackRelativeTo(child, other, false);
177 bool Layer::Contains(const Layer* other) const {
178 for (const Layer* parent = other; parent; parent = parent->parent()) {
185 void Layer::SetAnimator(LayerAnimator* animator) {
187 animator->SetDelegate(this);
188 animator_ = animator;
191 LayerAnimator* Layer::GetAnimator() {
192 if (!animator_.get())
193 SetAnimator(LayerAnimator::CreateDefaultAnimator());
194 return animator_.get();
197 void Layer::SetTransform(const gfx::Transform& transform) {
198 GetAnimator()->SetTransform(transform);
201 gfx::Transform Layer::GetTargetTransform() const {
202 if (animator_.get() && animator_->IsAnimatingProperty(
203 LayerAnimationElement::TRANSFORM)) {
204 return animator_->GetTargetTransform();
209 void Layer::SetBounds(const gfx::Rect& bounds) {
210 GetAnimator()->SetBounds(bounds);
213 gfx::Rect Layer::GetTargetBounds() const {
214 if (animator_.get() && animator_->IsAnimatingProperty(
215 LayerAnimationElement::BOUNDS)) {
216 return animator_->GetTargetBounds();
221 void Layer::SetMasksToBounds(bool masks_to_bounds) {
222 cc_layer_->SetMasksToBounds(masks_to_bounds);
225 bool Layer::GetMasksToBounds() const {
226 return cc_layer_->masks_to_bounds();
229 void Layer::SetOpacity(float opacity) {
230 GetAnimator()->SetOpacity(opacity);
233 float Layer::GetCombinedOpacity() const {
234 float opacity = this->opacity();
235 Layer* current = this->parent_;
237 opacity *= current->opacity();
238 current = current->parent_;
243 void Layer::SetBackgroundBlur(int blur_radius) {
244 background_blur_radius_ = blur_radius;
246 SetLayerBackgroundFilters();
249 void Layer::SetLayerSaturation(float saturation) {
250 layer_saturation_ = saturation;
254 void Layer::SetLayerBrightness(float brightness) {
255 GetAnimator()->SetBrightness(brightness);
258 float Layer::GetTargetBrightness() const {
259 if (animator_.get() && animator_->IsAnimatingProperty(
260 LayerAnimationElement::BRIGHTNESS)) {
261 return animator_->GetTargetBrightness();
263 return layer_brightness();
266 void Layer::SetLayerGrayscale(float grayscale) {
267 GetAnimator()->SetGrayscale(grayscale);
270 float Layer::GetTargetGrayscale() const {
271 if (animator_.get() && animator_->IsAnimatingProperty(
272 LayerAnimationElement::GRAYSCALE)) {
273 return animator_->GetTargetGrayscale();
275 return layer_grayscale();
278 void Layer::SetLayerInverted(bool inverted) {
279 layer_inverted_ = inverted;
283 void Layer::SetMaskLayer(Layer* layer_mask) {
284 // The provided mask should not have a layer mask itself.
285 DCHECK(!layer_mask ||
286 (!layer_mask->layer_mask_layer() &&
287 layer_mask->children().empty() &&
288 !layer_mask->layer_mask_back_link_));
289 DCHECK(!layer_mask_back_link_);
290 if (layer_mask_ == layer_mask)
292 // We need to de-reference the currently linked object so that no problem
293 // arises if the mask layer gets deleted before this object.
295 layer_mask_->layer_mask_back_link_ = NULL;
296 layer_mask_ = layer_mask;
297 cc_layer_->SetMaskLayer(
298 layer_mask ? layer_mask->cc_layer() : NULL);
299 // We need to reference the linked object so that it can properly break the
300 // link to us when it gets deleted.
302 layer_mask->layer_mask_back_link_ = this;
303 layer_mask->OnDeviceScaleFactorChanged(device_scale_factor_);
307 void Layer::SetBackgroundZoom(float zoom, int inset) {
311 SetLayerBackgroundFilters();
314 void Layer::SetLayerFilters() {
315 cc::FilterOperations filters;
316 if (layer_saturation_) {
317 filters.Append(cc::FilterOperation::CreateSaturateFilter(
320 if (layer_grayscale_) {
321 filters.Append(cc::FilterOperation::CreateGrayscaleFilter(
325 filters.Append(cc::FilterOperation::CreateInvertFilter(1.0));
326 // Brightness goes last, because the resulting colors neeed clamping, which
327 // cause further color matrix filters to be applied separately. In this order,
328 // they all can be combined in a single pass.
329 if (layer_brightness_) {
330 filters.Append(cc::FilterOperation::CreateSaturatingBrightnessFilter(
334 cc_layer_->SetFilters(filters);
337 void Layer::SetLayerBackgroundFilters() {
338 cc::FilterOperations filters;
340 filters.Append(cc::FilterOperation::CreateZoomFilter(zoom_, zoom_inset_));
342 if (background_blur_radius_) {
343 filters.Append(cc::FilterOperation::CreateBlurFilter(
344 background_blur_radius_));
347 cc_layer_->SetBackgroundFilters(filters);
350 float Layer::GetTargetOpacity() const {
351 if (animator_.get() && animator_->IsAnimatingProperty(
352 LayerAnimationElement::OPACITY))
353 return animator_->GetTargetOpacity();
357 void Layer::SetVisible(bool visible) {
358 GetAnimator()->SetVisibility(visible);
361 bool Layer::GetTargetVisibility() const {
362 if (animator_.get() && animator_->IsAnimatingProperty(
363 LayerAnimationElement::VISIBILITY))
364 return animator_->GetTargetVisibility();
368 bool Layer::IsDrawn() const {
369 const Layer* layer = this;
370 while (layer && layer->visible_)
371 layer = layer->parent_;
372 return layer == NULL;
375 bool Layer::ShouldDraw() const {
376 return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f;
380 void Layer::ConvertPointToLayer(const Layer* source,
383 if (source == target)
386 const Layer* root_layer = GetRoot(source);
387 CHECK_EQ(root_layer, GetRoot(target));
389 if (source != root_layer)
390 source->ConvertPointForAncestor(root_layer, point);
391 if (target != root_layer)
392 target->ConvertPointFromAncestor(root_layer, point);
395 bool Layer::GetTargetTransformRelativeTo(const Layer* ancestor,
396 gfx::Transform* transform) const {
397 const Layer* p = this;
398 for (; p && p != ancestor; p = p->parent()) {
399 gfx::Transform translation;
400 translation.Translate(static_cast<float>(p->bounds().x()),
401 static_cast<float>(p->bounds().y()));
402 // Use target transform so that result will be correct once animation is
404 if (!p->GetTargetTransform().IsIdentity())
405 transform->ConcatTransform(p->GetTargetTransform());
406 transform->ConcatTransform(translation);
408 return p == ancestor;
412 gfx::Transform Layer::ConvertTransformToCCTransform(
413 const gfx::Transform& transform,
414 float device_scale_factor) {
415 gfx::Transform cc_transform;
416 cc_transform.Scale(device_scale_factor, device_scale_factor);
417 cc_transform.PreconcatTransform(transform);
418 cc_transform.Scale(1.0f / device_scale_factor, 1.0f / device_scale_factor);
422 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
423 if (fills_bounds_opaquely_ == fills_bounds_opaquely)
426 fills_bounds_opaquely_ = fills_bounds_opaquely;
428 cc_layer_->SetContentsOpaque(fills_bounds_opaquely);
431 void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
432 // Finish animations being handled by cc_layer_.
433 if (animator_.get()) {
434 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
435 animator_->StopAnimatingProperty(LayerAnimationElement::OPACITY);
438 if (texture_layer_.get())
439 texture_layer_->WillModifyTexture();
440 // TODO(piman): delegated_renderer_layer_ cleanup.
442 cc_layer_->RemoveAllChildren();
444 DCHECK(parent_->cc_layer_);
445 parent_->cc_layer_->ReplaceChild(cc_layer_, new_layer);
447 cc_layer_->SetLayerClient(NULL);
448 cc_layer_->RemoveLayerAnimationEventObserver(this);
449 new_layer->SetOpacity(cc_layer_->opacity());
450 new_layer->SetTransform(cc_layer_->transform());
451 new_layer->SetPosition(cc_layer_->position());
453 cc_layer_ = new_layer.get();
454 content_layer_ = NULL;
455 solid_color_layer_ = NULL;
456 texture_layer_ = NULL;
457 delegated_renderer_layer_ = NULL;
459 cc_layer_->AddLayerAnimationEventObserver(this);
460 for (size_t i = 0; i < children_.size(); ++i) {
461 DCHECK(children_[i]->cc_layer_);
462 cc_layer_->AddChild(children_[i]->cc_layer_);
464 cc_layer_->SetLayerClient(this);
465 cc_layer_->SetAnchorPoint(gfx::PointF());
466 cc_layer_->SetContentsOpaque(fills_bounds_opaquely_);
467 cc_layer_->SetForceRenderSurface(force_render_surface_);
468 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
469 cc_layer_->SetHideLayerAndSubtree(!visible_);
472 void Layer::SwitchCCLayerForTest() {
473 scoped_refptr<cc::ContentLayer> new_layer = cc::ContentLayer::Create(this);
474 SwitchToLayer(new_layer);
475 content_layer_ = new_layer;
478 void Layer::SetExternalTexture(Texture* texture) {
481 // Hold a ref to the old |Texture| until we have updated all
482 // compositor references to the texture id that it holds.
483 scoped_refptr<ui::Texture> old_texture = texture_;
485 DCHECK_EQ(type_, LAYER_TEXTURED);
486 DCHECK(!solid_color_layer_.get());
487 layer_updated_externally_ = true;
489 if (!texture_layer_.get()) {
490 scoped_refptr<cc::TextureLayer> new_layer = cc::TextureLayer::Create(this);
491 new_layer->SetFlipped(texture_->flipped());
492 SwitchToLayer(new_layer);
493 texture_layer_ = new_layer;
495 RecomputeDrawsContentAndUVRect();
498 void Layer::SetTextureMailbox(
499 const cc::TextureMailbox& mailbox,
500 scoped_ptr<cc::SingleReleaseCallback> release_callback,
501 float scale_factor) {
502 DCHECK_EQ(type_, LAYER_TEXTURED);
503 DCHECK(!solid_color_layer_.get());
504 layer_updated_externally_ = true;
506 if (!texture_layer_.get() || !texture_layer_->uses_mailbox()) {
507 scoped_refptr<cc::TextureLayer> new_layer =
508 cc::TextureLayer::CreateForMailbox(this);
509 new_layer->SetFlipped(false);
510 SwitchToLayer(new_layer);
511 texture_layer_ = new_layer;
513 texture_layer_->SetTextureMailbox(mailbox, release_callback.Pass());
515 mailbox_scale_factor_ = scale_factor;
516 RecomputeDrawsContentAndUVRect();
519 cc::TextureMailbox Layer::GetTextureMailbox(float* scale_factor) {
521 *scale_factor = mailbox_scale_factor_;
525 void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
526 gfx::Size frame_size_in_dip) {
527 DCHECK_EQ(type_, LAYER_TEXTURED);
529 scoped_refptr<cc::DelegatedRendererLayer> new_layer =
530 cc::DelegatedRendererLayer::Create(NULL, frame_provider);
531 SwitchToLayer(new_layer);
532 delegated_renderer_layer_ = new_layer;
533 layer_updated_externally_ = true;
535 delegated_frame_size_in_dip_ = frame_size_in_dip;
536 RecomputeDrawsContentAndUVRect();
539 void Layer::SetShowPaintedContent() {
540 if (content_layer_.get())
543 scoped_refptr<cc::ContentLayer> new_layer = cc::ContentLayer::Create(this);
544 SwitchToLayer(new_layer);
545 content_layer_ = new_layer;
547 layer_updated_externally_ = false;
548 mailbox_ = cc::TextureMailbox();
551 RecomputeDrawsContentAndUVRect();
554 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
556 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
557 if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !texture_.get()))
560 damaged_region_.op(invalid_rect.x(),
562 invalid_rect.right(),
563 invalid_rect.bottom(),
564 SkRegion::kUnion_Op);
569 void Layer::ScheduleDraw() {
570 Compositor* compositor = GetCompositor();
572 compositor->ScheduleDraw();
575 void Layer::SendDamagedRects() {
576 if ((delegate_ || texture_.get()) && !damaged_region_.isEmpty()) {
577 for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) {
578 const SkIRect& sk_damaged = iter.rect();
583 sk_damaged.height());
585 gfx::Rect damaged_in_pixel = ConvertRectToPixel(this, damaged);
586 cc_layer_->SetNeedsDisplayRect(damaged_in_pixel);
588 damaged_region_.setEmpty();
590 for (size_t i = 0; i < children_.size(); ++i)
591 children_[i]->SendDamagedRects();
594 void Layer::SuppressPaint() {
598 for (size_t i = 0; i < children_.size(); ++i)
599 children_[i]->SuppressPaint();
602 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) {
603 if (device_scale_factor_ == device_scale_factor)
606 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
607 gfx::Transform transform = this->transform();
608 device_scale_factor_ = device_scale_factor;
609 RecomputeCCTransformFromTransform(transform);
610 RecomputeDrawsContentAndUVRect();
612 SchedulePaint(gfx::Rect(bounds_.size()));
614 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
615 for (size_t i = 0; i < children_.size(); ++i)
616 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
618 layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor);
621 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
622 cc_layer_->RequestCopyOfOutput(request.Pass());
625 void Layer::PaintContents(SkCanvas* sk_canvas,
627 gfx::RectF* opaque) {
628 TRACE_EVENT0("ui", "Layer::PaintContents");
629 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
630 sk_canvas, device_scale_factor_));
632 bool scale_content = scale_content_;
635 canvas->sk_canvas()->scale(SkFloatToScalar(device_scale_factor_),
636 SkFloatToScalar(device_scale_factor_));
640 delegate_->OnPaintLayer(canvas.get());
645 unsigned Layer::PrepareTexture() {
646 DCHECK(texture_layer_.get());
647 return texture_->PrepareTexture();
650 WebKit::WebGraphicsContext3D* Layer::Context3d() {
651 DCHECK(texture_layer_.get());
653 return texture_->HostContext3D();
657 bool Layer::PrepareTextureMailbox(
658 cc::TextureMailbox* mailbox,
659 scoped_ptr<cc::SingleReleaseCallback>* release_callback,
660 bool use_shared_memory) {
664 void Layer::SetForceRenderSurface(bool force) {
665 if (force_render_surface_ == force)
668 force_render_surface_ = force;
669 cc_layer_->SetForceRenderSurface(force_render_surface_);
672 std::string Layer::DebugName() {
676 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
678 animator_->OnThreadedAnimationStarted(event);
681 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
682 DCHECK_NE(child, other);
683 DCHECK_EQ(this, child->parent());
684 DCHECK_EQ(this, other->parent());
686 const size_t child_i =
687 std::find(children_.begin(), children_.end(), child) - children_.begin();
688 const size_t other_i =
689 std::find(children_.begin(), children_.end(), other) - children_.begin();
690 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
693 const size_t dest_i =
695 (child_i < other_i ? other_i : other_i + 1) :
696 (child_i < other_i ? other_i - 1 : other_i);
697 children_.erase(children_.begin() + child_i);
698 children_.insert(children_.begin() + dest_i, child);
700 child->cc_layer_->RemoveFromParent();
701 cc_layer_->InsertChild(child->cc_layer_, dest_i);
704 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
705 gfx::Point* point) const {
706 gfx::Transform transform;
707 bool result = GetTargetTransformRelativeTo(ancestor, &transform);
708 gfx::Point3F p(*point);
709 transform.TransformPoint(&p);
710 *point = gfx::ToFlooredPoint(p.AsPointF());
714 bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
715 gfx::Point* point) const {
716 gfx::Transform transform;
717 bool result = GetTargetTransformRelativeTo(ancestor, &transform);
718 gfx::Point3F p(*point);
719 transform.TransformPointReverse(&p);
720 *point = gfx::ToFlooredPoint(p.AsPointF());
724 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) {
725 if (bounds == bounds_)
728 base::Closure closure;
730 closure = delegate_->PrepareForLayerBoundsChange();
731 bool was_move = bounds_.size() == bounds.size();
734 RecomputeDrawsContentAndUVRect();
737 if (!closure.is_null())
741 // Don't schedule a draw if we're invisible. We'll schedule one
742 // automatically when we get visible.
746 // Always schedule a paint, even if we're invisible.
747 SchedulePaint(gfx::Rect(bounds.size()));
751 void Layer::SetTransformImmediately(const gfx::Transform& transform) {
752 RecomputeCCTransformFromTransform(transform);
755 void Layer::SetOpacityImmediately(float opacity) {
756 cc_layer_->SetOpacity(opacity);
760 void Layer::SetVisibilityImmediately(bool visible) {
761 if (visible_ == visible)
765 cc_layer_->SetHideLayerAndSubtree(!visible_);
768 void Layer::SetBrightnessImmediately(float brightness) {
769 layer_brightness_ = brightness;
773 void Layer::SetGrayscaleImmediately(float grayscale) {
774 layer_grayscale_ = grayscale;
778 void Layer::SetColorImmediately(SkColor color) {
779 DCHECK_EQ(type_, LAYER_SOLID_COLOR);
780 solid_color_layer_->SetBackgroundColor(color);
781 SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
784 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
785 SetBoundsImmediately(bounds);
788 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
789 SetTransformImmediately(transform);
792 void Layer::SetOpacityFromAnimation(float opacity) {
793 SetOpacityImmediately(opacity);
796 void Layer::SetVisibilityFromAnimation(bool visibility) {
797 SetVisibilityImmediately(visibility);
800 void Layer::SetBrightnessFromAnimation(float brightness) {
801 SetBrightnessImmediately(brightness);
804 void Layer::SetGrayscaleFromAnimation(float grayscale) {
805 SetGrayscaleImmediately(grayscale);
808 void Layer::SetColorFromAnimation(SkColor color) {
809 SetColorImmediately(color);
812 void Layer::ScheduleDrawForAnimation() {
816 const gfx::Rect& Layer::GetBoundsForAnimation() const {
820 gfx::Transform Layer::GetTransformForAnimation() const {
824 float Layer::GetOpacityForAnimation() const {
828 bool Layer::GetVisibilityForAnimation() const {
832 float Layer::GetBrightnessForAnimation() const {
833 return layer_brightness();
836 float Layer::GetGrayscaleForAnimation() const {
837 return layer_grayscale();
840 SkColor Layer::GetColorForAnimation() const {
841 // WebColor is equivalent to SkColor, per WebColor.h.
842 // The NULL check is here since this is invoked regardless of whether we have
843 // been configured as LAYER_SOLID_COLOR.
844 return solid_color_layer_.get() ?
845 solid_color_layer_->background_color() : SK_ColorBLACK;
848 float Layer::GetDeviceScaleFactor() const {
849 return device_scale_factor_;
852 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
854 // Until this layer has a compositor (and hence cc_layer_ has a
855 // LayerTreeHost), addAnimation will fail.
857 cc_layer_->AddAnimation(animation.Pass());
859 pending_threaded_animations_.push_back(animation.Pass());
864 struct HasAnimationId {
865 HasAnimationId(int id): id_(id) {
868 bool operator()(cc::Animation* animation) const {
869 return animation->id() == id_;
878 void Layer::RemoveThreadedAnimation(int animation_id) {
880 if (pending_threaded_animations_.size() == 0) {
881 cc_layer_->RemoveAnimation(animation_id);
885 pending_threaded_animations_.erase(
886 cc::remove_if(&pending_threaded_animations_,
887 pending_threaded_animations_.begin(),
888 pending_threaded_animations_.end(),
889 HasAnimationId(animation_id)),
890 pending_threaded_animations_.end());
893 void Layer::SendPendingThreadedAnimations() {
894 for (cc::ScopedPtrVector<cc::Animation>::iterator it =
895 pending_threaded_animations_.begin();
896 it != pending_threaded_animations_.end();
898 cc_layer_->AddAnimation(pending_threaded_animations_.take(it));
900 pending_threaded_animations_.clear();
902 for (size_t i = 0; i < children_.size(); ++i)
903 children_[i]->SendPendingThreadedAnimations();
906 void Layer::CreateWebLayer() {
907 if (type_ == LAYER_SOLID_COLOR) {
908 solid_color_layer_ = cc::SolidColorLayer::Create();
909 cc_layer_ = solid_color_layer_.get();
911 content_layer_ = cc::ContentLayer::Create(this);
912 cc_layer_ = content_layer_.get();
914 cc_layer_->SetAnchorPoint(gfx::PointF());
915 cc_layer_->SetContentsOpaque(true);
916 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
917 cc_layer_->AddLayerAnimationEventObserver(this);
918 cc_layer_->SetLayerClient(this);
922 void Layer::RecomputeCCTransformFromTransform(const gfx::Transform& transform) {
923 cc_layer_->SetTransform(ConvertTransformToCCTransform(transform,
924 device_scale_factor_));
927 gfx::Transform Layer::transform() const {
928 gfx::Transform transform;
929 transform.Scale(1.0f / device_scale_factor_, 1.0f / device_scale_factor_);
930 transform.PreconcatTransform(cc_layer_->transform());
931 transform.Scale(device_scale_factor_, device_scale_factor_);
935 void Layer::RecomputeDrawsContentAndUVRect() {
937 gfx::Size size(bounds_.size());
938 if (texture_layer_.get()) {
939 gfx::Size texture_size;
940 if (!texture_layer_->uses_mailbox()) {
941 DCHECK(texture_.get());
942 float texture_scale_factor = 1.0f / texture_->device_scale_factor();
943 texture_size = gfx::ToFlooredSize(
944 gfx::ScaleSize(texture_->size(), texture_scale_factor));
946 DCHECK(mailbox_.IsSharedMemory());
947 float texture_scale_factor = 1.0f / mailbox_scale_factor_;
948 texture_size = gfx::ToFlooredSize(
949 gfx::ScaleSize(mailbox_.shared_memory_size(), texture_scale_factor));
951 size.SetToMin(texture_size);
953 gfx::PointF uv_top_left(0.f, 0.f);
954 gfx::PointF uv_bottom_right(
955 static_cast<float>(size.width())/texture_size.width(),
956 static_cast<float>(size.height())/texture_size.height());
957 texture_layer_->SetUV(uv_top_left, uv_bottom_right);
958 } else if (delegated_renderer_layer_.get()) {
959 delegated_renderer_layer_->SetDisplaySize(
960 ConvertSizeToPixel(this, delegated_frame_size_in_dip_));
961 size.SetToMin(delegated_frame_size_in_dip_);
963 cc_layer_->SetBounds(ConvertSizeToPixel(this, size));
966 void Layer::RecomputePosition() {
967 cc_layer_->SetPosition(gfx::ScalePoint(
968 gfx::PointF(bounds_.x(), bounds_.y()),
969 device_scale_factor_));