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(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 bool Layer::PrepareTextureMailbox( 651 cc::TextureMailbox* mailbox, 652 scoped_ptr<cc::SingleReleaseCallback>* release_callback, 653 bool use_shared_memory) { 654 return false; 655 } 656 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 665 std::string Layer::DebugName() { 666 return name_; 667 } 668 669 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() { 670 // TODO: return something useful here. 671 return NULL; 672 } 673 674 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) { 675 if (animator_.get()) 676 animator_->OnThreadedAnimationStarted(event); 677 } 678 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 702 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 712 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 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 749 void Layer::SetTransformImmediately(const gfx::Transform& transform) { 750 RecomputeCCTransformFromTransform(transform); 751 } 752 753 void Layer::SetOpacityImmediately(float opacity) { 754 cc_layer_->SetOpacity(opacity); 755 ScheduleDraw(); 756 } 757 758 void Layer::SetVisibilityImmediately(bool visible) { 759 if (visible_ == visible) 760 return; 761 762 visible_ = visible; 763 cc_layer_->SetHideLayerAndSubtree(!visible_); 764 } 765 766 void Layer::SetBrightnessImmediately(float brightness) { 767 layer_brightness_ = brightness; 768 SetLayerFilters(); 769 } 770 771 void Layer::SetGrayscaleImmediately(float grayscale) { 772 layer_grayscale_ = grayscale; 773 SetLayerFilters(); 774 } 775 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 782 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { 783 SetBoundsImmediately(bounds); 784 } 785 786 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) { 787 SetTransformImmediately(transform); 788 } 789 790 void Layer::SetOpacityFromAnimation(float opacity) { 791 SetOpacityImmediately(opacity); 792 } 793 794 void Layer::SetVisibilityFromAnimation(bool visibility) { 795 SetVisibilityImmediately(visibility); 796 } 797 798 void Layer::SetBrightnessFromAnimation(float brightness) { 799 SetBrightnessImmediately(brightness); 800 } 801 802 void Layer::SetGrayscaleFromAnimation(float grayscale) { 803 SetGrayscaleImmediately(grayscale); 804 } 805 806 void Layer::SetColorFromAnimation(SkColor color) { 807 SetColorImmediately(color); 808 } 809 810 void Layer::ScheduleDrawForAnimation() { 811 ScheduleDraw(); 812 } 813 814 const gfx::Rect& Layer::GetBoundsForAnimation() const { 815 return bounds(); 816 } 817 818 gfx::Transform Layer::GetTransformForAnimation() const { 819 return transform(); 820 } 821 822 float Layer::GetOpacityForAnimation() const { 823 return opacity(); 824 } 825 826 bool Layer::GetVisibilityForAnimation() const { 827 return visible(); 828 } 829 830 float Layer::GetBrightnessForAnimation() const { 831 return layer_brightness(); 832 } 833 834 float Layer::GetGrayscaleForAnimation() const { 835 return layer_grayscale(); 836 } 837 838 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 846 float Layer::GetDeviceScaleFactor() const { 847 return device_scale_factor_; 848 } 849 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 { 863 HasAnimationId(int id): id_(id) { 864 } 865 866 bool operator()(cc::Animation* animation) const { 867 return animation->id() == id_; 868 } 869 870 private: 871 int id_; 872 }; 873 874 } 875 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 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 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 920 void Layer::RecomputeCCTransformFromTransform(const gfx::Transform& transform) { 921 cc_layer_->SetTransform(ConvertTransformToCCTransform(transform, 922 device_scale_factor_)); 923 } 924 925 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 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 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