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