layer.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 "third_party/WebKit/Source/Platform/chromium/public/Platform.h" 14#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorSupport.h" 15#include "third_party/WebKit/Source/Platform/chromium/public/WebContentLayer.h" 16#include "third_party/WebKit/Source/Platform/chromium/public/WebExternalTextureLayer.h" 17#include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.h" 18#include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h" 19#include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h" 20#include "third_party/WebKit/Source/Platform/chromium/public/WebFloatRect.h" 21#include "third_party/WebKit/Source/Platform/chromium/public/WebSolidColorLayer.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/point_conversions.h" 30#include "ui/gfx/point3_f.h" 31#include "ui/gfx/size_conversions.h" 32 33namespace { 34 35const float EPSILON = 1e-3f; 36 37bool IsApproximateMultipleOf(float value, float base) { 38 float remainder = fmod(fabs(value), base); 39 return remainder < EPSILON || base - remainder < EPSILON; 40} 41 42const ui::Layer* GetRoot(const ui::Layer* layer) { 43 return layer->parent() ? GetRoot(layer->parent()) : layer; 44} 45 46} // namespace 47 48namespace ui { 49 50Layer::Layer() 51 : type_(LAYER_TEXTURED), 52 compositor_(NULL), 53 parent_(NULL), 54 visible_(true), 55 force_render_surface_(false), 56 fills_bounds_opaquely_(true), 57 layer_updated_externally_(false), 58 opacity_(1.0f), 59 background_blur_radius_(0), 60 layer_saturation_(0.0f), 61 layer_brightness_(0.0f), 62 layer_grayscale_(0.0f), 63 layer_inverted_(false), 64 layer_mask_(NULL), 65 layer_mask_back_link_(NULL), 66 delegate_(NULL), 67 web_layer_(NULL), 68 scale_content_(true), 69 device_scale_factor_(1.0f) { 70 CreateWebLayer(); 71} 72 73Layer::Layer(LayerType type) 74 : type_(type), 75 compositor_(NULL), 76 parent_(NULL), 77 visible_(true), 78 force_render_surface_(false), 79 fills_bounds_opaquely_(true), 80 layer_updated_externally_(false), 81 opacity_(1.0f), 82 background_blur_radius_(0), 83 layer_saturation_(0.0f), 84 layer_brightness_(0.0f), 85 layer_grayscale_(0.0f), 86 layer_inverted_(false), 87 layer_mask_(NULL), 88 layer_mask_back_link_(NULL), 89 delegate_(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_) 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 web_layer_->removeFromParent(); 113} 114 115Compositor* Layer::GetCompositor() { 116 return GetRoot(this)->compositor_; 117} 118 119void Layer::SetCompositor(Compositor* compositor) { 120 // This function must only be called to set the compositor on the root layer, 121 // or to reset it. 122 DCHECK(!compositor || !compositor_); 123 DCHECK(!compositor || compositor->root_layer() == this); 124 DCHECK(!parent_); 125 compositor_ = compositor; 126 if (compositor) 127 OnDeviceScaleFactorChanged(compositor->device_scale_factor()); 128} 129 130void Layer::Add(Layer* child) { 131 DCHECK(!child->compositor_); 132 if (child->parent_) 133 child->parent_->Remove(child); 134 child->parent_ = this; 135 children_.push_back(child); 136 web_layer_->addChild(child->web_layer_); 137 child->OnDeviceScaleFactorChanged(device_scale_factor_); 138} 139 140void Layer::Remove(Layer* child) { 141 std::vector<Layer*>::iterator i = 142 std::find(children_.begin(), children_.end(), child); 143 DCHECK(i != children_.end()); 144 children_.erase(i); 145 child->parent_ = NULL; 146 child->web_layer_->removeFromParent(); 147} 148 149void Layer::StackAtTop(Layer* child) { 150 if (children_.size() <= 1 || child == children_.back()) 151 return; // Already in front. 152 StackAbove(child, children_.back()); 153} 154 155void Layer::StackAbove(Layer* child, Layer* other) { 156 StackRelativeTo(child, other, true); 157} 158 159void Layer::StackAtBottom(Layer* child) { 160 if (children_.size() <= 1 || child == children_.front()) 161 return; // Already on bottom. 162 StackBelow(child, children_.front()); 163} 164 165void Layer::StackBelow(Layer* child, Layer* other) { 166 StackRelativeTo(child, other, false); 167} 168 169bool Layer::Contains(const Layer* other) const { 170 for (const Layer* parent = other; parent; parent = parent->parent()) { 171 if (parent == this) 172 return true; 173 } 174 return false; 175} 176 177void Layer::SetAnimator(LayerAnimator* animator) { 178 if (animator) 179 animator->SetDelegate(this); 180 animator_ = animator; 181} 182 183LayerAnimator* Layer::GetAnimator() { 184 if (!animator_.get()) 185 SetAnimator(LayerAnimator::CreateDefaultAnimator()); 186 return animator_.get(); 187} 188 189void Layer::SetTransform(const gfx::Transform& transform) { 190 GetAnimator()->SetTransform(transform); 191} 192 193gfx::Transform Layer::GetTargetTransform() const { 194 if (animator_.get() && animator_->IsAnimatingProperty( 195 LayerAnimationElement::TRANSFORM)) { 196 return animator_->GetTargetTransform(); 197 } 198 return transform_; 199} 200 201void Layer::SetBounds(const gfx::Rect& bounds) { 202 GetAnimator()->SetBounds(bounds); 203} 204 205gfx::Rect Layer::GetTargetBounds() const { 206 if (animator_.get() && animator_->IsAnimatingProperty( 207 LayerAnimationElement::BOUNDS)) { 208 return animator_->GetTargetBounds(); 209 } 210 return bounds_; 211} 212 213void Layer::SetMasksToBounds(bool masks_to_bounds) { 214 web_layer_->setMasksToBounds(masks_to_bounds); 215} 216 217bool Layer::GetMasksToBounds() const { 218 return web_layer_->masksToBounds(); 219} 220 221void Layer::SetOpacity(float opacity) { 222 GetAnimator()->SetOpacity(opacity); 223} 224 225float Layer::GetCombinedOpacity() const { 226 float opacity = opacity_; 227 Layer* current = this->parent_; 228 while (current) { 229 opacity *= current->opacity_; 230 current = current->parent_; 231 } 232 return opacity; 233} 234 235void Layer::SetBackgroundBlur(int blur_radius) { 236 background_blur_radius_ = blur_radius; 237 238 WebKit::WebFilterOperations filters; 239 if (background_blur_radius_) { 240 filters.append(WebKit::WebFilterOperation::createBlurFilter( 241 background_blur_radius_)); 242 } 243 web_layer_->setBackgroundFilters(filters); 244} 245 246void Layer::SetLayerSaturation(float saturation) { 247 layer_saturation_ = saturation; 248 SetLayerFilters(); 249} 250 251void Layer::SetLayerBrightness(float brightness) { 252 GetAnimator()->SetBrightness(brightness); 253} 254 255float Layer::GetTargetBrightness() const { 256 if (animator_.get() && animator_->IsAnimatingProperty( 257 LayerAnimationElement::BRIGHTNESS)) { 258 return animator_->GetTargetBrightness(); 259 } 260 return layer_brightness(); 261} 262 263void Layer::SetLayerGrayscale(float grayscale) { 264 GetAnimator()->SetGrayscale(grayscale); 265} 266 267float Layer::GetTargetGrayscale() const { 268 if (animator_.get() && animator_->IsAnimatingProperty( 269 LayerAnimationElement::GRAYSCALE)) { 270 return animator_->GetTargetGrayscale(); 271 } 272 return layer_grayscale(); 273} 274 275void Layer::SetLayerInverted(bool inverted) { 276 layer_inverted_ = inverted; 277 SetLayerFilters(); 278} 279 280void Layer::SetMaskLayer(Layer* layer_mask) { 281 // The provided mask should not have a layer mask itself. 282 DCHECK(!layer_mask || 283 (!layer_mask->layer_mask_layer() && 284 layer_mask->children().empty() && 285 !layer_mask->layer_mask_back_link_)); 286 DCHECK(!layer_mask_back_link_); 287 if (layer_mask_ == layer_mask) 288 return; 289 // We need to de-reference the currently linked object so that no problem 290 // arises if the mask layer gets deleted before this object. 291 if (layer_mask_) 292 layer_mask_->layer_mask_back_link_ = NULL; 293 layer_mask_ = layer_mask; 294 web_layer_->setMaskLayer( 295 layer_mask ? layer_mask->web_layer() : NULL); 296 // We need to reference the linked object so that it can properly break the 297 // link to us when it gets deleted. 298 if (layer_mask) 299 layer_mask->layer_mask_back_link_ = this; 300} 301 302void Layer::SetLayerFilters() { 303 WebKit::WebFilterOperations filters; 304 if (layer_saturation_) { 305 filters.append(WebKit::WebFilterOperation::createSaturateFilter( 306 layer_saturation_)); 307 } 308 if (layer_grayscale_) { 309 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter( 310 layer_grayscale_)); 311 } 312 if (layer_inverted_) 313 filters.append(WebKit::WebFilterOperation::createInvertFilter(1.0)); 314 // Brightness goes last, because the resulting colors neeed clamping, which 315 // cause further color matrix filters to be applied separately. In this order, 316 // they all can be combined in a single pass. 317 if (layer_brightness_) { 318 filters.append(WebKit::WebFilterOperation::createBrightnessFilter( 319 layer_brightness_)); 320 } 321 322 web_layer_->setFilters(filters); 323} 324 325float Layer::GetTargetOpacity() const { 326 if (animator_.get() && animator_->IsAnimatingProperty( 327 LayerAnimationElement::OPACITY)) 328 return animator_->GetTargetOpacity(); 329 return opacity_; 330} 331 332void Layer::SetVisible(bool visible) { 333 GetAnimator()->SetVisibility(visible); 334} 335 336bool Layer::GetTargetVisibility() const { 337 if (animator_.get() && animator_->IsAnimatingProperty( 338 LayerAnimationElement::VISIBILITY)) 339 return animator_->GetTargetVisibility(); 340 return visible_; 341} 342 343bool Layer::IsDrawn() const { 344 const Layer* layer = this; 345 while (layer && layer->visible_) 346 layer = layer->parent_; 347 return layer == NULL; 348} 349 350bool Layer::ShouldDraw() const { 351 return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f; 352} 353 354// static 355void Layer::ConvertPointToLayer(const Layer* source, 356 const Layer* target, 357 gfx::Point* point) { 358 if (source == target) 359 return; 360 361 const Layer* root_layer = GetRoot(source); 362 CHECK_EQ(root_layer, GetRoot(target)); 363 364 if (source != root_layer) 365 source->ConvertPointForAncestor(root_layer, point); 366 if (target != root_layer) 367 target->ConvertPointFromAncestor(root_layer, point); 368} 369 370void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { 371 if (fills_bounds_opaquely_ == fills_bounds_opaquely) 372 return; 373 374 fills_bounds_opaquely_ = fills_bounds_opaquely; 375 376 web_layer_->setOpaque(fills_bounds_opaquely); 377 RecomputeDebugBorderColor(); 378} 379 380void Layer::SetExternalTexture(Texture* texture) { 381 DCHECK_EQ(type_, LAYER_TEXTURED); 382 layer_updated_externally_ = !!texture; 383 texture_ = texture; 384 if (web_layer_is_accelerated_ != layer_updated_externally_) { 385 // Switch to a different type of layer. 386 web_layer_->removeAllChildren(); 387 scoped_ptr<WebKit::WebContentLayer> old_content_layer( 388 content_layer_.release()); 389 scoped_ptr<WebKit::WebSolidColorLayer> old_solid_layer( 390 solid_color_layer_.release()); 391 scoped_ptr<WebKit::WebExternalTextureLayer> old_texture_layer( 392 texture_layer_.release()); 393 WebKit::WebLayer* new_layer = NULL; 394 WebKit::WebCompositorSupport* compositor_support = 395 WebKit::Platform::current()->compositorSupport(); 396 if (layer_updated_externally_) { 397 texture_layer_.reset( 398 compositor_support->createExternalTextureLayer(this)); 399 texture_layer_->setFlipped(texture_->flipped()); 400 new_layer = texture_layer_->layer(); 401 } else { 402 old_texture_layer->willModifyTexture(); 403 content_layer_.reset(compositor_support->createContentLayer(this)); 404 new_layer = content_layer_->layer(); 405 } 406 if (parent_) { 407 DCHECK(parent_->web_layer_); 408 parent_->web_layer_->replaceChild(web_layer_, new_layer); 409 } 410 web_layer_= new_layer; 411 web_layer_is_accelerated_ = layer_updated_externally_; 412 for (size_t i = 0; i < children_.size(); ++i) { 413 DCHECK(children_[i]->web_layer_); 414 web_layer_->addChild(children_[i]->web_layer_); 415 } 416 web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); 417 web_layer_->setOpaque(fills_bounds_opaquely_); 418 web_layer_->setOpacity(visible_ ? opacity_ : 0.f); 419 web_layer_->setDebugBorderWidth(show_debug_borders_ ? 2 : 0); 420 web_layer_->setForceRenderSurface(force_render_surface_); 421 RecomputeTransform(); 422 RecomputeDebugBorderColor(); 423 } 424 RecomputeDrawsContentAndUVRect(); 425} 426 427void Layer::SetColor(SkColor color) { 428 GetAnimator()->SetColor(color); 429} 430 431bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) { 432 if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !texture_)) 433 return false; 434 435 damaged_region_.op(invalid_rect.x(), 436 invalid_rect.y(), 437 invalid_rect.right(), 438 invalid_rect.bottom(), 439 SkRegion::kUnion_Op); 440 ScheduleDraw(); 441 return true; 442} 443 444void Layer::ScheduleDraw() { 445 Compositor* compositor = GetCompositor(); 446 if (compositor) 447 compositor->ScheduleDraw(); 448} 449 450void Layer::SendDamagedRects() { 451 if ((delegate_ || texture_) && !damaged_region_.isEmpty()) { 452 for (SkRegion::Iterator iter(damaged_region_); 453 !iter.done(); iter.next()) { 454 const SkIRect& sk_damaged = iter.rect(); 455 gfx::Rect damaged( 456 sk_damaged.x(), 457 sk_damaged.y(), 458 sk_damaged.width(), 459 sk_damaged.height()); 460 461 gfx::Rect damaged_in_pixel = ConvertRectToPixel(this, damaged); 462 WebKit::WebFloatRect web_rect( 463 damaged_in_pixel.x(), 464 damaged_in_pixel.y(), 465 damaged_in_pixel.width(), 466 damaged_in_pixel.height()); 467 web_layer_->invalidateRect(web_rect); 468 } 469 damaged_region_.setEmpty(); 470 } 471 for (size_t i = 0; i < children_.size(); ++i) 472 children_[i]->SendDamagedRects(); 473} 474 475void Layer::SuppressPaint() { 476 if (!delegate_) 477 return; 478 delegate_ = NULL; 479 for (size_t i = 0; i < children_.size(); ++i) 480 children_[i]->SuppressPaint(); 481} 482 483void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) { 484 if (device_scale_factor_ == device_scale_factor) 485 return; 486 device_scale_factor_ = device_scale_factor; 487 RecomputeTransform(); 488 RecomputeDrawsContentAndUVRect(); 489 SchedulePaint(gfx::Rect(bounds_.size())); 490 if (delegate_) 491 delegate_->OnDeviceScaleFactorChanged(device_scale_factor); 492 for (size_t i = 0; i < children_.size(); ++i) 493 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor); 494} 495 496void Layer::paintContents(WebKit::WebCanvas* web_canvas, 497 const WebKit::WebRect& clip, 498#if WEBCONTENTLAYERCLIENT_HAS_CANPAINTLCDTEXT 499 bool can_paint_lcd_text, 500#endif // WEBCONTENTLAYERCLIENT_HAS_CANPAINTLCDTEXT 501 WebKit::WebFloatRect& opaque) { 502 TRACE_EVENT0("ui", "Layer::paintContents"); 503 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling( 504 web_canvas, ui::GetScaleFactorFromScale(device_scale_factor_))); 505 506 bool scale_content = scale_content_; 507 if (scale_content) { 508 canvas->Save(); 509 canvas->sk_canvas()->scale(SkFloatToScalar(device_scale_factor_), 510 SkFloatToScalar(device_scale_factor_)); 511 } 512 513 if (delegate_) 514 delegate_->OnPaintLayer(canvas.get()); 515 if (scale_content) 516 canvas->Restore(); 517} 518 519unsigned Layer::prepareTexture(WebKit::WebTextureUpdater& /* updater */) { 520 DCHECK(layer_updated_externally_); 521 return texture_->PrepareTexture(); 522} 523 524WebKit::WebGraphicsContext3D* Layer::context() { 525 DCHECK(layer_updated_externally_); 526 return texture_->HostContext3D(); 527} 528 529void Layer::SetForceRenderSurface(bool force) { 530 if (force_render_surface_ == force) 531 return; 532 533 force_render_surface_ = force; 534 web_layer_->setForceRenderSurface(force_render_surface_); 535} 536 537void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) { 538 DCHECK_NE(child, other); 539 DCHECK_EQ(this, child->parent()); 540 DCHECK_EQ(this, other->parent()); 541 542 const size_t child_i = 543 std::find(children_.begin(), children_.end(), child) - children_.begin(); 544 const size_t other_i = 545 std::find(children_.begin(), children_.end(), other) - children_.begin(); 546 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i)) 547 return; 548 549 const size_t dest_i = 550 above ? 551 (child_i < other_i ? other_i : other_i + 1) : 552 (child_i < other_i ? other_i - 1 : other_i); 553 children_.erase(children_.begin() + child_i); 554 children_.insert(children_.begin() + dest_i, child); 555 556 child->web_layer_->removeFromParent(); 557 web_layer_->insertChild(child->web_layer_, dest_i); 558} 559 560bool Layer::ConvertPointForAncestor(const Layer* ancestor, 561 gfx::Point* point) const { 562 gfx::Transform transform; 563 bool result = GetTransformRelativeTo(ancestor, &transform); 564 gfx::Point3F p(*point); 565 transform.TransformPoint(p); 566 *point = gfx::ToFlooredPoint(p.AsPointF()); 567 return result; 568} 569 570bool Layer::ConvertPointFromAncestor(const Layer* ancestor, 571 gfx::Point* point) const { 572 gfx::Transform transform; 573 bool result = GetTransformRelativeTo(ancestor, &transform); 574 gfx::Point3F p(*point); 575 transform.TransformPointReverse(p); 576 *point = gfx::ToFlooredPoint(p.AsPointF()); 577 return result; 578} 579 580bool Layer::GetTransformRelativeTo(const Layer* ancestor, 581 gfx::Transform* transform) const { 582 const Layer* p = this; 583 for (; p && p != ancestor; p = p->parent()) { 584 if (p->transform().HasChange()) 585 transform->ConcatTransform(p->transform()); 586 transform->ConcatTranslate(static_cast<float>(p->bounds().x()), 587 static_cast<float>(p->bounds().y())); 588 } 589 return p == ancestor; 590} 591 592void Layer::SetBoundsImmediately(const gfx::Rect& bounds) { 593 if (bounds == bounds_) 594 return; 595 596 base::Closure closure; 597 if (delegate_) 598 closure = delegate_->PrepareForLayerBoundsChange(); 599 bool was_move = bounds_.size() == bounds.size(); 600 bounds_ = bounds; 601 602 RecomputeTransform(); 603 RecomputeDrawsContentAndUVRect(); 604 if (!closure.is_null()) 605 closure.Run(); 606 607 if (was_move) { 608 // Don't schedule a draw if we're invisible. We'll schedule one 609 // automatically when we get visible. 610 if (IsDrawn()) 611 ScheduleDraw(); 612 } else { 613 // Always schedule a paint, even if we're invisible. 614 SchedulePaint(gfx::Rect(bounds.size())); 615 } 616} 617 618void Layer::SetTransformImmediately(const gfx::Transform& transform) { 619 transform_ = transform; 620 621 RecomputeTransform(); 622} 623 624void Layer::SetOpacityImmediately(float opacity) { 625 bool schedule_draw = (opacity != opacity_ && IsDrawn()); 626 opacity_ = opacity; 627 628 if (visible_) 629 web_layer_->setOpacity(opacity); 630 RecomputeDebugBorderColor(); 631 if (schedule_draw) 632 ScheduleDraw(); 633} 634 635void Layer::SetVisibilityImmediately(bool visible) { 636 if (visible_ == visible) 637 return; 638 639 visible_ = visible; 640 // TODO(piman): Expose a visibility flag on WebLayer. 641 web_layer_->setOpacity(visible_ ? opacity_ : 0.f); 642} 643 644void Layer::SetBrightnessImmediately(float brightness) { 645 layer_brightness_ = brightness; 646 SetLayerFilters(); 647} 648 649void Layer::SetGrayscaleImmediately(float grayscale) { 650 layer_grayscale_ = grayscale; 651 SetLayerFilters(); 652} 653 654void Layer::SetColorImmediately(SkColor color) { 655 DCHECK_EQ(type_, LAYER_SOLID_COLOR); 656 // WebColor is equivalent to SkColor, per WebColor.h. 657 solid_color_layer_->setBackgroundColor(static_cast<WebKit::WebColor>(color)); 658 SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF); 659} 660 661void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { 662 SetBoundsImmediately(bounds); 663} 664 665void Layer::SetTransformFromAnimation(const gfx::Transform& transform) { 666 SetTransformImmediately(transform); 667} 668 669void Layer::SetOpacityFromAnimation(float opacity) { 670 SetOpacityImmediately(opacity); 671} 672 673void Layer::SetVisibilityFromAnimation(bool visibility) { 674 SetVisibilityImmediately(visibility); 675} 676 677void Layer::SetBrightnessFromAnimation(float brightness) { 678 SetBrightnessImmediately(brightness); 679} 680 681void Layer::SetGrayscaleFromAnimation(float grayscale) { 682 SetGrayscaleImmediately(grayscale); 683} 684 685void Layer::SetColorFromAnimation(SkColor color) { 686 SetColorImmediately(color); 687} 688 689void Layer::ScheduleDrawForAnimation() { 690 ScheduleDraw(); 691} 692 693const gfx::Rect& Layer::GetBoundsForAnimation() const { 694 return bounds(); 695} 696 697const gfx::Transform& Layer::GetTransformForAnimation() const { 698 return transform(); 699} 700 701float Layer::GetOpacityForAnimation() const { 702 return opacity(); 703} 704 705bool Layer::GetVisibilityForAnimation() const { 706 return visible(); 707} 708 709float Layer::GetBrightnessForAnimation() const { 710 return layer_brightness(); 711} 712 713float Layer::GetGrayscaleForAnimation() const { 714 return layer_grayscale(); 715} 716 717SkColor Layer::GetColorForAnimation() const { 718 // WebColor is equivalent to SkColor, per WebColor.h. 719 // The NULL check is here since this is invoked regardless of whether we have 720 // been configured as LAYER_SOLID_COLOR. 721 return solid_color_layer_.get() ? 722 solid_color_layer_->layer()->backgroundColor() : SK_ColorBLACK; 723} 724 725void Layer::CreateWebLayer() { 726 WebKit::WebCompositorSupport* compositor_support = 727 WebKit::Platform::current()->compositorSupport(); 728 if (type_ == LAYER_SOLID_COLOR) { 729 solid_color_layer_.reset(compositor_support->createSolidColorLayer()); 730 web_layer_ = solid_color_layer_->layer(); 731 } else { 732 content_layer_.reset(compositor_support->createContentLayer(this)); 733 web_layer_ = content_layer_->layer(); 734 } 735 web_layer_is_accelerated_ = false; 736 show_debug_borders_ = CommandLine::ForCurrentProcess()->HasSwitch( 737 switches::kUIShowLayerBorders); 738 web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); 739 web_layer_->setOpaque(true); 740 web_layer_->setDebugBorderWidth(show_debug_borders_ ? 2 : 0); 741} 742 743void Layer::RecomputeTransform() { 744 gfx::Transform scale_translate; 745 scale_translate.matrix().set3x3(device_scale_factor_, 0, 0, 746 0, device_scale_factor_, 0, 747 0, 0, 1); 748 // Start with the inverse matrix of above. 749 gfx::Transform transform; 750 transform.matrix().set3x3(1.0f / device_scale_factor_, 0, 0, 751 0, 1.0f / device_scale_factor_, 0, 752 0, 0, 1); 753 transform.ConcatTransform(transform_); 754 transform.ConcatTranslate(bounds_.x(), bounds_.y()); 755 transform.ConcatTransform(scale_translate); 756 web_layer_->setTransform(transform.matrix()); 757} 758 759void Layer::RecomputeDrawsContentAndUVRect() { 760 DCHECK(web_layer_); 761 bool should_draw = type_ != LAYER_NOT_DRAWN; 762 if (!web_layer_is_accelerated_) { 763 if (type_ != LAYER_SOLID_COLOR) { 764 web_layer_->setDrawsContent(should_draw); 765 } 766 web_layer_->setBounds(ConvertSizeToPixel(this, bounds_.size())); 767 } else { 768 DCHECK(texture_); 769 770 float texture_scale_factor = 1.0f / texture_->device_scale_factor(); 771 gfx::Size texture_size = gfx::ToFlooredSize( 772 gfx::ScaleSize(texture_->size(), texture_scale_factor)); 773 774 gfx::Size size(std::min(bounds().width(), texture_size.width()), 775 std::min(bounds().height(), texture_size.height())); 776 WebKit::WebFloatRect rect( 777 0, 778 0, 779 static_cast<float>(size.width())/texture_size.width(), 780 static_cast<float>(size.height())/texture_size.height()); 781 texture_layer_->setUVRect(rect); 782 783 gfx::Size size_in_pixel = ConvertSizeToPixel(this, size); 784 web_layer_->setBounds(size_in_pixel); 785 } 786} 787 788void Layer::RecomputeDebugBorderColor() { 789 if (!show_debug_borders_) 790 return; 791 unsigned int color = 0xFF000000; 792 color |= web_layer_is_accelerated_ ? 0x0000FF00 : 0x00FF0000; 793 bool opaque = fills_bounds_opaquely_ && (GetCombinedOpacity() == 1.f); 794 if (!opaque) 795 color |= 0xFF; 796 web_layer_->setDebugBorderColor(color); 797} 798 799} // namespace ui 800