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/lazy_instance.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "cc/base/scoped_ptr_algorithm.h"
16 #include "cc/layers/content_layer.h"
17 #include "cc/layers/delegated_renderer_layer.h"
18 #include "cc/layers/nine_patch_layer.h"
19 #include "cc/layers/picture_layer.h"
20 #include "cc/layers/solid_color_layer.h"
21 #include "cc/layers/surface_layer.h"
22 #include "cc/layers/texture_layer.h"
23 #include "cc/output/copy_output_request.h"
24 #include "cc/output/delegated_frame_data.h"
25 #include "cc/output/filter_operation.h"
26 #include "cc/output/filter_operations.h"
27 #include "cc/resources/transferable_resource.h"
28 #include "ui/compositor/compositor_switches.h"
29 #include "ui/compositor/dip_util.h"
30 #include "ui/compositor/layer_animator.h"
31 #include "ui/gfx/animation/animation.h"
32 #include "ui/gfx/canvas.h"
33 #include "ui/gfx/display.h"
34 #include "ui/gfx/geometry/point3_f.h"
35 #include "ui/gfx/geometry/point_conversions.h"
36 #include "ui/gfx/geometry/size_conversions.h"
37 #include "ui/gfx/interpolated_transform.h"
41 const ui::Layer
* GetRoot(const ui::Layer
* layer
) {
42 while (layer
->parent())
43 layer
= layer
->parent();
47 struct UIImplSidePaintingStatus
{
48 UIImplSidePaintingStatus()
49 : enabled(ui::IsUIImplSidePaintingEnabled()) {
53 base::LazyInstance
<UIImplSidePaintingStatus
> g_ui_impl_side_painting_status
=
54 LAZY_INSTANCE_INITIALIZER
;
61 : type_(LAYER_TEXTURED
),
65 force_render_surface_(false),
66 fills_bounds_opaquely_(true),
67 fills_bounds_completely_(false),
68 background_blur_radius_(0),
69 layer_saturation_(0.0f
),
70 layer_brightness_(0.0f
),
71 layer_grayscale_(0.0f
),
72 layer_inverted_(false),
74 layer_mask_back_link_(NULL
),
80 device_scale_factor_(1.0f
) {
84 Layer::Layer(LayerType type
)
89 force_render_surface_(false),
90 fills_bounds_opaquely_(true),
91 fills_bounds_completely_(false),
92 background_blur_radius_(0),
93 layer_saturation_(0.0f
),
94 layer_brightness_(0.0f
),
95 layer_grayscale_(0.0f
),
96 layer_inverted_(false),
98 layer_mask_back_link_(NULL
),
104 device_scale_factor_(1.0f
) {
109 // Destroying the animator may cause observers to use the layer (and
110 // indirectly the WebLayer). Destroy the animator first so that the WebLayer
113 animator_
->SetDelegate(NULL
);
116 compositor_
->SetRootLayer(NULL
);
118 parent_
->Remove(this);
121 if (layer_mask_back_link_
)
122 layer_mask_back_link_
->SetMaskLayer(NULL
);
123 for (size_t i
= 0; i
< children_
.size(); ++i
)
124 children_
[i
]->parent_
= NULL
;
125 cc_layer_
->RemoveLayerAnimationEventObserver(this);
126 cc_layer_
->RemoveFromParent();
130 bool Layer::UsingPictureLayer() {
131 return g_ui_impl_side_painting_status
.Get().enabled
;
134 const Compositor
* Layer::GetCompositor() const {
135 return GetRoot(this)->compositor_
;
138 float Layer::opacity() const {
139 return cc_layer_
->opacity();
142 void Layer::SetCompositor(Compositor
* compositor
) {
143 // This function must only be called to set the compositor on the root layer,
145 DCHECK(!compositor
|| !compositor_
);
146 DCHECK(!compositor
|| compositor
->root_layer() == this);
149 RemoveAnimatorsInTreeFromCollection(
150 compositor_
->layer_animator_collection());
152 compositor_
= compositor
;
154 OnDeviceScaleFactorChanged(compositor
->device_scale_factor());
155 SendPendingThreadedAnimations();
156 AddAnimatorsInTreeToCollection(compositor_
->layer_animator_collection());
160 void Layer::Add(Layer
* child
) {
161 DCHECK(!child
->compositor_
);
163 child
->parent_
->Remove(child
);
164 child
->parent_
= this;
165 children_
.push_back(child
);
166 cc_layer_
->AddChild(child
->cc_layer_
);
167 child
->OnDeviceScaleFactorChanged(device_scale_factor_
);
169 child
->SendPendingThreadedAnimations();
170 LayerAnimatorCollection
* collection
= GetLayerAnimatorCollection();
172 child
->AddAnimatorsInTreeToCollection(collection
);
175 void Layer::Remove(Layer
* child
) {
176 // Current bounds are used to calculate offsets when layers are reparented.
177 // Stop (and complete) an ongoing animation to update the bounds immediately.
178 LayerAnimator
* child_animator
= child
->animator_
.get();
180 child_animator
->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS
);
181 LayerAnimatorCollection
* collection
= GetLayerAnimatorCollection();
183 child
->RemoveAnimatorsInTreeFromCollection(collection
);
185 std::vector
<Layer
*>::iterator i
=
186 std::find(children_
.begin(), children_
.end(), child
);
187 DCHECK(i
!= children_
.end());
189 child
->parent_
= NULL
;
190 child
->cc_layer_
->RemoveFromParent();
193 void Layer::StackAtTop(Layer
* child
) {
194 if (children_
.size() <= 1 || child
== children_
.back())
195 return; // Already in front.
196 StackAbove(child
, children_
.back());
199 void Layer::StackAbove(Layer
* child
, Layer
* other
) {
200 StackRelativeTo(child
, other
, true);
203 void Layer::StackAtBottom(Layer
* child
) {
204 if (children_
.size() <= 1 || child
== children_
.front())
205 return; // Already on bottom.
206 StackBelow(child
, children_
.front());
209 void Layer::StackBelow(Layer
* child
, Layer
* other
) {
210 StackRelativeTo(child
, other
, false);
213 bool Layer::Contains(const Layer
* other
) const {
214 for (const Layer
* parent
= other
; parent
; parent
= parent
->parent()) {
221 void Layer::SetAnimator(LayerAnimator
* animator
) {
223 animator
->SetDelegate(this);
224 animator_
= animator
;
227 LayerAnimator
* Layer::GetAnimator() {
228 if (!animator_
.get())
229 SetAnimator(LayerAnimator::CreateDefaultAnimator());
230 return animator_
.get();
233 void Layer::SetTransform(const gfx::Transform
& transform
) {
234 GetAnimator()->SetTransform(transform
);
237 gfx::Transform
Layer::GetTargetTransform() const {
238 if (animator_
.get() && animator_
->IsAnimatingProperty(
239 LayerAnimationElement::TRANSFORM
)) {
240 return animator_
->GetTargetTransform();
245 void Layer::SetBounds(const gfx::Rect
& bounds
) {
246 GetAnimator()->SetBounds(bounds
);
249 void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF offset
) {
250 subpixel_position_offset_
= offset
;
254 gfx::Rect
Layer::GetTargetBounds() const {
255 if (animator_
.get() && animator_
->IsAnimatingProperty(
256 LayerAnimationElement::BOUNDS
)) {
257 return animator_
->GetTargetBounds();
262 void Layer::SetMasksToBounds(bool masks_to_bounds
) {
263 cc_layer_
->SetMasksToBounds(masks_to_bounds
);
266 bool Layer::GetMasksToBounds() const {
267 return cc_layer_
->masks_to_bounds();
270 void Layer::SetOpacity(float opacity
) {
271 GetAnimator()->SetOpacity(opacity
);
274 float Layer::GetCombinedOpacity() const {
275 float opacity
= this->opacity();
276 Layer
* current
= this->parent_
;
278 opacity
*= current
->opacity();
279 current
= current
->parent_
;
284 void Layer::SetBackgroundBlur(int blur_radius
) {
285 background_blur_radius_
= blur_radius
;
287 SetLayerBackgroundFilters();
290 void Layer::SetLayerSaturation(float saturation
) {
291 layer_saturation_
= saturation
;
295 void Layer::SetLayerBrightness(float brightness
) {
296 GetAnimator()->SetBrightness(brightness
);
299 float Layer::GetTargetBrightness() const {
300 if (animator_
.get() && animator_
->IsAnimatingProperty(
301 LayerAnimationElement::BRIGHTNESS
)) {
302 return animator_
->GetTargetBrightness();
304 return layer_brightness();
307 void Layer::SetLayerGrayscale(float grayscale
) {
308 GetAnimator()->SetGrayscale(grayscale
);
311 float Layer::GetTargetGrayscale() const {
312 if (animator_
.get() && animator_
->IsAnimatingProperty(
313 LayerAnimationElement::GRAYSCALE
)) {
314 return animator_
->GetTargetGrayscale();
316 return layer_grayscale();
319 void Layer::SetLayerInverted(bool inverted
) {
320 layer_inverted_
= inverted
;
324 void Layer::SetMaskLayer(Layer
* layer_mask
) {
325 // The provided mask should not have a layer mask itself.
326 DCHECK(!layer_mask
||
327 (!layer_mask
->layer_mask_layer() &&
328 layer_mask
->children().empty() &&
329 !layer_mask
->layer_mask_back_link_
));
330 DCHECK(!layer_mask_back_link_
);
331 if (layer_mask_
== layer_mask
)
333 // We need to de-reference the currently linked object so that no problem
334 // arises if the mask layer gets deleted before this object.
336 layer_mask_
->layer_mask_back_link_
= NULL
;
337 layer_mask_
= layer_mask
;
338 cc_layer_
->SetMaskLayer(
339 layer_mask
? layer_mask
->cc_layer() : NULL
);
340 // We need to reference the linked object so that it can properly break the
341 // link to us when it gets deleted.
343 layer_mask
->layer_mask_back_link_
= this;
344 layer_mask
->OnDeviceScaleFactorChanged(device_scale_factor_
);
348 void Layer::SetBackgroundZoom(float zoom
, int inset
) {
352 SetLayerBackgroundFilters();
355 void Layer::SetAlphaShape(scoped_ptr
<SkRegion
> region
) {
356 alpha_shape_
= region
.Pass();
361 void Layer::SetLayerFilters() {
362 cc::FilterOperations filters
;
363 if (layer_saturation_
) {
364 filters
.Append(cc::FilterOperation::CreateSaturateFilter(
367 if (layer_grayscale_
) {
368 filters
.Append(cc::FilterOperation::CreateGrayscaleFilter(
372 filters
.Append(cc::FilterOperation::CreateInvertFilter(1.0));
373 // Brightness goes last, because the resulting colors neeed clamping, which
374 // cause further color matrix filters to be applied separately. In this order,
375 // they all can be combined in a single pass.
376 if (layer_brightness_
) {
377 filters
.Append(cc::FilterOperation::CreateSaturatingBrightnessFilter(
381 filters
.Append(cc::FilterOperation::CreateAlphaThresholdFilter(
382 *alpha_shape_
, 0.f
, 0.f
));
385 cc_layer_
->SetFilters(filters
);
388 void Layer::SetLayerBackgroundFilters() {
389 cc::FilterOperations filters
;
391 filters
.Append(cc::FilterOperation::CreateZoomFilter(zoom_
, zoom_inset_
));
393 if (background_blur_radius_
) {
394 filters
.Append(cc::FilterOperation::CreateBlurFilter(
395 background_blur_radius_
));
398 cc_layer_
->SetBackgroundFilters(filters
);
401 float Layer::GetTargetOpacity() const {
402 if (animator_
.get() && animator_
->IsAnimatingProperty(
403 LayerAnimationElement::OPACITY
))
404 return animator_
->GetTargetOpacity();
408 void Layer::SetVisible(bool visible
) {
409 GetAnimator()->SetVisibility(visible
);
412 bool Layer::GetTargetVisibility() const {
413 if (animator_
.get() && animator_
->IsAnimatingProperty(
414 LayerAnimationElement::VISIBILITY
))
415 return animator_
->GetTargetVisibility();
419 bool Layer::IsDrawn() const {
420 const Layer
* layer
= this;
421 while (layer
&& layer
->visible_
)
422 layer
= layer
->parent_
;
423 return layer
== NULL
;
426 bool Layer::ShouldDraw() const {
427 return type_
!= LAYER_NOT_DRAWN
&& GetCombinedOpacity() > 0.0f
;
431 void Layer::ConvertPointToLayer(const Layer
* source
,
434 if (source
== target
)
437 const Layer
* root_layer
= GetRoot(source
);
438 CHECK_EQ(root_layer
, GetRoot(target
));
440 if (source
!= root_layer
)
441 source
->ConvertPointForAncestor(root_layer
, point
);
442 if (target
!= root_layer
)
443 target
->ConvertPointFromAncestor(root_layer
, point
);
446 bool Layer::GetTargetTransformRelativeTo(const Layer
* ancestor
,
447 gfx::Transform
* transform
) const {
448 const Layer
* p
= this;
449 for (; p
&& p
!= ancestor
; p
= p
->parent()) {
450 gfx::Transform translation
;
451 translation
.Translate(static_cast<float>(p
->bounds().x()),
452 static_cast<float>(p
->bounds().y()));
453 // Use target transform so that result will be correct once animation is
455 if (!p
->GetTargetTransform().IsIdentity())
456 transform
->ConcatTransform(p
->GetTargetTransform());
457 transform
->ConcatTransform(translation
);
459 return p
== ancestor
;
462 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely
) {
463 if (fills_bounds_opaquely_
== fills_bounds_opaquely
)
466 fills_bounds_opaquely_
= fills_bounds_opaquely
;
468 cc_layer_
->SetContentsOpaque(fills_bounds_opaquely
);
471 void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely
) {
472 fills_bounds_completely_
= fills_bounds_completely
;
475 void Layer::SwitchToLayer(scoped_refptr
<cc::Layer
> new_layer
) {
476 // Finish animations being handled by cc_layer_.
477 if (animator_
.get()) {
478 animator_
->StopAnimatingProperty(LayerAnimationElement::TRANSFORM
);
479 animator_
->StopAnimatingProperty(LayerAnimationElement::OPACITY
);
482 if (texture_layer_
.get())
483 texture_layer_
->ClearClient();
484 // TODO(piman): delegated_renderer_layer_ cleanup.
486 cc_layer_
->RemoveAllChildren();
487 if (cc_layer_
->parent()) {
488 cc_layer_
->parent()->ReplaceChild(cc_layer_
, new_layer
);
490 cc_layer_
->SetLayerClient(NULL
);
491 cc_layer_
->RemoveLayerAnimationEventObserver(this);
492 new_layer
->SetOpacity(cc_layer_
->opacity());
493 new_layer
->SetTransform(cc_layer_
->transform());
494 new_layer
->SetPosition(cc_layer_
->position());
495 new_layer
->SetBackgroundColor(cc_layer_
->background_color());
497 cc_layer_
= new_layer
.get();
498 content_layer_
= NULL
;
499 solid_color_layer_
= NULL
;
500 texture_layer_
= NULL
;
501 delegated_renderer_layer_
= NULL
;
502 surface_layer_
= NULL
;
504 cc_layer_
->AddLayerAnimationEventObserver(this);
505 for (size_t i
= 0; i
< children_
.size(); ++i
) {
506 DCHECK(children_
[i
]->cc_layer_
);
507 cc_layer_
->AddChild(children_
[i
]->cc_layer_
);
509 cc_layer_
->SetLayerClient(this);
510 cc_layer_
->SetTransformOrigin(gfx::Point3F());
511 cc_layer_
->SetContentsOpaque(fills_bounds_opaquely_
);
512 cc_layer_
->SetForceRenderSurface(force_render_surface_
);
513 cc_layer_
->SetIsDrawable(type_
!= LAYER_NOT_DRAWN
);
514 cc_layer_
->SetHideLayerAndSubtree(!visible_
);
517 SetLayerBackgroundFilters();
520 void Layer::SwitchCCLayerForTest() {
521 scoped_refptr
<cc::Layer
> new_layer
;
522 if (Layer::UsingPictureLayer())
523 new_layer
= cc::PictureLayer::Create(this);
525 new_layer
= cc::ContentLayer::Create(this);
526 SwitchToLayer(new_layer
);
527 content_layer_
= new_layer
;
530 void Layer::SetTextureMailbox(
531 const cc::TextureMailbox
& mailbox
,
532 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
,
533 gfx::Size texture_size_in_dip
) {
534 DCHECK(type_
== LAYER_TEXTURED
|| type_
== LAYER_SOLID_COLOR
);
535 DCHECK(mailbox
.IsValid());
536 DCHECK(release_callback
);
537 if (!texture_layer_
.get()) {
538 scoped_refptr
<cc::TextureLayer
> new_layer
=
539 cc::TextureLayer::CreateForMailbox(this);
540 new_layer
->SetFlipped(true);
541 SwitchToLayer(new_layer
);
542 texture_layer_
= new_layer
;
544 if (mailbox_release_callback_
)
545 mailbox_release_callback_
->Run(0, false);
546 mailbox_release_callback_
= release_callback
.Pass();
548 SetTextureSize(texture_size_in_dip
);
551 void Layer::SetTextureSize(gfx::Size texture_size_in_dip
) {
552 DCHECK(texture_layer_
.get());
553 if (frame_size_in_dip_
== texture_size_in_dip
)
555 frame_size_in_dip_
= texture_size_in_dip
;
556 RecomputeDrawsContentAndUVRect();
557 texture_layer_
->SetNeedsDisplay();
560 void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider
* frame_provider
,
561 gfx::Size frame_size_in_dip
) {
562 DCHECK(type_
== LAYER_TEXTURED
|| type_
== LAYER_SOLID_COLOR
);
564 scoped_refptr
<cc::DelegatedRendererLayer
> new_layer
=
565 cc::DelegatedRendererLayer::Create(frame_provider
);
566 SwitchToLayer(new_layer
);
567 delegated_renderer_layer_
= new_layer
;
569 frame_size_in_dip_
= frame_size_in_dip
;
570 RecomputeDrawsContentAndUVRect();
573 void Layer::SetShowSurface(
574 cc::SurfaceId surface_id
,
575 const cc::SurfaceLayer::SatisfyCallback
& satisfy_callback
,
576 const cc::SurfaceLayer::RequireCallback
& require_callback
,
577 gfx::Size surface_size
,
579 gfx::Size frame_size_in_dip
) {
580 DCHECK(type_
== LAYER_TEXTURED
|| type_
== LAYER_SOLID_COLOR
);
582 scoped_refptr
<cc::SurfaceLayer
> new_layer
=
583 cc::SurfaceLayer::Create(satisfy_callback
, require_callback
);
584 new_layer
->SetSurfaceId(surface_id
, scale
, surface_size
);
585 SwitchToLayer(new_layer
);
586 surface_layer_
= new_layer
;
588 frame_size_in_dip_
= frame_size_in_dip
;
589 RecomputeDrawsContentAndUVRect();
592 void Layer::SetShowSolidColorContent() {
593 DCHECK_EQ(type_
, LAYER_SOLID_COLOR
);
595 if (solid_color_layer_
.get())
598 scoped_refptr
<cc::SolidColorLayer
> new_layer
= cc::SolidColorLayer::Create();
599 SwitchToLayer(new_layer
);
600 solid_color_layer_
= new_layer
;
602 mailbox_
= cc::TextureMailbox();
603 if (mailbox_release_callback_
) {
604 mailbox_release_callback_
->Run(0, false);
605 mailbox_release_callback_
.reset();
607 RecomputeDrawsContentAndUVRect();
610 void Layer::UpdateNinePatchLayerBitmap(const SkBitmap
& bitmap
) {
611 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
612 SkBitmap bitmap_copy
;
613 if (bitmap
.isImmutable()) {
614 bitmap_copy
= bitmap
;
616 // UIResourceBitmap requires an immutable copy of the input |bitmap|.
617 bitmap
.copyTo(&bitmap_copy
);
618 bitmap_copy
.setImmutable();
620 nine_patch_layer_
->SetBitmap(bitmap_copy
);
623 void Layer::UpdateNinePatchLayerAperture(const gfx::Rect
& aperture
) {
624 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
625 nine_patch_layer_
->SetAperture(aperture
);
628 void Layer::UpdateNinePatchLayerBorder(const gfx::Rect
& border
) {
629 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
630 nine_patch_layer_
->SetBorder(border
);
633 void Layer::SetColor(SkColor color
) { GetAnimator()->SetColor(color
); }
635 bool Layer::SchedulePaint(const gfx::Rect
& invalid_rect
) {
636 if ((type_
== LAYER_SOLID_COLOR
&& !texture_layer_
.get()) ||
637 type_
== LAYER_NINE_PATCH
|| (!delegate_
&& !mailbox_
.IsValid()))
640 damaged_region_
.op(invalid_rect
.x(),
642 invalid_rect
.right(),
643 invalid_rect
.bottom(),
644 SkRegion::kUnion_Op
);
649 void Layer::ScheduleDraw() {
650 Compositor
* compositor
= GetCompositor();
652 compositor
->ScheduleDraw();
655 void Layer::SendDamagedRects() {
656 if ((delegate_
|| mailbox_
.IsValid()) && !damaged_region_
.isEmpty()) {
657 for (SkRegion::Iterator
iter(damaged_region_
); !iter
.done(); iter
.next()) {
658 const SkIRect
& sk_damaged
= iter
.rect();
663 sk_damaged
.height());
664 cc_layer_
->SetNeedsDisplayRect(damaged
);
666 damaged_region_
.setEmpty();
668 for (size_t i
= 0; i
< children_
.size(); ++i
)
669 children_
[i
]->SendDamagedRects();
672 void Layer::CompleteAllAnimations() {
673 typedef std::vector
<scoped_refptr
<LayerAnimator
> > LayerAnimatorVector
;
674 LayerAnimatorVector animators
;
675 CollectAnimators(&animators
);
676 for (LayerAnimatorVector::const_iterator it
= animators
.begin();
677 it
!= animators
.end();
679 (*it
)->StopAnimating();
683 void Layer::SuppressPaint() {
687 for (size_t i
= 0; i
< children_
.size(); ++i
)
688 children_
[i
]->SuppressPaint();
691 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor
) {
692 if (device_scale_factor_
== device_scale_factor
)
695 animator_
->StopAnimatingProperty(LayerAnimationElement::TRANSFORM
);
696 device_scale_factor_
= device_scale_factor
;
697 RecomputeDrawsContentAndUVRect();
699 SchedulePaint(gfx::Rect(bounds_
.size()));
701 delegate_
->OnDeviceScaleFactorChanged(device_scale_factor
);
702 for (size_t i
= 0; i
< children_
.size(); ++i
)
703 children_
[i
]->OnDeviceScaleFactorChanged(device_scale_factor
);
705 layer_mask_
->OnDeviceScaleFactorChanged(device_scale_factor
);
708 void Layer::OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) {
709 DCHECK(delegated_renderer_layer_
.get() || surface_layer_
.get());
712 delegate_
->OnDelegatedFrameDamage(damage_rect_in_dip
);
715 void Layer::RequestCopyOfOutput(scoped_ptr
<cc::CopyOutputRequest
> request
) {
716 cc_layer_
->RequestCopyOfOutput(request
.Pass());
719 void Layer::PaintContents(SkCanvas
* sk_canvas
,
720 const gfx::Rect
& clip
,
721 ContentLayerClient::GraphicsContextStatus gc_status
) {
722 TRACE_EVENT0("ui", "Layer::PaintContents");
723 scoped_ptr
<gfx::Canvas
> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
724 sk_canvas
, device_scale_factor_
));
726 delegate_
->OnPaintLayer(canvas
.get());
729 scoped_refptr
<cc::DisplayItemList
> Layer::PaintContentsToDisplayList(
730 const gfx::Rect
& clip
,
731 ContentLayerClient::GraphicsContextStatus gc_status
) {
733 return cc::DisplayItemList::Create();
736 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_
; }
738 bool Layer::PrepareTextureMailbox(
739 cc::TextureMailbox
* mailbox
,
740 scoped_ptr
<cc::SingleReleaseCallback
>* release_callback
,
741 bool use_shared_memory
) {
742 if (!mailbox_release_callback_
)
745 *release_callback
= mailbox_release_callback_
.Pass();
749 void Layer::SetForceRenderSurface(bool force
) {
750 if (force_render_surface_
== force
)
753 force_render_surface_
= force
;
754 cc_layer_
->SetForceRenderSurface(force_render_surface_
);
757 class LayerDebugInfo
: public base::debug::ConvertableToTraceFormat
{
759 explicit LayerDebugInfo(std::string name
) : name_(name
) { }
760 void AppendAsTraceFormat(std::string
* out
) const override
{
761 base::DictionaryValue dictionary
;
762 dictionary
.SetString("layer_name", name_
);
763 base::JSONWriter::Write(&dictionary
, out
);
767 ~LayerDebugInfo() override
{}
771 scoped_refptr
<base::debug::ConvertableToTraceFormat
> Layer::TakeDebugInfo() {
772 return new LayerDebugInfo(name_
);
775 void Layer::OnAnimationStarted(const cc::AnimationEvent
& event
) {
777 animator_
->OnThreadedAnimationStarted(event
);
780 void Layer::CollectAnimators(
781 std::vector
<scoped_refptr
<LayerAnimator
> >* animators
) {
783 animators
->push_back(animator_
);
784 std::for_each(children_
.begin(), children_
.end(),
785 std::bind2nd(std::mem_fun(&Layer::CollectAnimators
),
789 void Layer::StackRelativeTo(Layer
* child
, Layer
* other
, bool above
) {
790 DCHECK_NE(child
, other
);
791 DCHECK_EQ(this, child
->parent());
792 DCHECK_EQ(this, other
->parent());
794 const size_t child_i
=
795 std::find(children_
.begin(), children_
.end(), child
) - children_
.begin();
796 const size_t other_i
=
797 std::find(children_
.begin(), children_
.end(), other
) - children_
.begin();
798 if ((above
&& child_i
== other_i
+ 1) || (!above
&& child_i
+ 1 == other_i
))
801 const size_t dest_i
=
803 (child_i
< other_i
? other_i
: other_i
+ 1) :
804 (child_i
< other_i
? other_i
- 1 : other_i
);
805 children_
.erase(children_
.begin() + child_i
);
806 children_
.insert(children_
.begin() + dest_i
, child
);
808 child
->cc_layer_
->RemoveFromParent();
809 cc_layer_
->InsertChild(child
->cc_layer_
, dest_i
);
812 bool Layer::ConvertPointForAncestor(const Layer
* ancestor
,
813 gfx::Point
* point
) const {
814 gfx::Transform transform
;
815 bool result
= GetTargetTransformRelativeTo(ancestor
, &transform
);
816 gfx::Point3F
p(*point
);
817 transform
.TransformPoint(&p
);
818 *point
= gfx::ToFlooredPoint(p
.AsPointF());
822 bool Layer::ConvertPointFromAncestor(const Layer
* ancestor
,
823 gfx::Point
* point
) const {
824 gfx::Transform transform
;
825 bool result
= GetTargetTransformRelativeTo(ancestor
, &transform
);
826 gfx::Point3F
p(*point
);
827 transform
.TransformPointReverse(&p
);
828 *point
= gfx::ToFlooredPoint(p
.AsPointF());
832 void Layer::SetBoundsFromAnimation(const gfx::Rect
& bounds
) {
833 if (bounds
== bounds_
)
836 base::Closure closure
;
838 closure
= delegate_
->PrepareForLayerBoundsChange();
839 bool was_move
= bounds_
.size() == bounds
.size();
842 RecomputeDrawsContentAndUVRect();
845 if (!closure
.is_null())
849 // Don't schedule a draw if we're invisible. We'll schedule one
850 // automatically when we get visible.
854 // Always schedule a paint, even if we're invisible.
855 SchedulePaint(gfx::Rect(bounds
.size()));
859 void Layer::SetTransformFromAnimation(const gfx::Transform
& transform
) {
860 cc_layer_
->SetTransform(transform
);
863 void Layer::SetOpacityFromAnimation(float opacity
) {
864 cc_layer_
->SetOpacity(opacity
);
868 void Layer::SetVisibilityFromAnimation(bool visible
) {
869 if (visible_
== visible
)
873 cc_layer_
->SetHideLayerAndSubtree(!visible_
);
876 void Layer::SetBrightnessFromAnimation(float brightness
) {
877 layer_brightness_
= brightness
;
881 void Layer::SetGrayscaleFromAnimation(float grayscale
) {
882 layer_grayscale_
= grayscale
;
886 void Layer::SetColorFromAnimation(SkColor color
) {
887 DCHECK_EQ(type_
, LAYER_SOLID_COLOR
);
888 cc_layer_
->SetBackgroundColor(color
);
889 SetFillsBoundsOpaquely(SkColorGetA(color
) == 0xFF);
892 void Layer::ScheduleDrawForAnimation() {
896 const gfx::Rect
& Layer::GetBoundsForAnimation() const {
900 gfx::Transform
Layer::GetTransformForAnimation() const {
904 float Layer::GetOpacityForAnimation() const {
908 bool Layer::GetVisibilityForAnimation() const {
912 float Layer::GetBrightnessForAnimation() const {
913 return layer_brightness();
916 float Layer::GetGrayscaleForAnimation() const {
917 return layer_grayscale();
920 SkColor
Layer::GetColorForAnimation() const {
921 // WebColor is equivalent to SkColor, per WebColor.h.
922 // The NULL check is here since this is invoked regardless of whether we have
923 // been configured as LAYER_SOLID_COLOR.
924 return solid_color_layer_
.get() ?
925 solid_color_layer_
->background_color() : SK_ColorBLACK
;
928 float Layer::GetDeviceScaleFactor() const {
929 return device_scale_factor_
;
932 void Layer::AddThreadedAnimation(scoped_ptr
<cc::Animation
> animation
) {
934 // Until this layer has a compositor (and hence cc_layer_ has a
935 // LayerTreeHost), addAnimation will fail.
937 cc_layer_
->AddAnimation(animation
.Pass());
939 pending_threaded_animations_
.push_back(animation
.Pass());
944 struct HasAnimationId
{
945 HasAnimationId(int id
): id_(id
) {
948 bool operator()(cc::Animation
* animation
) const {
949 return animation
->id() == id_
;
958 void Layer::RemoveThreadedAnimation(int animation_id
) {
960 if (pending_threaded_animations_
.size() == 0) {
961 cc_layer_
->RemoveAnimation(animation_id
);
965 pending_threaded_animations_
.erase(
966 cc::remove_if(&pending_threaded_animations_
,
967 pending_threaded_animations_
.begin(),
968 pending_threaded_animations_
.end(),
969 HasAnimationId(animation_id
)),
970 pending_threaded_animations_
.end());
973 LayerAnimatorCollection
* Layer::GetLayerAnimatorCollection() {
974 Compositor
* compositor
= GetCompositor();
975 return compositor
? compositor
->layer_animator_collection() : NULL
;
978 void Layer::SendPendingThreadedAnimations() {
979 for (cc::ScopedPtrVector
<cc::Animation
>::iterator it
=
980 pending_threaded_animations_
.begin();
981 it
!= pending_threaded_animations_
.end();
983 cc_layer_
->AddAnimation(pending_threaded_animations_
.take(it
));
985 pending_threaded_animations_
.clear();
987 for (size_t i
= 0; i
< children_
.size(); ++i
)
988 children_
[i
]->SendPendingThreadedAnimations();
991 void Layer::CreateCcLayer() {
992 if (type_
== LAYER_SOLID_COLOR
) {
993 solid_color_layer_
= cc::SolidColorLayer::Create();
994 cc_layer_
= solid_color_layer_
.get();
995 } else if (type_
== LAYER_NINE_PATCH
) {
996 nine_patch_layer_
= cc::NinePatchLayer::Create();
997 cc_layer_
= nine_patch_layer_
.get();
999 if (Layer::UsingPictureLayer())
1000 content_layer_
= cc::PictureLayer::Create(this);
1002 content_layer_
= cc::ContentLayer::Create(this);
1003 cc_layer_
= content_layer_
.get();
1005 cc_layer_
->SetTransformOrigin(gfx::Point3F());
1006 cc_layer_
->SetContentsOpaque(true);
1007 cc_layer_
->SetIsDrawable(type_
!= LAYER_NOT_DRAWN
);
1008 cc_layer_
->AddLayerAnimationEventObserver(this);
1009 cc_layer_
->SetLayerClient(this);
1010 RecomputePosition();
1013 gfx::Transform
Layer::transform() const {
1014 return cc_layer_
->transform();
1017 void Layer::RecomputeDrawsContentAndUVRect() {
1019 gfx::Size
size(bounds_
.size());
1020 if (texture_layer_
.get()) {
1021 size
.SetToMin(frame_size_in_dip_
);
1022 gfx::PointF
uv_top_left(0.f
, 0.f
);
1023 gfx::PointF
uv_bottom_right(
1024 static_cast<float>(size
.width()) / frame_size_in_dip_
.width(),
1025 static_cast<float>(size
.height()) / frame_size_in_dip_
.height());
1026 texture_layer_
->SetUV(uv_top_left
, uv_bottom_right
);
1027 } else if (delegated_renderer_layer_
.get() || surface_layer_
.get()) {
1028 size
.SetToMin(frame_size_in_dip_
);
1030 cc_layer_
->SetBounds(size
);
1033 void Layer::RecomputePosition() {
1034 cc_layer_
->SetPosition(bounds_
.origin() + subpixel_position_offset_
);
1037 void Layer::AddAnimatorsInTreeToCollection(
1038 LayerAnimatorCollection
* collection
) {
1041 animator_
->AddToCollection(collection
);
1045 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection
),
1049 void Layer::RemoveAnimatorsInTreeFromCollection(
1050 LayerAnimatorCollection
* collection
) {
1053 animator_
->RemoveFromCollection(collection
);
1057 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection
),
1061 bool Layer::IsAnimating() const {
1062 return animator_
.get() && animator_
->is_animating();