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.
4
5 #include "ui/compositor/layer.h"
6
7 #include <algorithm>
8
9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h"
11 #include "base/json/json_writer.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "cc/base/scoped_ptr_algorithm.h"
15 #include "cc/layers/content_layer.h"
16 #include "cc/layers/delegated_renderer_layer.h"
17 #include "cc/layers/picture_layer.h"
18 #include "cc/layers/solid_color_layer.h"
19 #include "cc/layers/texture_layer.h"
20 #include "cc/output/copy_output_request.h"
21 #include "cc/output/delegated_frame_data.h"
22 #include "cc/output/filter_operation.h"
23 #include "cc/output/filter_operations.h"
24 #include "cc/resources/transferable_resource.h"
25 #include "ui/compositor/compositor_switches.h"
26 #include "ui/compositor/dip_util.h"
27 #include "ui/compositor/layer_animator.h"
28 #include "ui/gfx/animation/animation.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/display.h"
31 #include "ui/gfx/interpolated_transform.h"
32 #include "ui/gfx/point3_f.h"
33 #include "ui/gfx/point_conversions.h"
34 #include "ui/gfx/size_conversions.h"
35
36 namespace {
37
GetRoot(const ui::Layer * layer)38 const ui::Layer* GetRoot(const ui::Layer* layer) {
39 while (layer->parent())
40 layer = layer->parent();
41 return layer;
42 }
43
44 struct UIImplSidePaintingStatus {
UIImplSidePaintingStatus__anon081fd66b0111::UIImplSidePaintingStatus45 UIImplSidePaintingStatus()
46 : enabled(ui::IsUIImplSidePaintingEnabled()) {
47 }
48 bool enabled;
49 };
50 base::LazyInstance<UIImplSidePaintingStatus> g_ui_impl_side_painting_status =
51 LAZY_INSTANCE_INITIALIZER;
52
53 } // namespace
54
55 namespace ui {
56
Layer()57 Layer::Layer()
58 : type_(LAYER_TEXTURED),
59 compositor_(NULL),
60 parent_(NULL),
61 visible_(true),
62 force_render_surface_(false),
63 fills_bounds_opaquely_(true),
64 fills_bounds_completely_(false),
65 background_blur_radius_(0),
66 layer_saturation_(0.0f),
67 layer_brightness_(0.0f),
68 layer_grayscale_(0.0f),
69 layer_inverted_(false),
70 layer_mask_(NULL),
71 layer_mask_back_link_(NULL),
72 zoom_(1),
73 zoom_inset_(0),
74 delegate_(NULL),
75 owner_(NULL),
76 cc_layer_(NULL),
77 device_scale_factor_(1.0f) {
78 CreateWebLayer();
79 }
80
Layer(LayerType type)81 Layer::Layer(LayerType type)
82 : type_(type),
83 compositor_(NULL),
84 parent_(NULL),
85 visible_(true),
86 force_render_surface_(false),
87 fills_bounds_opaquely_(true),
88 fills_bounds_completely_(false),
89 background_blur_radius_(0),
90 layer_saturation_(0.0f),
91 layer_brightness_(0.0f),
92 layer_grayscale_(0.0f),
93 layer_inverted_(false),
94 layer_mask_(NULL),
95 layer_mask_back_link_(NULL),
96 zoom_(1),
97 zoom_inset_(0),
98 delegate_(NULL),
99 owner_(NULL),
100 cc_layer_(NULL),
101 device_scale_factor_(1.0f) {
102 CreateWebLayer();
103 }
104
~Layer()105 Layer::~Layer() {
106 // Destroying the animator may cause observers to use the layer (and
107 // indirectly the WebLayer). Destroy the animator first so that the WebLayer
108 // is still around.
109 if (animator_.get())
110 animator_->SetDelegate(NULL);
111 animator_ = NULL;
112 if (compositor_)
113 compositor_->SetRootLayer(NULL);
114 if (parent_)
115 parent_->Remove(this);
116 if (layer_mask_)
117 SetMaskLayer(NULL);
118 if (layer_mask_back_link_)
119 layer_mask_back_link_->SetMaskLayer(NULL);
120 for (size_t i = 0; i < children_.size(); ++i)
121 children_[i]->parent_ = NULL;
122 cc_layer_->RemoveLayerAnimationEventObserver(this);
123 cc_layer_->RemoveFromParent();
124 }
125
126 // static
UsingPictureLayer()127 bool Layer::UsingPictureLayer() {
128 return g_ui_impl_side_painting_status.Get().enabled;
129 }
130
GetCompositor()131 Compositor* Layer::GetCompositor() {
132 return GetRoot(this)->compositor_;
133 }
134
opacity() const135 float Layer::opacity() const {
136 return cc_layer_->opacity();
137 }
138
SetCompositor(Compositor * compositor)139 void Layer::SetCompositor(Compositor* compositor) {
140 // This function must only be called to set the compositor on the root layer,
141 // or to reset it.
142 DCHECK(!compositor || !compositor_);
143 DCHECK(!compositor || compositor->root_layer() == this);
144 DCHECK(!parent_);
145 if (compositor_) {
146 RemoveAnimatorsInTreeFromCollection(
147 compositor_->layer_animator_collection());
148 }
149 compositor_ = compositor;
150 if (compositor) {
151 OnDeviceScaleFactorChanged(compositor->device_scale_factor());
152 SendPendingThreadedAnimations();
153 AddAnimatorsInTreeToCollection(compositor_->layer_animator_collection());
154 }
155 }
156
Add(Layer * child)157 void Layer::Add(Layer* child) {
158 DCHECK(!child->compositor_);
159 if (child->parent_)
160 child->parent_->Remove(child);
161 child->parent_ = this;
162 children_.push_back(child);
163 cc_layer_->AddChild(child->cc_layer_);
164 child->OnDeviceScaleFactorChanged(device_scale_factor_);
165 if (GetCompositor())
166 child->SendPendingThreadedAnimations();
167 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
168 if (collection)
169 child->AddAnimatorsInTreeToCollection(collection);
170 }
171
Remove(Layer * child)172 void Layer::Remove(Layer* child) {
173 // Current bounds are used to calculate offsets when layers are reparented.
174 // Stop (and complete) an ongoing animation to update the bounds immediately.
175 LayerAnimator* child_animator = child->animator_;
176 if (child_animator)
177 child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS);
178 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
179 if (collection)
180 child->RemoveAnimatorsInTreeFromCollection(collection);
181
182 std::vector<Layer*>::iterator i =
183 std::find(children_.begin(), children_.end(), child);
184 DCHECK(i != children_.end());
185 children_.erase(i);
186 child->parent_ = NULL;
187 child->cc_layer_->RemoveFromParent();
188 }
189
StackAtTop(Layer * child)190 void Layer::StackAtTop(Layer* child) {
191 if (children_.size() <= 1 || child == children_.back())
192 return; // Already in front.
193 StackAbove(child, children_.back());
194 }
195
StackAbove(Layer * child,Layer * other)196 void Layer::StackAbove(Layer* child, Layer* other) {
197 StackRelativeTo(child, other, true);
198 }
199
StackAtBottom(Layer * child)200 void Layer::StackAtBottom(Layer* child) {
201 if (children_.size() <= 1 || child == children_.front())
202 return; // Already on bottom.
203 StackBelow(child, children_.front());
204 }
205
StackBelow(Layer * child,Layer * other)206 void Layer::StackBelow(Layer* child, Layer* other) {
207 StackRelativeTo(child, other, false);
208 }
209
Contains(const Layer * other) const210 bool Layer::Contains(const Layer* other) const {
211 for (const Layer* parent = other; parent; parent = parent->parent()) {
212 if (parent == this)
213 return true;
214 }
215 return false;
216 }
217
SetAnimator(LayerAnimator * animator)218 void Layer::SetAnimator(LayerAnimator* animator) {
219 if (animator)
220 animator->SetDelegate(this);
221 animator_ = animator;
222 }
223
GetAnimator()224 LayerAnimator* Layer::GetAnimator() {
225 if (!animator_.get())
226 SetAnimator(LayerAnimator::CreateDefaultAnimator());
227 return animator_.get();
228 }
229
SetTransform(const gfx::Transform & transform)230 void Layer::SetTransform(const gfx::Transform& transform) {
231 GetAnimator()->SetTransform(transform);
232 }
233
GetTargetTransform() const234 gfx::Transform Layer::GetTargetTransform() const {
235 if (animator_.get() && animator_->IsAnimatingProperty(
236 LayerAnimationElement::TRANSFORM)) {
237 return animator_->GetTargetTransform();
238 }
239 return transform();
240 }
241
SetBounds(const gfx::Rect & bounds)242 void Layer::SetBounds(const gfx::Rect& bounds) {
243 GetAnimator()->SetBounds(bounds);
244 }
245
SetSubpixelPositionOffset(const gfx::Vector2dF offset)246 void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF offset) {
247 subpixel_position_offset_ = offset;
248 RecomputePosition();
249 }
250
GetTargetBounds() const251 gfx::Rect Layer::GetTargetBounds() const {
252 if (animator_.get() && animator_->IsAnimatingProperty(
253 LayerAnimationElement::BOUNDS)) {
254 return animator_->GetTargetBounds();
255 }
256 return bounds_;
257 }
258
SetMasksToBounds(bool masks_to_bounds)259 void Layer::SetMasksToBounds(bool masks_to_bounds) {
260 cc_layer_->SetMasksToBounds(masks_to_bounds);
261 }
262
GetMasksToBounds() const263 bool Layer::GetMasksToBounds() const {
264 return cc_layer_->masks_to_bounds();
265 }
266
SetOpacity(float opacity)267 void Layer::SetOpacity(float opacity) {
268 GetAnimator()->SetOpacity(opacity);
269 }
270
GetCombinedOpacity() const271 float Layer::GetCombinedOpacity() const {
272 float opacity = this->opacity();
273 Layer* current = this->parent_;
274 while (current) {
275 opacity *= current->opacity();
276 current = current->parent_;
277 }
278 return opacity;
279 }
280
SetBackgroundBlur(int blur_radius)281 void Layer::SetBackgroundBlur(int blur_radius) {
282 background_blur_radius_ = blur_radius;
283
284 SetLayerBackgroundFilters();
285 }
286
SetLayerSaturation(float saturation)287 void Layer::SetLayerSaturation(float saturation) {
288 layer_saturation_ = saturation;
289 SetLayerFilters();
290 }
291
SetLayerBrightness(float brightness)292 void Layer::SetLayerBrightness(float brightness) {
293 GetAnimator()->SetBrightness(brightness);
294 }
295
GetTargetBrightness() const296 float Layer::GetTargetBrightness() const {
297 if (animator_.get() && animator_->IsAnimatingProperty(
298 LayerAnimationElement::BRIGHTNESS)) {
299 return animator_->GetTargetBrightness();
300 }
301 return layer_brightness();
302 }
303
SetLayerGrayscale(float grayscale)304 void Layer::SetLayerGrayscale(float grayscale) {
305 GetAnimator()->SetGrayscale(grayscale);
306 }
307
GetTargetGrayscale() const308 float Layer::GetTargetGrayscale() const {
309 if (animator_.get() && animator_->IsAnimatingProperty(
310 LayerAnimationElement::GRAYSCALE)) {
311 return animator_->GetTargetGrayscale();
312 }
313 return layer_grayscale();
314 }
315
SetLayerInverted(bool inverted)316 void Layer::SetLayerInverted(bool inverted) {
317 layer_inverted_ = inverted;
318 SetLayerFilters();
319 }
320
SetMaskLayer(Layer * layer_mask)321 void Layer::SetMaskLayer(Layer* layer_mask) {
322 // The provided mask should not have a layer mask itself.
323 DCHECK(!layer_mask ||
324 (!layer_mask->layer_mask_layer() &&
325 layer_mask->children().empty() &&
326 !layer_mask->layer_mask_back_link_));
327 DCHECK(!layer_mask_back_link_);
328 if (layer_mask_ == layer_mask)
329 return;
330 // We need to de-reference the currently linked object so that no problem
331 // arises if the mask layer gets deleted before this object.
332 if (layer_mask_)
333 layer_mask_->layer_mask_back_link_ = NULL;
334 layer_mask_ = layer_mask;
335 cc_layer_->SetMaskLayer(
336 layer_mask ? layer_mask->cc_layer() : NULL);
337 // We need to reference the linked object so that it can properly break the
338 // link to us when it gets deleted.
339 if (layer_mask) {
340 layer_mask->layer_mask_back_link_ = this;
341 layer_mask->OnDeviceScaleFactorChanged(device_scale_factor_);
342 }
343 }
344
SetBackgroundZoom(float zoom,int inset)345 void Layer::SetBackgroundZoom(float zoom, int inset) {
346 zoom_ = zoom;
347 zoom_inset_ = inset;
348
349 SetLayerBackgroundFilters();
350 }
351
SetAlphaShape(scoped_ptr<SkRegion> region)352 void Layer::SetAlphaShape(scoped_ptr<SkRegion> region) {
353 alpha_shape_ = region.Pass();
354
355 SetLayerFilters();
356 }
357
SetLayerFilters()358 void Layer::SetLayerFilters() {
359 cc::FilterOperations filters;
360 if (layer_saturation_) {
361 filters.Append(cc::FilterOperation::CreateSaturateFilter(
362 layer_saturation_));
363 }
364 if (layer_grayscale_) {
365 filters.Append(cc::FilterOperation::CreateGrayscaleFilter(
366 layer_grayscale_));
367 }
368 if (layer_inverted_)
369 filters.Append(cc::FilterOperation::CreateInvertFilter(1.0));
370 // Brightness goes last, because the resulting colors neeed clamping, which
371 // cause further color matrix filters to be applied separately. In this order,
372 // they all can be combined in a single pass.
373 if (layer_brightness_) {
374 filters.Append(cc::FilterOperation::CreateSaturatingBrightnessFilter(
375 layer_brightness_));
376 }
377 if (alpha_shape_) {
378 filters.Append(cc::FilterOperation::CreateAlphaThresholdFilter(
379 *alpha_shape_, 1.f, 0.f));
380 }
381
382 cc_layer_->SetFilters(filters);
383 }
384
SetLayerBackgroundFilters()385 void Layer::SetLayerBackgroundFilters() {
386 cc::FilterOperations filters;
387 if (zoom_ != 1)
388 filters.Append(cc::FilterOperation::CreateZoomFilter(zoom_, zoom_inset_));
389
390 if (background_blur_radius_) {
391 filters.Append(cc::FilterOperation::CreateBlurFilter(
392 background_blur_radius_));
393 }
394
395 cc_layer_->SetBackgroundFilters(filters);
396 }
397
GetTargetOpacity() const398 float Layer::GetTargetOpacity() const {
399 if (animator_.get() && animator_->IsAnimatingProperty(
400 LayerAnimationElement::OPACITY))
401 return animator_->GetTargetOpacity();
402 return opacity();
403 }
404
SetVisible(bool visible)405 void Layer::SetVisible(bool visible) {
406 GetAnimator()->SetVisibility(visible);
407 }
408
GetTargetVisibility() const409 bool Layer::GetTargetVisibility() const {
410 if (animator_.get() && animator_->IsAnimatingProperty(
411 LayerAnimationElement::VISIBILITY))
412 return animator_->GetTargetVisibility();
413 return visible_;
414 }
415
IsDrawn() const416 bool Layer::IsDrawn() const {
417 const Layer* layer = this;
418 while (layer && layer->visible_)
419 layer = layer->parent_;
420 return layer == NULL;
421 }
422
ShouldDraw() const423 bool Layer::ShouldDraw() const {
424 return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f;
425 }
426
427 // static
ConvertPointToLayer(const Layer * source,const Layer * target,gfx::Point * point)428 void Layer::ConvertPointToLayer(const Layer* source,
429 const Layer* target,
430 gfx::Point* point) {
431 if (source == target)
432 return;
433
434 const Layer* root_layer = GetRoot(source);
435 CHECK_EQ(root_layer, GetRoot(target));
436
437 if (source != root_layer)
438 source->ConvertPointForAncestor(root_layer, point);
439 if (target != root_layer)
440 target->ConvertPointFromAncestor(root_layer, point);
441 }
442
GetTargetTransformRelativeTo(const Layer * ancestor,gfx::Transform * transform) const443 bool Layer::GetTargetTransformRelativeTo(const Layer* ancestor,
444 gfx::Transform* transform) const {
445 const Layer* p = this;
446 for (; p && p != ancestor; p = p->parent()) {
447 gfx::Transform translation;
448 translation.Translate(static_cast<float>(p->bounds().x()),
449 static_cast<float>(p->bounds().y()));
450 // Use target transform so that result will be correct once animation is
451 // finished.
452 if (!p->GetTargetTransform().IsIdentity())
453 transform->ConcatTransform(p->GetTargetTransform());
454 transform->ConcatTransform(translation);
455 }
456 return p == ancestor;
457 }
458
SetFillsBoundsOpaquely(bool fills_bounds_opaquely)459 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
460 if (fills_bounds_opaquely_ == fills_bounds_opaquely)
461 return;
462
463 fills_bounds_opaquely_ = fills_bounds_opaquely;
464
465 cc_layer_->SetContentsOpaque(fills_bounds_opaquely);
466 }
467
SetFillsBoundsCompletely(bool fills_bounds_completely)468 void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely) {
469 fills_bounds_completely_ = fills_bounds_completely;
470 }
471
SwitchToLayer(scoped_refptr<cc::Layer> new_layer)472 void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
473 // Finish animations being handled by cc_layer_.
474 if (animator_.get()) {
475 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
476 animator_->StopAnimatingProperty(LayerAnimationElement::OPACITY);
477 }
478
479 if (texture_layer_.get())
480 texture_layer_->ClearClient();
481 // TODO(piman): delegated_renderer_layer_ cleanup.
482
483 cc_layer_->RemoveAllChildren();
484 if (cc_layer_->parent()) {
485 cc_layer_->parent()->ReplaceChild(cc_layer_, new_layer);
486 }
487 cc_layer_->SetLayerClient(NULL);
488 cc_layer_->RemoveLayerAnimationEventObserver(this);
489 new_layer->SetOpacity(cc_layer_->opacity());
490 new_layer->SetTransform(cc_layer_->transform());
491 new_layer->SetPosition(cc_layer_->position());
492
493 cc_layer_ = new_layer.get();
494 content_layer_ = NULL;
495 solid_color_layer_ = NULL;
496 texture_layer_ = NULL;
497 delegated_renderer_layer_ = NULL;
498
499 cc_layer_->AddLayerAnimationEventObserver(this);
500 for (size_t i = 0; i < children_.size(); ++i) {
501 DCHECK(children_[i]->cc_layer_);
502 cc_layer_->AddChild(children_[i]->cc_layer_);
503 }
504 cc_layer_->SetLayerClient(this);
505 cc_layer_->SetTransformOrigin(gfx::Point3F());
506 cc_layer_->SetContentsOpaque(fills_bounds_opaquely_);
507 cc_layer_->SetForceRenderSurface(force_render_surface_);
508 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
509 cc_layer_->SetHideLayerAndSubtree(!visible_);
510 }
511
SwitchCCLayerForTest()512 void Layer::SwitchCCLayerForTest() {
513 scoped_refptr<cc::Layer> new_layer;
514 if (Layer::UsingPictureLayer())
515 new_layer = cc::PictureLayer::Create(this);
516 else
517 new_layer = cc::ContentLayer::Create(this);
518 SwitchToLayer(new_layer);
519 content_layer_ = new_layer;
520 }
521
SetTextureMailbox(const cc::TextureMailbox & mailbox,scoped_ptr<cc::SingleReleaseCallback> release_callback,gfx::Size texture_size_in_dip)522 void Layer::SetTextureMailbox(
523 const cc::TextureMailbox& mailbox,
524 scoped_ptr<cc::SingleReleaseCallback> release_callback,
525 gfx::Size texture_size_in_dip) {
526 DCHECK_EQ(type_, LAYER_TEXTURED);
527 DCHECK(!solid_color_layer_.get());
528 DCHECK(mailbox.IsValid());
529 DCHECK(release_callback);
530 if (!texture_layer_) {
531 scoped_refptr<cc::TextureLayer> new_layer =
532 cc::TextureLayer::CreateForMailbox(this);
533 new_layer->SetFlipped(true);
534 SwitchToLayer(new_layer);
535 texture_layer_ = new_layer;
536 }
537 if (mailbox_release_callback_)
538 mailbox_release_callback_->Run(0, false);
539 mailbox_release_callback_ = release_callback.Pass();
540 mailbox_ = mailbox;
541 SetTextureSize(texture_size_in_dip);
542 }
543
SetTextureSize(gfx::Size texture_size_in_dip)544 void Layer::SetTextureSize(gfx::Size texture_size_in_dip) {
545 DCHECK(texture_layer_.get());
546 if (frame_size_in_dip_ == texture_size_in_dip)
547 return;
548 frame_size_in_dip_ = texture_size_in_dip;
549 RecomputeDrawsContentAndUVRect();
550 texture_layer_->SetNeedsDisplay();
551 }
552
SetShowDelegatedContent(cc::DelegatedFrameProvider * frame_provider,gfx::Size frame_size_in_dip)553 void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
554 gfx::Size frame_size_in_dip) {
555 DCHECK_EQ(type_, LAYER_TEXTURED);
556
557 scoped_refptr<cc::DelegatedRendererLayer> new_layer =
558 cc::DelegatedRendererLayer::Create(frame_provider);
559 SwitchToLayer(new_layer);
560 delegated_renderer_layer_ = new_layer;
561
562 frame_size_in_dip_ = frame_size_in_dip;
563 RecomputeDrawsContentAndUVRect();
564 }
565
SetShowPaintedContent()566 void Layer::SetShowPaintedContent() {
567 if (content_layer_.get())
568 return;
569
570 scoped_refptr<cc::Layer> new_layer;
571 if (Layer::UsingPictureLayer())
572 new_layer = cc::PictureLayer::Create(this);
573 else
574 new_layer = cc::ContentLayer::Create(this);
575 SwitchToLayer(new_layer);
576 content_layer_ = new_layer;
577
578 mailbox_ = cc::TextureMailbox();
579 if (mailbox_release_callback_) {
580 mailbox_release_callback_->Run(0, false);
581 mailbox_release_callback_.reset();
582 }
583 RecomputeDrawsContentAndUVRect();
584 }
585
SetColor(SkColor color)586 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
587
SchedulePaint(const gfx::Rect & invalid_rect)588 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
589 if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !mailbox_.IsValid()))
590 return false;
591
592 damaged_region_.op(invalid_rect.x(),
593 invalid_rect.y(),
594 invalid_rect.right(),
595 invalid_rect.bottom(),
596 SkRegion::kUnion_Op);
597 ScheduleDraw();
598 return true;
599 }
600
ScheduleDraw()601 void Layer::ScheduleDraw() {
602 Compositor* compositor = GetCompositor();
603 if (compositor)
604 compositor->ScheduleDraw();
605 }
606
SendDamagedRects()607 void Layer::SendDamagedRects() {
608 if ((delegate_ || mailbox_.IsValid()) && !damaged_region_.isEmpty()) {
609 for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) {
610 const SkIRect& sk_damaged = iter.rect();
611 gfx::Rect damaged(
612 sk_damaged.x(),
613 sk_damaged.y(),
614 sk_damaged.width(),
615 sk_damaged.height());
616 cc_layer_->SetNeedsDisplayRect(damaged);
617 }
618 damaged_region_.setEmpty();
619 }
620 for (size_t i = 0; i < children_.size(); ++i)
621 children_[i]->SendDamagedRects();
622 }
623
CompleteAllAnimations()624 void Layer::CompleteAllAnimations() {
625 std::vector<scoped_refptr<LayerAnimator> > animators;
626 CollectAnimators(&animators);
627 std::for_each(animators.begin(), animators.end(),
628 std::mem_fun(&LayerAnimator::StopAnimating));
629 }
630
SuppressPaint()631 void Layer::SuppressPaint() {
632 if (!delegate_)
633 return;
634 delegate_ = NULL;
635 for (size_t i = 0; i < children_.size(); ++i)
636 children_[i]->SuppressPaint();
637 }
638
OnDeviceScaleFactorChanged(float device_scale_factor)639 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) {
640 if (device_scale_factor_ == device_scale_factor)
641 return;
642 if (animator_.get())
643 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
644 device_scale_factor_ = device_scale_factor;
645 RecomputeDrawsContentAndUVRect();
646 RecomputePosition();
647 SchedulePaint(gfx::Rect(bounds_.size()));
648 if (delegate_)
649 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
650 for (size_t i = 0; i < children_.size(); ++i)
651 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
652 if (layer_mask_)
653 layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor);
654 }
655
RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request)656 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
657 cc_layer_->RequestCopyOfOutput(request.Pass());
658 }
659
PaintContents(SkCanvas * sk_canvas,const gfx::Rect & clip,gfx::RectF * opaque,ContentLayerClient::GraphicsContextStatus gc_status)660 void Layer::PaintContents(SkCanvas* sk_canvas,
661 const gfx::Rect& clip,
662 gfx::RectF* opaque,
663 ContentLayerClient::GraphicsContextStatus gc_status) {
664 TRACE_EVENT0("ui", "Layer::PaintContents");
665 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
666 sk_canvas, device_scale_factor_));
667 if (delegate_)
668 delegate_->OnPaintLayer(canvas.get());
669 }
670
FillsBoundsCompletely() const671 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_; }
672
PrepareTextureMailbox(cc::TextureMailbox * mailbox,scoped_ptr<cc::SingleReleaseCallback> * release_callback,bool use_shared_memory)673 bool Layer::PrepareTextureMailbox(
674 cc::TextureMailbox* mailbox,
675 scoped_ptr<cc::SingleReleaseCallback>* release_callback,
676 bool use_shared_memory) {
677 if (!mailbox_release_callback_)
678 return false;
679 *mailbox = mailbox_;
680 *release_callback = mailbox_release_callback_.Pass();
681 return true;
682 }
683
SetForceRenderSurface(bool force)684 void Layer::SetForceRenderSurface(bool force) {
685 if (force_render_surface_ == force)
686 return;
687
688 force_render_surface_ = force;
689 cc_layer_->SetForceRenderSurface(force_render_surface_);
690 }
691
692 class LayerDebugInfo : public base::debug::ConvertableToTraceFormat {
693 public:
LayerDebugInfo(std::string name)694 explicit LayerDebugInfo(std::string name) : name_(name) { }
AppendAsTraceFormat(std::string * out) const695 virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
696 base::DictionaryValue dictionary;
697 dictionary.SetString("layer_name", name_);
698 base::JSONWriter::Write(&dictionary, out);
699 }
700
701 private:
~LayerDebugInfo()702 virtual ~LayerDebugInfo() { }
703 std::string name_;
704 };
705
TakeDebugInfo()706 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
707 return new LayerDebugInfo(name_);
708 }
709
OnAnimationStarted(const cc::AnimationEvent & event)710 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
711 if (animator_.get())
712 animator_->OnThreadedAnimationStarted(event);
713 }
714
CollectAnimators(std::vector<scoped_refptr<LayerAnimator>> * animators)715 void Layer::CollectAnimators(
716 std::vector<scoped_refptr<LayerAnimator> >* animators) {
717 if (IsAnimating())
718 animators->push_back(animator_);
719 std::for_each(children_.begin(), children_.end(),
720 std::bind2nd(std::mem_fun(&Layer::CollectAnimators),
721 animators));
722 }
723
StackRelativeTo(Layer * child,Layer * other,bool above)724 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
725 DCHECK_NE(child, other);
726 DCHECK_EQ(this, child->parent());
727 DCHECK_EQ(this, other->parent());
728
729 const size_t child_i =
730 std::find(children_.begin(), children_.end(), child) - children_.begin();
731 const size_t other_i =
732 std::find(children_.begin(), children_.end(), other) - children_.begin();
733 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
734 return;
735
736 const size_t dest_i =
737 above ?
738 (child_i < other_i ? other_i : other_i + 1) :
739 (child_i < other_i ? other_i - 1 : other_i);
740 children_.erase(children_.begin() + child_i);
741 children_.insert(children_.begin() + dest_i, child);
742
743 child->cc_layer_->RemoveFromParent();
744 cc_layer_->InsertChild(child->cc_layer_, dest_i);
745 }
746
ConvertPointForAncestor(const Layer * ancestor,gfx::Point * point) const747 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
748 gfx::Point* point) const {
749 gfx::Transform transform;
750 bool result = GetTargetTransformRelativeTo(ancestor, &transform);
751 gfx::Point3F p(*point);
752 transform.TransformPoint(&p);
753 *point = gfx::ToFlooredPoint(p.AsPointF());
754 return result;
755 }
756
ConvertPointFromAncestor(const Layer * ancestor,gfx::Point * point) const757 bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
758 gfx::Point* point) const {
759 gfx::Transform transform;
760 bool result = GetTargetTransformRelativeTo(ancestor, &transform);
761 gfx::Point3F p(*point);
762 transform.TransformPointReverse(&p);
763 *point = gfx::ToFlooredPoint(p.AsPointF());
764 return result;
765 }
766
SetBoundsFromAnimation(const gfx::Rect & bounds)767 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
768 if (bounds == bounds_)
769 return;
770
771 base::Closure closure;
772 if (delegate_)
773 closure = delegate_->PrepareForLayerBoundsChange();
774 bool was_move = bounds_.size() == bounds.size();
775 bounds_ = bounds;
776
777 RecomputeDrawsContentAndUVRect();
778 RecomputePosition();
779
780 if (!closure.is_null())
781 closure.Run();
782
783 if (was_move) {
784 // Don't schedule a draw if we're invisible. We'll schedule one
785 // automatically when we get visible.
786 if (IsDrawn())
787 ScheduleDraw();
788 } else {
789 // Always schedule a paint, even if we're invisible.
790 SchedulePaint(gfx::Rect(bounds.size()));
791 }
792 }
793
SetTransformFromAnimation(const gfx::Transform & transform)794 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
795 cc_layer_->SetTransform(transform);
796 }
797
SetOpacityFromAnimation(float opacity)798 void Layer::SetOpacityFromAnimation(float opacity) {
799 cc_layer_->SetOpacity(opacity);
800 ScheduleDraw();
801 }
802
SetVisibilityFromAnimation(bool visible)803 void Layer::SetVisibilityFromAnimation(bool visible) {
804 if (visible_ == visible)
805 return;
806
807 visible_ = visible;
808 cc_layer_->SetHideLayerAndSubtree(!visible_);
809 }
810
SetBrightnessFromAnimation(float brightness)811 void Layer::SetBrightnessFromAnimation(float brightness) {
812 layer_brightness_ = brightness;
813 SetLayerFilters();
814 }
815
SetGrayscaleFromAnimation(float grayscale)816 void Layer::SetGrayscaleFromAnimation(float grayscale) {
817 layer_grayscale_ = grayscale;
818 SetLayerFilters();
819 }
820
SetColorFromAnimation(SkColor color)821 void Layer::SetColorFromAnimation(SkColor color) {
822 DCHECK_EQ(type_, LAYER_SOLID_COLOR);
823 solid_color_layer_->SetBackgroundColor(color);
824 SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
825 }
826
ScheduleDrawForAnimation()827 void Layer::ScheduleDrawForAnimation() {
828 ScheduleDraw();
829 }
830
GetBoundsForAnimation() const831 const gfx::Rect& Layer::GetBoundsForAnimation() const {
832 return bounds();
833 }
834
GetTransformForAnimation() const835 gfx::Transform Layer::GetTransformForAnimation() const {
836 return transform();
837 }
838
GetOpacityForAnimation() const839 float Layer::GetOpacityForAnimation() const {
840 return opacity();
841 }
842
GetVisibilityForAnimation() const843 bool Layer::GetVisibilityForAnimation() const {
844 return visible();
845 }
846
GetBrightnessForAnimation() const847 float Layer::GetBrightnessForAnimation() const {
848 return layer_brightness();
849 }
850
GetGrayscaleForAnimation() const851 float Layer::GetGrayscaleForAnimation() const {
852 return layer_grayscale();
853 }
854
GetColorForAnimation() const855 SkColor Layer::GetColorForAnimation() const {
856 // WebColor is equivalent to SkColor, per WebColor.h.
857 // The NULL check is here since this is invoked regardless of whether we have
858 // been configured as LAYER_SOLID_COLOR.
859 return solid_color_layer_.get() ?
860 solid_color_layer_->background_color() : SK_ColorBLACK;
861 }
862
GetDeviceScaleFactor() const863 float Layer::GetDeviceScaleFactor() const {
864 return device_scale_factor_;
865 }
866
AddThreadedAnimation(scoped_ptr<cc::Animation> animation)867 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
868 DCHECK(cc_layer_);
869 // Until this layer has a compositor (and hence cc_layer_ has a
870 // LayerTreeHost), addAnimation will fail.
871 if (GetCompositor())
872 cc_layer_->AddAnimation(animation.Pass());
873 else
874 pending_threaded_animations_.push_back(animation.Pass());
875 }
876
877 namespace{
878
879 struct HasAnimationId {
HasAnimationIdui::__anon081fd66b0211::HasAnimationId880 HasAnimationId(int id): id_(id) {
881 }
882
operator ()ui::__anon081fd66b0211::HasAnimationId883 bool operator()(cc::Animation* animation) const {
884 return animation->id() == id_;
885 }
886
887 private:
888 int id_;
889 };
890
891 }
892
RemoveThreadedAnimation(int animation_id)893 void Layer::RemoveThreadedAnimation(int animation_id) {
894 DCHECK(cc_layer_);
895 if (pending_threaded_animations_.size() == 0) {
896 cc_layer_->RemoveAnimation(animation_id);
897 return;
898 }
899
900 pending_threaded_animations_.erase(
901 cc::remove_if(&pending_threaded_animations_,
902 pending_threaded_animations_.begin(),
903 pending_threaded_animations_.end(),
904 HasAnimationId(animation_id)),
905 pending_threaded_animations_.end());
906 }
907
GetLayerAnimatorCollection()908 LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() {
909 Compositor* compositor = GetCompositor();
910 return compositor ? compositor->layer_animator_collection() : NULL;
911 }
912
SendPendingThreadedAnimations()913 void Layer::SendPendingThreadedAnimations() {
914 for (cc::ScopedPtrVector<cc::Animation>::iterator it =
915 pending_threaded_animations_.begin();
916 it != pending_threaded_animations_.end();
917 ++it)
918 cc_layer_->AddAnimation(pending_threaded_animations_.take(it));
919
920 pending_threaded_animations_.clear();
921
922 for (size_t i = 0; i < children_.size(); ++i)
923 children_[i]->SendPendingThreadedAnimations();
924 }
925
CreateWebLayer()926 void Layer::CreateWebLayer() {
927 if (type_ == LAYER_SOLID_COLOR) {
928 solid_color_layer_ = cc::SolidColorLayer::Create();
929 cc_layer_ = solid_color_layer_.get();
930 } else {
931 if (Layer::UsingPictureLayer())
932 content_layer_ = cc::PictureLayer::Create(this);
933 else
934 content_layer_ = cc::ContentLayer::Create(this);
935 cc_layer_ = content_layer_.get();
936 }
937 cc_layer_->SetTransformOrigin(gfx::Point3F());
938 cc_layer_->SetContentsOpaque(true);
939 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
940 cc_layer_->AddLayerAnimationEventObserver(this);
941 cc_layer_->SetLayerClient(this);
942 RecomputePosition();
943 }
944
transform() const945 gfx::Transform Layer::transform() const {
946 return cc_layer_->transform();
947 }
948
RecomputeDrawsContentAndUVRect()949 void Layer::RecomputeDrawsContentAndUVRect() {
950 DCHECK(cc_layer_);
951 gfx::Size size(bounds_.size());
952 if (texture_layer_.get()) {
953 size.SetToMin(frame_size_in_dip_);
954 gfx::PointF uv_top_left(0.f, 0.f);
955 gfx::PointF uv_bottom_right(
956 static_cast<float>(size.width()) / frame_size_in_dip_.width(),
957 static_cast<float>(size.height()) / frame_size_in_dip_.height());
958 texture_layer_->SetUV(uv_top_left, uv_bottom_right);
959 } else if (delegated_renderer_layer_.get()) {
960 size.SetToMin(frame_size_in_dip_);
961 }
962 cc_layer_->SetBounds(size);
963 }
964
RecomputePosition()965 void Layer::RecomputePosition() {
966 cc_layer_->SetPosition(bounds_.origin() + subpixel_position_offset_);
967 }
968
AddAnimatorsInTreeToCollection(LayerAnimatorCollection * collection)969 void Layer::AddAnimatorsInTreeToCollection(
970 LayerAnimatorCollection* collection) {
971 DCHECK(collection);
972 if (IsAnimating())
973 animator_->AddToCollection(collection);
974 std::for_each(
975 children_.begin(),
976 children_.end(),
977 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection),
978 collection));
979 }
980
RemoveAnimatorsInTreeFromCollection(LayerAnimatorCollection * collection)981 void Layer::RemoveAnimatorsInTreeFromCollection(
982 LayerAnimatorCollection* collection) {
983 DCHECK(collection);
984 if (IsAnimating())
985 animator_->RemoveFromCollection(collection);
986 std::for_each(
987 children_.begin(),
988 children_.end(),
989 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection),
990 collection));
991 }
992
IsAnimating() const993 bool Layer::IsAnimating() const {
994 return animator_ && animator_->is_animating();
995 }
996
997 } // namespace ui
998