- add sources.
[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/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
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
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
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
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
115 Compositor* Layer::GetCompositor() {
116   return GetRoot(this)->compositor_;
117 }
118
119 float Layer::opacity() const {
120   return cc_layer_->opacity();
121 }
122
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
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
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
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
163 void Layer::StackAbove(Layer* child, Layer* other) {
164   StackRelativeTo(child, other, true);
165 }
166
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
173 void Layer::StackBelow(Layer* child, Layer* other) {
174   StackRelativeTo(child, other, false);
175 }
176
177 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
185 void Layer::SetAnimator(LayerAnimator* animator) {
186   if (animator)
187     animator->SetDelegate(this);
188   animator_ = animator;
189 }
190
191 LayerAnimator* Layer::GetAnimator() {
192   if (!animator_.get())
193     SetAnimator(LayerAnimator::CreateDefaultAnimator());
194   return animator_.get();
195 }
196
197 void Layer::SetTransform(const gfx::Transform& transform) {
198   GetAnimator()->SetTransform(transform);
199 }
200
201 gfx::Transform Layer::GetTargetTransform() const {
202   if (animator_.get() && animator_->IsAnimatingProperty(
203       LayerAnimationElement::TRANSFORM)) {
204     return animator_->GetTargetTransform();
205   }
206   return transform();
207 }
208
209 void Layer::SetBounds(const gfx::Rect& bounds) {
210   GetAnimator()->SetBounds(bounds);
211 }
212
213 gfx::Rect Layer::GetTargetBounds() const {
214   if (animator_.get() && animator_->IsAnimatingProperty(
215       LayerAnimationElement::BOUNDS)) {
216     return animator_->GetTargetBounds();
217   }
218   return bounds_;
219 }
220
221 void Layer::SetMasksToBounds(bool masks_to_bounds) {
222   cc_layer_->SetMasksToBounds(masks_to_bounds);
223 }
224
225 bool Layer::GetMasksToBounds() const {
226   return cc_layer_->masks_to_bounds();
227 }
228
229 void Layer::SetOpacity(float opacity) {
230   GetAnimator()->SetOpacity(opacity);
231 }
232
233 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
243 void Layer::SetBackgroundBlur(int blur_radius) {
244   background_blur_radius_ = blur_radius;
245
246   SetLayerBackgroundFilters();
247 }
248
249 void Layer::SetLayerSaturation(float saturation) {
250   layer_saturation_ = saturation;
251   SetLayerFilters();
252 }
253
254 void Layer::SetLayerBrightness(float brightness) {
255   GetAnimator()->SetBrightness(brightness);
256 }
257
258 float Layer::GetTargetBrightness() const {
259   if (animator_.get() && animator_->IsAnimatingProperty(
260       LayerAnimationElement::BRIGHTNESS)) {
261     return animator_->GetTargetBrightness();
262   }
263   return layer_brightness();
264 }
265
266 void Layer::SetLayerGrayscale(float grayscale) {
267   GetAnimator()->SetGrayscale(grayscale);
268 }
269
270 float Layer::GetTargetGrayscale() const {
271   if (animator_.get() && animator_->IsAnimatingProperty(
272       LayerAnimationElement::GRAYSCALE)) {
273     return animator_->GetTargetGrayscale();
274   }
275   return layer_grayscale();
276 }
277
278 void Layer::SetLayerInverted(bool inverted) {
279   layer_inverted_ = inverted;
280   SetLayerFilters();
281 }
282
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
307 void Layer::SetBackgroundZoom(float zoom, int inset) {
308   zoom_ = zoom;
309   zoom_inset_ = inset;
310
311   SetLayerBackgroundFilters();
312 }
313
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
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
350 float Layer::GetTargetOpacity() const {
351   if (animator_.get() && animator_->IsAnimatingProperty(
352       LayerAnimationElement::OPACITY))
353     return animator_->GetTargetOpacity();
354   return opacity();
355 }
356
357 void Layer::SetVisible(bool visible) {
358   GetAnimator()->SetVisibility(visible);
359 }
360
361 bool Layer::GetTargetVisibility() const {
362   if (animator_.get() && animator_->IsAnimatingProperty(
363       LayerAnimationElement::VISIBILITY))
364     return animator_->GetTargetVisibility();
365   return visible_;
366 }
367
368 bool Layer::IsDrawn() const {
369   const Layer* layer = this;
370   while (layer && layer->visible_)
371     layer = layer->parent_;
372   return layer == NULL;
373 }
374
375 bool Layer::ShouldDraw() const {
376   return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f;
377 }
378
379 // static
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
395 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
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
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
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
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
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
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
519 cc::TextureMailbox Layer::GetTextureMailbox(float* scale_factor) {
520   if (scale_factor)
521     *scale_factor = mailbox_scale_factor_;
522   return mailbox_;
523 }
524
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(NULL, 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
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
554 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
555
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
569 void Layer::ScheduleDraw() {
570   Compositor* compositor = GetCompositor();
571   if (compositor)
572     compositor->ScheduleDraw();
573 }
574
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
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
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
621 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
622   cc_layer_->RequestCopyOfOutput(request.Pass());
623 }
624
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
645 unsigned Layer::PrepareTexture() {
646   DCHECK(texture_layer_.get());
647   return texture_->PrepareTexture();
648 }
649
650 WebKit::WebGraphicsContext3D* Layer::Context3d() {
651   DCHECK(texture_layer_.get());
652   if (texture_.get())
653     return texture_->HostContext3D();
654   return NULL;
655 }
656
657 bool Layer::PrepareTextureMailbox(
658     cc::TextureMailbox* mailbox,
659     scoped_ptr<cc::SingleReleaseCallback>* release_callback,
660     bool use_shared_memory) {
661   return false;
662 }
663
664 void Layer::SetForceRenderSurface(bool force) {
665   if (force_render_surface_ == force)
666     return;
667
668   force_render_surface_ = force;
669   cc_layer_->SetForceRenderSurface(force_render_surface_);
670 }
671
672 std::string Layer::DebugName() {
673   return name_;
674 }
675
676 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
677   if (animator_.get())
678     animator_->OnThreadedAnimationStarted(event);
679 }
680
681 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
682   DCHECK_NE(child, other);
683   DCHECK_EQ(this, child->parent());
684   DCHECK_EQ(this, other->parent());
685
686   const size_t child_i =
687       std::find(children_.begin(), children_.end(), child) - children_.begin();
688   const size_t other_i =
689       std::find(children_.begin(), children_.end(), other) - children_.begin();
690   if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
691     return;
692
693   const size_t dest_i =
694       above ?
695       (child_i < other_i ? other_i : other_i + 1) :
696       (child_i < other_i ? other_i - 1 : other_i);
697   children_.erase(children_.begin() + child_i);
698   children_.insert(children_.begin() + dest_i, child);
699
700   child->cc_layer_->RemoveFromParent();
701   cc_layer_->InsertChild(child->cc_layer_, dest_i);
702 }
703
704 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
705                                     gfx::Point* point) const {
706   gfx::Transform transform;
707   bool result = GetTargetTransformRelativeTo(ancestor, &transform);
708   gfx::Point3F p(*point);
709   transform.TransformPoint(&p);
710   *point = gfx::ToFlooredPoint(p.AsPointF());
711   return result;
712 }
713
714 bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
715                                      gfx::Point* point) const {
716   gfx::Transform transform;
717   bool result = GetTargetTransformRelativeTo(ancestor, &transform);
718   gfx::Point3F p(*point);
719   transform.TransformPointReverse(&p);
720   *point = gfx::ToFlooredPoint(p.AsPointF());
721   return result;
722 }
723
724 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) {
725   if (bounds == bounds_)
726     return;
727
728   base::Closure closure;
729   if (delegate_)
730     closure = delegate_->PrepareForLayerBoundsChange();
731   bool was_move = bounds_.size() == bounds.size();
732   bounds_ = bounds;
733
734   RecomputeDrawsContentAndUVRect();
735   RecomputePosition();
736
737   if (!closure.is_null())
738     closure.Run();
739
740   if (was_move) {
741     // Don't schedule a draw if we're invisible. We'll schedule one
742     // automatically when we get visible.
743     if (IsDrawn())
744       ScheduleDraw();
745   } else {
746     // Always schedule a paint, even if we're invisible.
747     SchedulePaint(gfx::Rect(bounds.size()));
748   }
749 }
750
751 void Layer::SetTransformImmediately(const gfx::Transform& transform) {
752   RecomputeCCTransformFromTransform(transform);
753 }
754
755 void Layer::SetOpacityImmediately(float opacity) {
756   cc_layer_->SetOpacity(opacity);
757   ScheduleDraw();
758 }
759
760 void Layer::SetVisibilityImmediately(bool visible) {
761   if (visible_ == visible)
762     return;
763
764   visible_ = visible;
765   cc_layer_->SetHideLayerAndSubtree(!visible_);
766 }
767
768 void Layer::SetBrightnessImmediately(float brightness) {
769   layer_brightness_ = brightness;
770   SetLayerFilters();
771 }
772
773 void Layer::SetGrayscaleImmediately(float grayscale) {
774   layer_grayscale_ = grayscale;
775   SetLayerFilters();
776 }
777
778 void Layer::SetColorImmediately(SkColor color) {
779   DCHECK_EQ(type_, LAYER_SOLID_COLOR);
780   solid_color_layer_->SetBackgroundColor(color);
781   SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
782 }
783
784 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
785   SetBoundsImmediately(bounds);
786 }
787
788 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
789   SetTransformImmediately(transform);
790 }
791
792 void Layer::SetOpacityFromAnimation(float opacity) {
793   SetOpacityImmediately(opacity);
794 }
795
796 void Layer::SetVisibilityFromAnimation(bool visibility) {
797   SetVisibilityImmediately(visibility);
798 }
799
800 void Layer::SetBrightnessFromAnimation(float brightness) {
801   SetBrightnessImmediately(brightness);
802 }
803
804 void Layer::SetGrayscaleFromAnimation(float grayscale) {
805   SetGrayscaleImmediately(grayscale);
806 }
807
808 void Layer::SetColorFromAnimation(SkColor color) {
809   SetColorImmediately(color);
810 }
811
812 void Layer::ScheduleDrawForAnimation() {
813   ScheduleDraw();
814 }
815
816 const gfx::Rect& Layer::GetBoundsForAnimation() const {
817   return bounds();
818 }
819
820 gfx::Transform Layer::GetTransformForAnimation() const {
821   return transform();
822 }
823
824 float Layer::GetOpacityForAnimation() const {
825   return opacity();
826 }
827
828 bool Layer::GetVisibilityForAnimation() const {
829   return visible();
830 }
831
832 float Layer::GetBrightnessForAnimation() const {
833   return layer_brightness();
834 }
835
836 float Layer::GetGrayscaleForAnimation() const {
837   return layer_grayscale();
838 }
839
840 SkColor Layer::GetColorForAnimation() const {
841   // WebColor is equivalent to SkColor, per WebColor.h.
842   // The NULL check is here since this is invoked regardless of whether we have
843   // been configured as LAYER_SOLID_COLOR.
844   return solid_color_layer_.get() ?
845       solid_color_layer_->background_color() : SK_ColorBLACK;
846 }
847
848 float Layer::GetDeviceScaleFactor() const {
849   return device_scale_factor_;
850 }
851
852 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
853   DCHECK(cc_layer_);
854   // Until this layer has a compositor (and hence cc_layer_ has a
855   // LayerTreeHost), addAnimation will fail.
856   if (GetCompositor())
857     cc_layer_->AddAnimation(animation.Pass());
858   else
859     pending_threaded_animations_.push_back(animation.Pass());
860 }
861
862 namespace{
863
864 struct HasAnimationId {
865   HasAnimationId(int id): id_(id) {
866   }
867
868   bool operator()(cc::Animation* animation) const {
869     return animation->id() == id_;
870   }
871
872  private:
873   int id_;
874 };
875
876 }
877
878 void Layer::RemoveThreadedAnimation(int animation_id) {
879   DCHECK(cc_layer_);
880   if (pending_threaded_animations_.size() == 0) {
881     cc_layer_->RemoveAnimation(animation_id);
882     return;
883   }
884
885   pending_threaded_animations_.erase(
886       cc::remove_if(&pending_threaded_animations_,
887                     pending_threaded_animations_.begin(),
888                     pending_threaded_animations_.end(),
889                     HasAnimationId(animation_id)),
890       pending_threaded_animations_.end());
891 }
892
893 void Layer::SendPendingThreadedAnimations() {
894   for (cc::ScopedPtrVector<cc::Animation>::iterator it =
895            pending_threaded_animations_.begin();
896        it != pending_threaded_animations_.end();
897        ++it)
898     cc_layer_->AddAnimation(pending_threaded_animations_.take(it));
899
900   pending_threaded_animations_.clear();
901
902   for (size_t i = 0; i < children_.size(); ++i)
903     children_[i]->SendPendingThreadedAnimations();
904 }
905
906 void Layer::CreateWebLayer() {
907   if (type_ == LAYER_SOLID_COLOR) {
908     solid_color_layer_ = cc::SolidColorLayer::Create();
909     cc_layer_ = solid_color_layer_.get();
910   } else {
911     content_layer_ = cc::ContentLayer::Create(this);
912     cc_layer_ = content_layer_.get();
913   }
914   cc_layer_->SetAnchorPoint(gfx::PointF());
915   cc_layer_->SetContentsOpaque(true);
916   cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
917   cc_layer_->AddLayerAnimationEventObserver(this);
918   cc_layer_->SetLayerClient(this);
919   RecomputePosition();
920 }
921
922 void Layer::RecomputeCCTransformFromTransform(const gfx::Transform& transform) {
923   cc_layer_->SetTransform(ConvertTransformToCCTransform(transform,
924                                                         device_scale_factor_));
925 }
926
927 gfx::Transform Layer::transform() const {
928   gfx::Transform transform;
929   transform.Scale(1.0f / device_scale_factor_, 1.0f / device_scale_factor_);
930   transform.PreconcatTransform(cc_layer_->transform());
931   transform.Scale(device_scale_factor_, device_scale_factor_);
932   return transform;
933 }
934
935 void Layer::RecomputeDrawsContentAndUVRect() {
936   DCHECK(cc_layer_);
937   gfx::Size size(bounds_.size());
938   if (texture_layer_.get()) {
939     gfx::Size texture_size;
940     if (!texture_layer_->uses_mailbox()) {
941       DCHECK(texture_.get());
942       float texture_scale_factor = 1.0f / texture_->device_scale_factor();
943       texture_size = gfx::ToFlooredSize(
944           gfx::ScaleSize(texture_->size(), texture_scale_factor));
945     } else {
946       DCHECK(mailbox_.IsSharedMemory());
947       float texture_scale_factor = 1.0f / mailbox_scale_factor_;
948       texture_size = gfx::ToFlooredSize(
949           gfx::ScaleSize(mailbox_.shared_memory_size(), texture_scale_factor));
950     }
951     size.SetToMin(texture_size);
952
953     gfx::PointF uv_top_left(0.f, 0.f);
954     gfx::PointF uv_bottom_right(
955         static_cast<float>(size.width())/texture_size.width(),
956         static_cast<float>(size.height())/texture_size.height());
957     texture_layer_->SetUV(uv_top_left, uv_bottom_right);
958   } else if (delegated_renderer_layer_.get()) {
959     delegated_renderer_layer_->SetDisplaySize(
960         ConvertSizeToPixel(this, delegated_frame_size_in_dip_));
961     size.SetToMin(delegated_frame_size_in_dip_);
962   }
963   cc_layer_->SetBounds(ConvertSizeToPixel(this, size));
964 }
965
966 void Layer::RecomputePosition() {
967   cc_layer_->SetPosition(gfx::ScalePoint(
968         gfx::PointF(bounds_.x(), bounds_.y()),
969         device_scale_factor_));
970 }
971
972 }  // namespace ui