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/auto_reset.h"
10 #include "base/command_line.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 "base/trace_event/trace_event.h"
16 #include "cc/base/scoped_ptr_algorithm.h"
17 #include "cc/layers/content_layer.h"
18 #include "cc/layers/delegated_renderer_layer.h"
19 #include "cc/layers/nine_patch_layer.h"
20 #include "cc/layers/picture_layer.h"
21 #include "cc/layers/solid_color_layer.h"
22 #include "cc/layers/surface_layer.h"
23 #include "cc/layers/texture_layer.h"
24 #include "cc/output/copy_output_request.h"
25 #include "cc/output/delegated_frame_data.h"
26 #include "cc/output/filter_operation.h"
27 #include "cc/output/filter_operations.h"
28 #include "cc/resources/transferable_resource.h"
29 #include "ui/compositor/compositor_switches.h"
30 #include "ui/compositor/dip_util.h"
31 #include "ui/compositor/layer_animator.h"
32 #include "ui/compositor/paint_context.h"
33 #include "ui/gfx/animation/animation.h"
34 #include "ui/gfx/canvas.h"
35 #include "ui/gfx/display.h"
36 #include "ui/gfx/geometry/point3_f.h"
37 #include "ui/gfx/geometry/point_conversions.h"
38 #include "ui/gfx/geometry/size_conversions.h"
39 #include "ui/gfx/interpolated_transform.h"
43 const ui::Layer
* GetRoot(const ui::Layer
* layer
) {
44 while (layer
->parent())
45 layer
= layer
->parent();
49 struct UIImplSidePaintingStatus
{
50 UIImplSidePaintingStatus()
51 : enabled(ui::IsUIImplSidePaintingEnabled()) {
55 base::LazyInstance
<UIImplSidePaintingStatus
> g_ui_impl_side_painting_status
=
56 LAZY_INSTANCE_INITIALIZER
;
63 : type_(LAYER_TEXTURED
),
67 force_render_surface_(false),
68 fills_bounds_opaquely_(true),
69 fills_bounds_completely_(false),
70 background_blur_radius_(0),
71 layer_saturation_(0.0f
),
72 layer_brightness_(0.0f
),
73 layer_grayscale_(0.0f
),
74 layer_inverted_(false),
76 layer_mask_back_link_(NULL
),
82 device_scale_factor_(1.0f
) {
86 Layer::Layer(LayerType type
)
91 force_render_surface_(false),
92 fills_bounds_opaquely_(true),
93 fills_bounds_completely_(false),
94 background_blur_radius_(0),
95 layer_saturation_(0.0f
),
96 layer_brightness_(0.0f
),
97 layer_grayscale_(0.0f
),
98 layer_inverted_(false),
100 layer_mask_back_link_(NULL
),
106 device_scale_factor_(1.0f
) {
111 // Destroying the animator may cause observers to use the layer (and
112 // indirectly the WebLayer). Destroy the animator first so that the WebLayer
115 animator_
->SetDelegate(NULL
);
118 compositor_
->SetRootLayer(NULL
);
120 parent_
->Remove(this);
123 if (layer_mask_back_link_
)
124 layer_mask_back_link_
->SetMaskLayer(NULL
);
125 for (size_t i
= 0; i
< children_
.size(); ++i
)
126 children_
[i
]->parent_
= NULL
;
127 cc_layer_
->RemoveLayerAnimationEventObserver(this);
128 cc_layer_
->RemoveFromParent();
132 bool Layer::UsingPictureLayer() {
133 return g_ui_impl_side_painting_status
.Get().enabled
;
136 const Compositor
* Layer::GetCompositor() const {
137 return GetRoot(this)->compositor_
;
140 float Layer::opacity() const {
141 return cc_layer_
->opacity();
144 void Layer::SetCompositor(Compositor
* compositor
) {
145 // This function must only be called to set the compositor on the root layer,
147 DCHECK(!compositor
|| !compositor_
);
148 DCHECK(!compositor
|| compositor
->root_layer() == this);
151 RemoveAnimatorsInTreeFromCollection(
152 compositor_
->layer_animator_collection());
154 compositor_
= compositor
;
156 OnDeviceScaleFactorChanged(compositor
->device_scale_factor());
157 SendPendingThreadedAnimations();
158 AddAnimatorsInTreeToCollection(compositor_
->layer_animator_collection());
162 void Layer::Add(Layer
* child
) {
163 DCHECK(!child
->compositor_
);
165 child
->parent_
->Remove(child
);
166 child
->parent_
= this;
167 children_
.push_back(child
);
168 cc_layer_
->AddChild(child
->cc_layer_
);
169 child
->OnDeviceScaleFactorChanged(device_scale_factor_
);
171 child
->SendPendingThreadedAnimations();
172 LayerAnimatorCollection
* collection
= GetLayerAnimatorCollection();
174 child
->AddAnimatorsInTreeToCollection(collection
);
177 void Layer::Remove(Layer
* child
) {
178 // Current bounds are used to calculate offsets when layers are reparented.
179 // Stop (and complete) an ongoing animation to update the bounds immediately.
180 LayerAnimator
* child_animator
= child
->animator_
.get();
182 child_animator
->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS
);
183 LayerAnimatorCollection
* collection
= GetLayerAnimatorCollection();
185 child
->RemoveAnimatorsInTreeFromCollection(collection
);
187 std::vector
<Layer
*>::iterator i
=
188 std::find(children_
.begin(), children_
.end(), child
);
189 DCHECK(i
!= children_
.end());
191 child
->parent_
= NULL
;
192 child
->cc_layer_
->RemoveFromParent();
195 void Layer::StackAtTop(Layer
* child
) {
196 if (children_
.size() <= 1 || child
== children_
.back())
197 return; // Already in front.
198 StackAbove(child
, children_
.back());
201 void Layer::StackAbove(Layer
* child
, Layer
* other
) {
202 StackRelativeTo(child
, other
, true);
205 void Layer::StackAtBottom(Layer
* child
) {
206 if (children_
.size() <= 1 || child
== children_
.front())
207 return; // Already on bottom.
208 StackBelow(child
, children_
.front());
211 void Layer::StackBelow(Layer
* child
, Layer
* other
) {
212 StackRelativeTo(child
, other
, false);
215 bool Layer::Contains(const Layer
* other
) const {
216 for (const Layer
* parent
= other
; parent
; parent
= parent
->parent()) {
223 void Layer::SetAnimator(LayerAnimator
* animator
) {
225 animator
->SetDelegate(this);
226 animator_
= animator
;
229 LayerAnimator
* Layer::GetAnimator() {
230 if (!animator_
.get())
231 SetAnimator(LayerAnimator::CreateDefaultAnimator());
232 return animator_
.get();
235 void Layer::SetTransform(const gfx::Transform
& transform
) {
236 GetAnimator()->SetTransform(transform
);
239 gfx::Transform
Layer::GetTargetTransform() const {
240 if (animator_
.get() && animator_
->IsAnimatingProperty(
241 LayerAnimationElement::TRANSFORM
)) {
242 return animator_
->GetTargetTransform();
247 void Layer::SetBounds(const gfx::Rect
& bounds
) {
248 GetAnimator()->SetBounds(bounds
);
251 void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF offset
) {
252 subpixel_position_offset_
= offset
;
256 gfx::Rect
Layer::GetTargetBounds() const {
257 if (animator_
.get() && animator_
->IsAnimatingProperty(
258 LayerAnimationElement::BOUNDS
)) {
259 return animator_
->GetTargetBounds();
264 void Layer::SetMasksToBounds(bool masks_to_bounds
) {
265 cc_layer_
->SetMasksToBounds(masks_to_bounds
);
268 bool Layer::GetMasksToBounds() const {
269 return cc_layer_
->masks_to_bounds();
272 void Layer::SetOpacity(float opacity
) {
273 GetAnimator()->SetOpacity(opacity
);
276 float Layer::GetCombinedOpacity() const {
277 float opacity
= this->opacity();
278 Layer
* current
= this->parent_
;
280 opacity
*= current
->opacity();
281 current
= current
->parent_
;
286 void Layer::SetBackgroundBlur(int blur_radius
) {
287 background_blur_radius_
= blur_radius
;
289 SetLayerBackgroundFilters();
292 void Layer::SetLayerSaturation(float saturation
) {
293 layer_saturation_
= saturation
;
297 void Layer::SetLayerBrightness(float brightness
) {
298 GetAnimator()->SetBrightness(brightness
);
301 float Layer::GetTargetBrightness() const {
302 if (animator_
.get() && animator_
->IsAnimatingProperty(
303 LayerAnimationElement::BRIGHTNESS
)) {
304 return animator_
->GetTargetBrightness();
306 return layer_brightness();
309 void Layer::SetLayerGrayscale(float grayscale
) {
310 GetAnimator()->SetGrayscale(grayscale
);
313 float Layer::GetTargetGrayscale() const {
314 if (animator_
.get() && animator_
->IsAnimatingProperty(
315 LayerAnimationElement::GRAYSCALE
)) {
316 return animator_
->GetTargetGrayscale();
318 return layer_grayscale();
321 void Layer::SetLayerInverted(bool inverted
) {
322 layer_inverted_
= inverted
;
326 void Layer::SetMaskLayer(Layer
* layer_mask
) {
327 // The provided mask should not have a layer mask itself.
328 DCHECK(!layer_mask
||
329 (!layer_mask
->layer_mask_layer() &&
330 layer_mask
->children().empty() &&
331 !layer_mask
->layer_mask_back_link_
));
332 DCHECK(!layer_mask_back_link_
);
333 if (layer_mask_
== layer_mask
)
335 // We need to de-reference the currently linked object so that no problem
336 // arises if the mask layer gets deleted before this object.
338 layer_mask_
->layer_mask_back_link_
= NULL
;
339 layer_mask_
= layer_mask
;
340 cc_layer_
->SetMaskLayer(
341 layer_mask
? layer_mask
->cc_layer() : NULL
);
342 // We need to reference the linked object so that it can properly break the
343 // link to us when it gets deleted.
345 layer_mask
->layer_mask_back_link_
= this;
346 layer_mask
->OnDeviceScaleFactorChanged(device_scale_factor_
);
350 void Layer::SetBackgroundZoom(float zoom
, int inset
) {
354 SetLayerBackgroundFilters();
357 void Layer::SetAlphaShape(scoped_ptr
<SkRegion
> region
) {
358 alpha_shape_
= region
.Pass();
363 void Layer::SetLayerFilters() {
364 cc::FilterOperations filters
;
365 if (layer_saturation_
) {
366 filters
.Append(cc::FilterOperation::CreateSaturateFilter(
369 if (layer_grayscale_
) {
370 filters
.Append(cc::FilterOperation::CreateGrayscaleFilter(
374 filters
.Append(cc::FilterOperation::CreateInvertFilter(1.0));
375 // Brightness goes last, because the resulting colors neeed clamping, which
376 // cause further color matrix filters to be applied separately. In this order,
377 // they all can be combined in a single pass.
378 if (layer_brightness_
) {
379 filters
.Append(cc::FilterOperation::CreateSaturatingBrightnessFilter(
383 filters
.Append(cc::FilterOperation::CreateAlphaThresholdFilter(
384 *alpha_shape_
, 0.f
, 0.f
));
387 cc_layer_
->SetFilters(filters
);
390 void Layer::SetLayerBackgroundFilters() {
391 cc::FilterOperations filters
;
393 filters
.Append(cc::FilterOperation::CreateZoomFilter(zoom_
, zoom_inset_
));
395 if (background_blur_radius_
) {
396 filters
.Append(cc::FilterOperation::CreateBlurFilter(
397 background_blur_radius_
));
400 cc_layer_
->SetBackgroundFilters(filters
);
403 float Layer::GetTargetOpacity() const {
404 if (animator_
.get() && animator_
->IsAnimatingProperty(
405 LayerAnimationElement::OPACITY
))
406 return animator_
->GetTargetOpacity();
410 void Layer::SetVisible(bool visible
) {
411 GetAnimator()->SetVisibility(visible
);
414 bool Layer::GetTargetVisibility() const {
415 if (animator_
.get() && animator_
->IsAnimatingProperty(
416 LayerAnimationElement::VISIBILITY
))
417 return animator_
->GetTargetVisibility();
421 bool Layer::IsDrawn() const {
422 const Layer
* layer
= this;
423 while (layer
&& layer
->visible_
)
424 layer
= layer
->parent_
;
425 return layer
== NULL
;
428 bool Layer::ShouldDraw() const {
429 return type_
!= LAYER_NOT_DRAWN
&& GetCombinedOpacity() > 0.0f
;
433 void Layer::ConvertPointToLayer(const Layer
* source
,
436 if (source
== target
)
439 const Layer
* root_layer
= GetRoot(source
);
440 CHECK_EQ(root_layer
, GetRoot(target
));
442 if (source
!= root_layer
)
443 source
->ConvertPointForAncestor(root_layer
, point
);
444 if (target
!= root_layer
)
445 target
->ConvertPointFromAncestor(root_layer
, point
);
448 bool Layer::GetTargetTransformRelativeTo(const Layer
* ancestor
,
449 gfx::Transform
* transform
) const {
450 const Layer
* p
= this;
451 for (; p
&& p
!= ancestor
; p
= p
->parent()) {
452 gfx::Transform translation
;
453 translation
.Translate(static_cast<float>(p
->bounds().x()),
454 static_cast<float>(p
->bounds().y()));
455 // Use target transform so that result will be correct once animation is
457 if (!p
->GetTargetTransform().IsIdentity())
458 transform
->ConcatTransform(p
->GetTargetTransform());
459 transform
->ConcatTransform(translation
);
461 return p
== ancestor
;
464 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely
) {
465 if (fills_bounds_opaquely_
== fills_bounds_opaquely
)
468 fills_bounds_opaquely_
= fills_bounds_opaquely
;
470 cc_layer_
->SetContentsOpaque(fills_bounds_opaquely
);
473 void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely
) {
474 fills_bounds_completely_
= fills_bounds_completely
;
477 void Layer::SwitchToLayer(scoped_refptr
<cc::Layer
> new_layer
) {
478 // Finish animations being handled by cc_layer_.
479 if (animator_
.get()) {
480 animator_
->StopAnimatingProperty(LayerAnimationElement::TRANSFORM
);
481 animator_
->StopAnimatingProperty(LayerAnimationElement::OPACITY
);
484 if (texture_layer_
.get())
485 texture_layer_
->ClearClient();
486 // TODO(piman): delegated_renderer_layer_ cleanup.
488 cc_layer_
->RemoveAllChildren();
489 if (cc_layer_
->parent()) {
490 cc_layer_
->parent()->ReplaceChild(cc_layer_
, new_layer
);
492 cc_layer_
->SetLayerClient(NULL
);
493 cc_layer_
->RemoveLayerAnimationEventObserver(this);
494 new_layer
->SetOpacity(cc_layer_
->opacity());
495 new_layer
->SetTransform(cc_layer_
->transform());
496 new_layer
->SetPosition(cc_layer_
->position());
497 new_layer
->SetBackgroundColor(cc_layer_
->background_color());
499 cc_layer_
= new_layer
.get();
500 content_layer_
= NULL
;
501 solid_color_layer_
= NULL
;
502 texture_layer_
= NULL
;
503 delegated_renderer_layer_
= NULL
;
504 surface_layer_
= NULL
;
506 cc_layer_
->AddLayerAnimationEventObserver(this);
507 for (size_t i
= 0; i
< children_
.size(); ++i
) {
508 DCHECK(children_
[i
]->cc_layer_
);
509 cc_layer_
->AddChild(children_
[i
]->cc_layer_
);
511 cc_layer_
->SetLayerClient(this);
512 cc_layer_
->SetTransformOrigin(gfx::Point3F());
513 cc_layer_
->SetContentsOpaque(fills_bounds_opaquely_
);
514 cc_layer_
->SetForceRenderSurface(force_render_surface_
);
515 cc_layer_
->SetIsDrawable(type_
!= LAYER_NOT_DRAWN
);
516 cc_layer_
->SetHideLayerAndSubtree(!visible_
);
519 SetLayerBackgroundFilters();
522 void Layer::SwitchCCLayerForTest() {
523 scoped_refptr
<cc::Layer
> new_layer
;
524 if (Layer::UsingPictureLayer())
525 new_layer
= cc::PictureLayer::Create(this);
527 new_layer
= cc::ContentLayer::Create(this);
528 SwitchToLayer(new_layer
);
529 content_layer_
= new_layer
;
532 void Layer::SetTextureMailbox(
533 const cc::TextureMailbox
& mailbox
,
534 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
,
535 gfx::Size texture_size_in_dip
) {
536 DCHECK(type_
== LAYER_TEXTURED
|| type_
== LAYER_SOLID_COLOR
);
537 DCHECK(mailbox
.IsValid());
538 DCHECK(release_callback
);
539 if (!texture_layer_
.get()) {
540 scoped_refptr
<cc::TextureLayer
> new_layer
=
541 cc::TextureLayer::CreateForMailbox(this);
542 new_layer
->SetFlipped(true);
543 SwitchToLayer(new_layer
);
544 texture_layer_
= new_layer
;
545 // Reset the frame_size_in_dip_ so that SetTextureSize() will not early out,
546 // the frame_size_in_dip_ was for a previous (different) |texture_layer_|.
547 frame_size_in_dip_
= gfx::Size();
549 if (mailbox_release_callback_
)
550 mailbox_release_callback_
->Run(0, false);
551 mailbox_release_callback_
= release_callback
.Pass();
553 SetTextureSize(texture_size_in_dip
);
556 void Layer::SetTextureSize(gfx::Size texture_size_in_dip
) {
557 DCHECK(texture_layer_
.get());
558 if (frame_size_in_dip_
== texture_size_in_dip
)
560 frame_size_in_dip_
= texture_size_in_dip
;
561 RecomputeDrawsContentAndUVRect();
562 texture_layer_
->SetNeedsDisplay();
565 void Layer::SetTextureFlipped(bool flipped
) {
566 DCHECK(texture_layer_
.get());
567 texture_layer_
->SetFlipped(flipped
);
570 bool Layer::TextureFlipped() const {
571 DCHECK(texture_layer_
.get());
572 return texture_layer_
->flipped();
575 void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider
* frame_provider
,
576 gfx::Size frame_size_in_dip
) {
577 DCHECK(type_
== LAYER_TEXTURED
|| type_
== LAYER_SOLID_COLOR
);
579 scoped_refptr
<cc::DelegatedRendererLayer
> new_layer
=
580 cc::DelegatedRendererLayer::Create(frame_provider
);
581 SwitchToLayer(new_layer
);
582 delegated_renderer_layer_
= new_layer
;
584 frame_size_in_dip_
= frame_size_in_dip
;
585 RecomputeDrawsContentAndUVRect();
588 void Layer::SetShowSurface(
589 cc::SurfaceId surface_id
,
590 const cc::SurfaceLayer::SatisfyCallback
& satisfy_callback
,
591 const cc::SurfaceLayer::RequireCallback
& require_callback
,
592 gfx::Size surface_size
,
594 gfx::Size frame_size_in_dip
) {
595 DCHECK(type_
== LAYER_TEXTURED
|| type_
== LAYER_SOLID_COLOR
);
597 scoped_refptr
<cc::SurfaceLayer
> new_layer
=
598 cc::SurfaceLayer::Create(satisfy_callback
, require_callback
);
599 new_layer
->SetSurfaceId(surface_id
, scale
, surface_size
);
600 SwitchToLayer(new_layer
);
601 surface_layer_
= new_layer
;
603 frame_size_in_dip_
= frame_size_in_dip
;
604 RecomputeDrawsContentAndUVRect();
607 void Layer::SetShowSolidColorContent() {
608 DCHECK_EQ(type_
, LAYER_SOLID_COLOR
);
610 if (solid_color_layer_
.get())
613 scoped_refptr
<cc::SolidColorLayer
> new_layer
= cc::SolidColorLayer::Create();
614 SwitchToLayer(new_layer
);
615 solid_color_layer_
= new_layer
;
617 mailbox_
= cc::TextureMailbox();
618 if (mailbox_release_callback_
) {
619 mailbox_release_callback_
->Run(0, false);
620 mailbox_release_callback_
.reset();
622 RecomputeDrawsContentAndUVRect();
625 void Layer::UpdateNinePatchLayerImage(const gfx::ImageSkia
& image
) {
626 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
627 nine_patch_layer_image_
= image
;
628 SkBitmap bitmap
= nine_patch_layer_image_
.GetRepresentation(
629 device_scale_factor_
).sk_bitmap();
630 SkBitmap bitmap_copy
;
631 if (bitmap
.isImmutable()) {
632 bitmap_copy
= bitmap
;
634 // UIResourceBitmap requires an immutable copy of the input |bitmap|.
635 bitmap
.copyTo(&bitmap_copy
);
636 bitmap_copy
.setImmutable();
638 nine_patch_layer_
->SetBitmap(bitmap_copy
);
641 void Layer::UpdateNinePatchLayerAperture(const gfx::Rect
& aperture_in_dip
) {
642 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
643 nine_patch_layer_aperture_
= aperture_in_dip
;
644 gfx::Rect aperture_in_pixel
= ConvertRectToPixel(this, aperture_in_dip
);
645 nine_patch_layer_
->SetAperture(aperture_in_pixel
);
648 void Layer::UpdateNinePatchLayerBorder(const gfx::Rect
& border
) {
649 DCHECK(type_
== LAYER_NINE_PATCH
&& nine_patch_layer_
.get());
650 nine_patch_layer_
->SetBorder(border
);
653 void Layer::SetColor(SkColor color
) { GetAnimator()->SetColor(color
); }
655 bool Layer::SchedulePaint(const gfx::Rect
& invalid_rect
) {
656 if ((type_
== LAYER_SOLID_COLOR
&& !texture_layer_
.get()) ||
657 type_
== LAYER_NINE_PATCH
|| (!delegate_
&& !mailbox_
.IsValid()))
660 damaged_region_
.op(invalid_rect
.x(),
662 invalid_rect
.right(),
663 invalid_rect
.bottom(),
664 SkRegion::kUnion_Op
);
669 void Layer::ScheduleDraw() {
670 Compositor
* compositor
= GetCompositor();
672 compositor
->ScheduleDraw();
675 void Layer::SendDamagedRects() {
676 if ((delegate_
|| mailbox_
.IsValid()) && !damaged_region_
.isEmpty()) {
677 for (SkRegion::Iterator
iter(damaged_region_
); !iter
.done(); iter
.next()) {
678 const SkIRect
& sk_damaged
= iter
.rect();
683 sk_damaged
.height());
684 cc_layer_
->SetNeedsDisplayRect(damaged
);
686 damaged_region_
.setEmpty();
688 for (size_t i
= 0; i
< children_
.size(); ++i
)
689 children_
[i
]->SendDamagedRects();
692 void Layer::CompleteAllAnimations() {
693 typedef std::vector
<scoped_refptr
<LayerAnimator
> > LayerAnimatorVector
;
694 LayerAnimatorVector animators
;
695 CollectAnimators(&animators
);
696 for (LayerAnimatorVector::const_iterator it
= animators
.begin();
697 it
!= animators
.end();
699 (*it
)->StopAnimating();
703 void Layer::SuppressPaint() {
707 for (size_t i
= 0; i
< children_
.size(); ++i
)
708 children_
[i
]->SuppressPaint();
711 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor
) {
712 if (device_scale_factor_
== device_scale_factor
)
715 animator_
->StopAnimatingProperty(LayerAnimationElement::TRANSFORM
);
716 device_scale_factor_
= device_scale_factor
;
717 RecomputeDrawsContentAndUVRect();
719 if (nine_patch_layer_
) {
720 UpdateNinePatchLayerImage(nine_patch_layer_image_
);
721 UpdateNinePatchLayerAperture(nine_patch_layer_aperture_
);
723 SchedulePaint(gfx::Rect(bounds_
.size()));
725 delegate_
->OnDeviceScaleFactorChanged(device_scale_factor
);
726 for (size_t i
= 0; i
< children_
.size(); ++i
)
727 children_
[i
]->OnDeviceScaleFactorChanged(device_scale_factor
);
729 layer_mask_
->OnDeviceScaleFactorChanged(device_scale_factor
);
732 void Layer::OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) {
733 DCHECK(delegated_renderer_layer_
.get() || surface_layer_
.get());
736 delegate_
->OnDelegatedFrameDamage(damage_rect_in_dip
);
739 void Layer::RequestCopyOfOutput(scoped_ptr
<cc::CopyOutputRequest
> request
) {
740 cc_layer_
->RequestCopyOfOutput(request
.Pass());
743 void Layer::PaintContents(
745 const gfx::Rect
& clip
,
746 ContentLayerClient::PaintingControlSetting painting_control
) {
747 TRACE_EVENT1("ui", "Layer::PaintContents", "name", name_
);
748 scoped_ptr
<gfx::Canvas
> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
749 sk_canvas
, device_scale_factor_
));
751 delegate_
->OnPaintLayer(PaintContext(canvas
.get(), clip
));
754 void Layer::PaintContentsToDisplayList(
755 cc::DisplayItemList
* display_list
,
756 const gfx::Rect
& clip
,
757 ContentLayerClient::PaintingControlSetting painting_control
) {
758 TRACE_EVENT1("ui", "Layer::PaintContentsToDisplayList", "name", name_
);
760 // TODO(danakj): Save the invalidation on the layer and pass that down
761 // instead of the |clip| here. That will break everything until View
762 // early-outs emit cached display items instead of nothing.
763 gfx::Rect invalidation
= clip
;
764 DCHECK(clip
.Contains(invalidation
));
765 delegate_
->OnPaintLayer(
766 PaintContext(display_list
, device_scale_factor_
, clip
, invalidation
));
770 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_
; }
772 bool Layer::PrepareTextureMailbox(
773 cc::TextureMailbox
* mailbox
,
774 scoped_ptr
<cc::SingleReleaseCallback
>* release_callback
,
775 bool use_shared_memory
) {
776 if (!mailbox_release_callback_
)
779 *release_callback
= mailbox_release_callback_
.Pass();
783 void Layer::SetForceRenderSurface(bool force
) {
784 if (force_render_surface_
== force
)
787 force_render_surface_
= force
;
788 cc_layer_
->SetForceRenderSurface(force_render_surface_
);
791 class LayerDebugInfo
: public base::trace_event::ConvertableToTraceFormat
{
793 explicit LayerDebugInfo(std::string name
) : name_(name
) { }
794 void AppendAsTraceFormat(std::string
* out
) const override
{
795 base::DictionaryValue dictionary
;
796 dictionary
.SetString("layer_name", name_
);
797 base::JSONWriter::Write(&dictionary
, out
);
801 ~LayerDebugInfo() override
{}
805 scoped_refptr
<base::trace_event::ConvertableToTraceFormat
>
806 Layer::TakeDebugInfo() {
807 return new LayerDebugInfo(name_
);
810 void Layer::OnAnimationStarted(const cc::AnimationEvent
& event
) {
812 animator_
->OnThreadedAnimationStarted(event
);
815 void Layer::CollectAnimators(
816 std::vector
<scoped_refptr
<LayerAnimator
> >* animators
) {
818 animators
->push_back(animator_
);
819 std::for_each(children_
.begin(), children_
.end(),
820 std::bind2nd(std::mem_fun(&Layer::CollectAnimators
),
824 void Layer::StackRelativeTo(Layer
* child
, Layer
* other
, bool above
) {
825 DCHECK_NE(child
, other
);
826 DCHECK_EQ(this, child
->parent());
827 DCHECK_EQ(this, other
->parent());
829 const size_t child_i
=
830 std::find(children_
.begin(), children_
.end(), child
) - children_
.begin();
831 const size_t other_i
=
832 std::find(children_
.begin(), children_
.end(), other
) - children_
.begin();
833 if ((above
&& child_i
== other_i
+ 1) || (!above
&& child_i
+ 1 == other_i
))
836 const size_t dest_i
=
838 (child_i
< other_i
? other_i
: other_i
+ 1) :
839 (child_i
< other_i
? other_i
- 1 : other_i
);
840 children_
.erase(children_
.begin() + child_i
);
841 children_
.insert(children_
.begin() + dest_i
, child
);
843 child
->cc_layer_
->RemoveFromParent();
844 cc_layer_
->InsertChild(child
->cc_layer_
, dest_i
);
847 bool Layer::ConvertPointForAncestor(const Layer
* ancestor
,
848 gfx::Point
* point
) const {
849 gfx::Transform transform
;
850 bool result
= GetTargetTransformRelativeTo(ancestor
, &transform
);
851 gfx::Point3F
p(*point
);
852 transform
.TransformPoint(&p
);
853 *point
= gfx::ToFlooredPoint(p
.AsPointF());
857 bool Layer::ConvertPointFromAncestor(const Layer
* ancestor
,
858 gfx::Point
* point
) const {
859 gfx::Transform transform
;
860 bool result
= GetTargetTransformRelativeTo(ancestor
, &transform
);
861 gfx::Point3F
p(*point
);
862 transform
.TransformPointReverse(&p
);
863 *point
= gfx::ToFlooredPoint(p
.AsPointF());
867 void Layer::SetBoundsFromAnimation(const gfx::Rect
& bounds
) {
868 if (bounds
== bounds_
)
871 base::Closure closure
;
873 closure
= delegate_
->PrepareForLayerBoundsChange();
874 bool was_move
= bounds_
.size() == bounds
.size();
877 RecomputeDrawsContentAndUVRect();
880 if (!closure
.is_null())
884 // Don't schedule a draw if we're invisible. We'll schedule one
885 // automatically when we get visible.
889 // Always schedule a paint, even if we're invisible.
890 SchedulePaint(gfx::Rect(bounds
.size()));
894 void Layer::SetTransformFromAnimation(const gfx::Transform
& transform
) {
895 cc_layer_
->SetTransform(transform
);
898 void Layer::SetOpacityFromAnimation(float opacity
) {
899 cc_layer_
->SetOpacity(opacity
);
903 void Layer::SetVisibilityFromAnimation(bool visible
) {
904 if (visible_
== visible
)
908 cc_layer_
->SetHideLayerAndSubtree(!visible_
);
911 void Layer::SetBrightnessFromAnimation(float brightness
) {
912 layer_brightness_
= brightness
;
916 void Layer::SetGrayscaleFromAnimation(float grayscale
) {
917 layer_grayscale_
= grayscale
;
921 void Layer::SetColorFromAnimation(SkColor color
) {
922 DCHECK_EQ(type_
, LAYER_SOLID_COLOR
);
923 cc_layer_
->SetBackgroundColor(color
);
924 SetFillsBoundsOpaquely(SkColorGetA(color
) == 0xFF);
927 void Layer::ScheduleDrawForAnimation() {
931 const gfx::Rect
& Layer::GetBoundsForAnimation() const {
935 gfx::Transform
Layer::GetTransformForAnimation() const {
939 float Layer::GetOpacityForAnimation() const {
943 bool Layer::GetVisibilityForAnimation() const {
947 float Layer::GetBrightnessForAnimation() const {
948 return layer_brightness();
951 float Layer::GetGrayscaleForAnimation() const {
952 return layer_grayscale();
955 SkColor
Layer::GetColorForAnimation() const {
956 // WebColor is equivalent to SkColor, per WebColor.h.
957 // The NULL check is here since this is invoked regardless of whether we have
958 // been configured as LAYER_SOLID_COLOR.
959 return solid_color_layer_
.get() ?
960 solid_color_layer_
->background_color() : SK_ColorBLACK
;
963 float Layer::GetDeviceScaleFactor() const {
964 return device_scale_factor_
;
967 void Layer::AddThreadedAnimation(scoped_ptr
<cc::Animation
> animation
) {
969 // Until this layer has a compositor (and hence cc_layer_ has a
970 // LayerTreeHost), addAnimation will fail.
972 cc_layer_
->AddAnimation(animation
.Pass());
974 pending_threaded_animations_
.push_back(animation
.Pass());
979 struct HasAnimationId
{
980 HasAnimationId(int id
): id_(id
) {
983 bool operator()(cc::Animation
* animation
) const {
984 return animation
->id() == id_
;
993 void Layer::RemoveThreadedAnimation(int animation_id
) {
995 if (pending_threaded_animations_
.size() == 0) {
996 cc_layer_
->RemoveAnimation(animation_id
);
1000 pending_threaded_animations_
.erase(
1001 cc::remove_if(&pending_threaded_animations_
,
1002 pending_threaded_animations_
.begin(),
1003 pending_threaded_animations_
.end(),
1004 HasAnimationId(animation_id
)),
1005 pending_threaded_animations_
.end());
1008 LayerAnimatorCollection
* Layer::GetLayerAnimatorCollection() {
1009 Compositor
* compositor
= GetCompositor();
1010 return compositor
? compositor
->layer_animator_collection() : NULL
;
1013 void Layer::SendPendingThreadedAnimations() {
1014 for (cc::ScopedPtrVector
<cc::Animation
>::iterator it
=
1015 pending_threaded_animations_
.begin();
1016 it
!= pending_threaded_animations_
.end();
1018 cc_layer_
->AddAnimation(pending_threaded_animations_
.take(it
));
1020 pending_threaded_animations_
.clear();
1022 for (size_t i
= 0; i
< children_
.size(); ++i
)
1023 children_
[i
]->SendPendingThreadedAnimations();
1026 void Layer::CreateCcLayer() {
1027 if (type_
== LAYER_SOLID_COLOR
) {
1028 solid_color_layer_
= cc::SolidColorLayer::Create();
1029 cc_layer_
= solid_color_layer_
.get();
1030 } else if (type_
== LAYER_NINE_PATCH
) {
1031 nine_patch_layer_
= cc::NinePatchLayer::Create();
1032 cc_layer_
= nine_patch_layer_
.get();
1034 if (Layer::UsingPictureLayer())
1035 content_layer_
= cc::PictureLayer::Create(this);
1037 content_layer_
= cc::ContentLayer::Create(this);
1038 cc_layer_
= content_layer_
.get();
1040 cc_layer_
->SetTransformOrigin(gfx::Point3F());
1041 cc_layer_
->SetContentsOpaque(true);
1042 cc_layer_
->SetIsDrawable(type_
!= LAYER_NOT_DRAWN
);
1043 cc_layer_
->AddLayerAnimationEventObserver(this);
1044 cc_layer_
->SetLayerClient(this);
1045 RecomputePosition();
1048 gfx::Transform
Layer::transform() const {
1049 return cc_layer_
->transform();
1052 void Layer::RecomputeDrawsContentAndUVRect() {
1054 gfx::Size
size(bounds_
.size());
1055 if (texture_layer_
.get()) {
1056 size
.SetToMin(frame_size_in_dip_
);
1057 gfx::PointF
uv_top_left(0.f
, 0.f
);
1058 gfx::PointF
uv_bottom_right(
1059 static_cast<float>(size
.width()) / frame_size_in_dip_
.width(),
1060 static_cast<float>(size
.height()) / frame_size_in_dip_
.height());
1061 texture_layer_
->SetUV(uv_top_left
, uv_bottom_right
);
1062 } else if (delegated_renderer_layer_
.get() || surface_layer_
.get()) {
1063 size
.SetToMin(frame_size_in_dip_
);
1065 cc_layer_
->SetBounds(size
);
1068 void Layer::RecomputePosition() {
1069 cc_layer_
->SetPosition(bounds_
.origin() + subpixel_position_offset_
);
1072 void Layer::AddAnimatorsInTreeToCollection(
1073 LayerAnimatorCollection
* collection
) {
1076 animator_
->AddToCollection(collection
);
1080 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection
),
1084 void Layer::RemoveAnimatorsInTreeFromCollection(
1085 LayerAnimatorCollection
* collection
) {
1088 animator_
->RemoveFromCollection(collection
);
1092 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection
),
1096 bool Layer::IsAnimating() const {
1097 return animator_
.get() && animator_
->is_animating();