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