layer_impl.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1// Copyright 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 "cc/layers/layer_impl.h" 6 7#include "base/debug/trace_event.h" 8#include "base/debug/trace_event_argument.h" 9#include "base/json/json_reader.h" 10#include "base/strings/stringprintf.h" 11#include "cc/animation/animation_registrar.h" 12#include "cc/animation/scrollbar_animation_controller.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/debug/micro_benchmark_impl.h" 17#include "cc/debug/traced_value.h" 18#include "cc/input/layer_scroll_offset_delegate.h" 19#include "cc/layers/layer_utils.h" 20#include "cc/layers/painted_scrollbar_layer_impl.h" 21#include "cc/output/copy_output_request.h" 22#include "cc/quads/debug_border_draw_quad.h" 23#include "cc/trees/layer_tree_host_common.h" 24#include "cc/trees/layer_tree_impl.h" 25#include "cc/trees/layer_tree_settings.h" 26#include "cc/trees/proxy.h" 27#include "ui/gfx/box_f.h" 28#include "ui/gfx/geometry/vector2d_conversions.h" 29#include "ui/gfx/point_conversions.h" 30#include "ui/gfx/quad_f.h" 31#include "ui/gfx/rect_conversions.h" 32#include "ui/gfx/size_conversions.h" 33 34namespace cc { 35LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) 36 : parent_(NULL), 37 scroll_parent_(NULL), 38 clip_parent_(NULL), 39 mask_layer_id_(-1), 40 replica_layer_id_(-1), 41 layer_id_(id), 42 layer_tree_impl_(tree_impl), 43 scroll_offset_delegate_(NULL), 44 scroll_clip_layer_(NULL), 45 should_scroll_on_main_thread_(false), 46 have_wheel_event_handlers_(false), 47 have_scroll_event_handlers_(false), 48 user_scrollable_horizontal_(true), 49 user_scrollable_vertical_(true), 50 stacking_order_changed_(false), 51 double_sided_(true), 52 should_flatten_transform_(true), 53 layer_property_changed_(false), 54 masks_to_bounds_(false), 55 contents_opaque_(false), 56 is_root_for_isolated_group_(false), 57 use_parent_backface_visibility_(false), 58 draw_checkerboard_for_missing_tiles_(false), 59 draws_content_(false), 60 hide_layer_and_subtree_(false), 61 force_render_surface_(false), 62 transform_is_invertible_(true), 63 is_container_for_fixed_position_layers_(false), 64 background_color_(0), 65 opacity_(1.0), 66 blend_mode_(SkXfermode::kSrcOver_Mode), 67 draw_depth_(0.f), 68 needs_push_properties_(false), 69 num_dependents_need_push_properties_(0), 70 sorting_context_id_(0), 71 current_draw_mode_(DRAW_MODE_NONE) { 72 DCHECK_GT(layer_id_, 0); 73 DCHECK(layer_tree_impl_); 74 layer_tree_impl_->RegisterLayer(this); 75 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); 76 layer_animation_controller_ = 77 registrar->GetAnimationControllerForId(layer_id_); 78 layer_animation_controller_->AddValueObserver(this); 79 if (IsActive()) { 80 layer_animation_controller_->set_value_provider(this); 81 layer_animation_controller_->set_layer_animation_delegate(this); 82 } 83 SetNeedsPushProperties(); 84} 85 86LayerImpl::~LayerImpl() { 87 DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_); 88 89 layer_animation_controller_->RemoveValueObserver(this); 90 layer_animation_controller_->remove_value_provider(this); 91 layer_animation_controller_->remove_layer_animation_delegate(this); 92 93 if (!copy_requests_.empty() && layer_tree_impl_->IsActiveTree()) 94 layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); 95 layer_tree_impl_->UnregisterLayer(this); 96 97 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 98 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerImpl", this); 99} 100 101void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) { 102 child->SetParent(this); 103 DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl()); 104 children_.push_back(child.Pass()); 105 layer_tree_impl()->set_needs_update_draw_properties(); 106} 107 108scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) { 109 for (OwnedLayerImplList::iterator it = children_.begin(); 110 it != children_.end(); 111 ++it) { 112 if (*it == child) { 113 scoped_ptr<LayerImpl> ret = children_.take(it); 114 children_.erase(it); 115 layer_tree_impl()->set_needs_update_draw_properties(); 116 return ret.Pass(); 117 } 118 } 119 return scoped_ptr<LayerImpl>(); 120} 121 122void LayerImpl::SetParent(LayerImpl* parent) { 123 if (parent_should_know_need_push_properties()) { 124 if (parent_) 125 parent_->RemoveDependentNeedsPushProperties(); 126 if (parent) 127 parent->AddDependentNeedsPushProperties(); 128 } 129 parent_ = parent; 130} 131 132void LayerImpl::ClearChildList() { 133 if (children_.empty()) 134 return; 135 136 children_.clear(); 137 layer_tree_impl()->set_needs_update_draw_properties(); 138} 139 140bool LayerImpl::HasAncestor(const LayerImpl* ancestor) const { 141 if (!ancestor) 142 return false; 143 144 for (const LayerImpl* layer = this; layer; layer = layer->parent()) { 145 if (layer == ancestor) 146 return true; 147 } 148 149 return false; 150} 151 152void LayerImpl::SetScrollParent(LayerImpl* parent) { 153 if (scroll_parent_ == parent) 154 return; 155 156 // Having both a scroll parent and a scroll offset delegate is unsupported. 157 DCHECK(!scroll_offset_delegate_); 158 159 if (parent) 160 DCHECK_EQ(layer_tree_impl()->LayerById(parent->id()), parent); 161 162 scroll_parent_ = parent; 163 SetNeedsPushProperties(); 164} 165 166void LayerImpl::SetDebugInfo( 167 scoped_refptr<base::debug::ConvertableToTraceFormat> other) { 168 debug_info_ = other; 169 SetNeedsPushProperties(); 170} 171 172void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) { 173 if (scroll_children_.get() == children) 174 return; 175 scroll_children_.reset(children); 176 SetNeedsPushProperties(); 177} 178 179void LayerImpl::SetClipParent(LayerImpl* ancestor) { 180 if (clip_parent_ == ancestor) 181 return; 182 183 clip_parent_ = ancestor; 184 SetNeedsPushProperties(); 185} 186 187void LayerImpl::SetClipChildren(std::set<LayerImpl*>* children) { 188 if (clip_children_.get() == children) 189 return; 190 clip_children_.reset(children); 191 SetNeedsPushProperties(); 192} 193 194void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) { 195 if (requests->empty()) 196 return; 197 198 bool was_empty = copy_requests_.empty(); 199 copy_requests_.insert_and_take(copy_requests_.end(), *requests); 200 requests->clear(); 201 202 if (was_empty && layer_tree_impl()->IsActiveTree()) 203 layer_tree_impl()->AddLayerWithCopyOutputRequest(this); 204 NoteLayerPropertyChangedForSubtree(); 205} 206 207void LayerImpl::TakeCopyRequestsAndTransformToTarget( 208 ScopedPtrVector<CopyOutputRequest>* requests) { 209 DCHECK(!copy_requests_.empty()); 210 DCHECK(layer_tree_impl()->IsActiveTree()); 211 212 size_t first_inserted_request = requests->size(); 213 requests->insert_and_take(requests->end(), copy_requests_); 214 copy_requests_.clear(); 215 216 for (size_t i = first_inserted_request; i < requests->size(); ++i) { 217 CopyOutputRequest* request = requests->at(i); 218 if (!request->has_area()) 219 continue; 220 221 gfx::Rect request_in_layer_space = request->area(); 222 gfx::Rect request_in_content_space = 223 LayerRectToContentRect(request_in_layer_space); 224 request->set_area(MathUtil::MapEnclosingClippedRect( 225 draw_properties_.target_space_transform, request_in_content_space)); 226 } 227 228 layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); 229} 230 231void LayerImpl::CreateRenderSurface() { 232 DCHECK(!draw_properties_.render_surface); 233 draw_properties_.render_surface = 234 make_scoped_ptr(new RenderSurfaceImpl(this)); 235 draw_properties_.render_target = this; 236} 237 238void LayerImpl::ClearRenderSurface() { 239 draw_properties_.render_surface.reset(); 240} 241 242void LayerImpl::ClearRenderSurfaceLayerList() { 243 if (draw_properties_.render_surface) 244 draw_properties_.render_surface->layer_list().clear(); 245} 246 247void LayerImpl::PopulateSharedQuadState(SharedQuadState* state) const { 248 state->SetAll(draw_properties_.target_space_transform, 249 draw_properties_.content_bounds, 250 draw_properties_.visible_content_rect, 251 draw_properties_.clip_rect, 252 draw_properties_.is_clipped, 253 draw_properties_.opacity, 254 blend_mode_, 255 sorting_context_id_); 256} 257 258bool LayerImpl::WillDraw(DrawMode draw_mode, 259 ResourceProvider* resource_provider) { 260 // WillDraw/DidDraw must be matched. 261 DCHECK_NE(DRAW_MODE_NONE, draw_mode); 262 DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_); 263 current_draw_mode_ = draw_mode; 264 return true; 265} 266 267void LayerImpl::DidDraw(ResourceProvider* resource_provider) { 268 DCHECK_NE(DRAW_MODE_NONE, current_draw_mode_); 269 current_draw_mode_ = DRAW_MODE_NONE; 270} 271 272bool LayerImpl::ShowDebugBorders() const { 273 return layer_tree_impl()->debug_state().show_debug_borders; 274} 275 276void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const { 277 if (draws_content_) { 278 *color = DebugColors::ContentLayerBorderColor(); 279 *width = DebugColors::ContentLayerBorderWidth(layer_tree_impl()); 280 return; 281 } 282 283 if (masks_to_bounds_) { 284 *color = DebugColors::MaskingLayerBorderColor(); 285 *width = DebugColors::MaskingLayerBorderWidth(layer_tree_impl()); 286 return; 287 } 288 289 *color = DebugColors::ContainerLayerBorderColor(); 290 *width = DebugColors::ContainerLayerBorderWidth(layer_tree_impl()); 291} 292 293void LayerImpl::AppendDebugBorderQuad( 294 RenderPass* render_pass, 295 const gfx::Size& content_bounds, 296 const SharedQuadState* shared_quad_state, 297 AppendQuadsData* append_quads_data) const { 298 SkColor color; 299 float width; 300 GetDebugBorderProperties(&color, &width); 301 AppendDebugBorderQuad(render_pass, 302 content_bounds, 303 shared_quad_state, 304 append_quads_data, 305 color, 306 width); 307} 308 309void LayerImpl::AppendDebugBorderQuad(RenderPass* render_pass, 310 const gfx::Size& content_bounds, 311 const SharedQuadState* shared_quad_state, 312 AppendQuadsData* append_quads_data, 313 SkColor color, 314 float width) const { 315 if (!ShowDebugBorders()) 316 return; 317 318 gfx::Rect quad_rect(content_bounds); 319 gfx::Rect visible_quad_rect(quad_rect); 320 DebugBorderDrawQuad* debug_border_quad = 321 render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>(); 322 debug_border_quad->SetNew( 323 shared_quad_state, quad_rect, visible_quad_rect, color, width); 324} 325 326bool LayerImpl::HasDelegatedContent() const { 327 return false; 328} 329 330bool LayerImpl::HasContributingDelegatedRenderPasses() const { 331 return false; 332} 333 334RenderPass::Id LayerImpl::FirstContributingRenderPassId() const { 335 return RenderPass::Id(0, 0); 336} 337 338RenderPass::Id LayerImpl::NextContributingRenderPassId(RenderPass::Id id) 339 const { 340 return RenderPass::Id(0, 0); 341} 342 343ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const { 344 NOTREACHED(); 345 return 0; 346} 347 348void LayerImpl::SetSentScrollDelta(const gfx::Vector2d& sent_scroll_delta) { 349 // Pending tree never has sent scroll deltas 350 DCHECK(layer_tree_impl()->IsActiveTree()); 351 352 if (sent_scroll_delta_ == sent_scroll_delta) 353 return; 354 355 sent_scroll_delta_ = sent_scroll_delta; 356} 357 358gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { 359 DCHECK(scrollable()); 360 gfx::Vector2dF min_delta = -scroll_offset_; 361 gfx::Vector2dF max_delta = MaxScrollOffset() - scroll_offset_; 362 // Clamp new_delta so that position + delta stays within scroll bounds. 363 gfx::Vector2dF new_delta = (ScrollDelta() + scroll); 364 new_delta.SetToMax(min_delta); 365 new_delta.SetToMin(max_delta); 366 gfx::Vector2dF unscrolled = 367 ScrollDelta() + scroll - new_delta; 368 SetScrollDelta(new_delta); 369 370 return unscrolled; 371} 372 373void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { 374 scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id); 375} 376 377void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { 378 // Pending tree never has sent scroll deltas 379 DCHECK(layer_tree_impl()->IsActiveTree()); 380 381 // Apply sent scroll deltas to scroll position / scroll delta as if the 382 // main thread had applied them and then committed those values. 383 // 384 // This function should not change the total scroll offset; it just shifts 385 // some of the scroll delta to the scroll offset. Therefore, adjust these 386 // variables directly rather than calling the scroll offset delegate to 387 // avoid sending it multiple spurious calls. 388 // 389 // Because of the way scroll delta is calculated with a delegate, this will 390 // leave the total scroll offset unchanged on this layer regardless of 391 // whether a delegate is being used. 392 scroll_offset_ += sent_scroll_delta_; 393 scroll_delta_ -= sent_scroll_delta_; 394 sent_scroll_delta_ = gfx::Vector2d(); 395} 396 397void LayerImpl::ApplyScrollDeltasSinceBeginMainFrame() { 398 // Only the pending tree can have missing scrolls. 399 DCHECK(layer_tree_impl()->IsPendingTree()); 400 if (!scrollable()) 401 return; 402 403 // Pending tree should never have sent scroll deltas. 404 DCHECK(sent_scroll_delta().IsZero()); 405 406 LayerImpl* active_twin = layer_tree_impl()->FindActiveTreeLayerById(id()); 407 if (active_twin) { 408 // Scrolls that happens after begin frame (where the sent scroll delta 409 // comes from) and commit need to be applied to the pending tree 410 // so that it is up to date with the total scroll. 411 SetScrollDelta(active_twin->ScrollDelta() - 412 active_twin->sent_scroll_delta()); 413 } 414} 415 416InputHandler::ScrollStatus LayerImpl::TryScroll( 417 const gfx::PointF& screen_space_point, 418 InputHandler::ScrollInputType type) const { 419 if (should_scroll_on_main_thread()) { 420 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); 421 return InputHandler::ScrollOnMainThread; 422 } 423 424 if (!screen_space_transform().IsInvertible()) { 425 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform"); 426 return InputHandler::ScrollIgnored; 427 } 428 429 if (!non_fast_scrollable_region().IsEmpty()) { 430 bool clipped = false; 431 gfx::Transform inverse_screen_space_transform( 432 gfx::Transform::kSkipInitialization); 433 if (!screen_space_transform().GetInverse(&inverse_screen_space_transform)) { 434 // TODO(shawnsingh): We shouldn't be applying a projection if screen space 435 // transform is uninvertible here. Perhaps we should be returning 436 // ScrollOnMainThread in this case? 437 } 438 439 gfx::PointF hit_test_point_in_content_space = 440 MathUtil::ProjectPoint(inverse_screen_space_transform, 441 screen_space_point, 442 &clipped); 443 gfx::PointF hit_test_point_in_layer_space = 444 gfx::ScalePoint(hit_test_point_in_content_space, 445 1.f / contents_scale_x(), 446 1.f / contents_scale_y()); 447 if (!clipped && 448 non_fast_scrollable_region().Contains( 449 gfx::ToRoundedPoint(hit_test_point_in_layer_space))) { 450 TRACE_EVENT0("cc", 451 "LayerImpl::tryScroll: Failed NonFastScrollableRegion"); 452 return InputHandler::ScrollOnMainThread; 453 } 454 } 455 456 if (type == InputHandler::Wheel && have_wheel_event_handlers()) { 457 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); 458 return InputHandler::ScrollOnMainThread; 459 } 460 461 if (!scrollable()) { 462 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); 463 return InputHandler::ScrollIgnored; 464 } 465 466 gfx::Vector2d max_scroll_offset = MaxScrollOffset(); 467 if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0) { 468 TRACE_EVENT0("cc", 469 "LayerImpl::tryScroll: Ignored. Technically scrollable," 470 " but has no affordance in either direction."); 471 return InputHandler::ScrollIgnored; 472 } 473 474 return InputHandler::ScrollStarted; 475} 476 477gfx::Rect LayerImpl::LayerRectToContentRect( 478 const gfx::RectF& layer_rect) const { 479 gfx::RectF content_rect = 480 gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y()); 481 // Intersect with content rect to avoid the extra pixel because for some 482 // values x and y, ceil((x / y) * y) may be x + 1. 483 content_rect.Intersect(gfx::Rect(content_bounds())); 484 return gfx::ToEnclosingRect(content_rect); 485} 486 487skia::RefPtr<SkPicture> LayerImpl::GetPicture() { 488 return skia::RefPtr<SkPicture>(); 489} 490 491scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { 492 return LayerImpl::Create(tree_impl, layer_id_); 493} 494 495void LayerImpl::PushPropertiesTo(LayerImpl* layer) { 496 layer->SetTransformOrigin(transform_origin_); 497 layer->SetBackgroundColor(background_color_); 498 layer->SetBounds(bounds_); 499 layer->SetContentBounds(content_bounds()); 500 layer->SetContentsScale(contents_scale_x(), contents_scale_y()); 501 layer->SetDoubleSided(double_sided_); 502 layer->SetDrawCheckerboardForMissingTiles( 503 draw_checkerboard_for_missing_tiles_); 504 layer->SetForceRenderSurface(force_render_surface_); 505 layer->SetDrawsContent(DrawsContent()); 506 layer->SetHideLayerAndSubtree(hide_layer_and_subtree_); 507 layer->SetFilters(filters()); 508 layer->SetBackgroundFilters(background_filters()); 509 layer->SetMasksToBounds(masks_to_bounds_); 510 layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); 511 layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); 512 layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_); 513 layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); 514 layer->SetTouchEventHandlerRegion(touch_event_handler_region_); 515 layer->SetContentsOpaque(contents_opaque_); 516 layer->SetOpacity(opacity_); 517 layer->SetBlendMode(blend_mode_); 518 layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_); 519 layer->SetPosition(position_); 520 layer->SetIsContainerForFixedPositionLayers( 521 is_container_for_fixed_position_layers_); 522 layer->SetPositionConstraint(position_constraint_); 523 layer->SetShouldFlattenTransform(should_flatten_transform_); 524 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); 525 layer->SetTransformAndInvertibility(transform_, transform_is_invertible_); 526 527 layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() 528 : Layer::INVALID_ID); 529 layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); 530 layer->set_user_scrollable_vertical(user_scrollable_vertical_); 531 layer->SetScrollOffsetAndDelta( 532 scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta()); 533 layer->SetSentScrollDelta(gfx::Vector2d()); 534 layer->Set3dSortingContextId(sorting_context_id_); 535 536 LayerImpl* scroll_parent = NULL; 537 if (scroll_parent_) { 538 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); 539 DCHECK(scroll_parent); 540 } 541 542 layer->SetScrollParent(scroll_parent); 543 if (scroll_children_) { 544 std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; 545 for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); 546 it != scroll_children_->end(); 547 ++it) { 548 DCHECK_EQ((*it)->scroll_parent(), this); 549 LayerImpl* scroll_child = 550 layer->layer_tree_impl()->LayerById((*it)->id()); 551 DCHECK(scroll_child); 552 scroll_children->insert(scroll_child); 553 } 554 layer->SetScrollChildren(scroll_children); 555 } else { 556 layer->SetScrollChildren(NULL); 557 } 558 559 LayerImpl* clip_parent = NULL; 560 if (clip_parent_) { 561 clip_parent = layer->layer_tree_impl()->LayerById( 562 clip_parent_->id()); 563 DCHECK(clip_parent); 564 } 565 566 layer->SetClipParent(clip_parent); 567 if (clip_children_) { 568 std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>; 569 for (std::set<LayerImpl*>::iterator it = clip_children_->begin(); 570 it != clip_children_->end(); ++it) 571 clip_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); 572 layer->SetClipChildren(clip_children); 573 } else { 574 layer->SetClipChildren(NULL); 575 } 576 577 layer->PassCopyRequests(©_requests_); 578 579 // If the main thread commits multiple times before the impl thread actually 580 // draws, then damage tracking will become incorrect if we simply clobber the 581 // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e. 582 // union) any update changes that have occurred on the main thread. 583 update_rect_.Union(layer->update_rect()); 584 layer->SetUpdateRect(update_rect_); 585 586 layer->SetStackingOrderChanged(stacking_order_changed_); 587 layer->SetDebugInfo(debug_info_); 588 589 // Reset any state that should be cleared for the next update. 590 stacking_order_changed_ = false; 591 update_rect_ = gfx::RectF(); 592 needs_push_properties_ = false; 593 num_dependents_need_push_properties_ = 0; 594} 595 596gfx::Vector2dF LayerImpl::FixedContainerSizeDelta() const { 597 if (!scroll_clip_layer_) 598 return gfx::Vector2dF(); 599 600 float scale_delta = layer_tree_impl()->page_scale_delta(); 601 float scale = layer_tree_impl()->page_scale_factor(); 602 603 gfx::Vector2dF delta_from_scroll = scroll_clip_layer_->BoundsDelta(); 604 delta_from_scroll.Scale(1.f / scale); 605 606 // The delta-from-pinch component requires some explanation: A viewport of 607 // size (w,h) will appear to be size (w/s,h/s) under scale s in the content 608 // space. If s -> s' on the impl thread, where s' = s * ds, then the apparent 609 // viewport size change in the content space due to ds is: 610 // 611 // (w/s',h/s') - (w/s,h/s) = (w,h)(1/s' - 1/s) = (w,h)(1 - ds)/(s ds) 612 // 613 gfx::Vector2dF delta_from_pinch = 614 gfx::Rect(scroll_clip_layer_->bounds()).bottom_right() - gfx::PointF(); 615 delta_from_pinch.Scale((1.f - scale_delta) / (scale * scale_delta)); 616 617 return delta_from_scroll + delta_from_pinch; 618} 619 620base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { 621 base::DictionaryValue* result = new base::DictionaryValue; 622 result->SetString("LayerType", LayerTypeAsString()); 623 624 base::ListValue* list = new base::ListValue; 625 list->AppendInteger(bounds().width()); 626 list->AppendInteger(bounds().height()); 627 result->Set("Bounds", list); 628 629 list = new base::ListValue; 630 list->AppendDouble(position_.x()); 631 list->AppendDouble(position_.y()); 632 result->Set("Position", list); 633 634 const gfx::Transform& gfx_transform = draw_properties_.target_space_transform; 635 double transform[16]; 636 gfx_transform.matrix().asColMajord(transform); 637 list = new base::ListValue; 638 for (int i = 0; i < 16; ++i) 639 list->AppendDouble(transform[i]); 640 result->Set("DrawTransform", list); 641 642 result->SetBoolean("DrawsContent", draws_content_); 643 result->SetBoolean("Is3dSorted", Is3dSorted()); 644 result->SetDouble("Opacity", opacity()); 645 result->SetBoolean("ContentsOpaque", contents_opaque_); 646 647 if (scrollable()) 648 result->SetBoolean("Scrollable", true); 649 650 if (have_wheel_event_handlers_) 651 result->SetBoolean("WheelHandler", have_wheel_event_handlers_); 652 if (have_scroll_event_handlers_) 653 result->SetBoolean("ScrollHandler", have_scroll_event_handlers_); 654 if (!touch_event_handler_region_.IsEmpty()) { 655 scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue(); 656 result->Set("TouchRegion", region.release()); 657 } 658 659 list = new base::ListValue; 660 for (size_t i = 0; i < children_.size(); ++i) 661 list->Append(children_[i]->LayerTreeAsJson()); 662 result->Set("Children", list); 663 664 return result; 665} 666 667void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { 668 if (stacking_order_changed) { 669 stacking_order_changed_ = true; 670 NoteLayerPropertyChangedForSubtree(); 671 } 672} 673 674void LayerImpl::NoteLayerPropertyChanged() { 675 layer_property_changed_ = true; 676 layer_tree_impl()->set_needs_update_draw_properties(); 677 SetNeedsPushProperties(); 678} 679 680void LayerImpl::NoteLayerPropertyChangedForSubtree() { 681 layer_property_changed_ = true; 682 layer_tree_impl()->set_needs_update_draw_properties(); 683 for (size_t i = 0; i < children_.size(); ++i) 684 children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); 685 SetNeedsPushProperties(); 686} 687 688void LayerImpl::NoteLayerPropertyChangedForDescendantsInternal() { 689 layer_property_changed_ = true; 690 for (size_t i = 0; i < children_.size(); ++i) 691 children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); 692} 693 694void LayerImpl::NoteLayerPropertyChangedForDescendants() { 695 layer_tree_impl()->set_needs_update_draw_properties(); 696 for (size_t i = 0; i < children_.size(); ++i) 697 children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); 698 SetNeedsPushProperties(); 699} 700 701const char* LayerImpl::LayerTypeAsString() const { 702 return "cc::LayerImpl"; 703} 704 705void LayerImpl::ResetAllChangeTrackingForSubtree() { 706 layer_property_changed_ = false; 707 708 update_rect_ = gfx::RectF(); 709 damage_rect_ = gfx::RectF(); 710 711 if (draw_properties_.render_surface) 712 draw_properties_.render_surface->ResetPropertyChangedFlag(); 713 714 if (mask_layer_) 715 mask_layer_->ResetAllChangeTrackingForSubtree(); 716 717 if (replica_layer_) { 718 // This also resets the replica mask, if it exists. 719 replica_layer_->ResetAllChangeTrackingForSubtree(); 720 } 721 722 for (size_t i = 0; i < children_.size(); ++i) 723 children_[i]->ResetAllChangeTrackingForSubtree(); 724 725 needs_push_properties_ = false; 726 num_dependents_need_push_properties_ = 0; 727} 728 729gfx::Vector2dF LayerImpl::ScrollOffsetForAnimation() const { 730 return TotalScrollOffset(); 731} 732 733void LayerImpl::OnFilterAnimated(const FilterOperations& filters) { 734 SetFilters(filters); 735} 736 737void LayerImpl::OnOpacityAnimated(float opacity) { 738 SetOpacity(opacity); 739} 740 741void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { 742 SetTransform(transform); 743} 744 745void LayerImpl::OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset) { 746 // Only layers in the active tree should need to do anything here, since 747 // layers in the pending tree will find out about these changes as a 748 // result of the call to SetScrollDelta. 749 if (!IsActive()) 750 return; 751 752 SetScrollDelta(scroll_offset - scroll_offset_); 753 754 layer_tree_impl_->DidAnimateScrollOffset(); 755} 756 757void LayerImpl::OnAnimationWaitingForDeletion() {} 758 759bool LayerImpl::IsActive() const { 760 return layer_tree_impl_->IsActiveTree(); 761} 762 763// TODO(wjmaclean) Convert so that bounds returns SizeF. 764gfx::Size LayerImpl::bounds() const { 765 return ToFlooredSize(temporary_impl_bounds_); 766} 767 768void LayerImpl::SetBounds(const gfx::Size& bounds) { 769 if (bounds_ == bounds) 770 return; 771 772 bounds_ = bounds; 773 temporary_impl_bounds_ = bounds; 774 775 ScrollbarParametersDidChange(); 776 if (masks_to_bounds()) 777 NoteLayerPropertyChangedForSubtree(); 778 else 779 NoteLayerPropertyChanged(); 780} 781 782void LayerImpl::SetTemporaryImplBounds(const gfx::SizeF& bounds) { 783 if (temporary_impl_bounds_ == bounds) 784 return; 785 786 temporary_impl_bounds_ = bounds; 787 788 ScrollbarParametersDidChange(); 789 if (masks_to_bounds()) 790 NoteLayerPropertyChangedForSubtree(); 791 else 792 NoteLayerPropertyChanged(); 793} 794 795void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { 796 int new_layer_id = mask_layer ? mask_layer->id() : -1; 797 798 if (mask_layer) { 799 DCHECK_EQ(layer_tree_impl(), mask_layer->layer_tree_impl()); 800 DCHECK_NE(new_layer_id, mask_layer_id_); 801 } else if (new_layer_id == mask_layer_id_) { 802 return; 803 } 804 805 mask_layer_ = mask_layer.Pass(); 806 mask_layer_id_ = new_layer_id; 807 if (mask_layer_) 808 mask_layer_->SetParent(this); 809 NoteLayerPropertyChangedForSubtree(); 810} 811 812scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { 813 mask_layer_id_ = -1; 814 return mask_layer_.Pass(); 815} 816 817void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { 818 int new_layer_id = replica_layer ? replica_layer->id() : -1; 819 820 if (replica_layer) { 821 DCHECK_EQ(layer_tree_impl(), replica_layer->layer_tree_impl()); 822 DCHECK_NE(new_layer_id, replica_layer_id_); 823 } else if (new_layer_id == replica_layer_id_) { 824 return; 825 } 826 827 replica_layer_ = replica_layer.Pass(); 828 replica_layer_id_ = new_layer_id; 829 if (replica_layer_) 830 replica_layer_->SetParent(this); 831 NoteLayerPropertyChangedForSubtree(); 832} 833 834scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { 835 replica_layer_id_ = -1; 836 return replica_layer_.Pass(); 837} 838 839ScrollbarLayerImplBase* LayerImpl::ToScrollbarLayer() { 840 return NULL; 841} 842 843void LayerImpl::SetDrawsContent(bool draws_content) { 844 if (draws_content_ == draws_content) 845 return; 846 847 draws_content_ = draws_content; 848 NoteLayerPropertyChanged(); 849} 850 851void LayerImpl::SetHideLayerAndSubtree(bool hide) { 852 if (hide_layer_and_subtree_ == hide) 853 return; 854 855 hide_layer_and_subtree_ = hide; 856 NoteLayerPropertyChangedForSubtree(); 857} 858 859void LayerImpl::SetTransformOrigin(const gfx::Point3F& transform_origin) { 860 if (transform_origin_ == transform_origin) 861 return; 862 transform_origin_ = transform_origin; 863 NoteLayerPropertyChangedForSubtree(); 864} 865 866void LayerImpl::SetBackgroundColor(SkColor background_color) { 867 if (background_color_ == background_color) 868 return; 869 870 background_color_ = background_color; 871 NoteLayerPropertyChanged(); 872} 873 874SkColor LayerImpl::SafeOpaqueBackgroundColor() const { 875 SkColor color = background_color(); 876 if (SkColorGetA(color) == 255 && !contents_opaque()) { 877 color = SK_ColorTRANSPARENT; 878 } else if (SkColorGetA(color) != 255 && contents_opaque()) { 879 for (const LayerImpl* layer = parent(); layer; 880 layer = layer->parent()) { 881 color = layer->background_color(); 882 if (SkColorGetA(color) == 255) 883 break; 884 } 885 if (SkColorGetA(color) != 255) 886 color = layer_tree_impl()->background_color(); 887 if (SkColorGetA(color) != 255) 888 color = SkColorSetA(color, 255); 889 } 890 return color; 891} 892 893void LayerImpl::SetFilters(const FilterOperations& filters) { 894 if (filters_ == filters) 895 return; 896 897 filters_ = filters; 898 NoteLayerPropertyChangedForSubtree(); 899} 900 901bool LayerImpl::FilterIsAnimating() const { 902 return layer_animation_controller_->IsAnimatingProperty(Animation::Filter); 903} 904 905bool LayerImpl::FilterIsAnimatingOnImplOnly() const { 906 Animation* filter_animation = 907 layer_animation_controller_->GetAnimation(Animation::Filter); 908 return filter_animation && filter_animation->is_impl_only(); 909} 910 911void LayerImpl::SetBackgroundFilters( 912 const FilterOperations& filters) { 913 if (background_filters_ == filters) 914 return; 915 916 background_filters_ = filters; 917 NoteLayerPropertyChanged(); 918} 919 920void LayerImpl::SetMasksToBounds(bool masks_to_bounds) { 921 if (masks_to_bounds_ == masks_to_bounds) 922 return; 923 924 masks_to_bounds_ = masks_to_bounds; 925 NoteLayerPropertyChangedForSubtree(); 926} 927 928void LayerImpl::SetContentsOpaque(bool opaque) { 929 if (contents_opaque_ == opaque) 930 return; 931 932 contents_opaque_ = opaque; 933 NoteLayerPropertyChangedForSubtree(); 934} 935 936void LayerImpl::SetOpacity(float opacity) { 937 if (opacity_ == opacity) 938 return; 939 940 opacity_ = opacity; 941 NoteLayerPropertyChangedForSubtree(); 942} 943 944bool LayerImpl::OpacityIsAnimating() const { 945 return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity); 946} 947 948bool LayerImpl::OpacityIsAnimatingOnImplOnly() const { 949 Animation* opacity_animation = 950 layer_animation_controller_->GetAnimation(Animation::Opacity); 951 return opacity_animation && opacity_animation->is_impl_only(); 952} 953 954void LayerImpl::SetBlendMode(SkXfermode::Mode blend_mode) { 955 if (blend_mode_ == blend_mode) 956 return; 957 958 blend_mode_ = blend_mode; 959 NoteLayerPropertyChangedForSubtree(); 960} 961 962void LayerImpl::SetIsRootForIsolatedGroup(bool root) { 963 if (is_root_for_isolated_group_ == root) 964 return; 965 966 is_root_for_isolated_group_ = root; 967 SetNeedsPushProperties(); 968} 969 970void LayerImpl::SetPosition(const gfx::PointF& position) { 971 if (position_ == position) 972 return; 973 974 position_ = position; 975 NoteLayerPropertyChangedForSubtree(); 976} 977 978void LayerImpl::SetShouldFlattenTransform(bool flatten) { 979 if (should_flatten_transform_ == flatten) 980 return; 981 982 should_flatten_transform_ = flatten; 983 NoteLayerPropertyChangedForSubtree(); 984} 985 986void LayerImpl::Set3dSortingContextId(int id) { 987 if (id == sorting_context_id_) 988 return; 989 sorting_context_id_ = id; 990 NoteLayerPropertyChangedForSubtree(); 991} 992 993void LayerImpl::SetTransform(const gfx::Transform& transform) { 994 if (transform_ == transform) 995 return; 996 997 transform_ = transform; 998 transform_is_invertible_ = transform_.IsInvertible(); 999 NoteLayerPropertyChangedForSubtree(); 1000} 1001 1002void LayerImpl::SetTransformAndInvertibility(const gfx::Transform& transform, 1003 bool transform_is_invertible) { 1004 if (transform_ == transform) { 1005 DCHECK(transform_is_invertible_ == transform_is_invertible) 1006 << "Can't change invertibility if transform is unchanged"; 1007 return; 1008 } 1009 transform_ = transform; 1010 transform_is_invertible_ = transform_is_invertible; 1011 NoteLayerPropertyChangedForSubtree(); 1012} 1013 1014bool LayerImpl::TransformIsAnimating() const { 1015 return layer_animation_controller_->IsAnimatingProperty(Animation::Transform); 1016} 1017 1018bool LayerImpl::TransformIsAnimatingOnImplOnly() const { 1019 Animation* transform_animation = 1020 layer_animation_controller_->GetAnimation(Animation::Transform); 1021 return transform_animation && transform_animation->is_impl_only(); 1022} 1023 1024void LayerImpl::SetUpdateRect(const gfx::RectF& update_rect) { 1025 update_rect_ = update_rect; 1026 SetNeedsPushProperties(); 1027} 1028 1029void LayerImpl::AddDamageRect(const gfx::RectF& damage_rect) { 1030 damage_rect_ = gfx::UnionRects(damage_rect_, damage_rect); 1031} 1032 1033void LayerImpl::SetContentBounds(const gfx::Size& content_bounds) { 1034 if (this->content_bounds() == content_bounds) 1035 return; 1036 1037 draw_properties_.content_bounds = content_bounds; 1038 NoteLayerPropertyChanged(); 1039} 1040 1041void LayerImpl::SetContentsScale(float contents_scale_x, 1042 float contents_scale_y) { 1043 if (this->contents_scale_x() == contents_scale_x && 1044 this->contents_scale_y() == contents_scale_y) 1045 return; 1046 1047 draw_properties_.contents_scale_x = contents_scale_x; 1048 draw_properties_.contents_scale_y = contents_scale_y; 1049 NoteLayerPropertyChanged(); 1050} 1051 1052void LayerImpl::SetScrollOffsetDelegate( 1053 ScrollOffsetDelegate* scroll_offset_delegate) { 1054 // Having both a scroll parent and a scroll offset delegate is unsupported. 1055 DCHECK(!scroll_parent_); 1056 if (!scroll_offset_delegate && scroll_offset_delegate_) { 1057 scroll_delta_ = 1058 scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; 1059 } 1060 gfx::Vector2dF total_offset = TotalScrollOffset(); 1061 scroll_offset_delegate_ = scroll_offset_delegate; 1062 if (scroll_offset_delegate_) 1063 scroll_offset_delegate_->SetTotalScrollOffset(total_offset); 1064} 1065 1066bool LayerImpl::IsExternalFlingActive() const { 1067 return scroll_offset_delegate_ && 1068 scroll_offset_delegate_->IsExternalFlingActive(); 1069} 1070 1071void LayerImpl::SetScrollOffset(const gfx::Vector2d& scroll_offset) { 1072 SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); 1073} 1074 1075void LayerImpl::SetScrollOffsetAndDelta(const gfx::Vector2d& scroll_offset, 1076 const gfx::Vector2dF& scroll_delta) { 1077 bool changed = false; 1078 1079 last_scroll_offset_ = scroll_offset; 1080 1081 if (scroll_offset_ != scroll_offset) { 1082 changed = true; 1083 scroll_offset_ = scroll_offset; 1084 1085 if (scroll_offset_delegate_) 1086 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); 1087 } 1088 1089 if (ScrollDelta() != scroll_delta) { 1090 changed = true; 1091 if (layer_tree_impl()->IsActiveTree()) { 1092 LayerImpl* pending_twin = 1093 layer_tree_impl()->FindPendingTreeLayerById(id()); 1094 if (pending_twin) { 1095 // The pending twin can't mirror the scroll delta of the active 1096 // layer. Although the delta - sent scroll delta difference is 1097 // identical for both twins, the sent scroll delta for the pending 1098 // layer is zero, as anything that has been sent has been baked 1099 // into the layer's position/scroll offset as a part of commit. 1100 DCHECK(pending_twin->sent_scroll_delta().IsZero()); 1101 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta()); 1102 } 1103 } 1104 1105 if (scroll_offset_delegate_) { 1106 scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ + 1107 scroll_delta); 1108 } else { 1109 scroll_delta_ = scroll_delta; 1110 } 1111 } 1112 1113 if (changed) { 1114 NoteLayerPropertyChangedForSubtree(); 1115 ScrollbarParametersDidChange(); 1116 } 1117} 1118 1119gfx::Vector2dF LayerImpl::ScrollDelta() const { 1120 if (scroll_offset_delegate_) 1121 return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; 1122 return scroll_delta_; 1123} 1124 1125void LayerImpl::SetScrollDelta(const gfx::Vector2dF& scroll_delta) { 1126 SetScrollOffsetAndDelta(scroll_offset_, scroll_delta); 1127} 1128 1129gfx::Vector2dF LayerImpl::TotalScrollOffset() const { 1130 return scroll_offset_ + ScrollDelta(); 1131} 1132 1133void LayerImpl::SetDoubleSided(bool double_sided) { 1134 if (double_sided_ == double_sided) 1135 return; 1136 1137 double_sided_ = double_sided; 1138 NoteLayerPropertyChangedForSubtree(); 1139} 1140 1141Region LayerImpl::VisibleContentOpaqueRegion() const { 1142 if (contents_opaque()) 1143 return visible_content_rect(); 1144 return Region(); 1145} 1146 1147void LayerImpl::DidBeginTracing() {} 1148 1149void LayerImpl::ReleaseResources() {} 1150 1151gfx::Vector2d LayerImpl::MaxScrollOffset() const { 1152 if (!scroll_clip_layer_ || bounds().IsEmpty()) 1153 return gfx::Vector2d(); 1154 1155 LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer(); 1156 DCHECK(this != page_scale_layer); 1157 DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || 1158 IsContainerForFixedPositionLayers()); 1159 1160 gfx::SizeF scaled_scroll_bounds(bounds()); 1161 1162 float scale_factor = 1.f; 1163 for (LayerImpl const* current_layer = this; 1164 current_layer != scroll_clip_layer_; 1165 current_layer = current_layer->parent()) { 1166 DCHECK(current_layer); 1167 float current_layer_scale = 1.f; 1168 1169 const gfx::Transform& layer_transform = current_layer->transform(); 1170 if (current_layer == page_scale_layer) { 1171 DCHECK(layer_transform.IsIdentity()); 1172 current_layer_scale = layer_tree_impl()->total_page_scale_factor(); 1173 } else { 1174 // TODO(wjmaclean) Should we allow for translation too? 1175 DCHECK(layer_transform.IsScale2d()); 1176 gfx::Vector2dF layer_scale = layer_transform.Scale2d(); 1177 // TODO(wjmaclean) Allow for non-isotropic scales. 1178 DCHECK(layer_scale.x() == layer_scale.y()); 1179 current_layer_scale = layer_scale.x(); 1180 } 1181 1182 scale_factor *= current_layer_scale; 1183 } 1184 // TODO(wjmaclean) Once we move to a model where the two-viewport model is 1185 // turned on in all builds, remove the next two lines. For now however, the 1186 // page scale layer may coincide with the clip layer, and so this is 1187 // necessary. 1188 if (page_scale_layer == scroll_clip_layer_) 1189 scale_factor *= layer_tree_impl()->total_page_scale_factor(); 1190 1191 scaled_scroll_bounds.SetSize(scale_factor * scaled_scroll_bounds.width(), 1192 scale_factor * scaled_scroll_bounds.height()); 1193 scaled_scroll_bounds = gfx::ToFlooredSize(scaled_scroll_bounds); 1194 1195 gfx::Vector2dF max_offset( 1196 scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), 1197 scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); 1198 // We need the final scroll offset to be in CSS coords. 1199 max_offset.Scale(1 / scale_factor); 1200 max_offset.SetToMax(gfx::Vector2dF()); 1201 return gfx::ToFlooredVector2d(max_offset); 1202} 1203 1204gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { 1205 gfx::Vector2dF max_offset = MaxScrollOffset(); 1206 gfx::Vector2dF old_offset = TotalScrollOffset(); 1207 gfx::Vector2dF clamped_offset = old_offset; 1208 1209 clamped_offset.SetToMin(max_offset); 1210 clamped_offset.SetToMax(gfx::Vector2d()); 1211 gfx::Vector2dF delta = clamped_offset - old_offset; 1212 if (!delta.IsZero()) 1213 ScrollBy(delta); 1214 1215 return delta; 1216} 1217 1218void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, 1219 LayerImpl* scrollbar_clip_layer) const { 1220 DCHECK(scrollbar_layer); 1221 LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer(); 1222 1223 DCHECK(this != page_scale_layer); 1224 DCHECK(scrollbar_clip_layer); 1225 DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || 1226 IsContainerForFixedPositionLayers()); 1227 gfx::RectF clip_rect(gfx::PointF(), scrollbar_clip_layer->bounds()); 1228 1229 // See comment in MaxScrollOffset() regarding the use of the content layer 1230 // bounds here. 1231 gfx::RectF scroll_rect(gfx::PointF(), bounds()); 1232 1233 if (scroll_rect.size().IsEmpty()) 1234 return; 1235 1236 // TODO(wjmaclean) This computation is nearly identical to the one in 1237 // MaxScrollOffset. Find some way to combine these. 1238 gfx::Vector2dF current_offset; 1239 for (LayerImpl const* current_layer = this; 1240 current_layer != scrollbar_clip_layer; 1241 current_layer = current_layer->parent()) { 1242 DCHECK(current_layer); 1243 const gfx::Transform& layer_transform = current_layer->transform(); 1244 if (current_layer == page_scale_layer) { 1245 DCHECK(layer_transform.IsIdentity()); 1246 float scale_factor = layer_tree_impl()->total_page_scale_factor(); 1247 current_offset.Scale(scale_factor); 1248 scroll_rect.Scale(scale_factor); 1249 } else { 1250 DCHECK(layer_transform.IsScale2d()); 1251 gfx::Vector2dF layer_scale = layer_transform.Scale2d(); 1252 DCHECK(layer_scale.x() == layer_scale.y()); 1253 gfx::Vector2dF new_offset = 1254 current_layer->scroll_offset() + current_layer->ScrollDelta(); 1255 new_offset.Scale(layer_scale.x(), layer_scale.y()); 1256 current_offset += new_offset; 1257 } 1258 } 1259 // TODO(wjmaclean) Once we move to a model where the two-viewport model is 1260 // turned on in all builds, remove the next two lines. For now however, the 1261 // page scale layer may coincide with the clip layer, and so this is 1262 // necessary. 1263 if (page_scale_layer == scrollbar_clip_layer) { 1264 scroll_rect.Scale(layer_tree_impl()->total_page_scale_factor()); 1265 current_offset.Scale(layer_tree_impl()->total_page_scale_factor()); 1266 } 1267 1268 scrollbar_layer->SetVerticalAdjust( 1269 layer_tree_impl()->VerticalAdjust(scrollbar_clip_layer->id())); 1270 if (scrollbar_layer->orientation() == HORIZONTAL) { 1271 float visible_ratio = clip_rect.width() / scroll_rect.width(); 1272 scrollbar_layer->SetCurrentPos(current_offset.x()); 1273 scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width()); 1274 scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); 1275 } else { 1276 float visible_ratio = clip_rect.height() / scroll_rect.height(); 1277 scrollbar_layer->SetCurrentPos(current_offset.y()); 1278 scrollbar_layer->SetMaximum(scroll_rect.height() - clip_rect.height()); 1279 scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); 1280 } 1281 1282 layer_tree_impl()->set_needs_update_draw_properties(); 1283 // TODO(wjmaclean) The scrollbar animator for the pinch-zoom scrollbars should 1284 // activate for every scroll on the main frame, not just the scrolls that move 1285 // the pinch virtual viewport (i.e. trigger from either inner or outer 1286 // viewport). 1287 if (scrollbar_animation_controller_) { 1288 // When both non-overlay and overlay scrollbars are both present, don't 1289 // animate the overlay scrollbars when page scale factor is at the min. 1290 // Non-overlay scrollbars also shouldn't trigger animations. 1291 bool is_animatable_scrollbar = 1292 scrollbar_layer->is_overlay_scrollbar() && 1293 ((layer_tree_impl()->total_page_scale_factor() > 1294 layer_tree_impl()->min_page_scale_factor()) || 1295 !layer_tree_impl()->settings().use_pinch_zoom_scrollbars); 1296 if (is_animatable_scrollbar) 1297 scrollbar_animation_controller_->DidScrollUpdate(); 1298 } 1299} 1300 1301void LayerImpl::DidBecomeActive() { 1302 if (layer_tree_impl_->settings().scrollbar_animator == 1303 LayerTreeSettings::NoAnimator) { 1304 return; 1305 } 1306 1307 bool need_scrollbar_animation_controller = scrollable() && scrollbars_; 1308 if (!need_scrollbar_animation_controller) { 1309 scrollbar_animation_controller_.reset(); 1310 return; 1311 } 1312 1313 if (scrollbar_animation_controller_) 1314 return; 1315 1316 scrollbar_animation_controller_ = 1317 layer_tree_impl_->CreateScrollbarAnimationController(this); 1318} 1319 1320void LayerImpl::ClearScrollbars() { 1321 if (!scrollbars_) 1322 return; 1323 1324 scrollbars_.reset(NULL); 1325} 1326 1327void LayerImpl::AddScrollbar(ScrollbarLayerImplBase* layer) { 1328 DCHECK(layer); 1329 DCHECK(!scrollbars_ || scrollbars_->find(layer) == scrollbars_->end()); 1330 if (!scrollbars_) 1331 scrollbars_.reset(new ScrollbarSet()); 1332 1333 scrollbars_->insert(layer); 1334} 1335 1336void LayerImpl::RemoveScrollbar(ScrollbarLayerImplBase* layer) { 1337 DCHECK(scrollbars_); 1338 DCHECK(layer); 1339 DCHECK(scrollbars_->find(layer) != scrollbars_->end()); 1340 1341 scrollbars_->erase(layer); 1342 if (scrollbars_->empty()) 1343 scrollbars_.reset(); 1344} 1345 1346bool LayerImpl::HasScrollbar(ScrollbarOrientation orientation) const { 1347 if (!scrollbars_) 1348 return false; 1349 1350 for (ScrollbarSet::iterator it = scrollbars_->begin(); 1351 it != scrollbars_->end(); 1352 ++it) 1353 if ((*it)->orientation() == orientation) 1354 return true; 1355 1356 return false; 1357} 1358 1359void LayerImpl::ScrollbarParametersDidChange() { 1360 if (!scrollbars_) 1361 return; 1362 1363 for (ScrollbarSet::iterator it = scrollbars_->begin(); 1364 it != scrollbars_->end(); 1365 ++it) 1366 (*it)->ScrollbarParametersDidChange(); 1367} 1368 1369void LayerImpl::SetNeedsPushProperties() { 1370 if (needs_push_properties_) 1371 return; 1372 if (!parent_should_know_need_push_properties() && parent_) 1373 parent_->AddDependentNeedsPushProperties(); 1374 needs_push_properties_ = true; 1375} 1376 1377void LayerImpl::AddDependentNeedsPushProperties() { 1378 DCHECK_GE(num_dependents_need_push_properties_, 0); 1379 1380 if (!parent_should_know_need_push_properties() && parent_) 1381 parent_->AddDependentNeedsPushProperties(); 1382 1383 num_dependents_need_push_properties_++; 1384} 1385 1386void LayerImpl::RemoveDependentNeedsPushProperties() { 1387 num_dependents_need_push_properties_--; 1388 DCHECK_GE(num_dependents_need_push_properties_, 0); 1389 1390 if (!parent_should_know_need_push_properties() && parent_) 1391 parent_->RemoveDependentNeedsPushProperties(); 1392} 1393 1394void LayerImpl::AsValueInto(base::debug::TracedValue* state) const { 1395 TracedValue::MakeDictIntoImplicitSnapshotWithCategory( 1396 TRACE_DISABLED_BY_DEFAULT("cc.debug"), 1397 state, 1398 "cc::LayerImpl", 1399 LayerTypeAsString(), 1400 this); 1401 state->SetInteger("layer_id", id()); 1402 state->BeginDictionary("bounds"); 1403 MathUtil::AddToTracedValue(bounds_, state); 1404 state->EndDictionary(); 1405 1406 state->BeginArray("position"); 1407 MathUtil::AddToTracedValue(position_, state); 1408 state->EndArray(); 1409 1410 state->SetInteger("draws_content", DrawsContent()); 1411 state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes()); 1412 1413 state->BeginArray("scroll_offset"); 1414 MathUtil::AddToTracedValue(scroll_offset_, state); 1415 state->EndArray(); 1416 1417 state->BeginArray("transform_origin"); 1418 MathUtil::AddToTracedValue(transform_origin_, state); 1419 state->EndArray(); 1420 1421 bool clipped; 1422 gfx::QuadF layer_quad = MathUtil::MapQuad( 1423 screen_space_transform(), 1424 gfx::QuadF(gfx::Rect(content_bounds())), 1425 &clipped); 1426 state->BeginArray("layer_quad"); 1427 MathUtil::AddToTracedValue(layer_quad, state); 1428 state->EndArray(); 1429 if (!touch_event_handler_region_.IsEmpty()) { 1430 state->BeginArray("touch_event_handler_region"); 1431 touch_event_handler_region_.AsValueInto(state); 1432 state->EndArray(); 1433 } 1434 if (have_wheel_event_handlers_) { 1435 gfx::Rect wheel_rect(content_bounds()); 1436 Region wheel_region(wheel_rect); 1437 state->BeginArray("wheel_event_handler_region"); 1438 wheel_region.AsValueInto(state); 1439 state->EndArray(); 1440 } 1441 if (have_scroll_event_handlers_) { 1442 gfx::Rect scroll_rect(content_bounds()); 1443 Region scroll_region(scroll_rect); 1444 state->BeginArray("scroll_event_handler_region"); 1445 scroll_region.AsValueInto(state); 1446 state->EndArray(); 1447 } 1448 if (!non_fast_scrollable_region_.IsEmpty()) { 1449 state->BeginArray("non_fast_scrollable_region"); 1450 non_fast_scrollable_region_.AsValueInto(state); 1451 state->EndArray(); 1452 } 1453 1454 state->BeginArray("children"); 1455 for (size_t i = 0; i < children_.size(); ++i) { 1456 state->BeginDictionary(); 1457 children_[i]->AsValueInto(state); 1458 state->EndDictionary(); 1459 } 1460 state->EndArray(); 1461 if (mask_layer_) { 1462 state->BeginDictionary("mask_layer"); 1463 mask_layer_->AsValueInto(state); 1464 state->EndDictionary(); 1465 } 1466 if (replica_layer_) { 1467 state->BeginDictionary("replica_layer"); 1468 replica_layer_->AsValueInto(state); 1469 state->EndDictionary(); 1470 } 1471 1472 if (scroll_parent_) 1473 state->SetInteger("scroll_parent", scroll_parent_->id()); 1474 1475 if (clip_parent_) 1476 state->SetInteger("clip_parent", clip_parent_->id()); 1477 1478 state->SetBoolean("can_use_lcd_text", can_use_lcd_text()); 1479 state->SetBoolean("contents_opaque", contents_opaque()); 1480 1481 state->SetBoolean( 1482 "has_animation_bounds", 1483 layer_animation_controller()->HasAnimationThatInflatesBounds()); 1484 1485 gfx::BoxF box; 1486 if (LayerUtils::GetAnimationBounds(*this, &box)) { 1487 state->BeginArray("animation_bounds"); 1488 MathUtil::AddToTracedValue(box, state); 1489 state->EndArray(); 1490 } 1491 1492 if (debug_info_.get()) { 1493 std::string str; 1494 debug_info_->AppendAsTraceFormat(&str); 1495 base::JSONReader json_reader; 1496 scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(str)); 1497 1498 if (debug_info_value->IsType(base::Value::TYPE_DICTIONARY)) { 1499 base::DictionaryValue* dictionary_value = NULL; 1500 bool converted_to_dictionary = 1501 debug_info_value->GetAsDictionary(&dictionary_value); 1502 DCHECK(converted_to_dictionary); 1503 for (base::DictionaryValue::Iterator it(*dictionary_value); !it.IsAtEnd(); 1504 it.Advance()) { 1505 state->SetValue(it.key().data(), it.value().DeepCopy()); 1506 } 1507 } else { 1508 NOTREACHED(); 1509 } 1510 } 1511} 1512 1513bool LayerImpl::IsDrawnRenderSurfaceLayerListMember() const { 1514 return draw_properties_.last_drawn_render_surface_layer_list_id == 1515 layer_tree_impl_->current_render_surface_list_id(); 1516} 1517 1518size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; } 1519 1520void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { 1521 benchmark->RunOnLayer(this); 1522} 1523 1524void LayerImpl::NotifyAnimationFinished( 1525 base::TimeTicks monotonic_time, 1526 Animation::TargetProperty target_property) { 1527 if (target_property == Animation::ScrollOffset) 1528 layer_tree_impl_->InputScrollAnimationFinished(); 1529} 1530 1531} // namespace cc 1532