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_.get(); 178 if (child_animator) 179 child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS); 180 LayerAnimatorCollection* collection = GetLayerAnimatorCollection(); 181 if (collection) 182 child->RemoveAnimatorsInTreeFromCollection(collection); 183 184 std::vector<Layer*>::iterator i = 185 std::find(children_.begin(), children_.end(), child); 186 DCHECK(i != children_.end()); 187 children_.erase(i); 188 child->parent_ = NULL; 189 child->cc_layer_->RemoveFromParent(); 190 } 191 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_, 0.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_.get()) { 534 scoped_refptr<cc::TextureLayer> new_layer = 535 cc::TextureLayer::CreateForMailbox(this); 536 new_layer->SetFlipped(true); 537 SwitchToLayer(new_layer); 538 texture_layer_ = new_layer; 539 } 540 if (mailbox_release_callback_) 541 mailbox_release_callback_->Run(0, false); 542 mailbox_release_callback_ = release_callback.Pass(); 543 mailbox_ = mailbox; 544 SetTextureSize(texture_size_in_dip); 545 } 546 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 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get()); 603 SkBitmap bitmap_copy; 604 if (bitmap.isImmutable()) { 605 bitmap_copy = bitmap; 606 } else { 607 // UIResourceBitmap requires an immutable copy of the input |bitmap|. 608 bitmap.copyTo(&bitmap_copy); 609 bitmap_copy.setImmutable(); 610 } 611 nine_patch_layer_->SetBitmap(bitmap_copy); 612 } 613 614 void Layer::UpdateNinePatchLayerAperture(const gfx::Rect& aperture) { 615 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get()); 616 nine_patch_layer_->SetAperture(aperture); 617 } 618 619 void Layer::UpdateNinePatchLayerBorder(const gfx::Rect& border) { 620 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get()); 621 nine_patch_layer_->SetBorder(border); 622 } 623 624 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); } 625 626 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) { 627 if (type_ == LAYER_SOLID_COLOR || 628 type_ == LAYER_NINE_PATCH || 629 (!delegate_ && !mailbox_.IsValid())) 630 return false; 631 632 damaged_region_.op(invalid_rect.x(), 633 invalid_rect.y(), 634 invalid_rect.right(), 635 invalid_rect.bottom(), 636 SkRegion::kUnion_Op); 637 ScheduleDraw(); 638 return true; 639 } 640 641 void Layer::ScheduleDraw() { 642 Compositor* compositor = GetCompositor(); 643 if (compositor) 644 compositor->ScheduleDraw(); 645 } 646 647 void Layer::SendDamagedRects() { 648 if ((delegate_ || mailbox_.IsValid()) && !damaged_region_.isEmpty()) { 649 for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) { 650 const SkIRect& sk_damaged = iter.rect(); 651 gfx::Rect damaged( 652 sk_damaged.x(), 653 sk_damaged.y(), 654 sk_damaged.width(), 655 sk_damaged.height()); 656 cc_layer_->SetNeedsDisplayRect(damaged); 657 } 658 damaged_region_.setEmpty(); 659 } 660 for (size_t i = 0; i < children_.size(); ++i) 661 children_[i]->SendDamagedRects(); 662 } 663 664 void Layer::CompleteAllAnimations() { 665 typedef std::vector<scoped_refptr<LayerAnimator> > LayerAnimatorVector; 666 LayerAnimatorVector animators; 667 CollectAnimators(&animators); 668 for (LayerAnimatorVector::const_iterator it = animators.begin(); 669 it != animators.end(); 670 ++it) { 671 (*it)->StopAnimating(); 672 } 673 } 674 675 void Layer::SuppressPaint() { 676 if (!delegate_) 677 return; 678 delegate_ = NULL; 679 for (size_t i = 0; i < children_.size(); ++i) 680 children_[i]->SuppressPaint(); 681 } 682 683 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) { 684 if (device_scale_factor_ == device_scale_factor) 685 return; 686 if (animator_.get()) 687 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM); 688 device_scale_factor_ = device_scale_factor; 689 RecomputeDrawsContentAndUVRect(); 690 RecomputePosition(); 691 SchedulePaint(gfx::Rect(bounds_.size())); 692 if (delegate_) 693 delegate_->OnDeviceScaleFactorChanged(device_scale_factor); 694 for (size_t i = 0; i < children_.size(); ++i) 695 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor); 696 if (layer_mask_) 697 layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor); 698 } 699 700 void Layer::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) { 701 DCHECK(delegated_renderer_layer_.get() || surface_layer_.get()); 702 if (!delegate_) 703 return; 704 delegate_->OnDelegatedFrameDamage(damage_rect_in_dip); 705 } 706 707 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) { 708 cc_layer_->RequestCopyOfOutput(request.Pass()); 709 } 710 711 void Layer::PaintContents(SkCanvas* sk_canvas, 712 const gfx::Rect& clip, 713 ContentLayerClient::GraphicsContextStatus gc_status) { 714 TRACE_EVENT0("ui", "Layer::PaintContents"); 715 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling( 716 sk_canvas, device_scale_factor_)); 717 if (delegate_) 718 delegate_->OnPaintLayer(canvas.get()); 719 } 720 721 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_; } 722 723 bool Layer::PrepareTextureMailbox( 724 cc::TextureMailbox* mailbox, 725 scoped_ptr<cc::SingleReleaseCallback>* release_callback, 726 bool use_shared_memory) { 727 if (!mailbox_release_callback_) 728 return false; 729 *mailbox = mailbox_; 730 *release_callback = mailbox_release_callback_.Pass(); 731 return true; 732 } 733 734 void Layer::SetForceRenderSurface(bool force) { 735 if (force_render_surface_ == force) 736 return; 737 738 force_render_surface_ = force; 739 cc_layer_->SetForceRenderSurface(force_render_surface_); 740 } 741 742 class LayerDebugInfo : public base::debug::ConvertableToTraceFormat { 743 public: 744 explicit LayerDebugInfo(std::string name) : name_(name) { } 745 virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE { 746 base::DictionaryValue dictionary; 747 dictionary.SetString("layer_name", name_); 748 base::JSONWriter::Write(&dictionary, out); 749 } 750 751 private: 752 virtual ~LayerDebugInfo() { } 753 std::string name_; 754 }; 755 756 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() { 757 return new LayerDebugInfo(name_); 758 } 759 760 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) { 761 if (animator_.get()) 762 animator_->OnThreadedAnimationStarted(event); 763 } 764 765 void Layer::CollectAnimators( 766 std::vector<scoped_refptr<LayerAnimator> >* animators) { 767 if (IsAnimating()) 768 animators->push_back(animator_); 769 std::for_each(children_.begin(), children_.end(), 770 std::bind2nd(std::mem_fun(&Layer::CollectAnimators), 771 animators)); 772 } 773 774 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) { 775 DCHECK_NE(child, other); 776 DCHECK_EQ(this, child->parent()); 777 DCHECK_EQ(this, other->parent()); 778 779 const size_t child_i = 780 std::find(children_.begin(), children_.end(), child) - children_.begin(); 781 const size_t other_i = 782 std::find(children_.begin(), children_.end(), other) - children_.begin(); 783 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i)) 784 return; 785 786 const size_t dest_i = 787 above ? 788 (child_i < other_i ? other_i : other_i + 1) : 789 (child_i < other_i ? other_i - 1 : other_i); 790 children_.erase(children_.begin() + child_i); 791 children_.insert(children_.begin() + dest_i, child); 792 793 child->cc_layer_->RemoveFromParent(); 794 cc_layer_->InsertChild(child->cc_layer_, dest_i); 795 } 796 797 bool Layer::ConvertPointForAncestor(const Layer* ancestor, 798 gfx::Point* point) const { 799 gfx::Transform transform; 800 bool result = GetTargetTransformRelativeTo(ancestor, &transform); 801 gfx::Point3F p(*point); 802 transform.TransformPoint(&p); 803 *point = gfx::ToFlooredPoint(p.AsPointF()); 804 return result; 805 } 806 807 bool Layer::ConvertPointFromAncestor(const Layer* ancestor, 808 gfx::Point* point) const { 809 gfx::Transform transform; 810 bool result = GetTargetTransformRelativeTo(ancestor, &transform); 811 gfx::Point3F p(*point); 812 transform.TransformPointReverse(&p); 813 *point = gfx::ToFlooredPoint(p.AsPointF()); 814 return result; 815 } 816 817 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { 818 if (bounds == bounds_) 819 return; 820 821 base::Closure closure; 822 if (delegate_) 823 closure = delegate_->PrepareForLayerBoundsChange(); 824 bool was_move = bounds_.size() == bounds.size(); 825 bounds_ = bounds; 826 827 RecomputeDrawsContentAndUVRect(); 828 RecomputePosition(); 829 830 if (!closure.is_null()) 831 closure.Run(); 832 833 if (was_move) { 834 // Don't schedule a draw if we're invisible. We'll schedule one 835 // automatically when we get visible. 836 if (IsDrawn()) 837 ScheduleDraw(); 838 } else { 839 // Always schedule a paint, even if we're invisible. 840 SchedulePaint(gfx::Rect(bounds.size())); 841 } 842 } 843 844 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) { 845 cc_layer_->SetTransform(transform); 846 } 847 848 void Layer::SetOpacityFromAnimation(float opacity) { 849 cc_layer_->SetOpacity(opacity); 850 ScheduleDraw(); 851 } 852 853 void Layer::SetVisibilityFromAnimation(bool visible) { 854 if (visible_ == visible) 855 return; 856 857 visible_ = visible; 858 cc_layer_->SetHideLayerAndSubtree(!visible_); 859 } 860 861 void Layer::SetBrightnessFromAnimation(float brightness) { 862 layer_brightness_ = brightness; 863 SetLayerFilters(); 864 } 865 866 void Layer::SetGrayscaleFromAnimation(float grayscale) { 867 layer_grayscale_ = grayscale; 868 SetLayerFilters(); 869 } 870 871 void Layer::SetColorFromAnimation(SkColor color) { 872 DCHECK_EQ(type_, LAYER_SOLID_COLOR); 873 solid_color_layer_->SetBackgroundColor(color); 874 SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF); 875 } 876 877 void Layer::ScheduleDrawForAnimation() { 878 ScheduleDraw(); 879 } 880 881 const gfx::Rect& Layer::GetBoundsForAnimation() const { 882 return bounds(); 883 } 884 885 gfx::Transform Layer::GetTransformForAnimation() const { 886 return transform(); 887 } 888 889 float Layer::GetOpacityForAnimation() const { 890 return opacity(); 891 } 892 893 bool Layer::GetVisibilityForAnimation() const { 894 return visible(); 895 } 896 897 float Layer::GetBrightnessForAnimation() const { 898 return layer_brightness(); 899 } 900 901 float Layer::GetGrayscaleForAnimation() const { 902 return layer_grayscale(); 903 } 904 905 SkColor Layer::GetColorForAnimation() const { 906 // WebColor is equivalent to SkColor, per WebColor.h. 907 // The NULL check is here since this is invoked regardless of whether we have 908 // been configured as LAYER_SOLID_COLOR. 909 return solid_color_layer_.get() ? 910 solid_color_layer_->background_color() : SK_ColorBLACK; 911 } 912 913 float Layer::GetDeviceScaleFactor() const { 914 return device_scale_factor_; 915 } 916 917 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) { 918 DCHECK(cc_layer_); 919 // Until this layer has a compositor (and hence cc_layer_ has a 920 // LayerTreeHost), addAnimation will fail. 921 if (GetCompositor()) 922 cc_layer_->AddAnimation(animation.Pass()); 923 else 924 pending_threaded_animations_.push_back(animation.Pass()); 925 } 926 927 namespace{ 928 929 struct HasAnimationId { 930 HasAnimationId(int id): id_(id) { 931 } 932 933 bool operator()(cc::Animation* animation) const { 934 return animation->id() == id_; 935 } 936 937 private: 938 int id_; 939 }; 940 941 } 942 943 void Layer::RemoveThreadedAnimation(int animation_id) { 944 DCHECK(cc_layer_); 945 if (pending_threaded_animations_.size() == 0) { 946 cc_layer_->RemoveAnimation(animation_id); 947 return; 948 } 949 950 pending_threaded_animations_.erase( 951 cc::remove_if(&pending_threaded_animations_, 952 pending_threaded_animations_.begin(), 953 pending_threaded_animations_.end(), 954 HasAnimationId(animation_id)), 955 pending_threaded_animations_.end()); 956 } 957 958 LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() { 959 Compositor* compositor = GetCompositor(); 960 return compositor ? compositor->layer_animator_collection() : NULL; 961 } 962 963 void Layer::SendPendingThreadedAnimations() { 964 for (cc::ScopedPtrVector<cc::Animation>::iterator it = 965 pending_threaded_animations_.begin(); 966 it != pending_threaded_animations_.end(); 967 ++it) 968 cc_layer_->AddAnimation(pending_threaded_animations_.take(it)); 969 970 pending_threaded_animations_.clear(); 971 972 for (size_t i = 0; i < children_.size(); ++i) 973 children_[i]->SendPendingThreadedAnimations(); 974 } 975 976 void Layer::CreateWebLayer() { 977 if (type_ == LAYER_SOLID_COLOR) { 978 solid_color_layer_ = cc::SolidColorLayer::Create(); 979 cc_layer_ = solid_color_layer_.get(); 980 } else if (type_ == LAYER_NINE_PATCH) { 981 nine_patch_layer_ = cc::NinePatchLayer::Create(); 982 cc_layer_ = nine_patch_layer_.get(); 983 } else { 984 if (Layer::UsingPictureLayer()) 985 content_layer_ = cc::PictureLayer::Create(this); 986 else 987 content_layer_ = cc::ContentLayer::Create(this); 988 cc_layer_ = content_layer_.get(); 989 } 990 cc_layer_->SetTransformOrigin(gfx::Point3F()); 991 cc_layer_->SetContentsOpaque(true); 992 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); 993 cc_layer_->AddLayerAnimationEventObserver(this); 994 cc_layer_->SetLayerClient(this); 995 RecomputePosition(); 996 } 997 998 gfx::Transform Layer::transform() const { 999 return cc_layer_->transform(); 1000 } 1001 1002 void Layer::RecomputeDrawsContentAndUVRect() { 1003 DCHECK(cc_layer_); 1004 gfx::Size size(bounds_.size()); 1005 if (texture_layer_.get()) { 1006 size.SetToMin(frame_size_in_dip_); 1007 gfx::PointF uv_top_left(0.f, 0.f); 1008 gfx::PointF uv_bottom_right( 1009 static_cast<float>(size.width()) / frame_size_in_dip_.width(), 1010 static_cast<float>(size.height()) / frame_size_in_dip_.height()); 1011 texture_layer_->SetUV(uv_top_left, uv_bottom_right); 1012 } else if (delegated_renderer_layer_.get() || surface_layer_.get()) { 1013 size.SetToMin(frame_size_in_dip_); 1014 } 1015 cc_layer_->SetBounds(size); 1016 } 1017 1018 void Layer::RecomputePosition() { 1019 cc_layer_->SetPosition(bounds_.origin() + subpixel_position_offset_); 1020 } 1021 1022 void Layer::AddAnimatorsInTreeToCollection( 1023 LayerAnimatorCollection* collection) { 1024 DCHECK(collection); 1025 if (IsAnimating()) 1026 animator_->AddToCollection(collection); 1027 std::for_each( 1028 children_.begin(), 1029 children_.end(), 1030 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection), 1031 collection)); 1032 } 1033 1034 void Layer::RemoveAnimatorsInTreeFromCollection( 1035 LayerAnimatorCollection* collection) { 1036 DCHECK(collection); 1037 if (IsAnimating()) 1038 animator_->RemoveFromCollection(collection); 1039 std::for_each( 1040 children_.begin(), 1041 children_.end(), 1042 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection), 1043 collection)); 1044 } 1045 1046 bool Layer::IsAnimating() const { 1047 return animator_.get() && animator_->is_animating(); 1048 } 1049 1050 } // namespace ui 1051