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/base/animation/animation.h" 24 #include "ui/compositor/compositor_switches.h" 25 #include "ui/compositor/dip_util.h" 26 #include "ui/compositor/layer_animator.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_->RemoveLayerAnimationEventObserver(this); 448 new_layer->SetOpacity(cc_layer_->opacity()); 449 new_layer->SetTransform(cc_layer_->transform()); 450 new_layer->SetPosition(cc_layer_->position()); 451 452 cc_layer_ = new_layer.get(); 453 content_layer_ = NULL; 454 solid_color_layer_ = NULL; 455 texture_layer_ = NULL; 456 delegated_renderer_layer_ = NULL; 457 458 cc_layer_->AddLayerAnimationEventObserver(this); 459 for (size_t i = 0; i < children_.size(); ++i) { 460 DCHECK(children_[i]->cc_layer_); 461 cc_layer_->AddChild(children_[i]->cc_layer_); 462 } 463 cc_layer_->SetAnchorPoint(gfx::PointF()); 464 cc_layer_->SetContentsOpaque(fills_bounds_opaquely_); 465 cc_layer_->SetForceRenderSurface(force_render_surface_); 466 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); 467 cc_layer_->SetHideLayerAndSubtree(!visible_); 468 } 469 470 void Layer::SwitchCCLayerForTest() { 471 scoped_refptr<cc::ContentLayer> new_layer = cc::ContentLayer::Create(this); 472 SwitchToLayer(new_layer); 473 content_layer_ = new_layer; 474 } 475 476 void Layer::SetExternalTexture(Texture* texture) { 477 // Hold a ref to the old |Texture| until we have updated all 478 // compositor references to the texture id that it holds. 479 scoped_refptr<ui::Texture> old_texture = texture_; 480 481 DCHECK_EQ(type_, LAYER_TEXTURED); 482 DCHECK(!solid_color_layer_.get()); 483 bool has_texture = !!texture; 484 layer_updated_externally_ = has_texture; 485 texture_ = texture; 486 if (!!texture_layer_.get() != has_texture) { 487 // Switch to a different type of layer. 488 if (has_texture) { 489 scoped_refptr<cc::TextureLayer> new_layer = 490 cc::TextureLayer::Create(this); 491 new_layer->SetFlipped(texture_->flipped()); 492 SwitchToLayer(new_layer); 493 texture_layer_ = new_layer; 494 } else { 495 scoped_refptr<cc::ContentLayer> new_layer = 496 cc::ContentLayer::Create(this); 497 SwitchToLayer(new_layer); 498 content_layer_ = new_layer; 499 } 500 } 501 RecomputeDrawsContentAndUVRect(); 502 } 503 504 void Layer::SetTextureMailbox(const cc::TextureMailbox& mailbox, 505 float scale_factor) { 506 DCHECK_EQ(type_, LAYER_TEXTURED); 507 DCHECK(!solid_color_layer_.get()); 508 layer_updated_externally_ = true; 509 texture_ = NULL; 510 if (!texture_layer_.get() || !texture_layer_->uses_mailbox()) { 511 scoped_refptr<cc::TextureLayer> new_layer = 512 cc::TextureLayer::CreateForMailbox(this); 513 new_layer->SetFlipped(false); 514 SwitchToLayer(new_layer); 515 texture_layer_ = new_layer; 516 } 517 texture_layer_->SetTextureMailbox(mailbox); 518 mailbox_ = mailbox; 519 mailbox_scale_factor_ = scale_factor; 520 RecomputeDrawsContentAndUVRect(); 521 } 522 523 cc::TextureMailbox Layer::GetTextureMailbox(float* scale_factor) { 524 if (scale_factor) 525 *scale_factor = mailbox_scale_factor_; 526 cc::TextureMailbox::ReleaseCallback callback; 527 return mailbox_.CopyWithNewCallback(callback); 528 } 529 530 void Layer::SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame, 531 gfx::Size frame_size_in_dip) { 532 DCHECK_EQ(type_, LAYER_TEXTURED); 533 bool has_frame = frame.get() && !frame->render_pass_list.empty(); 534 layer_updated_externally_ = has_frame; 535 delegated_frame_size_in_dip_ = frame_size_in_dip; 536 if (!!delegated_renderer_layer_.get() != has_frame) { 537 if (has_frame) { 538 scoped_refptr<cc::DelegatedRendererLayer> new_layer = 539 cc::DelegatedRendererLayer::Create(NULL); 540 SwitchToLayer(new_layer); 541 delegated_renderer_layer_ = new_layer; 542 } else { 543 scoped_refptr<cc::ContentLayer> new_layer = 544 cc::ContentLayer::Create(this); 545 SwitchToLayer(new_layer); 546 content_layer_ = new_layer; 547 } 548 } 549 if (has_frame) 550 delegated_renderer_layer_->SetFrameData(frame.Pass()); 551 RecomputeDrawsContentAndUVRect(); 552 } 553 554 void Layer::TakeUnusedResourcesForChildCompositor( 555 cc::TransferableResourceArray* list) { 556 if (delegated_renderer_layer_.get()) 557 delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor(list); 558 } 559 560 void Layer::SetColor(SkColor color) { 561 GetAnimator()->SetColor(color); 562 } 563 564 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) { 565 if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !texture_.get())) 566 return false; 567 568 damaged_region_.op(invalid_rect.x(), 569 invalid_rect.y(), 570 invalid_rect.right(), 571 invalid_rect.bottom(), 572 SkRegion::kUnion_Op); 573 ScheduleDraw(); 574 return true; 575 } 576 577 void Layer::ScheduleDraw() { 578 Compositor* compositor = GetCompositor(); 579 if (compositor) 580 compositor->ScheduleDraw(); 581 } 582 583 void Layer::SendDamagedRects() { 584 if ((delegate_ || texture_.get()) && !damaged_region_.isEmpty()) { 585 for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) { 586 const SkIRect& sk_damaged = iter.rect(); 587 gfx::Rect damaged( 588 sk_damaged.x(), 589 sk_damaged.y(), 590 sk_damaged.width(), 591 sk_damaged.height()); 592 593 gfx::Rect damaged_in_pixel = ConvertRectToPixel(this, damaged); 594 cc_layer_->SetNeedsDisplayRect(damaged_in_pixel); 595 } 596 damaged_region_.setEmpty(); 597 } 598 for (size_t i = 0; i < children_.size(); ++i) 599 children_[i]->SendDamagedRects(); 600 } 601 602 void Layer::SuppressPaint() { 603 if (!delegate_) 604 return; 605 delegate_ = NULL; 606 for (size_t i = 0; i < children_.size(); ++i) 607 children_[i]->SuppressPaint(); 608 } 609 610 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) { 611 if (device_scale_factor_ == device_scale_factor) 612 return; 613 if (animator_.get()) 614 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM); 615 gfx::Transform transform = this->transform(); 616 device_scale_factor_ = device_scale_factor; 617 RecomputeCCTransformFromTransform(transform); 618 RecomputeDrawsContentAndUVRect(); 619 RecomputePosition(); 620 SchedulePaint(gfx::Rect(bounds_.size())); 621 if (delegate_) 622 delegate_->OnDeviceScaleFactorChanged(device_scale_factor); 623 for (size_t i = 0; i < children_.size(); ++i) 624 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor); 625 if (layer_mask_) 626 layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor); 627 } 628 629 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) { 630 cc_layer_->RequestCopyOfOutput(request.Pass()); 631 } 632 633 void Layer::PaintContents(SkCanvas* sk_canvas, 634 gfx::Rect clip, 635 gfx::RectF* opaque) { 636 TRACE_EVENT0("ui", "Layer::PaintContents"); 637 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling( 638 sk_canvas, ui::GetScaleFactorFromScale(device_scale_factor_))); 639 640 bool scale_content = scale_content_; 641 if (scale_content) { 642 canvas->Save(); 643 canvas->sk_canvas()->scale(SkFloatToScalar(device_scale_factor_), 644 SkFloatToScalar(device_scale_factor_)); 645 } 646 647 if (delegate_) 648 delegate_->OnPaintLayer(canvas.get()); 649 if (scale_content) 650 canvas->Restore(); 651 } 652 653 unsigned Layer::PrepareTexture() { 654 DCHECK(texture_layer_.get()); 655 return texture_->PrepareTexture(); 656 } 657 658 WebKit::WebGraphicsContext3D* Layer::Context3d() { 659 DCHECK(texture_layer_.get()); 660 if (texture_.get()) 661 return texture_->HostContext3D(); 662 return NULL; 663 } 664 665 bool Layer::PrepareTextureMailbox(cc::TextureMailbox* mailbox, 666 bool use_shared_memory) { 667 return false; 668 } 669 670 void Layer::SetForceRenderSurface(bool force) { 671 if (force_render_surface_ == force) 672 return; 673 674 force_render_surface_ = force; 675 cc_layer_->SetForceRenderSurface(force_render_surface_); 676 } 677 678 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) { 679 if (animator_.get()) 680 animator_->OnThreadedAnimationStarted(event); 681 } 682 683 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) { 684 DCHECK_NE(child, other); 685 DCHECK_EQ(this, child->parent()); 686 DCHECK_EQ(this, other->parent()); 687 688 const size_t child_i = 689 std::find(children_.begin(), children_.end(), child) - children_.begin(); 690 const size_t other_i = 691 std::find(children_.begin(), children_.end(), other) - children_.begin(); 692 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i)) 693 return; 694 695 const size_t dest_i = 696 above ? 697 (child_i < other_i ? other_i : other_i + 1) : 698 (child_i < other_i ? other_i - 1 : other_i); 699 children_.erase(children_.begin() + child_i); 700 children_.insert(children_.begin() + dest_i, child); 701 702 child->cc_layer_->RemoveFromParent(); 703 cc_layer_->InsertChild(child->cc_layer_, dest_i); 704 } 705 706 bool Layer::ConvertPointForAncestor(const Layer* ancestor, 707 gfx::Point* point) const { 708 gfx::Transform transform; 709 bool result = GetTargetTransformRelativeTo(ancestor, &transform); 710 gfx::Point3F p(*point); 711 transform.TransformPoint(p); 712 *point = gfx::ToFlooredPoint(p.AsPointF()); 713 return result; 714 } 715 716 bool Layer::ConvertPointFromAncestor(const Layer* ancestor, 717 gfx::Point* point) const { 718 gfx::Transform transform; 719 bool result = GetTargetTransformRelativeTo(ancestor, &transform); 720 gfx::Point3F p(*point); 721 transform.TransformPointReverse(p); 722 *point = gfx::ToFlooredPoint(p.AsPointF()); 723 return result; 724 } 725 726 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) { 727 if (bounds == bounds_) 728 return; 729 730 base::Closure closure; 731 if (delegate_) 732 closure = delegate_->PrepareForLayerBoundsChange(); 733 bool was_move = bounds_.size() == bounds.size(); 734 bounds_ = bounds; 735 736 RecomputeDrawsContentAndUVRect(); 737 RecomputePosition(); 738 739 if (!closure.is_null()) 740 closure.Run(); 741 742 if (was_move) { 743 // Don't schedule a draw if we're invisible. We'll schedule one 744 // automatically when we get visible. 745 if (IsDrawn()) 746 ScheduleDraw(); 747 } else { 748 // Always schedule a paint, even if we're invisible. 749 SchedulePaint(gfx::Rect(bounds.size())); 750 } 751 } 752 753 void Layer::SetTransformImmediately(const gfx::Transform& transform) { 754 RecomputeCCTransformFromTransform(transform); 755 } 756 757 void Layer::SetOpacityImmediately(float opacity) { 758 cc_layer_->SetOpacity(opacity); 759 ScheduleDraw(); 760 } 761 762 void Layer::SetVisibilityImmediately(bool visible) { 763 if (visible_ == visible) 764 return; 765 766 visible_ = visible; 767 cc_layer_->SetHideLayerAndSubtree(!visible_); 768 } 769 770 void Layer::SetBrightnessImmediately(float brightness) { 771 layer_brightness_ = brightness; 772 SetLayerFilters(); 773 } 774 775 void Layer::SetGrayscaleImmediately(float grayscale) { 776 layer_grayscale_ = grayscale; 777 SetLayerFilters(); 778 } 779 780 void Layer::SetColorImmediately(SkColor color) { 781 DCHECK_EQ(type_, LAYER_SOLID_COLOR); 782 solid_color_layer_->SetBackgroundColor(color); 783 SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF); 784 } 785 786 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { 787 SetBoundsImmediately(bounds); 788 } 789 790 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) { 791 SetTransformImmediately(transform); 792 } 793 794 void Layer::SetOpacityFromAnimation(float opacity) { 795 SetOpacityImmediately(opacity); 796 } 797 798 void Layer::SetVisibilityFromAnimation(bool visibility) { 799 SetVisibilityImmediately(visibility); 800 } 801 802 void Layer::SetBrightnessFromAnimation(float brightness) { 803 SetBrightnessImmediately(brightness); 804 } 805 806 void Layer::SetGrayscaleFromAnimation(float grayscale) { 807 SetGrayscaleImmediately(grayscale); 808 } 809 810 void Layer::SetColorFromAnimation(SkColor color) { 811 SetColorImmediately(color); 812 } 813 814 void Layer::ScheduleDrawForAnimation() { 815 ScheduleDraw(); 816 } 817 818 const gfx::Rect& Layer::GetBoundsForAnimation() const { 819 return bounds(); 820 } 821 822 gfx::Transform Layer::GetTransformForAnimation() const { 823 return transform(); 824 } 825 826 float Layer::GetOpacityForAnimation() const { 827 return opacity(); 828 } 829 830 bool Layer::GetVisibilityForAnimation() const { 831 return visible(); 832 } 833 834 float Layer::GetBrightnessForAnimation() const { 835 return layer_brightness(); 836 } 837 838 float Layer::GetGrayscaleForAnimation() const { 839 return layer_grayscale(); 840 } 841 842 SkColor Layer::GetColorForAnimation() const { 843 // WebColor is equivalent to SkColor, per WebColor.h. 844 // The NULL check is here since this is invoked regardless of whether we have 845 // been configured as LAYER_SOLID_COLOR. 846 return solid_color_layer_.get() ? 847 solid_color_layer_->background_color() : SK_ColorBLACK; 848 } 849 850 float Layer::GetDeviceScaleFactor() const { 851 return device_scale_factor_; 852 } 853 854 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) { 855 DCHECK(cc_layer_); 856 // Until this layer has a compositor (and hence cc_layer_ has a 857 // LayerTreeHost), addAnimation will fail. 858 if (GetCompositor()) 859 cc_layer_->AddAnimation(animation.Pass()); 860 else 861 pending_threaded_animations_.push_back(animation.Pass()); 862 } 863 864 namespace{ 865 866 struct HasAnimationId { 867 HasAnimationId(int id): id_(id) { 868 } 869 870 bool operator()(cc::Animation* animation) const { 871 return animation->id() == id_; 872 } 873 874 private: 875 int id_; 876 }; 877 878 } 879 880 void Layer::RemoveThreadedAnimation(int animation_id) { 881 DCHECK(cc_layer_); 882 if (pending_threaded_animations_.size() == 0) { 883 cc_layer_->RemoveAnimation(animation_id); 884 return; 885 } 886 887 pending_threaded_animations_.erase( 888 cc::remove_if(&pending_threaded_animations_, 889 pending_threaded_animations_.begin(), 890 pending_threaded_animations_.end(), 891 HasAnimationId(animation_id)), 892 pending_threaded_animations_.end()); 893 } 894 895 void Layer::SendPendingThreadedAnimations() { 896 for (cc::ScopedPtrVector<cc::Animation>::iterator it = 897 pending_threaded_animations_.begin(); 898 it != pending_threaded_animations_.end(); 899 ++it) 900 cc_layer_->AddAnimation(pending_threaded_animations_.take(it)); 901 902 pending_threaded_animations_.clear(); 903 904 for (size_t i = 0; i < children_.size(); ++i) 905 children_[i]->SendPendingThreadedAnimations(); 906 } 907 908 void Layer::CreateWebLayer() { 909 if (type_ == LAYER_SOLID_COLOR) { 910 solid_color_layer_ = cc::SolidColorLayer::Create(); 911 cc_layer_ = solid_color_layer_.get(); 912 } else { 913 content_layer_ = cc::ContentLayer::Create(this); 914 cc_layer_ = content_layer_.get(); 915 } 916 cc_layer_->SetAnchorPoint(gfx::PointF()); 917 cc_layer_->SetContentsOpaque(true); 918 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); 919 cc_layer_->AddLayerAnimationEventObserver(this); 920 RecomputePosition(); 921 } 922 923 void Layer::RecomputeCCTransformFromTransform(const gfx::Transform& transform) { 924 cc_layer_->SetTransform(ConvertTransformToCCTransform(transform, 925 device_scale_factor_)); 926 } 927 928 gfx::Transform Layer::transform() const { 929 gfx::Transform transform; 930 transform.Scale(1.0f / device_scale_factor_, 1.0f / device_scale_factor_); 931 transform.PreconcatTransform(cc_layer_->transform()); 932 transform.Scale(device_scale_factor_, device_scale_factor_); 933 return transform; 934 } 935 936 void Layer::RecomputeDrawsContentAndUVRect() { 937 DCHECK(cc_layer_); 938 gfx::Size size(bounds_.size()); 939 if (texture_layer_.get()) { 940 gfx::Size texture_size; 941 if (!texture_layer_->uses_mailbox()) { 942 DCHECK(texture_.get()); 943 float texture_scale_factor = 1.0f / texture_->device_scale_factor(); 944 texture_size = gfx::ToFlooredSize( 945 gfx::ScaleSize(texture_->size(), texture_scale_factor)); 946 } else { 947 DCHECK(mailbox_.IsSharedMemory()); 948 float texture_scale_factor = 1.0f / mailbox_scale_factor_; 949 texture_size = gfx::ToFlooredSize( 950 gfx::ScaleSize(mailbox_.shared_memory_size(), texture_scale_factor)); 951 } 952 size.SetToMin(texture_size); 953 954 gfx::PointF uv_top_left(0.f, 0.f); 955 gfx::PointF uv_bottom_right( 956 static_cast<float>(size.width())/texture_size.width(), 957 static_cast<float>(size.height())/texture_size.height()); 958 texture_layer_->SetUV(uv_top_left, uv_bottom_right); 959 } else if (delegated_renderer_layer_.get()) { 960 delegated_renderer_layer_->SetDisplaySize( 961 ConvertSizeToPixel(this, delegated_frame_size_in_dip_)); 962 size.SetToMin(delegated_frame_size_in_dip_); 963 } 964 cc_layer_->SetBounds(ConvertSizeToPixel(this, size)); 965 } 966 967 void Layer::RecomputePosition() { 968 cc_layer_->SetPosition(gfx::ScalePoint( 969 gfx::PointF(bounds_.x(), bounds_.y()), 970 device_scale_factor_)); 971 } 972 973 } // namespace ui 974