Skip direct map from apk check for Samsung Mega.
[chromium-blink-merge.git] / ui / compositor / layer.cc
blob947cf6241dbf4adb4fe0e3ea67d2c15a60f9bd02
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"
7 #include <algorithm>
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"
39 namespace {
41 const ui::Layer* GetRoot(const ui::Layer* layer) {
42 while (layer->parent())
43 layer = layer->parent();
44 return layer;
47 struct UIImplSidePaintingStatus {
48 UIImplSidePaintingStatus()
49 : enabled(ui::IsUIImplSidePaintingEnabled()) {
51 bool enabled;
53 base::LazyInstance<UIImplSidePaintingStatus> g_ui_impl_side_painting_status =
54 LAZY_INSTANCE_INITIALIZER;
56 } // namespace
58 namespace ui {
60 Layer::Layer()
61 : type_(LAYER_TEXTURED),
62 compositor_(NULL),
63 parent_(NULL),
64 visible_(true),
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),
73 layer_mask_(NULL),
74 layer_mask_back_link_(NULL),
75 zoom_(1),
76 zoom_inset_(0),
77 delegate_(NULL),
78 owner_(NULL),
79 cc_layer_(NULL),
80 device_scale_factor_(1.0f) {
81 CreateCcLayer();
84 Layer::Layer(LayerType type)
85 : type_(type),
86 compositor_(NULL),
87 parent_(NULL),
88 visible_(true),
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),
97 layer_mask_(NULL),
98 layer_mask_back_link_(NULL),
99 zoom_(1),
100 zoom_inset_(0),
101 delegate_(NULL),
102 owner_(NULL),
103 cc_layer_(NULL),
104 device_scale_factor_(1.0f) {
105 CreateCcLayer();
108 Layer::~Layer() {
109 // Destroying the animator may cause observers to use the layer (and
110 // indirectly the WebLayer). Destroy the animator first so that the WebLayer
111 // is still around.
112 if (animator_.get())
113 animator_->SetDelegate(NULL);
114 animator_ = NULL;
115 if (compositor_)
116 compositor_->SetRootLayer(NULL);
117 if (parent_)
118 parent_->Remove(this);
119 if (layer_mask_)
120 SetMaskLayer(NULL);
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();
129 // static
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,
144 // or to reset it.
145 DCHECK(!compositor || !compositor_);
146 DCHECK(!compositor || compositor->root_layer() == this);
147 DCHECK(!parent_);
148 if (compositor_) {
149 RemoveAnimatorsInTreeFromCollection(
150 compositor_->layer_animator_collection());
152 compositor_ = compositor;
153 if (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_);
162 if (child->parent_)
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_);
168 if (GetCompositor())
169 child->SendPendingThreadedAnimations();
170 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
171 if (collection)
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();
179 if (child_animator)
180 child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS);
181 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
182 if (collection)
183 child->RemoveAnimatorsInTreeFromCollection(collection);
185 std::vector<Layer*>::iterator i =
186 std::find(children_.begin(), children_.end(), child);
187 DCHECK(i != children_.end());
188 children_.erase(i);
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()) {
215 if (parent == this)
216 return true;
218 return false;
221 void Layer::SetAnimator(LayerAnimator* animator) {
222 if (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();
242 return transform();
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;
251 RecomputePosition();
254 gfx::Rect Layer::GetTargetBounds() const {
255 if (animator_.get() && animator_->IsAnimatingProperty(
256 LayerAnimationElement::BOUNDS)) {
257 return animator_->GetTargetBounds();
259 return bounds_;
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_;
277 while (current) {
278 opacity *= current->opacity();
279 current = current->parent_;
281 return opacity;
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;
292 SetLayerFilters();
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;
321 SetLayerFilters();
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)
332 return;
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.
335 if (layer_mask_)
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.
342 if (layer_mask) {
343 layer_mask->layer_mask_back_link_ = this;
344 layer_mask->OnDeviceScaleFactorChanged(device_scale_factor_);
348 void Layer::SetBackgroundZoom(float zoom, int inset) {
349 zoom_ = zoom;
350 zoom_inset_ = inset;
352 SetLayerBackgroundFilters();
355 void Layer::SetAlphaShape(scoped_ptr<SkRegion> region) {
356 alpha_shape_ = region.Pass();
358 SetLayerFilters();
361 void Layer::SetLayerFilters() {
362 cc::FilterOperations filters;
363 if (layer_saturation_) {
364 filters.Append(cc::FilterOperation::CreateSaturateFilter(
365 layer_saturation_));
367 if (layer_grayscale_) {
368 filters.Append(cc::FilterOperation::CreateGrayscaleFilter(
369 layer_grayscale_));
371 if (layer_inverted_)
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(
378 layer_brightness_));
380 if (alpha_shape_) {
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;
390 if (zoom_ != 1)
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();
405 return opacity();
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();
416 return visible_;
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;
430 // static
431 void Layer::ConvertPointToLayer(const Layer* source,
432 const Layer* target,
433 gfx::Point* point) {
434 if (source == target)
435 return;
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
454 // finished.
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)
464 return;
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_);
516 SetLayerFilters();
517 SetLayerBackgroundFilters();
520 void Layer::SwitchCCLayerForTest() {
521 scoped_refptr<cc::Layer> new_layer;
522 if (Layer::UsingPictureLayer())
523 new_layer = cc::PictureLayer::Create(this);
524 else
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();
547 mailbox_ = mailbox;
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)
554 return;
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,
578 float scale,
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())
596 return;
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;
615 } else {
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()))
638 return false;
640 damaged_region_.op(invalid_rect.x(),
641 invalid_rect.y(),
642 invalid_rect.right(),
643 invalid_rect.bottom(),
644 SkRegion::kUnion_Op);
645 ScheduleDraw();
646 return true;
649 void Layer::ScheduleDraw() {
650 Compositor* compositor = GetCompositor();
651 if (compositor)
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();
659 gfx::Rect damaged(
660 sk_damaged.x(),
661 sk_damaged.y(),
662 sk_damaged.width(),
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();
678 ++it) {
679 (*it)->StopAnimating();
683 void Layer::SuppressPaint() {
684 if (!delegate_)
685 return;
686 delegate_ = NULL;
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)
693 return;
694 if (animator_.get())
695 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
696 device_scale_factor_ = device_scale_factor;
697 RecomputeDrawsContentAndUVRect();
698 RecomputePosition();
699 SchedulePaint(gfx::Rect(bounds_.size()));
700 if (delegate_)
701 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
702 for (size_t i = 0; i < children_.size(); ++i)
703 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
704 if (layer_mask_)
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());
710 if (!delegate_)
711 return;
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_));
725 if (delegate_)
726 delegate_->OnPaintLayer(canvas.get());
729 scoped_refptr<cc::DisplayItemList> Layer::PaintContentsToDisplayList(
730 const gfx::Rect& clip,
731 ContentLayerClient::GraphicsContextStatus gc_status) {
732 NOTIMPLEMENTED();
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_)
743 return false;
744 *mailbox = mailbox_;
745 *release_callback = mailbox_release_callback_.Pass();
746 return true;
749 void Layer::SetForceRenderSurface(bool force) {
750 if (force_render_surface_ == force)
751 return;
753 force_render_surface_ = force;
754 cc_layer_->SetForceRenderSurface(force_render_surface_);
757 class LayerDebugInfo : public base::debug::ConvertableToTraceFormat {
758 public:
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);
766 private:
767 ~LayerDebugInfo() override {}
768 std::string name_;
771 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
772 return new LayerDebugInfo(name_);
775 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
776 if (animator_.get())
777 animator_->OnThreadedAnimationStarted(event);
780 void Layer::CollectAnimators(
781 std::vector<scoped_refptr<LayerAnimator> >* animators) {
782 if (IsAnimating())
783 animators->push_back(animator_);
784 std::for_each(children_.begin(), children_.end(),
785 std::bind2nd(std::mem_fun(&Layer::CollectAnimators),
786 animators));
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))
799 return;
801 const size_t dest_i =
802 above ?
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());
819 return result;
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());
829 return result;
832 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
833 if (bounds == bounds_)
834 return;
836 base::Closure closure;
837 if (delegate_)
838 closure = delegate_->PrepareForLayerBoundsChange();
839 bool was_move = bounds_.size() == bounds.size();
840 bounds_ = bounds;
842 RecomputeDrawsContentAndUVRect();
843 RecomputePosition();
845 if (!closure.is_null())
846 closure.Run();
848 if (was_move) {
849 // Don't schedule a draw if we're invisible. We'll schedule one
850 // automatically when we get visible.
851 if (IsDrawn())
852 ScheduleDraw();
853 } else {
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);
865 ScheduleDraw();
868 void Layer::SetVisibilityFromAnimation(bool visible) {
869 if (visible_ == visible)
870 return;
872 visible_ = visible;
873 cc_layer_->SetHideLayerAndSubtree(!visible_);
876 void Layer::SetBrightnessFromAnimation(float brightness) {
877 layer_brightness_ = brightness;
878 SetLayerFilters();
881 void Layer::SetGrayscaleFromAnimation(float grayscale) {
882 layer_grayscale_ = grayscale;
883 SetLayerFilters();
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() {
893 ScheduleDraw();
896 const gfx::Rect& Layer::GetBoundsForAnimation() const {
897 return bounds();
900 gfx::Transform Layer::GetTransformForAnimation() const {
901 return transform();
904 float Layer::GetOpacityForAnimation() const {
905 return opacity();
908 bool Layer::GetVisibilityForAnimation() const {
909 return visible();
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) {
933 DCHECK(cc_layer_);
934 // Until this layer has a compositor (and hence cc_layer_ has a
935 // LayerTreeHost), addAnimation will fail.
936 if (GetCompositor())
937 cc_layer_->AddAnimation(animation.Pass());
938 else
939 pending_threaded_animations_.push_back(animation.Pass());
942 namespace{
944 struct HasAnimationId {
945 HasAnimationId(int id): id_(id) {
948 bool operator()(cc::Animation* animation) const {
949 return animation->id() == id_;
952 private:
953 int id_;
958 void Layer::RemoveThreadedAnimation(int animation_id) {
959 DCHECK(cc_layer_);
960 if (pending_threaded_animations_.size() == 0) {
961 cc_layer_->RemoveAnimation(animation_id);
962 return;
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();
982 ++it)
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();
998 } else {
999 if (Layer::UsingPictureLayer())
1000 content_layer_ = cc::PictureLayer::Create(this);
1001 else
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() {
1018 DCHECK(cc_layer_);
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) {
1039 DCHECK(collection);
1040 if (IsAnimating())
1041 animator_->AddToCollection(collection);
1042 std::for_each(
1043 children_.begin(),
1044 children_.end(),
1045 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection),
1046 collection));
1049 void Layer::RemoveAnimatorsInTreeFromCollection(
1050 LayerAnimatorCollection* collection) {
1051 DCHECK(collection);
1052 if (IsAnimating())
1053 animator_->RemoveFromCollection(collection);
1054 std::for_each(
1055 children_.begin(),
1056 children_.end(),
1057 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection),
1058 collection));
1061 bool Layer::IsAnimating() const {
1062 return animator_.get() && animator_->is_animating();
1065 } // namespace ui