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/json/json_writer.h"
11 #include "base/lazy_instance.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/trace_event/trace_event.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
;
543 // Reset the frame_size_in_dip_ so that SetTextureSize() will not early out,
544 // the frame_size_in_dip_ was for a previous (different) |texture_layer_|.
545 frame_size_in_dip_
= gfx::Size();
547 if (mailbox_release_callback_
)
548 mailbox_release_callback_
->Run(0, false);
549 mailbox_release_callback_
= release_callback
.Pass();
551 SetTextureSize(texture_size_in_dip
);
554 void Layer::SetTextureSize(gfx::Size texture_size_in_dip
) {
555 DCHECK(texture_layer_
.get());
556 if (frame_size_in_dip_
== texture_size_in_dip
)
558 frame_size_in_dip_
= texture_size_in_dip
;
559 RecomputeDrawsContentAndUVRect();
560 texture_layer_
->SetNeedsDisplay();
563 void Layer::SetTextureFlipped(bool flipped
) {
564 DCHECK(texture_layer_
.get());
565 texture_layer_
->SetFlipped(flipped
);
568 bool Layer::TextureFlipped() const {
569 DCHECK(texture_layer_
.get());
570 return texture_layer_
->flipped();
573 void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider
* frame_provider
,
574 gfx::Size frame_size_in_dip
) {
575 DCHECK(type_
== LAYER_TEXTURED
|| type_
== LAYER_SOLID_COLOR
);
577 scoped_refptr
<cc::DelegatedRendererLayer
> new_layer
=
578 cc::DelegatedRendererLayer::Create(frame_provider
);
579 SwitchToLayer(new_layer
);
580 delegated_renderer_layer_
= new_layer
;
582 frame_size_in_dip_
= frame_size_in_dip
;
583 RecomputeDrawsContentAndUVRect();
586 void Layer::SetShowSurface(
587 cc::SurfaceId surface_id
,
588 const cc::SurfaceLayer::SatisfyCallback
& satisfy_callback
,
589 const cc::SurfaceLayer::RequireCallback
& require_callback
,
590 gfx::Size surface_size
,
592 gfx::Size frame_size_in_dip
) {
593 DCHECK(type_
== LAYER_TEXTURED
|| type_
== LAYER_SOLID_COLOR
);
595 scoped_refptr
<cc::SurfaceLayer
> new_layer
=
596 cc::SurfaceLayer::Create(satisfy_callback
, require_callback
);
597 new_layer
->SetSurfaceId(surface_id
, scale
, surface_size
);
598 SwitchToLayer(new_layer
);
599 surface_layer_
= new_layer
;
601 frame_size_in_dip_
= frame_size_in_dip
;
602 RecomputeDrawsContentAndUVRect();
605 void Layer::SetShowSolidColorContent() {
606 DCHECK_EQ(type_
, LAYER_SOLID_COLOR
);
608 if (solid_color_layer_
.get())
611 scoped_refptr
<cc::SolidColorLayer
> new_layer
= cc::SolidColorLayer::Create();
612 SwitchToLayer(new_layer
);
613 solid_color_layer_
= new_layer
;
615 mailbox_
= cc::TextureMailbox();
616 if (mailbox_release_callback_
) {
617 mailbox_release_callback_
->Run(0, false);
618 mailbox_release_callback_
.reset();
620 RecomputeDrawsContentAndUVRect();
623 void Layer::UpdateNinePatchLayerBitmap(const SkBitmap
& bitmap
) {
624 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
625 SkBitmap bitmap_copy
;
626 if (bitmap
.isImmutable()) {
627 bitmap_copy
= bitmap
;
629 // UIResourceBitmap requires an immutable copy of the input |bitmap|.
630 bitmap
.copyTo(&bitmap_copy
);
631 bitmap_copy
.setImmutable();
633 nine_patch_layer_
->SetBitmap(bitmap_copy
);
636 void Layer::UpdateNinePatchLayerAperture(const gfx::Rect
& aperture
) {
637 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
638 nine_patch_layer_
->SetAperture(aperture
);
641 void Layer::UpdateNinePatchLayerBorder(const gfx::Rect
& border
) {
642 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
643 nine_patch_layer_
->SetBorder(border
);
646 void Layer::SetColor(SkColor color
) { GetAnimator()->SetColor(color
); }
648 bool Layer::SchedulePaint(const gfx::Rect
& invalid_rect
) {
649 if ((type_
== LAYER_SOLID_COLOR
&& !texture_layer_
.get()) ||
650 type_
== LAYER_NINE_PATCH
|| (!delegate_
&& !mailbox_
.IsValid()))
653 damaged_region_
.op(invalid_rect
.x(),
655 invalid_rect
.right(),
656 invalid_rect
.bottom(),
657 SkRegion::kUnion_Op
);
662 void Layer::ScheduleDraw() {
663 Compositor
* compositor
= GetCompositor();
665 compositor
->ScheduleDraw();
668 void Layer::SendDamagedRects() {
669 if ((delegate_
|| mailbox_
.IsValid()) && !damaged_region_
.isEmpty()) {
670 for (SkRegion::Iterator
iter(damaged_region_
); !iter
.done(); iter
.next()) {
671 const SkIRect
& sk_damaged
= iter
.rect();
676 sk_damaged
.height());
677 cc_layer_
->SetNeedsDisplayRect(damaged
);
679 damaged_region_
.setEmpty();
681 for (size_t i
= 0; i
< children_
.size(); ++i
)
682 children_
[i
]->SendDamagedRects();
685 void Layer::CompleteAllAnimations() {
686 typedef std::vector
<scoped_refptr
<LayerAnimator
> > LayerAnimatorVector
;
687 LayerAnimatorVector animators
;
688 CollectAnimators(&animators
);
689 for (LayerAnimatorVector::const_iterator it
= animators
.begin();
690 it
!= animators
.end();
692 (*it
)->StopAnimating();
696 void Layer::SuppressPaint() {
700 for (size_t i
= 0; i
< children_
.size(); ++i
)
701 children_
[i
]->SuppressPaint();
704 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor
) {
705 if (device_scale_factor_
== device_scale_factor
)
708 animator_
->StopAnimatingProperty(LayerAnimationElement::TRANSFORM
);
709 device_scale_factor_
= device_scale_factor
;
710 RecomputeDrawsContentAndUVRect();
712 SchedulePaint(gfx::Rect(bounds_
.size()));
714 delegate_
->OnDeviceScaleFactorChanged(device_scale_factor
);
715 for (size_t i
= 0; i
< children_
.size(); ++i
)
716 children_
[i
]->OnDeviceScaleFactorChanged(device_scale_factor
);
718 layer_mask_
->OnDeviceScaleFactorChanged(device_scale_factor
);
721 void Layer::OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) {
722 DCHECK(delegated_renderer_layer_
.get() || surface_layer_
.get());
725 delegate_
->OnDelegatedFrameDamage(damage_rect_in_dip
);
728 void Layer::RequestCopyOfOutput(scoped_ptr
<cc::CopyOutputRequest
> request
) {
729 cc_layer_
->RequestCopyOfOutput(request
.Pass());
732 void Layer::PaintContents(
734 const gfx::Rect
& clip
,
735 ContentLayerClient::PaintingControlSetting painting_control
) {
736 TRACE_EVENT1("ui", "Layer::PaintContents", "name", name_
);
737 scoped_ptr
<gfx::Canvas
> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
738 sk_canvas
, device_scale_factor_
));
740 delegate_
->OnPaintLayer(canvas
.get());
743 scoped_refptr
<cc::DisplayItemList
> Layer::PaintContentsToDisplayList(
744 const gfx::Rect
& clip
,
745 ContentLayerClient::PaintingControlSetting painting_control
) {
747 return cc::DisplayItemList::Create();
750 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_
; }
752 bool Layer::PrepareTextureMailbox(
753 cc::TextureMailbox
* mailbox
,
754 scoped_ptr
<cc::SingleReleaseCallback
>* release_callback
,
755 bool use_shared_memory
) {
756 if (!mailbox_release_callback_
)
759 *release_callback
= mailbox_release_callback_
.Pass();
763 void Layer::SetForceRenderSurface(bool force
) {
764 if (force_render_surface_
== force
)
767 force_render_surface_
= force
;
768 cc_layer_
->SetForceRenderSurface(force_render_surface_
);
771 class LayerDebugInfo
: public base::trace_event::ConvertableToTraceFormat
{
773 explicit LayerDebugInfo(std::string name
) : name_(name
) { }
774 void AppendAsTraceFormat(std::string
* out
) const override
{
775 base::DictionaryValue dictionary
;
776 dictionary
.SetString("layer_name", name_
);
777 base::JSONWriter::Write(&dictionary
, out
);
781 ~LayerDebugInfo() override
{}
785 scoped_refptr
<base::trace_event::ConvertableToTraceFormat
>
786 Layer::TakeDebugInfo() {
787 return new LayerDebugInfo(name_
);
790 void Layer::OnAnimationStarted(const cc::AnimationEvent
& event
) {
792 animator_
->OnThreadedAnimationStarted(event
);
795 void Layer::CollectAnimators(
796 std::vector
<scoped_refptr
<LayerAnimator
> >* animators
) {
798 animators
->push_back(animator_
);
799 std::for_each(children_
.begin(), children_
.end(),
800 std::bind2nd(std::mem_fun(&Layer::CollectAnimators
),
804 void Layer::StackRelativeTo(Layer
* child
, Layer
* other
, bool above
) {
805 DCHECK_NE(child
, other
);
806 DCHECK_EQ(this, child
->parent());
807 DCHECK_EQ(this, other
->parent());
809 const size_t child_i
=
810 std::find(children_
.begin(), children_
.end(), child
) - children_
.begin();
811 const size_t other_i
=
812 std::find(children_
.begin(), children_
.end(), other
) - children_
.begin();
813 if ((above
&& child_i
== other_i
+ 1) || (!above
&& child_i
+ 1 == other_i
))
816 const size_t dest_i
=
818 (child_i
< other_i
? other_i
: other_i
+ 1) :
819 (child_i
< other_i
? other_i
- 1 : other_i
);
820 children_
.erase(children_
.begin() + child_i
);
821 children_
.insert(children_
.begin() + dest_i
, child
);
823 child
->cc_layer_
->RemoveFromParent();
824 cc_layer_
->InsertChild(child
->cc_layer_
, dest_i
);
827 bool Layer::ConvertPointForAncestor(const Layer
* ancestor
,
828 gfx::Point
* point
) const {
829 gfx::Transform transform
;
830 bool result
= GetTargetTransformRelativeTo(ancestor
, &transform
);
831 gfx::Point3F
p(*point
);
832 transform
.TransformPoint(&p
);
833 *point
= gfx::ToFlooredPoint(p
.AsPointF());
837 bool Layer::ConvertPointFromAncestor(const Layer
* ancestor
,
838 gfx::Point
* point
) const {
839 gfx::Transform transform
;
840 bool result
= GetTargetTransformRelativeTo(ancestor
, &transform
);
841 gfx::Point3F
p(*point
);
842 transform
.TransformPointReverse(&p
);
843 *point
= gfx::ToFlooredPoint(p
.AsPointF());
847 void Layer::SetBoundsFromAnimation(const gfx::Rect
& bounds
) {
848 if (bounds
== bounds_
)
851 base::Closure closure
;
853 closure
= delegate_
->PrepareForLayerBoundsChange();
854 bool was_move
= bounds_
.size() == bounds
.size();
857 RecomputeDrawsContentAndUVRect();
860 if (!closure
.is_null())
864 // Don't schedule a draw if we're invisible. We'll schedule one
865 // automatically when we get visible.
869 // Always schedule a paint, even if we're invisible.
870 SchedulePaint(gfx::Rect(bounds
.size()));
874 void Layer::SetTransformFromAnimation(const gfx::Transform
& transform
) {
875 cc_layer_
->SetTransform(transform
);
878 void Layer::SetOpacityFromAnimation(float opacity
) {
879 cc_layer_
->SetOpacity(opacity
);
883 void Layer::SetVisibilityFromAnimation(bool visible
) {
884 if (visible_
== visible
)
888 cc_layer_
->SetHideLayerAndSubtree(!visible_
);
891 void Layer::SetBrightnessFromAnimation(float brightness
) {
892 layer_brightness_
= brightness
;
896 void Layer::SetGrayscaleFromAnimation(float grayscale
) {
897 layer_grayscale_
= grayscale
;
901 void Layer::SetColorFromAnimation(SkColor color
) {
902 DCHECK_EQ(type_
, LAYER_SOLID_COLOR
);
903 cc_layer_
->SetBackgroundColor(color
);
904 SetFillsBoundsOpaquely(SkColorGetA(color
) == 0xFF);
907 void Layer::ScheduleDrawForAnimation() {
911 const gfx::Rect
& Layer::GetBoundsForAnimation() const {
915 gfx::Transform
Layer::GetTransformForAnimation() const {
919 float Layer::GetOpacityForAnimation() const {
923 bool Layer::GetVisibilityForAnimation() const {
927 float Layer::GetBrightnessForAnimation() const {
928 return layer_brightness();
931 float Layer::GetGrayscaleForAnimation() const {
932 return layer_grayscale();
935 SkColor
Layer::GetColorForAnimation() const {
936 // WebColor is equivalent to SkColor, per WebColor.h.
937 // The NULL check is here since this is invoked regardless of whether we have
938 // been configured as LAYER_SOLID_COLOR.
939 return solid_color_layer_
.get() ?
940 solid_color_layer_
->background_color() : SK_ColorBLACK
;
943 float Layer::GetDeviceScaleFactor() const {
944 return device_scale_factor_
;
947 void Layer::AddThreadedAnimation(scoped_ptr
<cc::Animation
> animation
) {
949 // Until this layer has a compositor (and hence cc_layer_ has a
950 // LayerTreeHost), addAnimation will fail.
952 cc_layer_
->AddAnimation(animation
.Pass());
954 pending_threaded_animations_
.push_back(animation
.Pass());
959 struct HasAnimationId
{
960 HasAnimationId(int id
): id_(id
) {
963 bool operator()(cc::Animation
* animation
) const {
964 return animation
->id() == id_
;
973 void Layer::RemoveThreadedAnimation(int animation_id
) {
975 if (pending_threaded_animations_
.size() == 0) {
976 cc_layer_
->RemoveAnimation(animation_id
);
980 pending_threaded_animations_
.erase(
981 cc::remove_if(&pending_threaded_animations_
,
982 pending_threaded_animations_
.begin(),
983 pending_threaded_animations_
.end(),
984 HasAnimationId(animation_id
)),
985 pending_threaded_animations_
.end());
988 LayerAnimatorCollection
* Layer::GetLayerAnimatorCollection() {
989 Compositor
* compositor
= GetCompositor();
990 return compositor
? compositor
->layer_animator_collection() : NULL
;
993 void Layer::SendPendingThreadedAnimations() {
994 for (cc::ScopedPtrVector
<cc::Animation
>::iterator it
=
995 pending_threaded_animations_
.begin();
996 it
!= pending_threaded_animations_
.end();
998 cc_layer_
->AddAnimation(pending_threaded_animations_
.take(it
));
1000 pending_threaded_animations_
.clear();
1002 for (size_t i
= 0; i
< children_
.size(); ++i
)
1003 children_
[i
]->SendPendingThreadedAnimations();
1006 void Layer::CreateCcLayer() {
1007 if (type_
== LAYER_SOLID_COLOR
) {
1008 solid_color_layer_
= cc::SolidColorLayer::Create();
1009 cc_layer_
= solid_color_layer_
.get();
1010 } else if (type_
== LAYER_NINE_PATCH
) {
1011 nine_patch_layer_
= cc::NinePatchLayer::Create();
1012 cc_layer_
= nine_patch_layer_
.get();
1014 if (Layer::UsingPictureLayer())
1015 content_layer_
= cc::PictureLayer::Create(this);
1017 content_layer_
= cc::ContentLayer::Create(this);
1018 cc_layer_
= content_layer_
.get();
1020 cc_layer_
->SetTransformOrigin(gfx::Point3F());
1021 cc_layer_
->SetContentsOpaque(true);
1022 cc_layer_
->SetIsDrawable(type_
!= LAYER_NOT_DRAWN
);
1023 cc_layer_
->AddLayerAnimationEventObserver(this);
1024 cc_layer_
->SetLayerClient(this);
1025 RecomputePosition();
1028 gfx::Transform
Layer::transform() const {
1029 return cc_layer_
->transform();
1032 void Layer::RecomputeDrawsContentAndUVRect() {
1034 gfx::Size
size(bounds_
.size());
1035 if (texture_layer_
.get()) {
1036 size
.SetToMin(frame_size_in_dip_
);
1037 gfx::PointF
uv_top_left(0.f
, 0.f
);
1038 gfx::PointF
uv_bottom_right(
1039 static_cast<float>(size
.width()) / frame_size_in_dip_
.width(),
1040 static_cast<float>(size
.height()) / frame_size_in_dip_
.height());
1041 texture_layer_
->SetUV(uv_top_left
, uv_bottom_right
);
1042 } else if (delegated_renderer_layer_
.get() || surface_layer_
.get()) {
1043 size
.SetToMin(frame_size_in_dip_
);
1045 cc_layer_
->SetBounds(size
);
1048 void Layer::RecomputePosition() {
1049 cc_layer_
->SetPosition(bounds_
.origin() + subpixel_position_offset_
);
1052 void Layer::AddAnimatorsInTreeToCollection(
1053 LayerAnimatorCollection
* collection
) {
1056 animator_
->AddToCollection(collection
);
1060 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection
),
1064 void Layer::RemoveAnimatorsInTreeFromCollection(
1065 LayerAnimatorCollection
* collection
) {
1068 animator_
->RemoveFromCollection(collection
);
1072 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection
),
1076 bool Layer::IsAnimating() const {
1077 return animator_
.get() && animator_
->is_animating();