layer.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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/delegated_frame_data.h" 19#include "cc/resources/transferable_resource.h" 20#include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.h" 21#include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h" 22#include "ui/base/animation/animation.h" 23#include "ui/compositor/compositor_switches.h" 24#include "ui/compositor/dip_util.h" 25#include "ui/compositor/layer_animator.h" 26#include "ui/gfx/canvas.h" 27#include "ui/gfx/display.h" 28#include "ui/gfx/interpolated_transform.h" 29#include "ui/gfx/point3_f.h" 30#include "ui/gfx/point_conversions.h" 31#include "ui/gfx/size_conversions.h" 32 33namespace { 34 35const ui::Layer* GetRoot(const ui::Layer* layer) { 36 while (layer->parent()) 37 layer = layer->parent(); 38 return layer; 39} 40 41} // namespace 42 43namespace ui { 44 45Layer::Layer() 46 : type_(LAYER_TEXTURED), 47 compositor_(NULL), 48 parent_(NULL), 49 visible_(true), 50 is_drawn_(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 70Layer::Layer(LayerType type) 71 : type_(type), 72 compositor_(NULL), 73 parent_(NULL), 74 visible_(true), 75 is_drawn_(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 scale_content_(true), 90 device_scale_factor_(1.0f) { 91 CreateWebLayer(); 92} 93 94Layer::~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_) 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 115Compositor* Layer::GetCompositor() { 116 return GetRoot(this)->compositor_; 117} 118 119float Layer::opacity() const { 120 return cc_layer_->opacity(); 121} 122 123void 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 136void 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 child->UpdateIsDrawn(); 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 WebKit::WebFilterOperations filters; 317 if (layer_saturation_) { 318 filters.append(WebKit::WebFilterOperation::createSaturateFilter( 319 layer_saturation_)); 320 } 321 if (layer_grayscale_) { 322 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter( 323 layer_grayscale_)); 324 } 325 if (layer_inverted_) 326 filters.append(WebKit::WebFilterOperation::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(WebKit::WebFilterOperation::createSaturatingBrightnessFilter( 332 layer_brightness_)); 333 } 334 335 cc_layer_->SetFilters(filters); 336} 337 338void Layer::SetLayerBackgroundFilters() { 339 WebKit::WebFilterOperations filters; 340 if (zoom_ != 1) { 341 filters.append(WebKit::WebFilterOperation::createZoomFilter(zoom_, 342 zoom_inset_)); 343 } 344 345 if (background_blur_radius_) { 346 filters.append(WebKit::WebFilterOperation::createBlurFilter( 347 background_blur_radius_)); 348 } 349 350 cc_layer_->SetBackgroundFilters(filters); 351} 352 353float Layer::GetTargetOpacity() const { 354 if (animator_.get() && animator_->IsAnimatingProperty( 355 LayerAnimationElement::OPACITY)) 356 return animator_->GetTargetOpacity(); 357 return opacity(); 358} 359 360void Layer::SetVisible(bool visible) { 361 GetAnimator()->SetVisibility(visible); 362} 363 364bool Layer::GetTargetVisibility() const { 365 if (animator_.get() && animator_->IsAnimatingProperty( 366 LayerAnimationElement::VISIBILITY)) 367 return animator_->GetTargetVisibility(); 368 return visible_; 369} 370 371bool Layer::IsDrawn() const { 372 return is_drawn_; 373} 374 375void Layer::UpdateIsDrawn() { 376 bool updated_is_drawn = visible_ && (!parent_ || parent_->IsDrawn()); 377 378 if (updated_is_drawn == is_drawn_) 379 return; 380 381 is_drawn_ = updated_is_drawn; 382 cc_layer_->SetIsDrawable(is_drawn_ && type_ != LAYER_NOT_DRAWN); 383 384 for (size_t i = 0; i < children_.size(); ++i) { 385 children_[i]->UpdateIsDrawn(); 386 } 387} 388 389bool Layer::ShouldDraw() const { 390 return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f; 391} 392 393// static 394void Layer::ConvertPointToLayer(const Layer* source, 395 const Layer* target, 396 gfx::Point* point) { 397 if (source == target) 398 return; 399 400 const Layer* root_layer = GetRoot(source); 401 CHECK_EQ(root_layer, GetRoot(target)); 402 403 if (source != root_layer) 404 source->ConvertPointForAncestor(root_layer, point); 405 if (target != root_layer) 406 target->ConvertPointFromAncestor(root_layer, point); 407} 408 409bool Layer::GetTargetTransformRelativeTo(const Layer* ancestor, 410 gfx::Transform* transform) const { 411 const Layer* p = this; 412 for (; p && p != ancestor; p = p->parent()) { 413 gfx::Transform translation; 414 translation.Translate(static_cast<float>(p->bounds().x()), 415 static_cast<float>(p->bounds().y())); 416 // Use target transform so that result will be correct once animation is 417 // finished. 418 if (!p->GetTargetTransform().IsIdentity()) 419 transform->ConcatTransform(p->GetTargetTransform()); 420 transform->ConcatTransform(translation); 421 } 422 return p == ancestor; 423} 424 425// static 426gfx::Transform Layer::ConvertTransformToCCTransform( 427 const gfx::Transform& transform, 428 float device_scale_factor) { 429 gfx::Transform cc_transform; 430 cc_transform.Scale(device_scale_factor, device_scale_factor); 431 cc_transform.PreconcatTransform(transform); 432 cc_transform.Scale(1.0f / device_scale_factor, 1.0f / device_scale_factor); 433 return cc_transform; 434} 435 436void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { 437 if (fills_bounds_opaquely_ == fills_bounds_opaquely) 438 return; 439 440 fills_bounds_opaquely_ = fills_bounds_opaquely; 441 442 cc_layer_->SetContentsOpaque(fills_bounds_opaquely); 443} 444 445void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) { 446 // Finish animations being handled by cc_layer_. 447 if (animator_) { 448 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM); 449 animator_->StopAnimatingProperty(LayerAnimationElement::OPACITY); 450 } 451 452 if (texture_layer_.get()) 453 texture_layer_->WillModifyTexture(); 454 // TODO(piman): delegated_renderer_layer_ cleanup. 455 456 cc_layer_->RemoveAllChildren(); 457 if (parent_) { 458 DCHECK(parent_->cc_layer_); 459 parent_->cc_layer_->ReplaceChild(cc_layer_, new_layer); 460 } 461 cc_layer_->RemoveLayerAnimationEventObserver(this); 462 new_layer->SetOpacity(cc_layer_->opacity()); 463 new_layer->SetTransform(cc_layer_->transform()); 464 new_layer->SetPosition(cc_layer_->position()); 465 466 cc_layer_= new_layer; 467 content_layer_ = NULL; 468 solid_color_layer_ = NULL; 469 texture_layer_ = NULL; 470 delegated_renderer_layer_ = NULL; 471 472 cc_layer_->AddLayerAnimationEventObserver(this); 473 for (size_t i = 0; i < children_.size(); ++i) { 474 DCHECK(children_[i]->cc_layer_); 475 cc_layer_->AddChild(children_[i]->cc_layer_); 476 } 477 cc_layer_->SetAnchorPoint(gfx::PointF()); 478 cc_layer_->SetContentsOpaque(fills_bounds_opaquely_); 479 cc_layer_->SetForceRenderSurface(force_render_surface_); 480 cc_layer_->SetIsDrawable(IsDrawn()); 481} 482 483void Layer::SwitchCCLayerForTest() { 484 scoped_refptr<cc::ContentLayer> new_layer = cc::ContentLayer::Create(this); 485 SwitchToLayer(new_layer); 486 content_layer_ = new_layer; 487} 488 489void Layer::SetExternalTexture(Texture* texture) { 490 // Hold a ref to the old |Texture| until we have updated all 491 // compositor references to the texture id that it holds. 492 scoped_refptr<ui::Texture> old_texture = texture_; 493 494 DCHECK_EQ(type_, LAYER_TEXTURED); 495 DCHECK(!solid_color_layer_); 496 bool has_texture = !!texture; 497 layer_updated_externally_ = has_texture; 498 texture_ = texture; 499 if (!!texture_layer_ != has_texture) { 500 // Switch to a different type of layer. 501 if (has_texture) { 502 scoped_refptr<cc::TextureLayer> new_layer = 503 cc::TextureLayer::Create(this); 504 new_layer->SetFlipped(texture_->flipped()); 505 SwitchToLayer(new_layer); 506 texture_layer_ = new_layer; 507 } else { 508 scoped_refptr<cc::ContentLayer> new_layer = 509 cc::ContentLayer::Create(this); 510 SwitchToLayer(new_layer); 511 content_layer_ = new_layer; 512 } 513 } 514 RecomputeDrawsContentAndUVRect(); 515} 516 517void Layer::SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame, 518 gfx::Size frame_size_in_dip) { 519 DCHECK_EQ(type_, LAYER_TEXTURED); 520 bool has_frame = frame.get() && !frame->render_pass_list.empty(); 521 layer_updated_externally_ = has_frame; 522 delegated_frame_size_in_dip_ = frame_size_in_dip; 523 if (!!delegated_renderer_layer_ != has_frame) { 524 if (has_frame) { 525 scoped_refptr<cc::DelegatedRendererLayer> new_layer = 526 cc::DelegatedRendererLayer::Create(NULL); 527 SwitchToLayer(new_layer); 528 delegated_renderer_layer_ = new_layer; 529 } else { 530 scoped_refptr<cc::ContentLayer> new_layer = 531 cc::ContentLayer::Create(this); 532 SwitchToLayer(new_layer); 533 content_layer_ = new_layer; 534 } 535 } 536 if (has_frame) 537 delegated_renderer_layer_->SetFrameData(frame.Pass()); 538 RecomputeDrawsContentAndUVRect(); 539} 540 541void Layer::TakeUnusedResourcesForChildCompositor( 542 cc::TransferableResourceArray* list) { 543 if (delegated_renderer_layer_) 544 delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor(list); 545} 546 547void Layer::SetColor(SkColor color) { 548 GetAnimator()->SetColor(color); 549} 550 551bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) { 552 if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !texture_)) 553 return false; 554 555 damaged_region_.op(invalid_rect.x(), 556 invalid_rect.y(), 557 invalid_rect.right(), 558 invalid_rect.bottom(), 559 SkRegion::kUnion_Op); 560 ScheduleDraw(); 561 return true; 562} 563 564void Layer::ScheduleDraw() { 565 Compositor* compositor = GetCompositor(); 566 if (compositor) 567 compositor->ScheduleDraw(); 568} 569 570void Layer::SendDamagedRects() { 571 if ((delegate_ || texture_) && !damaged_region_.isEmpty()) { 572 for (SkRegion::Iterator iter(damaged_region_); 573 !iter.done(); iter.next()) { 574 const SkIRect& sk_damaged = iter.rect(); 575 gfx::Rect damaged( 576 sk_damaged.x(), 577 sk_damaged.y(), 578 sk_damaged.width(), 579 sk_damaged.height()); 580 581 gfx::Rect damaged_in_pixel = ConvertRectToPixel(this, damaged); 582 cc_layer_->SetNeedsDisplayRect(damaged_in_pixel); 583 } 584 damaged_region_.setEmpty(); 585 } 586 for (size_t i = 0; i < children_.size(); ++i) 587 children_[i]->SendDamagedRects(); 588} 589 590void Layer::SuppressPaint() { 591 if (!delegate_) 592 return; 593 delegate_ = NULL; 594 for (size_t i = 0; i < children_.size(); ++i) 595 children_[i]->SuppressPaint(); 596} 597 598void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) { 599 if (device_scale_factor_ == device_scale_factor) 600 return; 601 if (animator_) 602 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM); 603 gfx::Transform transform = this->transform(); 604 device_scale_factor_ = device_scale_factor; 605 RecomputeCCTransformFromTransform(transform); 606 RecomputeDrawsContentAndUVRect(); 607 RecomputePosition(); 608 SchedulePaint(gfx::Rect(bounds_.size())); 609 if (delegate_) 610 delegate_->OnDeviceScaleFactorChanged(device_scale_factor); 611 for (size_t i = 0; i < children_.size(); ++i) 612 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor); 613 if (layer_mask_) 614 layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor); 615} 616 617void Layer::PaintContents(SkCanvas* sk_canvas, 618 gfx::Rect clip, 619 gfx::RectF* opaque) { 620 TRACE_EVENT0("ui", "Layer::PaintContents"); 621 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling( 622 sk_canvas, ui::GetScaleFactorFromScale(device_scale_factor_))); 623 624 bool scale_content = scale_content_; 625 if (scale_content) { 626 canvas->Save(); 627 canvas->sk_canvas()->scale(SkFloatToScalar(device_scale_factor_), 628 SkFloatToScalar(device_scale_factor_)); 629 } 630 631 if (delegate_) 632 delegate_->OnPaintLayer(canvas.get()); 633 if (scale_content) 634 canvas->Restore(); 635} 636 637unsigned Layer::PrepareTexture(cc::ResourceUpdateQueue* queue) { 638 DCHECK(texture_layer_); 639 return texture_->PrepareTexture(); 640} 641 642WebKit::WebGraphicsContext3D* Layer::Context3d() { 643 DCHECK(texture_layer_); 644 return texture_->HostContext3D(); 645} 646 647bool Layer::PrepareTextureMailbox(cc::TextureMailbox* mailbox) { 648 return false; 649} 650 651void Layer::SetForceRenderSurface(bool force) { 652 if (force_render_surface_ == force) 653 return; 654 655 force_render_surface_ = force; 656 cc_layer_->SetForceRenderSurface(force_render_surface_); 657} 658 659void Layer::OnAnimationStarted(const cc::AnimationEvent& event) { 660 if (animator_) 661 animator_->OnThreadedAnimationStarted(event); 662} 663 664void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) { 665 DCHECK_NE(child, other); 666 DCHECK_EQ(this, child->parent()); 667 DCHECK_EQ(this, other->parent()); 668 669 const size_t child_i = 670 std::find(children_.begin(), children_.end(), child) - children_.begin(); 671 const size_t other_i = 672 std::find(children_.begin(), children_.end(), other) - children_.begin(); 673 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i)) 674 return; 675 676 const size_t dest_i = 677 above ? 678 (child_i < other_i ? other_i : other_i + 1) : 679 (child_i < other_i ? other_i - 1 : other_i); 680 children_.erase(children_.begin() + child_i); 681 children_.insert(children_.begin() + dest_i, child); 682 683 child->cc_layer_->RemoveFromParent(); 684 cc_layer_->InsertChild(child->cc_layer_, dest_i); 685} 686 687bool Layer::ConvertPointForAncestor(const Layer* ancestor, 688 gfx::Point* point) const { 689 gfx::Transform transform; 690 bool result = GetTargetTransformRelativeTo(ancestor, &transform); 691 gfx::Point3F p(*point); 692 transform.TransformPoint(p); 693 *point = gfx::ToFlooredPoint(p.AsPointF()); 694 return result; 695} 696 697bool Layer::ConvertPointFromAncestor(const Layer* ancestor, 698 gfx::Point* point) const { 699 gfx::Transform transform; 700 bool result = GetTargetTransformRelativeTo(ancestor, &transform); 701 gfx::Point3F p(*point); 702 transform.TransformPointReverse(p); 703 *point = gfx::ToFlooredPoint(p.AsPointF()); 704 return result; 705} 706 707void Layer::SetBoundsImmediately(const gfx::Rect& bounds) { 708 if (bounds == bounds_) 709 return; 710 711 base::Closure closure; 712 if (delegate_) 713 closure = delegate_->PrepareForLayerBoundsChange(); 714 bool was_move = bounds_.size() == bounds.size(); 715 bounds_ = bounds; 716 717 RecomputeDrawsContentAndUVRect(); 718 RecomputePosition(); 719 720 if (!closure.is_null()) 721 closure.Run(); 722 723 if (was_move) { 724 // Don't schedule a draw if we're invisible. We'll schedule one 725 // automatically when we get visible. 726 if (IsDrawn()) 727 ScheduleDraw(); 728 } else { 729 // Always schedule a paint, even if we're invisible. 730 SchedulePaint(gfx::Rect(bounds.size())); 731 } 732} 733 734void Layer::SetTransformImmediately(const gfx::Transform& transform) { 735 RecomputeCCTransformFromTransform(transform); 736} 737 738void Layer::SetOpacityImmediately(float opacity) { 739 cc_layer_->SetOpacity(opacity); 740 ScheduleDraw(); 741} 742 743void Layer::SetVisibilityImmediately(bool visible) { 744 if (visible_ == visible) 745 return; 746 747 visible_ = visible; 748 UpdateIsDrawn(); 749} 750 751void Layer::SetBrightnessImmediately(float brightness) { 752 layer_brightness_ = brightness; 753 SetLayerFilters(); 754} 755 756void Layer::SetGrayscaleImmediately(float grayscale) { 757 layer_grayscale_ = grayscale; 758 SetLayerFilters(); 759} 760 761void Layer::SetColorImmediately(SkColor color) { 762 DCHECK_EQ(type_, LAYER_SOLID_COLOR); 763 // WebColor is equivalent to SkColor, per WebColor.h. 764 solid_color_layer_->SetBackgroundColor(static_cast<WebKit::WebColor>(color)); 765 SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF); 766} 767 768void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { 769 SetBoundsImmediately(bounds); 770} 771 772void Layer::SetTransformFromAnimation(const gfx::Transform& transform) { 773 SetTransformImmediately(transform); 774} 775 776void Layer::SetOpacityFromAnimation(float opacity) { 777 SetOpacityImmediately(opacity); 778} 779 780void Layer::SetVisibilityFromAnimation(bool visibility) { 781 SetVisibilityImmediately(visibility); 782} 783 784void Layer::SetBrightnessFromAnimation(float brightness) { 785 SetBrightnessImmediately(brightness); 786} 787 788void Layer::SetGrayscaleFromAnimation(float grayscale) { 789 SetGrayscaleImmediately(grayscale); 790} 791 792void Layer::SetColorFromAnimation(SkColor color) { 793 SetColorImmediately(color); 794} 795 796void Layer::ScheduleDrawForAnimation() { 797 ScheduleDraw(); 798} 799 800const gfx::Rect& Layer::GetBoundsForAnimation() const { 801 return bounds(); 802} 803 804gfx::Transform Layer::GetTransformForAnimation() const { 805 return transform(); 806} 807 808float Layer::GetOpacityForAnimation() const { 809 return opacity(); 810} 811 812bool Layer::GetVisibilityForAnimation() const { 813 return visible(); 814} 815 816float Layer::GetBrightnessForAnimation() const { 817 return layer_brightness(); 818} 819 820float Layer::GetGrayscaleForAnimation() const { 821 return layer_grayscale(); 822} 823 824SkColor Layer::GetColorForAnimation() const { 825 // WebColor is equivalent to SkColor, per WebColor.h. 826 // The NULL check is here since this is invoked regardless of whether we have 827 // been configured as LAYER_SOLID_COLOR. 828 return solid_color_layer_.get() ? 829 solid_color_layer_->background_color() : SK_ColorBLACK; 830} 831 832float Layer::GetDeviceScaleFactor() const { 833 return device_scale_factor_; 834} 835 836void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) { 837 DCHECK(cc_layer_); 838 // Until this layer has a compositor (and hence cc_layer_ has a 839 // LayerTreeHost), addAnimation will fail. 840 if (GetCompositor()) 841 cc_layer_->AddAnimation(animation.Pass()); 842 else 843 pending_threaded_animations_.push_back(animation.Pass()); 844} 845 846namespace{ 847 848struct HasAnimationId { 849 HasAnimationId(int id): id_(id) { 850 } 851 852 bool operator()(cc::Animation* animation) const { 853 return animation->id() == id_; 854 } 855 856 private: 857 int id_; 858}; 859 860} 861 862void Layer::RemoveThreadedAnimation(int animation_id) { 863 DCHECK(cc_layer_); 864 if (pending_threaded_animations_.size() == 0) { 865 cc_layer_->RemoveAnimation(animation_id); 866 return; 867 } 868 869 pending_threaded_animations_.erase( 870 cc::remove_if(&pending_threaded_animations_, 871 pending_threaded_animations_.begin(), 872 pending_threaded_animations_.end(), 873 HasAnimationId(animation_id)), 874 pending_threaded_animations_.end()); 875} 876 877void Layer::SendPendingThreadedAnimations() { 878 for (cc::ScopedPtrVector<cc::Animation>::iterator it = 879 pending_threaded_animations_.begin(); 880 it != pending_threaded_animations_.end(); 881 ++it) 882 cc_layer_->AddAnimation(pending_threaded_animations_.take(it)); 883 884 pending_threaded_animations_.clear(); 885 886 for (size_t i = 0; i < children_.size(); ++i) 887 children_[i]->SendPendingThreadedAnimations(); 888} 889 890void Layer::CreateWebLayer() { 891 if (type_ == LAYER_SOLID_COLOR) { 892 solid_color_layer_ = cc::SolidColorLayer::Create(); 893 cc_layer_ = solid_color_layer_.get(); 894 } else { 895 content_layer_ = cc::ContentLayer::Create(this); 896 cc_layer_ = content_layer_.get(); 897 } 898 cc_layer_->SetAnchorPoint(gfx::PointF()); 899 cc_layer_->SetContentsOpaque(true); 900 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); 901 cc_layer_->AddLayerAnimationEventObserver(this); 902 RecomputePosition(); 903} 904 905void Layer::RecomputeCCTransformFromTransform(const gfx::Transform& transform) { 906 cc_layer_->SetTransform(ConvertTransformToCCTransform(transform, 907 device_scale_factor_)); 908} 909 910gfx::Transform Layer::transform() const { 911 gfx::Transform transform; 912 transform.Scale(1.0f / device_scale_factor_, 1.0f / device_scale_factor_); 913 transform.PreconcatTransform(cc_layer_->transform()); 914 transform.Scale(device_scale_factor_, device_scale_factor_); 915 return transform; 916} 917 918void Layer::RecomputeDrawsContentAndUVRect() { 919 DCHECK(cc_layer_); 920 gfx::Size size(bounds_.size()); 921 if (texture_layer_.get()) { 922 DCHECK(texture_); 923 924 float texture_scale_factor = 1.0f / texture_->device_scale_factor(); 925 gfx::Size texture_size = gfx::ToFlooredSize( 926 gfx::ScaleSize(texture_->size(), texture_scale_factor)); 927 size.ClampToMax(texture_size); 928 929 gfx::PointF uv_top_left(0.f, 0.f); 930 gfx::PointF uv_bottom_right( 931 static_cast<float>(size.width())/texture_size.width(), 932 static_cast<float>(size.height())/texture_size.height()); 933 texture_layer_->SetUV(uv_top_left, uv_bottom_right); 934 } else if (delegated_renderer_layer_.get()) { 935 delegated_renderer_layer_->SetDisplaySize( 936 ConvertSizeToPixel(this, delegated_frame_size_in_dip_)); 937 size.ClampToMax(delegated_frame_size_in_dip_); 938 } 939 cc_layer_->SetBounds(ConvertSizeToPixel(this, size)); 940} 941 942void Layer::RecomputePosition() { 943 cc_layer_->SetPosition(gfx::ScalePoint( 944 gfx::PointF(bounds_.x(), bounds_.y()), 945 device_scale_factor_)); 946} 947 948} // namespace ui 949