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