layer_impl.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright 2011 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 "cc/layers/layer_impl.h" 6 7#include "base/debug/trace_event.h" 8#include "base/stringprintf.h" 9#include "base/values.h" 10#include "cc/animation/animation_registrar.h" 11#include "cc/animation/scrollbar_animation_controller.h" 12#include "cc/animation/scrollbar_animation_controller_linear_fade.h" 13#include "cc/base/math_util.h" 14#include "cc/debug/debug_colors.h" 15#include "cc/debug/layer_tree_debug_state.h" 16#include "cc/layers/quad_sink.h" 17#include "cc/layers/scrollbar_layer_impl.h" 18#include "cc/quads/debug_border_draw_quad.h" 19#include "cc/trees/layer_tree_impl.h" 20#include "cc/trees/layer_tree_settings.h" 21#include "cc/trees/proxy.h" 22#include "ui/gfx/point_conversions.h" 23#include "ui/gfx/quad_f.h" 24#include "ui/gfx/rect_conversions.h" 25 26namespace cc { 27 28LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) 29 : parent_(NULL), 30 mask_layer_id_(-1), 31 replica_layer_id_(-1), 32 layer_id_(id), 33 layer_tree_impl_(tree_impl), 34 anchor_point_(0.5f, 0.5f), 35 anchor_point_z_(0.f), 36 scrollable_(false), 37 should_scroll_on_main_thread_(false), 38 have_wheel_event_handlers_(false), 39 background_color_(0), 40 stacking_order_changed_(false), 41 double_sided_(true), 42 layer_property_changed_(false), 43 layer_surface_property_changed_(false), 44 masks_to_bounds_(false), 45 contents_opaque_(false), 46 opacity_(1.0), 47 preserves_3d_(false), 48 use_parent_backface_visibility_(false), 49 draw_checkerboard_for_missing_tiles_(false), 50 draws_content_(false), 51 force_render_surface_(false), 52 is_container_for_fixed_position_layers_(false), 53 fixed_to_container_layer_(false), 54 draw_depth_(0.f), 55#ifndef NDEBUG 56 between_will_draw_and_did_draw_(false), 57#endif 58 horizontal_scrollbar_layer_(NULL), 59 vertical_scrollbar_layer_(NULL) { 60 DCHECK(layer_id_ > 0); 61 DCHECK(layer_tree_impl_); 62 layer_tree_impl_->RegisterLayer(this); 63 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); 64 layer_animation_controller_ = 65 registrar->GetAnimationControllerForId(layer_id_); 66 layer_animation_controller_->AddObserver(this); 67} 68 69LayerImpl::~LayerImpl() { 70#ifndef NDEBUG 71 DCHECK(!between_will_draw_and_did_draw_); 72#endif 73 layer_tree_impl_->UnregisterLayer(this); 74 layer_animation_controller_->RemoveObserver(this); 75} 76 77void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) { 78 child->set_parent(this); 79 DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl()); 80 children_.push_back(child.Pass()); 81 layer_tree_impl()->set_needs_update_draw_properties(); 82} 83 84scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) { 85 for (ScopedPtrVector<LayerImpl>::iterator it = children_.begin(); 86 it != children_.end(); 87 ++it) { 88 if (*it == child) { 89 scoped_ptr<LayerImpl> ret = children_.take(it); 90 children_.erase(it); 91 layer_tree_impl()->set_needs_update_draw_properties(); 92 return ret.Pass(); 93 } 94 } 95 return scoped_ptr<LayerImpl>(); 96} 97 98void LayerImpl::ClearChildList() { 99 if (children_.empty()) 100 return; 101 102 children_.clear(); 103 layer_tree_impl()->set_needs_update_draw_properties(); 104} 105 106void LayerImpl::CreateRenderSurface() { 107 DCHECK(!draw_properties_.render_surface); 108 draw_properties_.render_surface = 109 make_scoped_ptr(new RenderSurfaceImpl(this)); 110 draw_properties_.render_target = this; 111} 112 113scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const { 114 scoped_ptr<SharedQuadState> state = SharedQuadState::Create(); 115 state->SetAll(draw_properties_.target_space_transform, 116 draw_properties_.content_bounds, 117 draw_properties_.visible_content_rect, 118 draw_properties_.clip_rect, 119 draw_properties_.is_clipped, 120 draw_properties_.opacity); 121 return state.Pass(); 122} 123 124void LayerImpl::WillDraw(ResourceProvider* resource_provider) { 125#ifndef NDEBUG 126 // WillDraw/DidDraw must be matched. 127 DCHECK(!between_will_draw_and_did_draw_); 128 between_will_draw_and_did_draw_ = true; 129#endif 130} 131 132void LayerImpl::DidDraw(ResourceProvider* resource_provider) { 133#ifndef NDEBUG 134 DCHECK(between_will_draw_and_did_draw_); 135 between_will_draw_and_did_draw_ = false; 136#endif 137} 138 139bool LayerImpl::ShowDebugBorders() const { 140 return layer_tree_impl()->debug_state().show_debug_borders; 141} 142 143void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const { 144 if (draws_content_) { 145 *color = DebugColors::ContentLayerBorderColor(); 146 *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl()); 147 return; 148 } 149 150 if (masks_to_bounds_) { 151 *color = DebugColors::MaskingLayerBorderColor(); 152 *width = DebugColors::MaskingLayerBorderWidth(layer_tree_impl()); 153 return; 154 } 155 156 *color = DebugColors::ContainerLayerBorderColor(); 157 *width = DebugColors::ContainerLayerBorderWidth(layer_tree_impl()); 158} 159 160void LayerImpl::AppendDebugBorderQuad( 161 QuadSink* quad_sink, 162 const SharedQuadState* shared_quad_state, 163 AppendQuadsData* append_quads_data) const { 164 if (!ShowDebugBorders()) 165 return; 166 167 SkColor color; 168 float width; 169 GetDebugBorderProperties(&color, &width); 170 171 gfx::Rect content_rect(content_bounds()); 172 scoped_ptr<DebugBorderDrawQuad> debug_border_quad = 173 DebugBorderDrawQuad::Create(); 174 debug_border_quad->SetNew(shared_quad_state, content_rect, color, width); 175 quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(), append_quads_data); 176} 177 178bool LayerImpl::HasDelegatedContent() const { 179 return false; 180} 181 182bool LayerImpl::HasContributingDelegatedRenderPasses() const { 183 return false; 184} 185 186RenderPass::Id LayerImpl::FirstContributingRenderPassId() const { 187 return RenderPass::Id(0, 0); 188} 189 190RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id) 191 const { 192 return RenderPass::Id(0, 0); 193} 194 195ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const { 196 NOTREACHED(); 197 return 0; 198} 199 200void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) { 201 // Pending tree never has sent scroll deltas 202 DCHECK(layer_tree_impl()->IsActiveTree()); 203 204 if (sent_scroll_delta_ == sent_scroll_delta) 205 return; 206 207 sent_scroll_delta_ = sent_scroll_delta; 208} 209 210gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { 211 gfx::Vector2dF min_delta = -scroll_offset_; 212 gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_; 213 // Clamp new_delta so that position + delta stays within scroll bounds. 214 gfx::Vector2dF new_delta = (scroll_delta_ + scroll); 215 new_delta.ClampToMin(min_delta); 216 new_delta.ClampToMax(max_delta); 217 gfx::Vector2dF unscrolled = scroll_delta_ + scroll - new_delta; 218 219 SetScrollDelta(new_delta); 220 return unscrolled; 221} 222 223InputHandlerClient::ScrollStatus LayerImpl::TryScroll( 224 gfx::PointF screen_space_point, 225 InputHandlerClient::ScrollInputType type) const { 226 if (should_scroll_on_main_thread()) { 227 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); 228 return InputHandlerClient::ScrollOnMainThread; 229 } 230 231 if (!screen_space_transform().IsInvertible()) { 232 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform"); 233 return InputHandlerClient::ScrollIgnored; 234 } 235 236 if (!non_fast_scrollable_region().IsEmpty()) { 237 bool clipped = false; 238 gfx::Transform inverse_screen_space_transform( 239 gfx::Transform::kSkipInitialization); 240 if (!screen_space_transform().GetInverse(&inverse_screen_space_transform)) { 241 // TODO(shawnsingh): We shouldn't be applying a projection if screen space 242 // transform is uninvertible here. Perhaps we should be returning 243 // ScrollOnMainThread in this case? 244 } 245 246 gfx::PointF hit_test_point_in_content_space = 247 MathUtil::ProjectPoint(inverse_screen_space_transform, 248 screen_space_point, 249 &clipped); 250 gfx::PointF hit_test_point_in_layer_space = 251 gfx::ScalePoint(hit_test_point_in_content_space, 252 1.f / contents_scale_x(), 253 1.f / contents_scale_y()); 254 if (!clipped && 255 non_fast_scrollable_region().Contains( 256 gfx::ToRoundedPoint(hit_test_point_in_layer_space))) { 257 TRACE_EVENT0("cc", 258 "LayerImpl::tryScroll: Failed NonFastScrollableRegion"); 259 return InputHandlerClient::ScrollOnMainThread; 260 } 261 } 262 263 if (type == InputHandlerClient::Wheel && have_wheel_event_handlers()) { 264 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); 265 return InputHandlerClient::ScrollOnMainThread; 266 } 267 268 if (!scrollable()) { 269 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); 270 return InputHandlerClient::ScrollIgnored; 271 } 272 273 if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { 274 TRACE_EVENT0("cc", 275 "LayerImpl::tryScroll: Ignored. Technically scrollable," 276 " but has no affordance in either direction."); 277 return InputHandlerClient::ScrollIgnored; 278 } 279 280 return InputHandlerClient::ScrollStarted; 281} 282 283bool LayerImpl::DrawCheckerboardForMissingTiles() const { 284 return draw_checkerboard_for_missing_tiles_ && 285 !layer_tree_impl()->settings().background_color_instead_of_checkerboard; 286} 287 288gfx::Rect LayerImpl::LayerRectToContentRect( 289 const gfx::RectF& layer_rect) const { 290 gfx::RectF content_rect = 291 gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y()); 292 // Intersect with content rect to avoid the extra pixel because for some 293 // values x and y, ceil((x / y) * y) may be x + 1. 294 content_rect.Intersect(gfx::Rect(content_bounds())); 295 return gfx::ToEnclosingRect(content_rect); 296} 297 298skia::RefPtr<SkPicture> LayerImpl::GetPicture() { 299 return skia::RefPtr<SkPicture>(); 300} 301 302bool LayerImpl::CanClipSelf() const { 303 return false; 304} 305 306bool LayerImpl::AreVisibleResourcesReady() const { 307 return true; 308} 309 310scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { 311 return LayerImpl::Create(tree_impl, layer_id_); 312} 313 314void LayerImpl::PushPropertiesTo(LayerImpl* layer) { 315 layer->SetAnchorPoint(anchor_point_); 316 layer->SetAnchorPointZ(anchor_point_z_); 317 layer->SetBackgroundColor(background_color_); 318 layer->SetBounds(bounds_); 319 layer->SetContentBounds(content_bounds()); 320 layer->SetContentsScale(contents_scale_x(), contents_scale_y()); 321 layer->SetDebugName(debug_name_); 322 layer->SetDoubleSided(double_sided_); 323 layer->SetDrawCheckerboardForMissingTiles( 324 draw_checkerboard_for_missing_tiles_); 325 layer->SetForceRenderSurface(force_render_surface_); 326 layer->SetDrawsContent(DrawsContent()); 327 layer->SetFilters(filters()); 328 layer->SetFilter(filter()); 329 layer->SetBackgroundFilters(background_filters()); 330 layer->SetMasksToBounds(masks_to_bounds_); 331 layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); 332 layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); 333 layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); 334 layer->SetTouchEventHandlerRegion(touch_event_handler_region_); 335 layer->SetContentsOpaque(contents_opaque_); 336 layer->SetOpacity(opacity_); 337 layer->SetPosition(position_); 338 layer->SetIsContainerForFixedPositionLayers( 339 is_container_for_fixed_position_layers_); 340 layer->SetFixedToContainerLayer(fixed_to_container_layer_); 341 layer->SetPreserves3d(preserves_3d()); 342 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); 343 layer->SetSublayerTransform(sublayer_transform_); 344 layer->SetTransform(transform_); 345 346 layer->SetScrollable(scrollable_); 347 layer->SetScrollOffset(scroll_offset_); 348 layer->SetMaxScrollOffset(max_scroll_offset_); 349 350 // If the main thread commits multiple times before the impl thread actually 351 // draws, then damage tracking will become incorrect if we simply clobber the 352 // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e. 353 // union) any update changes that have occurred on the main thread. 354 update_rect_.Union(layer->update_rect()); 355 layer->set_update_rect(update_rect_); 356 357 layer->SetScrollDelta(layer->scroll_delta() - layer->sent_scroll_delta()); 358 layer->SetSentScrollDelta(gfx::Vector2d()); 359 360 layer->SetStackingOrderChanged(stacking_order_changed_); 361 362 layer_animation_controller_->PushAnimationUpdatesTo( 363 layer->layer_animation_controller()); 364 365 // Reset any state that should be cleared for the next update. 366 stacking_order_changed_ = false; 367 update_rect_ = gfx::RectF(); 368} 369 370std::string LayerImpl::IndentString(int indent) { 371 std::string str; 372 for (int i = 0; i != indent; ++i) 373 str.append(" "); 374 return str; 375} 376 377void LayerImpl::DumpLayerProperties(std::string* str, int indent) const { 378 std::string indent_str = IndentString(indent); 379 str->append(indent_str); 380 base::StringAppendF(str, "layer ID: %d\n", layer_id_); 381 382 str->append(indent_str); 383 base::StringAppendF( 384 str, "bounds: %d, %d\n", bounds().width(), bounds().height()); 385 386 if (draw_properties_.render_target) { 387 str->append(indent_str); 388 base::StringAppendF( 389 str, "renderTarget: %d\n", draw_properties_.render_target->layer_id_); 390 } 391 392 str->append(indent_str); 393 base::StringAppendF(str, "position: %f, %f\n", position_.x(), position_.y()); 394 395 str->append(indent_str); 396 base::StringAppendF(str, "contentsOpaque: %d\n", contents_opaque_); 397 398 str->append(indent_str); 399 const gfx::Transform& transform = draw_properties_.target_space_transform; 400 base::StringAppendF(str, 401 "drawTransform: %f, %f, %f, %f // %f, %f, %f, %f" 402 " // %f, %f, %f, %f // %f, %f, %f, %f\n", 403 transform.matrix().getDouble(0, 0), 404 transform.matrix().getDouble(0, 1), 405 transform.matrix().getDouble(0, 2), 406 transform.matrix().getDouble(0, 3), 407 transform.matrix().getDouble(1, 0), 408 transform.matrix().getDouble(1, 1), 409 transform.matrix().getDouble(1, 2), 410 transform.matrix().getDouble(1, 3), 411 transform.matrix().getDouble(2, 0), 412 transform.matrix().getDouble(2, 1), 413 transform.matrix().getDouble(2, 2), 414 transform.matrix().getDouble(2, 3), 415 transform.matrix().getDouble(3, 0), 416 transform.matrix().getDouble(3, 1), 417 transform.matrix().getDouble(3, 2), 418 transform.matrix().getDouble(3, 3)); 419 420 str->append(indent_str); 421 base::StringAppendF( 422 str, "draws_content: %s\n", draws_content_ ? "yes" : "no"); 423} 424 425std::string LayerImpl::LayerTreeAsText() const { 426 std::string str; 427 DumpLayer(&str, 0); 428 return str; 429} 430 431void LayerImpl::DumpLayer(std::string* str, int indent) const { 432 str->append(IndentString(indent)); 433 base::StringAppendF(str, "%s(%s)\n", LayerTypeAsString(), debug_name_.data()); 434 DumpLayerProperties(str, indent+2); 435 if (replica_layer_) { 436 str->append(IndentString(indent+2)); 437 str->append("Replica:\n"); 438 replica_layer_->DumpLayer(str, indent+3); 439 } 440 if (mask_layer_) { 441 str->append(IndentString(indent+2)); 442 str->append("Mask:\n"); 443 mask_layer_->DumpLayer(str, indent+3); 444 } 445 for (size_t i = 0; i < children_.size(); ++i) 446 children_[i]->DumpLayer(str, indent+1); 447} 448 449base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { 450 base::ListValue* list; 451 base::DictionaryValue* result = new base::DictionaryValue; 452 result->SetString("LayerType", LayerTypeAsString()); 453 454 list = new base::ListValue; 455 list->AppendInteger(bounds().width()); 456 list->AppendInteger(bounds().height()); 457 result->Set("Bounds", list); 458 459 list = new base::ListValue; 460 list->AppendDouble(position_.x()); 461 list->AppendDouble(position_.y()); 462 result->Set("Position", list); 463 464 const gfx::Transform& gfx_transform = draw_properties_.target_space_transform; 465 double transform[16]; 466 gfx_transform.matrix().asColMajord(transform); 467 list = new base::ListValue; 468 for (int i = 0; i < 16; ++i) 469 list->AppendDouble(transform[i]); 470 result->Set("DrawTransform", list); 471 472 result->SetBoolean("DrawsContent", draws_content_); 473 result->SetDouble("Opacity", opacity()); 474 475 list = new base::ListValue; 476 for (size_t i = 0; i < children_.size(); ++i) 477 list->Append(children_[i]->LayerTreeAsJson()); 478 result->Set("Children", list); 479 480 return result; 481} 482 483void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { 484 if (stacking_order_changed) { 485 stacking_order_changed_ = true; 486 NoteLayerPropertyChangedForSubtree(); 487 } 488} 489 490bool LayerImpl::LayerSurfacePropertyChanged() const { 491 if (layer_surface_property_changed_) 492 return true; 493 494 // If this layer's surface property hasn't changed, we want to see if 495 // some layer above us has changed this property. This is done for the 496 // case when such parent layer does not draw content, and therefore will 497 // not be traversed by the damage tracker. We need to make sure that 498 // property change on such layer will be caught by its descendants. 499 LayerImpl* current = this->parent_; 500 while (current && !current->draw_properties_.render_surface) { 501 if (current->layer_surface_property_changed_) 502 return true; 503 current = current->parent_; 504 } 505 506 return false; 507} 508 509void LayerImpl::NoteLayerSurfacePropertyChanged() { 510 layer_surface_property_changed_ = true; 511 layer_tree_impl()->set_needs_update_draw_properties(); 512} 513 514void LayerImpl::NoteLayerPropertyChanged() { 515 layer_property_changed_ = true; 516 layer_tree_impl()->set_needs_update_draw_properties(); 517} 518 519void LayerImpl::NoteLayerPropertyChangedForSubtree() { 520 NoteLayerPropertyChanged(); 521 NoteLayerPropertyChangedForDescendants(); 522} 523 524void LayerImpl::NoteLayerPropertyChangedForDescendants() { 525 layer_tree_impl()->set_needs_update_draw_properties(); 526 for (size_t i = 0; i < children_.size(); ++i) 527 children_[i]->NoteLayerPropertyChangedForSubtree(); 528} 529 530const char* LayerImpl::LayerTypeAsString() const { 531 return "Layer"; 532} 533 534void LayerImpl::ResetAllChangeTrackingForSubtree() { 535 layer_property_changed_ = false; 536 layer_surface_property_changed_ = false; 537 538 update_rect_ = gfx::RectF(); 539 540 if (draw_properties_.render_surface) 541 draw_properties_.render_surface->ResetPropertyChangedFlag(); 542 543 if (mask_layer_) 544 mask_layer_->ResetAllChangeTrackingForSubtree(); 545 546 if (replica_layer_) { 547 // This also resets the replica mask, if it exists. 548 replica_layer_->ResetAllChangeTrackingForSubtree(); 549 } 550 551 for (size_t i = 0; i < children_.size(); ++i) 552 children_[i]->ResetAllChangeTrackingForSubtree(); 553} 554 555bool LayerImpl::LayerIsAlwaysDamaged() const { 556 return false; 557} 558 559void LayerImpl::OnOpacityAnimated(float opacity) { 560 SetOpacity(opacity); 561} 562 563void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { 564 SetTransform(transform); 565} 566 567bool LayerImpl::IsActive() const { 568 return layer_tree_impl_->IsActiveTree(); 569} 570 571void LayerImpl::SetBounds(gfx::Size bounds) { 572 if (bounds_ == bounds) 573 return; 574 575 bounds_ = bounds; 576 577 if (masks_to_bounds()) 578 NoteLayerPropertyChangedForSubtree(); 579 else 580 NoteLayerPropertyChanged(); 581} 582 583void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { 584 int new_layer_id = mask_layer ? mask_layer->id() : -1; 585 586 if (mask_layer) { 587 DCHECK_EQ(layer_tree_impl(), mask_layer->layer_tree_impl()); 588 DCHECK_NE(new_layer_id, mask_layer_id_); 589 } else if (new_layer_id == mask_layer_id_) { 590 return; 591 } 592 593 mask_layer_ = mask_layer.Pass(); 594 mask_layer_id_ = new_layer_id; 595 if (mask_layer_) 596 mask_layer_->set_parent(this); 597 NoteLayerPropertyChangedForSubtree(); 598} 599 600scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { 601 mask_layer_id_ = -1; 602 return mask_layer_.Pass(); 603} 604 605void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { 606 int new_layer_id = replica_layer ? replica_layer->id() : -1; 607 608 if (replica_layer) { 609 DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl()); 610 DCHECK_NE(new_layer_id, replica_layer_id_); 611 } else if (new_layer_id == replica_layer_id_) { 612 return; 613 } 614 615 replica_layer_ = replica_layer.Pass(); 616 replica_layer_id_ = new_layer_id; 617 if (replica_layer_) 618 replica_layer_->set_parent(this); 619 NoteLayerPropertyChangedForSubtree(); 620} 621 622scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { 623 replica_layer_id_ = -1; 624 return replica_layer_.Pass(); 625} 626 627ScrollbarLayerImpl* LayerImpl::ToScrollbarLayer() { 628 return NULL; 629} 630 631void LayerImpl::SetDrawsContent(bool draws_content) { 632 if (draws_content_ == draws_content) 633 return; 634 635 draws_content_ = draws_content; 636 NoteLayerPropertyChanged(); 637} 638 639void LayerImpl::SetAnchorPoint(gfx::PointF anchor_point) { 640 if (anchor_point_ == anchor_point) 641 return; 642 643 anchor_point_ = anchor_point; 644 NoteLayerPropertyChangedForSubtree(); 645} 646 647void LayerImpl::SetAnchorPointZ(float anchor_point_z) { 648 if (anchor_point_z_ == anchor_point_z) 649 return; 650 651 anchor_point_z_ = anchor_point_z; 652 NoteLayerPropertyChangedForSubtree(); 653} 654 655void LayerImpl::SetBackgroundColor(SkColor background_color) { 656 if (background_color_ == background_color) 657 return; 658 659 background_color_ = background_color; 660 NoteLayerPropertyChanged(); 661} 662 663void LayerImpl::SetFilters(const WebKit::WebFilterOperations& filters) { 664 if (filters_ == filters) 665 return; 666 667 DCHECK(!filter_); 668 filters_ = filters; 669 NoteLayerPropertyChangedForSubtree(); 670} 671 672void LayerImpl::SetBackgroundFilters( 673 const WebKit::WebFilterOperations& filters) { 674 if (background_filters_ == filters) 675 return; 676 677 background_filters_ = filters; 678 NoteLayerPropertyChanged(); 679} 680 681void LayerImpl::SetFilter(const skia::RefPtr<SkImageFilter>& filter) { 682 if (filter_.get() == filter.get()) 683 return; 684 685 DCHECK(filters_.isEmpty()); 686 filter_ = filter; 687 NoteLayerPropertyChangedForSubtree(); 688} 689 690void LayerImpl::SetMasksToBounds(bool masks_to_bounds) { 691 if (masks_to_bounds_ == masks_to_bounds) 692 return; 693 694 masks_to_bounds_ = masks_to_bounds; 695 NoteLayerPropertyChangedForSubtree(); 696} 697 698void LayerImpl::SetContentsOpaque(bool opaque) { 699 if (contents_opaque_ == opaque) 700 return; 701 702 contents_opaque_ = opaque; 703 NoteLayerPropertyChangedForSubtree(); 704} 705 706void LayerImpl::SetOpacity(float opacity) { 707 if (opacity_ == opacity) 708 return; 709 710 opacity_ = opacity; 711 NoteLayerSurfacePropertyChanged(); 712} 713 714bool LayerImpl::OpacityIsAnimating() const { 715 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity); 716} 717 718bool LayerImpl::OpacityIsAnimatingOnImplOnly() const { 719 Animation* opacity_animation = 720 layer_animation_controller_->GetAnimation(Animation::Opacity); 721 return opacity_animation && opacity_animation->is_impl_only(); 722} 723 724void LayerImpl::SetPosition(gfx::PointF position) { 725 if (position_ == position) 726 return; 727 728 position_ = position; 729 NoteLayerPropertyChangedForSubtree(); 730} 731 732void LayerImpl::SetPreserves3d(bool preserves3_d) { 733 if (preserves_3d_ == preserves3_d) 734 return; 735 736 preserves_3d_ = preserves3_d; 737 NoteLayerPropertyChangedForSubtree(); 738} 739 740void LayerImpl::SetSublayerTransform(const gfx::Transform& sublayer_transform) { 741 if (sublayer_transform_ == sublayer_transform) 742 return; 743 744 sublayer_transform_ = sublayer_transform; 745 // Sublayer transform does not affect the current layer; it affects only its 746 // children. 747 NoteLayerPropertyChangedForDescendants(); 748} 749 750void LayerImpl::SetTransform(const gfx::Transform& transform) { 751 if (transform_ == transform) 752 return; 753 754 transform_ = transform; 755 NoteLayerSurfacePropertyChanged(); 756} 757 758bool LayerImpl::TransformIsAnimating() const { 759 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform); 760} 761 762bool LayerImpl::TransformIsAnimatingOnImplOnly() const { 763 Animation* transform_animation = 764 layer_animation_controller_->GetAnimation(Animation::Transform); 765 return transform_animation && transform_animation->is_impl_only(); 766} 767 768void LayerImpl::SetContentBounds(gfx::Size content_bounds) { 769 if (this->content_bounds() == content_bounds) 770 return; 771 772 draw_properties_.content_bounds = content_bounds; 773 NoteLayerPropertyChanged(); 774} 775 776void LayerImpl::SetContentsScale(float contents_scale_x, 777 float contents_scale_y) { 778 if (this->contents_scale_x() == contents_scale_x && 779 this->contents_scale_y() == contents_scale_y) 780 return; 781 782 draw_properties_.contents_scale_x = contents_scale_x; 783 draw_properties_.contents_scale_y = contents_scale_y; 784 NoteLayerPropertyChanged(); 785} 786 787void LayerImpl::CalculateContentsScale( 788 float ideal_contents_scale, 789 bool animating_transform_to_screen, 790 float* contents_scale_x, 791 float* contents_scale_y, 792 gfx::Size* content_bounds) { 793 // Base LayerImpl has all of its content scales and content bounds pushed 794 // from its Layer during commit and just reuses those values as-is. 795 *contents_scale_x = this->contents_scale_x(); 796 *contents_scale_y = this->contents_scale_y(); 797 *content_bounds = this->content_bounds(); 798} 799 800void LayerImpl::UpdateScrollbarPositions() { 801 gfx::Vector2dF current_offset = scroll_offset_ + scroll_delta_; 802 803 gfx::RectF viewport(PointAtOffsetFromOrigin(current_offset), bounds_); 804 gfx::SizeF scrollable_size(max_scroll_offset_.x() + bounds_.width(), 805 max_scroll_offset_.y() + bounds_.height()); 806 if (horizontal_scrollbar_layer_) { 807 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); 808 horizontal_scrollbar_layer_->SetTotalSize(bounds_.width()); 809 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); 810 horizontal_scrollbar_layer_->SetViewportWithinScrollableArea( 811 viewport, scrollable_size); 812 } 813 if (vertical_scrollbar_layer_) { 814 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); 815 vertical_scrollbar_layer_->SetTotalSize(bounds_.height()); 816 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); 817 vertical_scrollbar_layer_->SetViewportWithinScrollableArea( 818 viewport, scrollable_size); 819 } 820 821 if (current_offset == last_scroll_offset_) 822 return; 823 last_scroll_offset_ = current_offset; 824 825 if (scrollbar_animation_controller_ && 826 !scrollbar_animation_controller_->IsScrollGestureInProgress()) { 827 scrollbar_animation_controller_->DidProgrammaticallyUpdateScroll( 828 base::TimeTicks::Now()); 829 } 830 831 // Get the current_offset_.y() value for a sanity-check on scrolling 832 // benchmark metrics. Specifically, we want to make sure 833 // BasicMouseWheelSmoothScrollGesture has proper scroll curves. 834 if (layer_tree_impl()->IsActiveTree()) { 835 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); 836 } 837} 838 839void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { 840 if (scroll_offset_ == scroll_offset) 841 return; 842 843 scroll_offset_ = scroll_offset; 844 NoteLayerPropertyChangedForSubtree(); 845 UpdateScrollbarPositions(); 846} 847 848void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { 849 if (scroll_delta_ == scroll_delta) 850 return; 851 852 if (layer_tree_impl()->IsActiveTree()) { 853 LayerImpl* pending_twin = layer_tree_impl()->FindPendingTreeLayerById(id()); 854 if (pending_twin) { 855 // The pending twin can't mirror the scroll delta of the active 856 // layer. Although the delta - sent scroll delta difference is 857 // identical for both twins, the sent scroll delta for the pending 858 // layer is zero, as anything that has been sent has been baked 859 // into the layer's position/scroll offset as a part of commit. 860 DCHECK(pending_twin->sent_scroll_delta().IsZero()); 861 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta()); 862 } 863 } 864 865 scroll_delta_ = scroll_delta; 866 NoteLayerPropertyChangedForSubtree(); 867 868 UpdateScrollbarPositions(); 869} 870 871gfx::Vector2dF LayerImpl::TotalScrollOffset() const { 872 return scroll_offset_ + scroll_delta_; 873} 874 875void LayerImpl::SetImplTransform(const gfx::Transform& transform) { 876 if (impl_transform_ == transform) 877 return; 878 879 impl_transform_ = transform; 880 NoteLayerPropertyChangedForSubtree(); 881} 882 883void LayerImpl::SetDoubleSided(bool double_sided) { 884 if (double_sided_ == double_sided) 885 return; 886 887 double_sided_ = double_sided; 888 NoteLayerPropertyChangedForSubtree(); 889} 890 891Region LayerImpl::VisibleContentOpaqueRegion() const { 892 if (contents_opaque()) 893 return visible_content_rect(); 894 return Region(); 895} 896 897void LayerImpl::DidLoseOutputSurface() {} 898 899void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { 900 if (max_scroll_offset_ == max_scroll_offset) 901 return; 902 max_scroll_offset_ = max_scroll_offset; 903 904 layer_tree_impl()->set_needs_update_draw_properties(); 905 UpdateScrollbarPositions(); 906} 907 908void LayerImpl::SetScrollbarOpacity(float opacity) { 909 if (horizontal_scrollbar_layer_) 910 horizontal_scrollbar_layer_->SetOpacity(opacity); 911 if (vertical_scrollbar_layer_) 912 vertical_scrollbar_layer_->SetOpacity(opacity); 913} 914 915inline scoped_ptr<ScrollbarAnimationController> 916CreateScrollbarAnimationControllerWithFade(LayerImpl* layer) { 917 base::TimeDelta fadeout_delay = base::TimeDelta::FromMilliseconds(300); 918 base::TimeDelta fadeout_length = base::TimeDelta::FromMilliseconds(300); 919 return ScrollbarAnimationControllerLinearFade::Create( 920 layer, fadeout_delay, fadeout_length) 921 .PassAs<ScrollbarAnimationController>(); 922} 923 924void LayerImpl::DidBecomeActive() { 925 if (!layer_tree_impl_->settings().use_linear_fade_scrollbar_animator) 926 return; 927 928 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || 929 vertical_scrollbar_layer_; 930 if (need_scrollbar_animation_controller) { 931 if (!scrollbar_animation_controller_) { 932 scrollbar_animation_controller_ = 933 CreateScrollbarAnimationControllerWithFade(this); 934 } 935 } else { 936 scrollbar_animation_controller_.reset(); 937 } 938 939} 940void LayerImpl::SetHorizontalScrollbarLayer( 941 ScrollbarLayerImpl* scrollbar_layer) { 942 horizontal_scrollbar_layer_ = scrollbar_layer; 943 if (horizontal_scrollbar_layer_) 944 horizontal_scrollbar_layer_->set_scroll_layer_id(id()); 945} 946 947void LayerImpl::SetVerticalScrollbarLayer(ScrollbarLayerImpl* scrollbar_layer) { 948 vertical_scrollbar_layer_ = scrollbar_layer; 949 if (vertical_scrollbar_layer_) 950 vertical_scrollbar_layer_->set_scroll_layer_id(id()); 951} 952 953void LayerImpl::AsValueInto(base::DictionaryValue* dict) const { 954 dict->SetInteger("id", id()); 955 dict->Set("bounds", MathUtil::AsValue(bounds()).release()); 956 dict->SetInteger("draws_content", DrawsContent()); 957 958 bool clipped; 959 gfx::QuadF layer_quad = MathUtil::MapQuad( 960 screen_space_transform(), 961 gfx::QuadF(gfx::Rect(content_bounds())), 962 &clipped); 963 dict->Set("layer_quad", MathUtil::AsValue(layer_quad).release()); 964 965} 966 967scoped_ptr<base::Value> LayerImpl::AsValue() const { 968 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 969 AsValueInto(state.get()); 970 return state.PassAs<base::Value>(); 971} 972 973} // namespace cc 974