Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / compositor / layer.cc
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
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 {
47   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
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
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
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
129 bool Layer::UsingPictureLayer() {
130   return g_ui_impl_side_painting_status.Get().enabled;
131 }
132
133 Compositor* Layer::GetCompositor() {
134   return GetRoot(this)->compositor_;
135 }
136
137 float Layer::opacity() const {
138   return cc_layer_->opacity();
139 }
140
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
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
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_;
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
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
198 void Layer::StackAbove(Layer* child, Layer* other) {
199   StackRelativeTo(child, other, true);
200 }
201
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
208 void Layer::StackBelow(Layer* child, Layer* other) {
209   StackRelativeTo(child, other, false);
210 }
211
212 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
220 void Layer::SetAnimator(LayerAnimator* animator) {
221   if (animator)
222     animator->SetDelegate(this);
223   animator_ = animator;
224 }
225
226 LayerAnimator* Layer::GetAnimator() {
227   if (!animator_.get())
228     SetAnimator(LayerAnimator::CreateDefaultAnimator());
229   return animator_.get();
230 }
231
232 void Layer::SetTransform(const gfx::Transform& transform) {
233   GetAnimator()->SetTransform(transform);
234 }
235
236 gfx::Transform Layer::GetTargetTransform() const {
237   if (animator_.get() && animator_->IsAnimatingProperty(
238       LayerAnimationElement::TRANSFORM)) {
239     return animator_->GetTargetTransform();
240   }
241   return transform();
242 }
243
244 void Layer::SetBounds(const gfx::Rect& bounds) {
245   GetAnimator()->SetBounds(bounds);
246 }
247
248 void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF offset) {
249   subpixel_position_offset_ = offset;
250   RecomputePosition();
251 }
252
253 gfx::Rect Layer::GetTargetBounds() const {
254   if (animator_.get() && animator_->IsAnimatingProperty(
255       LayerAnimationElement::BOUNDS)) {
256     return animator_->GetTargetBounds();
257   }
258   return bounds_;
259 }
260
261 void Layer::SetMasksToBounds(bool masks_to_bounds) {
262   cc_layer_->SetMasksToBounds(masks_to_bounds);
263 }
264
265 bool Layer::GetMasksToBounds() const {
266   return cc_layer_->masks_to_bounds();
267 }
268
269 void Layer::SetOpacity(float opacity) {
270   GetAnimator()->SetOpacity(opacity);
271 }
272
273 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
283 void Layer::SetBackgroundBlur(int blur_radius) {
284   background_blur_radius_ = blur_radius;
285
286   SetLayerBackgroundFilters();
287 }
288
289 void Layer::SetLayerSaturation(float saturation) {
290   layer_saturation_ = saturation;
291   SetLayerFilters();
292 }
293
294 void Layer::SetLayerBrightness(float brightness) {
295   GetAnimator()->SetBrightness(brightness);
296 }
297
298 float Layer::GetTargetBrightness() const {
299   if (animator_.get() && animator_->IsAnimatingProperty(
300       LayerAnimationElement::BRIGHTNESS)) {
301     return animator_->GetTargetBrightness();
302   }
303   return layer_brightness();
304 }
305
306 void Layer::SetLayerGrayscale(float grayscale) {
307   GetAnimator()->SetGrayscale(grayscale);
308 }
309
310 float Layer::GetTargetGrayscale() const {
311   if (animator_.get() && animator_->IsAnimatingProperty(
312       LayerAnimationElement::GRAYSCALE)) {
313     return animator_->GetTargetGrayscale();
314   }
315   return layer_grayscale();
316 }
317
318 void Layer::SetLayerInverted(bool inverted) {
319   layer_inverted_ = inverted;
320   SetLayerFilters();
321 }
322
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
347 void Layer::SetBackgroundZoom(float zoom, int inset) {
348   zoom_ = zoom;
349   zoom_inset_ = inset;
350
351   SetLayerBackgroundFilters();
352 }
353
354 void Layer::SetAlphaShape(scoped_ptr<SkRegion> region) {
355   alpha_shape_ = region.Pass();
356
357   SetLayerFilters();
358 }
359
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_, 1.f, 0.f));
382   }
383
384   cc_layer_->SetFilters(filters);
385 }
386
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
400 float Layer::GetTargetOpacity() const {
401   if (animator_.get() && animator_->IsAnimatingProperty(
402       LayerAnimationElement::OPACITY))
403     return animator_->GetTargetOpacity();
404   return opacity();
405 }
406
407 void Layer::SetVisible(bool visible) {
408   GetAnimator()->SetVisibility(visible);
409 }
410
411 bool Layer::GetTargetVisibility() const {
412   if (animator_.get() && animator_->IsAnimatingProperty(
413       LayerAnimationElement::VISIBILITY))
414     return animator_->GetTargetVisibility();
415   return visible_;
416 }
417
418 bool Layer::IsDrawn() const {
419   const Layer* layer = this;
420   while (layer && layer->visible_)
421     layer = layer->parent_;
422   return layer == NULL;
423 }
424
425 bool Layer::ShouldDraw() const {
426   return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f;
427 }
428
429 // static
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
445 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
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
470 void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely) {
471   fills_bounds_completely_ = fills_bounds_completely;
472 }
473
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
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
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_) {
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
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
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
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
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
601 void Layer::UpdateNinePatchLayerBitmap(const SkBitmap& bitmap,
602                                        const gfx::Rect& aperture) {
603   DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
604   SkBitmap bitmap_copy;
605   if (bitmap.isImmutable()) {
606     bitmap_copy = bitmap;
607   } else {
608     // UIResourceBitmap requires an immutable copy of the input |bitmap|.
609     bitmap.copyTo(&bitmap_copy);
610     bitmap_copy.setImmutable();
611   }
612   nine_patch_layer_->SetBitmap(bitmap_copy);
613   nine_patch_layer_->SetAperture(aperture);
614 }
615
616 void Layer::UpdateNinePatchLayerBorder(const gfx::Rect& border) {
617   DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
618   nine_patch_layer_->SetBorder(border);
619 }
620
621 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
622
623 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
624   if (type_ == LAYER_SOLID_COLOR ||
625       type_ == LAYER_NINE_PATCH ||
626       (!delegate_ && !mailbox_.IsValid()))
627     return false;
628
629   damaged_region_.op(invalid_rect.x(),
630                      invalid_rect.y(),
631                      invalid_rect.right(),
632                      invalid_rect.bottom(),
633                      SkRegion::kUnion_Op);
634   ScheduleDraw();
635   return true;
636 }
637
638 void Layer::ScheduleDraw() {
639   Compositor* compositor = GetCompositor();
640   if (compositor)
641     compositor->ScheduleDraw();
642 }
643
644 void Layer::SendDamagedRects() {
645   if ((delegate_ || mailbox_.IsValid()) && !damaged_region_.isEmpty()) {
646     for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) {
647       const SkIRect& sk_damaged = iter.rect();
648       gfx::Rect damaged(
649           sk_damaged.x(),
650           sk_damaged.y(),
651           sk_damaged.width(),
652           sk_damaged.height());
653       cc_layer_->SetNeedsDisplayRect(damaged);
654     }
655     damaged_region_.setEmpty();
656   }
657   for (size_t i = 0; i < children_.size(); ++i)
658     children_[i]->SendDamagedRects();
659 }
660
661 void Layer::CompleteAllAnimations() {
662   std::vector<scoped_refptr<LayerAnimator> > animators;
663   CollectAnimators(&animators);
664   std::for_each(animators.begin(), animators.end(),
665                 std::mem_fun(&LayerAnimator::StopAnimating));
666 }
667
668 void Layer::SuppressPaint() {
669   if (!delegate_)
670     return;
671   delegate_ = NULL;
672   for (size_t i = 0; i < children_.size(); ++i)
673     children_[i]->SuppressPaint();
674 }
675
676 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) {
677   if (device_scale_factor_ == device_scale_factor)
678     return;
679   if (animator_.get())
680     animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
681   device_scale_factor_ = device_scale_factor;
682   RecomputeDrawsContentAndUVRect();
683   RecomputePosition();
684   SchedulePaint(gfx::Rect(bounds_.size()));
685   if (delegate_)
686     delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
687   for (size_t i = 0; i < children_.size(); ++i)
688     children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
689   if (layer_mask_)
690     layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor);
691 }
692
693 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
694   cc_layer_->RequestCopyOfOutput(request.Pass());
695 }
696
697 void Layer::PaintContents(SkCanvas* sk_canvas,
698                           const gfx::Rect& clip,
699                           gfx::RectF* opaque,
700                           ContentLayerClient::GraphicsContextStatus gc_status) {
701   TRACE_EVENT0("ui", "Layer::PaintContents");
702   scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
703       sk_canvas, device_scale_factor_));
704   if (delegate_)
705     delegate_->OnPaintLayer(canvas.get());
706 }
707
708 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_; }
709
710 bool Layer::PrepareTextureMailbox(
711     cc::TextureMailbox* mailbox,
712     scoped_ptr<cc::SingleReleaseCallback>* release_callback,
713     bool use_shared_memory) {
714   if (!mailbox_release_callback_)
715     return false;
716   *mailbox = mailbox_;
717   *release_callback = mailbox_release_callback_.Pass();
718   return true;
719 }
720
721 void Layer::SetForceRenderSurface(bool force) {
722   if (force_render_surface_ == force)
723     return;
724
725   force_render_surface_ = force;
726   cc_layer_->SetForceRenderSurface(force_render_surface_);
727 }
728
729 class LayerDebugInfo : public base::debug::ConvertableToTraceFormat {
730  public:
731   explicit LayerDebugInfo(std::string name) : name_(name) { }
732   virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
733     base::DictionaryValue dictionary;
734     dictionary.SetString("layer_name", name_);
735     base::JSONWriter::Write(&dictionary, out);
736   }
737
738  private:
739   virtual ~LayerDebugInfo() { }
740   std::string name_;
741 };
742
743 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
744   return new LayerDebugInfo(name_);
745 }
746
747 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
748   if (animator_.get())
749     animator_->OnThreadedAnimationStarted(event);
750 }
751
752 void Layer::CollectAnimators(
753     std::vector<scoped_refptr<LayerAnimator> >* animators) {
754   if (IsAnimating())
755     animators->push_back(animator_);
756   std::for_each(children_.begin(), children_.end(),
757                 std::bind2nd(std::mem_fun(&Layer::CollectAnimators),
758                              animators));
759 }
760
761 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
762   DCHECK_NE(child, other);
763   DCHECK_EQ(this, child->parent());
764   DCHECK_EQ(this, other->parent());
765
766   const size_t child_i =
767       std::find(children_.begin(), children_.end(), child) - children_.begin();
768   const size_t other_i =
769       std::find(children_.begin(), children_.end(), other) - children_.begin();
770   if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
771     return;
772
773   const size_t dest_i =
774       above ?
775       (child_i < other_i ? other_i : other_i + 1) :
776       (child_i < other_i ? other_i - 1 : other_i);
777   children_.erase(children_.begin() + child_i);
778   children_.insert(children_.begin() + dest_i, child);
779
780   child->cc_layer_->RemoveFromParent();
781   cc_layer_->InsertChild(child->cc_layer_, dest_i);
782 }
783
784 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
785                                     gfx::Point* point) const {
786   gfx::Transform transform;
787   bool result = GetTargetTransformRelativeTo(ancestor, &transform);
788   gfx::Point3F p(*point);
789   transform.TransformPoint(&p);
790   *point = gfx::ToFlooredPoint(p.AsPointF());
791   return result;
792 }
793
794 bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
795                                      gfx::Point* point) const {
796   gfx::Transform transform;
797   bool result = GetTargetTransformRelativeTo(ancestor, &transform);
798   gfx::Point3F p(*point);
799   transform.TransformPointReverse(&p);
800   *point = gfx::ToFlooredPoint(p.AsPointF());
801   return result;
802 }
803
804 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
805   if (bounds == bounds_)
806     return;
807
808   base::Closure closure;
809   if (delegate_)
810     closure = delegate_->PrepareForLayerBoundsChange();
811   bool was_move = bounds_.size() == bounds.size();
812   bounds_ = bounds;
813
814   RecomputeDrawsContentAndUVRect();
815   RecomputePosition();
816
817   if (!closure.is_null())
818     closure.Run();
819
820   if (was_move) {
821     // Don't schedule a draw if we're invisible. We'll schedule one
822     // automatically when we get visible.
823     if (IsDrawn())
824       ScheduleDraw();
825   } else {
826     // Always schedule a paint, even if we're invisible.
827     SchedulePaint(gfx::Rect(bounds.size()));
828   }
829 }
830
831 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
832   cc_layer_->SetTransform(transform);
833 }
834
835 void Layer::SetOpacityFromAnimation(float opacity) {
836   cc_layer_->SetOpacity(opacity);
837   ScheduleDraw();
838 }
839
840 void Layer::SetVisibilityFromAnimation(bool visible) {
841   if (visible_ == visible)
842     return;
843
844   visible_ = visible;
845   cc_layer_->SetHideLayerAndSubtree(!visible_);
846 }
847
848 void Layer::SetBrightnessFromAnimation(float brightness) {
849   layer_brightness_ = brightness;
850   SetLayerFilters();
851 }
852
853 void Layer::SetGrayscaleFromAnimation(float grayscale) {
854   layer_grayscale_ = grayscale;
855   SetLayerFilters();
856 }
857
858 void Layer::SetColorFromAnimation(SkColor color) {
859   DCHECK_EQ(type_, LAYER_SOLID_COLOR);
860   solid_color_layer_->SetBackgroundColor(color);
861   SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
862 }
863
864 void Layer::ScheduleDrawForAnimation() {
865   ScheduleDraw();
866 }
867
868 const gfx::Rect& Layer::GetBoundsForAnimation() const {
869   return bounds();
870 }
871
872 gfx::Transform Layer::GetTransformForAnimation() const {
873   return transform();
874 }
875
876 float Layer::GetOpacityForAnimation() const {
877   return opacity();
878 }
879
880 bool Layer::GetVisibilityForAnimation() const {
881   return visible();
882 }
883
884 float Layer::GetBrightnessForAnimation() const {
885   return layer_brightness();
886 }
887
888 float Layer::GetGrayscaleForAnimation() const {
889   return layer_grayscale();
890 }
891
892 SkColor Layer::GetColorForAnimation() const {
893   // WebColor is equivalent to SkColor, per WebColor.h.
894   // The NULL check is here since this is invoked regardless of whether we have
895   // been configured as LAYER_SOLID_COLOR.
896   return solid_color_layer_.get() ?
897       solid_color_layer_->background_color() : SK_ColorBLACK;
898 }
899
900 float Layer::GetDeviceScaleFactor() const {
901   return device_scale_factor_;
902 }
903
904 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
905   DCHECK(cc_layer_);
906   // Until this layer has a compositor (and hence cc_layer_ has a
907   // LayerTreeHost), addAnimation will fail.
908   if (GetCompositor())
909     cc_layer_->AddAnimation(animation.Pass());
910   else
911     pending_threaded_animations_.push_back(animation.Pass());
912 }
913
914 namespace{
915
916 struct HasAnimationId {
917   HasAnimationId(int id): id_(id) {
918   }
919
920   bool operator()(cc::Animation* animation) const {
921     return animation->id() == id_;
922   }
923
924  private:
925   int id_;
926 };
927
928 }
929
930 void Layer::RemoveThreadedAnimation(int animation_id) {
931   DCHECK(cc_layer_);
932   if (pending_threaded_animations_.size() == 0) {
933     cc_layer_->RemoveAnimation(animation_id);
934     return;
935   }
936
937   pending_threaded_animations_.erase(
938       cc::remove_if(&pending_threaded_animations_,
939                     pending_threaded_animations_.begin(),
940                     pending_threaded_animations_.end(),
941                     HasAnimationId(animation_id)),
942       pending_threaded_animations_.end());
943 }
944
945 LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() {
946   Compositor* compositor = GetCompositor();
947   return compositor ? compositor->layer_animator_collection() : NULL;
948 }
949
950 void Layer::SendPendingThreadedAnimations() {
951   for (cc::ScopedPtrVector<cc::Animation>::iterator it =
952            pending_threaded_animations_.begin();
953        it != pending_threaded_animations_.end();
954        ++it)
955     cc_layer_->AddAnimation(pending_threaded_animations_.take(it));
956
957   pending_threaded_animations_.clear();
958
959   for (size_t i = 0; i < children_.size(); ++i)
960     children_[i]->SendPendingThreadedAnimations();
961 }
962
963 void Layer::CreateWebLayer() {
964   if (type_ == LAYER_SOLID_COLOR) {
965     solid_color_layer_ = cc::SolidColorLayer::Create();
966     cc_layer_ = solid_color_layer_.get();
967   } else if (type_ == LAYER_NINE_PATCH) {
968     nine_patch_layer_ = cc::NinePatchLayer::Create();
969     cc_layer_ = nine_patch_layer_.get();
970   } else {
971     if (Layer::UsingPictureLayer())
972       content_layer_ = cc::PictureLayer::Create(this);
973     else
974       content_layer_ = cc::ContentLayer::Create(this);
975     cc_layer_ = content_layer_.get();
976   }
977   cc_layer_->SetTransformOrigin(gfx::Point3F());
978   cc_layer_->SetContentsOpaque(true);
979   cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
980   cc_layer_->AddLayerAnimationEventObserver(this);
981   cc_layer_->SetLayerClient(this);
982   RecomputePosition();
983 }
984
985 gfx::Transform Layer::transform() const {
986   return cc_layer_->transform();
987 }
988
989 void Layer::RecomputeDrawsContentAndUVRect() {
990   DCHECK(cc_layer_);
991   gfx::Size size(bounds_.size());
992   if (texture_layer_.get()) {
993     size.SetToMin(frame_size_in_dip_);
994     gfx::PointF uv_top_left(0.f, 0.f);
995     gfx::PointF uv_bottom_right(
996         static_cast<float>(size.width()) / frame_size_in_dip_.width(),
997         static_cast<float>(size.height()) / frame_size_in_dip_.height());
998     texture_layer_->SetUV(uv_top_left, uv_bottom_right);
999   } else if (delegated_renderer_layer_.get() || surface_layer_.get()) {
1000     size.SetToMin(frame_size_in_dip_);
1001   }
1002   cc_layer_->SetBounds(size);
1003 }
1004
1005 void Layer::RecomputePosition() {
1006   cc_layer_->SetPosition(bounds_.origin() + subpixel_position_offset_);
1007 }
1008
1009 void Layer::AddAnimatorsInTreeToCollection(
1010     LayerAnimatorCollection* collection) {
1011   DCHECK(collection);
1012   if (IsAnimating())
1013     animator_->AddToCollection(collection);
1014   std::for_each(
1015       children_.begin(),
1016       children_.end(),
1017       std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection),
1018                    collection));
1019 }
1020
1021 void Layer::RemoveAnimatorsInTreeFromCollection(
1022     LayerAnimatorCollection* collection) {
1023   DCHECK(collection);
1024   if (IsAnimating())
1025     animator_->RemoveFromCollection(collection);
1026   std::for_each(
1027       children_.begin(),
1028       children_.end(),
1029       std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection),
1030                    collection));
1031 }
1032
1033 bool Layer::IsAnimating() const {
1034   return animator_ && animator_->is_animating();
1035 }
1036
1037 }  // namespace ui