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