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