ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / ui / compositor / layer.cc
blob700ed69d5641d8b9d1792482b1fdb65e0c6f9f54
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/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"
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;
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();
550 mailbox_ = mailbox;
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)
557 return;
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,
591 float scale,
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())
609 return;
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;
628 } else {
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()))
651 return false;
653 damaged_region_.op(invalid_rect.x(),
654 invalid_rect.y(),
655 invalid_rect.right(),
656 invalid_rect.bottom(),
657 SkRegion::kUnion_Op);
658 ScheduleDraw();
659 return true;
662 void Layer::ScheduleDraw() {
663 Compositor* compositor = GetCompositor();
664 if (compositor)
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();
672 gfx::Rect damaged(
673 sk_damaged.x(),
674 sk_damaged.y(),
675 sk_damaged.width(),
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();
691 ++it) {
692 (*it)->StopAnimating();
696 void Layer::SuppressPaint() {
697 if (!delegate_)
698 return;
699 delegate_ = NULL;
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)
706 return;
707 if (animator_.get())
708 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
709 device_scale_factor_ = device_scale_factor;
710 RecomputeDrawsContentAndUVRect();
711 RecomputePosition();
712 SchedulePaint(gfx::Rect(bounds_.size()));
713 if (delegate_)
714 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
715 for (size_t i = 0; i < children_.size(); ++i)
716 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
717 if (layer_mask_)
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());
723 if (!delegate_)
724 return;
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(
733 SkCanvas* sk_canvas,
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_));
739 if (delegate_)
740 delegate_->OnPaintLayer(canvas.get());
743 scoped_refptr<cc::DisplayItemList> Layer::PaintContentsToDisplayList(
744 const gfx::Rect& clip,
745 ContentLayerClient::PaintingControlSetting painting_control) {
746 NOTIMPLEMENTED();
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_)
757 return false;
758 *mailbox = mailbox_;
759 *release_callback = mailbox_release_callback_.Pass();
760 return true;
763 void Layer::SetForceRenderSurface(bool force) {
764 if (force_render_surface_ == force)
765 return;
767 force_render_surface_ = force;
768 cc_layer_->SetForceRenderSurface(force_render_surface_);
771 class LayerDebugInfo : public base::trace_event::ConvertableToTraceFormat {
772 public:
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);
780 private:
781 ~LayerDebugInfo() override {}
782 std::string name_;
785 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
786 Layer::TakeDebugInfo() {
787 return new LayerDebugInfo(name_);
790 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
791 if (animator_.get())
792 animator_->OnThreadedAnimationStarted(event);
795 void Layer::CollectAnimators(
796 std::vector<scoped_refptr<LayerAnimator> >* animators) {
797 if (IsAnimating())
798 animators->push_back(animator_);
799 std::for_each(children_.begin(), children_.end(),
800 std::bind2nd(std::mem_fun(&Layer::CollectAnimators),
801 animators));
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))
814 return;
816 const size_t dest_i =
817 above ?
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());
834 return result;
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());
844 return result;
847 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
848 if (bounds == bounds_)
849 return;
851 base::Closure closure;
852 if (delegate_)
853 closure = delegate_->PrepareForLayerBoundsChange();
854 bool was_move = bounds_.size() == bounds.size();
855 bounds_ = bounds;
857 RecomputeDrawsContentAndUVRect();
858 RecomputePosition();
860 if (!closure.is_null())
861 closure.Run();
863 if (was_move) {
864 // Don't schedule a draw if we're invisible. We'll schedule one
865 // automatically when we get visible.
866 if (IsDrawn())
867 ScheduleDraw();
868 } else {
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);
880 ScheduleDraw();
883 void Layer::SetVisibilityFromAnimation(bool visible) {
884 if (visible_ == visible)
885 return;
887 visible_ = visible;
888 cc_layer_->SetHideLayerAndSubtree(!visible_);
891 void Layer::SetBrightnessFromAnimation(float brightness) {
892 layer_brightness_ = brightness;
893 SetLayerFilters();
896 void Layer::SetGrayscaleFromAnimation(float grayscale) {
897 layer_grayscale_ = grayscale;
898 SetLayerFilters();
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() {
908 ScheduleDraw();
911 const gfx::Rect& Layer::GetBoundsForAnimation() const {
912 return bounds();
915 gfx::Transform Layer::GetTransformForAnimation() const {
916 return transform();
919 float Layer::GetOpacityForAnimation() const {
920 return opacity();
923 bool Layer::GetVisibilityForAnimation() const {
924 return visible();
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) {
948 DCHECK(cc_layer_);
949 // Until this layer has a compositor (and hence cc_layer_ has a
950 // LayerTreeHost), addAnimation will fail.
951 if (GetCompositor())
952 cc_layer_->AddAnimation(animation.Pass());
953 else
954 pending_threaded_animations_.push_back(animation.Pass());
957 namespace{
959 struct HasAnimationId {
960 HasAnimationId(int id): id_(id) {
963 bool operator()(cc::Animation* animation) const {
964 return animation->id() == id_;
967 private:
968 int id_;
973 void Layer::RemoveThreadedAnimation(int animation_id) {
974 DCHECK(cc_layer_);
975 if (pending_threaded_animations_.size() == 0) {
976 cc_layer_->RemoveAnimation(animation_id);
977 return;
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();
997 ++it)
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();
1013 } else {
1014 if (Layer::UsingPictureLayer())
1015 content_layer_ = cc::PictureLayer::Create(this);
1016 else
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() {
1033 DCHECK(cc_layer_);
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) {
1054 DCHECK(collection);
1055 if (IsAnimating())
1056 animator_->AddToCollection(collection);
1057 std::for_each(
1058 children_.begin(),
1059 children_.end(),
1060 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection),
1061 collection));
1064 void Layer::RemoveAnimatorsInTreeFromCollection(
1065 LayerAnimatorCollection* collection) {
1066 DCHECK(collection);
1067 if (IsAnimating())
1068 animator_->RemoveFromCollection(collection);
1069 std::for_each(
1070 children_.begin(),
1071 children_.end(),
1072 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection),
1073 collection));
1076 bool Layer::IsAnimating() const {
1077 return animator_.get() && animator_->is_animating();
1080 } // namespace ui