| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/layers/layer_impl.h" | 5 #include "cc/layers/layer_impl.h" |
| 6 | 6 |
| 7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
| 9 #include "base/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
| 10 #include "base/trace_event/trace_event_argument.h" | 10 #include "base/trace_event/trace_event_argument.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "cc/trees/layer_tree_settings.h" | 27 #include "cc/trees/layer_tree_settings.h" |
| 28 #include "cc/trees/proxy.h" | 28 #include "cc/trees/proxy.h" |
| 29 #include "ui/gfx/geometry/box_f.h" | 29 #include "ui/gfx/geometry/box_f.h" |
| 30 #include "ui/gfx/geometry/point_conversions.h" | 30 #include "ui/gfx/geometry/point_conversions.h" |
| 31 #include "ui/gfx/geometry/quad_f.h" | 31 #include "ui/gfx/geometry/quad_f.h" |
| 32 #include "ui/gfx/geometry/rect_conversions.h" | 32 #include "ui/gfx/geometry/rect_conversions.h" |
| 33 #include "ui/gfx/geometry/size_conversions.h" | 33 #include "ui/gfx/geometry/size_conversions.h" |
| 34 #include "ui/gfx/geometry/vector2d_conversions.h" | 34 #include "ui/gfx/geometry/vector2d_conversions.h" |
| 35 | 35 |
| 36 namespace cc { | 36 namespace cc { |
| 37 LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) | 37 LayerImpl::LayerImpl(LayerTreeImpl* layer_impl, int id) |
| 38 : LayerImpl(layer_impl, id, new LayerImpl::SyncedScrollOffset) { |
| 39 } |
| 40 |
| 41 LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, |
| 42 int id, |
| 43 scoped_refptr<SyncedScrollOffset> scroll_offset) |
| 38 : parent_(nullptr), | 44 : parent_(nullptr), |
| 39 scroll_parent_(nullptr), | 45 scroll_parent_(nullptr), |
| 40 clip_parent_(nullptr), | 46 clip_parent_(nullptr), |
| 41 mask_layer_id_(-1), | 47 mask_layer_id_(-1), |
| 42 replica_layer_id_(-1), | 48 replica_layer_id_(-1), |
| 43 layer_id_(id), | 49 layer_id_(id), |
| 44 layer_tree_impl_(tree_impl), | 50 layer_tree_impl_(tree_impl), |
| 51 scroll_offset_(scroll_offset), |
| 45 scroll_offset_delegate_(nullptr), | 52 scroll_offset_delegate_(nullptr), |
| 46 scroll_clip_layer_(nullptr), | 53 scroll_clip_layer_(nullptr), |
| 47 should_scroll_on_main_thread_(false), | 54 should_scroll_on_main_thread_(false), |
| 48 have_wheel_event_handlers_(false), | 55 have_wheel_event_handlers_(false), |
| 49 have_scroll_event_handlers_(false), | 56 have_scroll_event_handlers_(false), |
| 50 user_scrollable_horizontal_(true), | 57 user_scrollable_horizontal_(true), |
| 51 user_scrollable_vertical_(true), | 58 user_scrollable_vertical_(true), |
| 52 stacking_order_changed_(false), | 59 stacking_order_changed_(false), |
| 53 double_sided_(true), | 60 double_sided_(true), |
| 54 should_flatten_transform_(true), | 61 should_flatten_transform_(true), |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 bool resourceless_software_draw) { | 348 bool resourceless_software_draw) { |
| 342 return false; | 349 return false; |
| 343 } | 350 } |
| 344 | 351 |
| 345 void LayerImpl::GetContentsResourceId(ResourceProvider::ResourceId* resource_id, | 352 void LayerImpl::GetContentsResourceId(ResourceProvider::ResourceId* resource_id, |
| 346 gfx::Size* resource_size) const { | 353 gfx::Size* resource_size) const { |
| 347 NOTREACHED(); | 354 NOTREACHED(); |
| 348 *resource_id = 0; | 355 *resource_id = 0; |
| 349 } | 356 } |
| 350 | 357 |
| 351 void LayerImpl::SetSentScrollDelta(const gfx::Vector2dF& sent_scroll_delta) { | 358 gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { |
| 352 // Pending tree never has sent scroll deltas | 359 RefreshFromScrollDelegate(); |
| 353 DCHECK(layer_tree_impl()->IsActiveTree()); | |
| 354 | 360 |
| 355 if (sent_scroll_delta_ == sent_scroll_delta) | 361 gfx::ScrollOffset adjusted_scroll(scroll); |
| 356 return; | |
| 357 | |
| 358 sent_scroll_delta_ = sent_scroll_delta; | |
| 359 } | |
| 360 | |
| 361 gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { | |
| 362 gfx::Vector2dF adjusted_scroll = scroll; | |
| 363 if (layer_tree_impl()->settings().use_pinch_virtual_viewport) { | 362 if (layer_tree_impl()->settings().use_pinch_virtual_viewport) { |
| 364 if (!user_scrollable_horizontal_) | 363 if (!user_scrollable_horizontal_) |
| 365 adjusted_scroll.set_x(0); | 364 adjusted_scroll.set_x(0); |
| 366 if (!user_scrollable_vertical_) | 365 if (!user_scrollable_vertical_) |
| 367 adjusted_scroll.set_y(0); | 366 adjusted_scroll.set_y(0); |
| 368 } | 367 } |
| 369 DCHECK(scrollable()); | 368 DCHECK(scrollable()); |
| 370 gfx::Vector2dF min_delta = -ScrollOffsetToVector2dF(scroll_offset_); | 369 gfx::ScrollOffset old_offset = CurrentScrollOffset(); |
| 371 gfx::Vector2dF max_delta = MaxScrollOffset().DeltaFrom(scroll_offset_); | 370 gfx::ScrollOffset new_offset = |
| 372 // Clamp new_delta so that position + delta stays within scroll bounds. | 371 ClampScrollOffsetToLimits(old_offset + adjusted_scroll); |
| 373 gfx::Vector2dF new_delta = (ScrollDelta() + adjusted_scroll); | 372 SetCurrentScrollOffset(new_offset); |
| 374 new_delta.SetToMax(min_delta); | |
| 375 new_delta.SetToMin(max_delta); | |
| 376 gfx::Vector2dF unscrolled = | |
| 377 ScrollDelta() + scroll - new_delta; | |
| 378 SetScrollDelta(new_delta); | |
| 379 | 373 |
| 380 return unscrolled; | 374 gfx::ScrollOffset unscrolled = |
| 375 old_offset + gfx::ScrollOffset(scroll) - new_offset; |
| 376 return gfx::Vector2dF(unscrolled.x(), unscrolled.y()); |
| 381 } | 377 } |
| 382 | 378 |
| 383 void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { | 379 void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { |
| 384 scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id); | 380 scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id); |
| 385 } | 381 } |
| 386 | 382 |
| 387 bool LayerImpl::user_scrollable(ScrollbarOrientation orientation) const { | 383 bool LayerImpl::user_scrollable(ScrollbarOrientation orientation) const { |
| 388 return (orientation == HORIZONTAL) ? user_scrollable_horizontal_ | 384 return (orientation == HORIZONTAL) ? user_scrollable_horizontal_ |
| 389 : user_scrollable_vertical_; | 385 : user_scrollable_vertical_; |
| 390 } | 386 } |
| 391 | 387 |
| 392 void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { | 388 void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { |
| 393 if (sent_scroll_delta_.IsZero()) | |
| 394 return; | |
| 395 | |
| 396 // Pending tree never has sent scroll deltas | |
| 397 DCHECK(layer_tree_impl()->IsActiveTree()); | 389 DCHECK(layer_tree_impl()->IsActiveTree()); |
| 398 | 390 scroll_offset_->AbortCommit(); |
| 399 // The combination of pending tree and aborted commits with impl scrolls | |
| 400 // shouldn't happen; we don't know how to update its deltas correctly. | |
| 401 DCHECK(!layer_tree_impl()->FindPendingTreeLayerById(id())); | |
| 402 | |
| 403 // Apply sent scroll deltas to scroll position / scroll delta as if the | |
| 404 // main thread had applied them and then committed those values. | |
| 405 SetScrollOffsetAndDelta( | |
| 406 scroll_offset_ + gfx::ScrollOffset(sent_scroll_delta_), | |
| 407 ScrollDelta() - sent_scroll_delta_); | |
| 408 SetSentScrollDelta(gfx::Vector2dF()); | |
| 409 } | |
| 410 | |
| 411 void LayerImpl::ApplyScrollDeltasSinceBeginMainFrame() { | |
| 412 // Only the pending tree can have missing scrolls. | |
| 413 DCHECK(layer_tree_impl()->IsPendingTree()); | |
| 414 if (!scrollable()) | |
| 415 return; | |
| 416 | |
| 417 // Pending tree should never have sent scroll deltas. | |
| 418 DCHECK(sent_scroll_delta().IsZero()); | |
| 419 | |
| 420 LayerImpl* active_twin = layer_tree_impl()->FindActiveTreeLayerById(id()); | |
| 421 if (active_twin) { | |
| 422 // Scrolls that happens after begin frame (where the sent scroll delta | |
| 423 // comes from) and commit need to be applied to the pending tree | |
| 424 // so that it is up to date with the total scroll. | |
| 425 SetScrollDelta(active_twin->ScrollDelta() - | |
| 426 active_twin->sent_scroll_delta()); | |
| 427 } | |
| 428 } | 391 } |
| 429 | 392 |
| 430 InputHandler::ScrollStatus LayerImpl::TryScroll( | 393 InputHandler::ScrollStatus LayerImpl::TryScroll( |
| 431 const gfx::PointF& screen_space_point, | 394 const gfx::PointF& screen_space_point, |
| 432 InputHandler::ScrollInputType type) const { | 395 InputHandler::ScrollInputType type) const { |
| 433 if (should_scroll_on_main_thread()) { | 396 if (should_scroll_on_main_thread()) { |
| 434 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); | 397 TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); |
| 435 return InputHandler::ScrollOnMainThread; | 398 return InputHandler::ScrollOnMainThread; |
| 436 } | 399 } |
| 437 | 400 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 // values x and y, ceil((x / y) * y) may be x + 1. | 459 // values x and y, ceil((x / y) * y) may be x + 1. |
| 497 content_rect.Intersect(gfx::Rect(content_bounds())); | 460 content_rect.Intersect(gfx::Rect(content_bounds())); |
| 498 return gfx::ToEnclosingRect(content_rect); | 461 return gfx::ToEnclosingRect(content_rect); |
| 499 } | 462 } |
| 500 | 463 |
| 501 skia::RefPtr<SkPicture> LayerImpl::GetPicture() { | 464 skia::RefPtr<SkPicture> LayerImpl::GetPicture() { |
| 502 return skia::RefPtr<SkPicture>(); | 465 return skia::RefPtr<SkPicture>(); |
| 503 } | 466 } |
| 504 | 467 |
| 505 scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { | 468 scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { |
| 506 return LayerImpl::Create(tree_impl, layer_id_); | 469 return LayerImpl::Create(tree_impl, layer_id_, scroll_offset_); |
| 507 } | 470 } |
| 508 | 471 |
| 509 void LayerImpl::PushPropertiesTo(LayerImpl* layer) { | 472 void LayerImpl::PushPropertiesTo(LayerImpl* layer) { |
| 510 layer->SetTransformOrigin(transform_origin_); | 473 layer->SetTransformOrigin(transform_origin_); |
| 511 layer->SetBackgroundColor(background_color_); | 474 layer->SetBackgroundColor(background_color_); |
| 512 layer->SetBounds(bounds_); | 475 layer->SetBounds(bounds_); |
| 513 layer->SetContentBounds(content_bounds()); | 476 layer->SetContentBounds(content_bounds()); |
| 514 layer->SetContentsScale(contents_scale_x(), contents_scale_y()); | 477 layer->SetContentsScale(contents_scale_x(), contents_scale_y()); |
| 515 layer->SetDoubleSided(double_sided_); | 478 layer->SetDoubleSided(double_sided_); |
| 516 layer->SetDrawCheckerboardForMissingTiles( | 479 layer->SetDrawCheckerboardForMissingTiles( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 536 layer->SetPositionConstraint(position_constraint_); | 499 layer->SetPositionConstraint(position_constraint_); |
| 537 layer->SetShouldFlattenTransform(should_flatten_transform_); | 500 layer->SetShouldFlattenTransform(should_flatten_transform_); |
| 538 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); | 501 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); |
| 539 layer->SetTransformAndInvertibility(transform_, transform_is_invertible_); | 502 layer->SetTransformAndInvertibility(transform_, transform_is_invertible_); |
| 540 | 503 |
| 541 layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() | 504 layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() |
| 542 : Layer::INVALID_ID); | 505 : Layer::INVALID_ID); |
| 543 layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); | 506 layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); |
| 544 layer->set_user_scrollable_vertical(user_scrollable_vertical_); | 507 layer->set_user_scrollable_vertical(user_scrollable_vertical_); |
| 545 | 508 |
| 546 // Save the difference but clear the sent delta so that we don't subtract | 509 layer->SetScrollCompensationAdjustment(scroll_compensation_adjustment_); |
| 547 // it again in SetScrollOffsetAndDelta's pending twin mirroring logic. | |
| 548 gfx::Vector2dF remaining_delta = | |
| 549 layer_animation_controller_->scroll_offset_animation_was_interrupted() | |
| 550 ? gfx::Vector2dF() | |
| 551 : layer->ScrollDelta() - layer->sent_scroll_delta(); | |
| 552 | 510 |
| 553 layer->SetSentScrollDelta(gfx::Vector2dF()); | 511 layer->PushScrollOffset(nullptr); |
| 554 layer->SetScrollOffsetAndDelta(scroll_offset_, remaining_delta); | |
| 555 layer->SetScrollCompensationAdjustment(scroll_compensation_adjustment_); | |
| 556 | 512 |
| 557 layer->Set3dSortingContextId(sorting_context_id_); | 513 layer->Set3dSortingContextId(sorting_context_id_); |
| 558 layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_); | 514 layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_); |
| 559 | 515 |
| 560 LayerImpl* scroll_parent = nullptr; | 516 LayerImpl* scroll_parent = nullptr; |
| 561 if (scroll_parent_) { | 517 if (scroll_parent_) { |
| 562 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); | 518 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); |
| 563 DCHECK(scroll_parent); | 519 DCHECK(scroll_parent); |
| 564 } | 520 } |
| 565 | 521 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 } | 713 } |
| 758 | 714 |
| 759 for (size_t i = 0; i < children_.size(); ++i) | 715 for (size_t i = 0; i < children_.size(); ++i) |
| 760 children_[i]->ResetAllChangeTrackingForSubtree(); | 716 children_[i]->ResetAllChangeTrackingForSubtree(); |
| 761 | 717 |
| 762 needs_push_properties_ = false; | 718 needs_push_properties_ = false; |
| 763 num_dependents_need_push_properties_ = 0; | 719 num_dependents_need_push_properties_ = 0; |
| 764 } | 720 } |
| 765 | 721 |
| 766 gfx::ScrollOffset LayerImpl::ScrollOffsetForAnimation() const { | 722 gfx::ScrollOffset LayerImpl::ScrollOffsetForAnimation() const { |
| 767 return TotalScrollOffset(); | 723 return CurrentScrollOffset(); |
| 768 } | 724 } |
| 769 | 725 |
| 770 void LayerImpl::OnFilterAnimated(const FilterOperations& filters) { | 726 void LayerImpl::OnFilterAnimated(const FilterOperations& filters) { |
| 771 SetFilters(filters); | 727 SetFilters(filters); |
| 772 } | 728 } |
| 773 | 729 |
| 774 void LayerImpl::OnOpacityAnimated(float opacity) { | 730 void LayerImpl::OnOpacityAnimated(float opacity) { |
| 775 SetOpacity(opacity); | 731 SetOpacity(opacity); |
| 776 } | 732 } |
| 777 | 733 |
| 778 void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { | 734 void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { |
| 779 SetTransform(transform); | 735 SetTransform(transform); |
| 780 } | 736 } |
| 781 | 737 |
| 782 void LayerImpl::OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) { | 738 void LayerImpl::OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) { |
| 783 // Only layers in the active tree should need to do anything here, since | 739 // Only layers in the active tree should need to do anything here, since |
| 784 // layers in the pending tree will find out about these changes as a | 740 // layers in the pending tree will find out about these changes as a |
| 785 // result of the call to SetScrollDelta. | 741 // result of the shared SyncedProperty. |
| 786 if (!IsActive()) | 742 if (!IsActive()) |
| 787 return; | 743 return; |
| 788 | 744 |
| 789 SetScrollDelta(scroll_offset.DeltaFrom(scroll_offset_)); | 745 SetCurrentScrollOffset(scroll_offset); |
| 790 | 746 |
| 791 layer_tree_impl_->DidAnimateScrollOffset(); | 747 layer_tree_impl_->DidAnimateScrollOffset(); |
| 792 } | 748 } |
| 793 | 749 |
| 794 void LayerImpl::OnAnimationWaitingForDeletion() {} | 750 void LayerImpl::OnAnimationWaitingForDeletion() {} |
| 795 | 751 |
| 796 bool LayerImpl::IsActive() const { | 752 bool LayerImpl::IsActive() const { |
| 797 return layer_tree_impl_->IsActiveTree(); | 753 return layer_tree_impl_->IsActiveTree(); |
| 798 } | 754 } |
| 799 | 755 |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 | 1051 |
| 1096 draw_properties_.contents_scale_x = contents_scale_x; | 1052 draw_properties_.contents_scale_x = contents_scale_x; |
| 1097 draw_properties_.contents_scale_y = contents_scale_y; | 1053 draw_properties_.contents_scale_y = contents_scale_y; |
| 1098 NoteLayerPropertyChanged(); | 1054 NoteLayerPropertyChanged(); |
| 1099 } | 1055 } |
| 1100 | 1056 |
| 1101 void LayerImpl::SetScrollOffsetDelegate( | 1057 void LayerImpl::SetScrollOffsetDelegate( |
| 1102 ScrollOffsetDelegate* scroll_offset_delegate) { | 1058 ScrollOffsetDelegate* scroll_offset_delegate) { |
| 1103 // Having both a scroll parent and a scroll offset delegate is unsupported. | 1059 // Having both a scroll parent and a scroll offset delegate is unsupported. |
| 1104 DCHECK(!scroll_parent_); | 1060 DCHECK(!scroll_parent_); |
| 1105 if (!scroll_offset_delegate && scroll_offset_delegate_) { | 1061 RefreshFromScrollDelegate(); |
| 1106 scroll_delta_ = scroll_offset_delegate_->GetTotalScrollOffset().DeltaFrom( | |
| 1107 scroll_offset_); | |
| 1108 } | |
| 1109 gfx::ScrollOffset total_offset = TotalScrollOffset(); | |
| 1110 scroll_offset_delegate_ = scroll_offset_delegate; | 1062 scroll_offset_delegate_ = scroll_offset_delegate; |
| 1111 if (scroll_offset_delegate_) | 1063 if (scroll_offset_delegate_) |
| 1112 scroll_offset_delegate_->SetTotalScrollOffset(total_offset); | 1064 scroll_offset_delegate_->SetCurrentScrollOffset(CurrentScrollOffset()); |
| 1113 } | 1065 } |
| 1114 | 1066 |
| 1115 bool LayerImpl::IsExternalFlingActive() const { | 1067 bool LayerImpl::IsExternalFlingActive() const { |
| 1116 return scroll_offset_delegate_ && | 1068 return scroll_offset_delegate_ && |
| 1117 scroll_offset_delegate_->IsExternalFlingActive(); | 1069 scroll_offset_delegate_->IsExternalFlingActive(); |
| 1118 } | 1070 } |
| 1119 | 1071 |
| 1120 void LayerImpl::DidScroll() { | 1072 void LayerImpl::SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset) { |
| 1073 DCHECK(IsActive()); |
| 1074 if (scroll_offset_->SetCurrent(scroll_offset)) |
| 1075 DidUpdateScrollOffset(); |
| 1076 } |
| 1077 |
| 1078 void LayerImpl::PushScrollOffsetFromMainThread( |
| 1079 const gfx::ScrollOffset& scroll_offset) { |
| 1080 PushScrollOffset(&scroll_offset); |
| 1081 } |
| 1082 |
| 1083 gfx::ScrollOffset LayerImpl::PullDeltaForMainThread() { |
| 1084 RefreshFromScrollDelegate(); |
| 1085 |
| 1086 // TODO(aelias): Remove all this temporary flooring machinery when Blink |
| 1087 // fully supports fractional scrolls. |
| 1088 gfx::ScrollOffset current = CurrentScrollOffset(); |
| 1089 gfx::ScrollOffset floored(floor(current.x()), floor(current.y())); |
| 1090 scroll_offset_->SetCurrent(floored); |
| 1091 gfx::ScrollOffset delta = scroll_offset_->PullDeltaForMainThread(); |
| 1092 scroll_offset_->SetCurrent(current); |
| 1093 return delta; |
| 1094 } |
| 1095 |
| 1096 void LayerImpl::RefreshFromScrollDelegate() { |
| 1097 if (scroll_offset_delegate_) { |
| 1098 SetCurrentScrollOffset( |
| 1099 gfx::ScrollOffset(scroll_offset_delegate_->GetCurrentScrollOffset())); |
| 1100 } |
| 1101 } |
| 1102 |
| 1103 gfx::ScrollOffset LayerImpl::CurrentScrollOffset() const { |
| 1104 return scroll_offset_->Current(IsActive()); |
| 1105 } |
| 1106 |
| 1107 gfx::Vector2dF LayerImpl::ScrollDelta() const { |
| 1108 if (IsActive()) |
| 1109 return gfx::Vector2dF(scroll_offset_->Delta().x(), |
| 1110 scroll_offset_->Delta().y()); |
| 1111 else |
| 1112 return gfx::Vector2dF(scroll_offset_->PendingDelta().get().x(), |
| 1113 scroll_offset_->PendingDelta().get().y()); |
| 1114 } |
| 1115 |
| 1116 void LayerImpl::SetScrollDelta(const gfx::Vector2dF& delta) { |
| 1117 DCHECK(IsActive()); |
| 1118 SetCurrentScrollOffset(scroll_offset_->ActiveBase() + |
| 1119 gfx::ScrollOffset(delta)); |
| 1120 } |
| 1121 |
| 1122 gfx::ScrollOffset LayerImpl::BaseScrollOffset() const { |
| 1123 if (IsActive()) |
| 1124 return scroll_offset_->ActiveBase(); |
| 1125 else |
| 1126 return scroll_offset_->PendingBase(); |
| 1127 } |
| 1128 |
| 1129 void LayerImpl::PushScrollOffset(const gfx::ScrollOffset* scroll_offset) { |
| 1130 DCHECK(scroll_offset || IsActive()); |
| 1131 bool changed = false; |
| 1132 if (scroll_offset) { |
| 1133 DCHECK(!IsActive() || !layer_tree_impl_->FindPendingTreeLayerById(id())); |
| 1134 changed |= scroll_offset_->PushFromMainThread(*scroll_offset); |
| 1135 } |
| 1136 if (IsActive()) { |
| 1137 changed |= scroll_offset_->PushPendingToActive(); |
| 1138 if (layer_animation_controller_->scroll_offset_animation_was_interrupted()) |
| 1139 SetScrollDelta(gfx::Vector2dF()); |
| 1140 } |
| 1141 |
| 1142 if (changed) |
| 1143 DidUpdateScrollOffset(); |
| 1144 } |
| 1145 |
| 1146 void LayerImpl::DidUpdateScrollOffset() { |
| 1147 if (scroll_offset_delegate_) { |
| 1148 scroll_offset_delegate_->SetCurrentScrollOffset(CurrentScrollOffset()); |
| 1149 scroll_offset_delegate_->Update(); |
| 1150 RefreshFromScrollDelegate(); |
| 1151 } |
| 1152 |
| 1121 NoteLayerPropertyChangedForSubtree(); | 1153 NoteLayerPropertyChangedForSubtree(); |
| 1122 ScrollbarParametersDidChange(false); | 1154 ScrollbarParametersDidChange(false); |
| 1123 } | 1155 } |
| 1124 | 1156 |
| 1125 void LayerImpl::SetScrollOffset(const gfx::ScrollOffset& scroll_offset) { | |
| 1126 SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); | |
| 1127 } | |
| 1128 | |
| 1129 void LayerImpl::SetScrollOffsetAndDelta(const gfx::ScrollOffset& scroll_offset, | |
| 1130 const gfx::Vector2dF& scroll_delta) { | |
| 1131 bool changed = false; | |
| 1132 | |
| 1133 last_scroll_offset_ = scroll_offset; | |
| 1134 | |
| 1135 if (scroll_offset_ != scroll_offset) { | |
| 1136 changed = true; | |
| 1137 scroll_offset_ = scroll_offset; | |
| 1138 | |
| 1139 if (scroll_offset_delegate_) | |
| 1140 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); | |
| 1141 } | |
| 1142 | |
| 1143 if (ScrollDelta() != scroll_delta) { | |
| 1144 changed = true; | |
| 1145 if (layer_tree_impl()->IsActiveTree()) { | |
| 1146 LayerImpl* pending_twin = | |
| 1147 layer_tree_impl()->FindPendingTreeLayerById(id()); | |
| 1148 if (pending_twin) { | |
| 1149 // The pending twin can't mirror the scroll delta of the active | |
| 1150 // layer. Although the delta - sent scroll delta difference is | |
| 1151 // identical for both twins, the sent scroll delta for the pending | |
| 1152 // layer is zero, as anything that has been sent has been baked | |
| 1153 // into the layer's position/scroll offset as a part of commit. | |
| 1154 DCHECK(pending_twin->sent_scroll_delta().IsZero()); | |
| 1155 pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta()); | |
| 1156 } | |
| 1157 } | |
| 1158 | |
| 1159 if (scroll_offset_delegate_) { | |
| 1160 scroll_offset_delegate_->SetTotalScrollOffset( | |
| 1161 ScrollOffsetWithDelta(scroll_offset_, scroll_delta)); | |
| 1162 } else { | |
| 1163 scroll_delta_ = scroll_delta; | |
| 1164 } | |
| 1165 } | |
| 1166 | |
| 1167 if (changed) { | |
| 1168 if (scroll_offset_delegate_) | |
| 1169 scroll_offset_delegate_->Update(); | |
| 1170 DidScroll(); | |
| 1171 } | |
| 1172 } | |
| 1173 | |
| 1174 gfx::Vector2dF LayerImpl::ScrollDelta() const { | |
| 1175 if (scroll_offset_delegate_) { | |
| 1176 return scroll_offset_delegate_->GetTotalScrollOffset().DeltaFrom( | |
| 1177 scroll_offset_); | |
| 1178 } | |
| 1179 return scroll_delta_; | |
| 1180 } | |
| 1181 | |
| 1182 void LayerImpl::SetScrollDelta(const gfx::Vector2dF& scroll_delta) { | |
| 1183 SetScrollOffsetAndDelta(scroll_offset_, scroll_delta); | |
| 1184 } | |
| 1185 | |
| 1186 gfx::ScrollOffset LayerImpl::TotalScrollOffset() const { | |
| 1187 return ScrollOffsetWithDelta(scroll_offset_, ScrollDelta()); | |
| 1188 } | |
| 1189 | |
| 1190 void LayerImpl::SetDoubleSided(bool double_sided) { | 1157 void LayerImpl::SetDoubleSided(bool double_sided) { |
| 1191 if (double_sided_ == double_sided) | 1158 if (double_sided_ == double_sided) |
| 1192 return; | 1159 return; |
| 1193 | 1160 |
| 1194 double_sided_ = double_sided; | 1161 double_sided_ = double_sided; |
| 1195 NoteLayerPropertyChangedForSubtree(); | 1162 NoteLayerPropertyChangedForSubtree(); |
| 1196 } | 1163 } |
| 1197 | 1164 |
| 1198 SimpleEnclosedRegion LayerImpl::VisibleContentOpaqueRegion() const { | 1165 SimpleEnclosedRegion LayerImpl::VisibleContentOpaqueRegion() const { |
| 1199 if (contents_opaque()) | 1166 if (contents_opaque()) |
| 1200 return SimpleEnclosedRegion(visible_content_rect()); | 1167 return SimpleEnclosedRegion(visible_content_rect()); |
| 1201 return SimpleEnclosedRegion(); | 1168 return SimpleEnclosedRegion(); |
| 1202 } | 1169 } |
| 1203 | 1170 |
| 1204 void LayerImpl::DidBeginTracing() {} | 1171 void LayerImpl::DidBeginTracing() {} |
| 1205 | 1172 |
| 1206 void LayerImpl::ReleaseResources() {} | 1173 void LayerImpl::ReleaseResources() {} |
| 1207 | 1174 |
| 1208 gfx::ScrollOffset LayerImpl::MaxScrollOffset() const { | 1175 gfx::ScrollOffset LayerImpl::MaxScrollOffset() const { |
| 1209 if (!scroll_clip_layer_ || bounds().IsEmpty()) | 1176 if (!scroll_clip_layer_ || bounds().IsEmpty()) |
| 1210 return gfx::ScrollOffset(); | 1177 return gfx::ScrollOffset(); |
| 1211 | 1178 |
| 1212 LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer(); | 1179 LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer(); |
| 1213 DCHECK(this != page_scale_layer); | 1180 DCHECK(this != page_scale_layer); |
| 1214 DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || | 1181 DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || |
| 1215 IsContainerForFixedPositionLayers()); | 1182 IsContainerForFixedPositionLayers()); |
| 1216 | 1183 |
| 1217 gfx::SizeF scaled_scroll_bounds(BoundsForScrolling()); | |
| 1218 | |
| 1219 float scale_factor = 1.f; | 1184 float scale_factor = 1.f; |
| 1220 for (LayerImpl const* current_layer = this; | 1185 for (LayerImpl const* current_layer = this; |
| 1221 current_layer != scroll_clip_layer_; | 1186 current_layer != scroll_clip_layer_->parent(); |
| 1222 current_layer = current_layer->parent()) { | 1187 current_layer = current_layer->parent()) { |
| 1223 DCHECK(current_layer); | 1188 if (current_layer == page_scale_layer) |
| 1224 float current_layer_scale = 1.f; | 1189 scale_factor = layer_tree_impl()->current_page_scale_factor(); |
| 1190 } |
| 1225 | 1191 |
| 1226 const gfx::Transform& layer_transform = current_layer->transform(); | 1192 gfx::SizeF scaled_scroll_bounds = |
| 1227 if (current_layer == page_scale_layer) { | 1193 gfx::ToFlooredSize(gfx::ScaleSize(BoundsForScrolling(), scale_factor)); |
| 1228 DCHECK(layer_transform.IsIdentity()); | |
| 1229 current_layer_scale = layer_tree_impl()->current_page_scale_factor(); | |
| 1230 } else { | |
| 1231 // TODO(wjmaclean) Should we allow for translation too? | |
| 1232 DCHECK(layer_transform.IsScale2d()); | |
| 1233 gfx::Vector2dF layer_scale = layer_transform.Scale2d(); | |
| 1234 // TODO(wjmaclean) Allow for non-isotropic scales. | |
| 1235 DCHECK(layer_scale.x() == layer_scale.y()); | |
| 1236 current_layer_scale = layer_scale.x(); | |
| 1237 } | |
| 1238 | |
| 1239 scale_factor *= current_layer_scale; | |
| 1240 } | |
| 1241 // TODO(wjmaclean) Once we move to a model where the two-viewport model is | |
| 1242 // turned on in all builds, remove the next two lines. For now however, the | |
| 1243 // page scale layer may coincide with the clip layer, and so this is | |
| 1244 // necessary. | |
| 1245 if (page_scale_layer == scroll_clip_layer_) | |
| 1246 scale_factor *= layer_tree_impl()->current_page_scale_factor(); | |
| 1247 | |
| 1248 scaled_scroll_bounds.SetSize(scale_factor * scaled_scroll_bounds.width(), | |
| 1249 scale_factor * scaled_scroll_bounds.height()); | |
| 1250 scaled_scroll_bounds = gfx::ToFlooredSize(scaled_scroll_bounds); | 1194 scaled_scroll_bounds = gfx::ToFlooredSize(scaled_scroll_bounds); |
| 1251 | 1195 |
| 1252 gfx::ScrollOffset max_offset( | 1196 gfx::ScrollOffset max_offset( |
| 1253 scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), | 1197 scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), |
| 1254 scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); | 1198 scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); |
| 1255 // We need the final scroll offset to be in CSS coords. | 1199 // We need the final scroll offset to be in CSS coords. |
| 1256 max_offset.Scale(1 / scale_factor); | 1200 max_offset.Scale(1 / scale_factor); |
| 1257 max_offset.SetToMax(gfx::ScrollOffset()); | 1201 max_offset.SetToMax(gfx::ScrollOffset()); |
| 1258 return max_offset; | 1202 return max_offset; |
| 1259 } | 1203 } |
| 1260 | 1204 |
| 1205 gfx::ScrollOffset LayerImpl::ClampScrollOffsetToLimits( |
| 1206 gfx::ScrollOffset offset) const { |
| 1207 offset.SetToMin(MaxScrollOffset()); |
| 1208 offset.SetToMax(gfx::ScrollOffset()); |
| 1209 return offset; |
| 1210 } |
| 1211 |
| 1261 gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { | 1212 gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { |
| 1262 gfx::ScrollOffset max_offset = MaxScrollOffset(); | 1213 gfx::ScrollOffset old_offset = CurrentScrollOffset(); |
| 1263 gfx::ScrollOffset old_offset = TotalScrollOffset(); | 1214 gfx::ScrollOffset clamped_offset = ClampScrollOffsetToLimits(old_offset); |
| 1264 gfx::ScrollOffset clamped_offset = old_offset; | |
| 1265 | |
| 1266 clamped_offset.SetToMin(max_offset); | |
| 1267 clamped_offset.SetToMax(gfx::ScrollOffset()); | |
| 1268 gfx::Vector2dF delta = clamped_offset.DeltaFrom(old_offset); | 1215 gfx::Vector2dF delta = clamped_offset.DeltaFrom(old_offset); |
| 1269 if (!delta.IsZero()) | 1216 if (!delta.IsZero()) |
| 1270 ScrollBy(delta); | 1217 ScrollBy(delta); |
| 1271 | |
| 1272 return delta; | 1218 return delta; |
| 1273 } | 1219 } |
| 1274 | 1220 |
| 1275 void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, | 1221 void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, |
| 1276 LayerImpl* scrollbar_clip_layer, | 1222 LayerImpl* scrollbar_clip_layer, |
| 1277 bool on_resize) const { | 1223 bool on_resize) const { |
| 1278 DCHECK(scrollbar_layer); | 1224 DCHECK(scrollbar_layer); |
| 1279 LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer(); | 1225 LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer(); |
| 1280 | 1226 |
| 1281 DCHECK(this != page_scale_layer); | 1227 DCHECK(this != page_scale_layer); |
| 1282 DCHECK(scrollbar_clip_layer); | 1228 DCHECK(scrollbar_clip_layer); |
| 1283 gfx::RectF clip_rect(gfx::PointF(), | 1229 gfx::RectF clip_rect(gfx::PointF(), |
| 1284 scrollbar_clip_layer->BoundsForScrolling()); | 1230 scrollbar_clip_layer->BoundsForScrolling()); |
| 1285 | 1231 |
| 1286 // See comment in MaxScrollOffset() regarding the use of the content layer | 1232 // See comment in MaxScrollOffset() regarding the use of the content layer |
| 1287 // bounds here. | 1233 // bounds here. |
| 1288 gfx::RectF scroll_rect(gfx::PointF(), BoundsForScrolling()); | 1234 gfx::RectF scroll_rect(gfx::PointF(), BoundsForScrolling()); |
| 1289 | 1235 |
| 1290 if (scroll_rect.size().IsEmpty()) | 1236 if (scroll_rect.size().IsEmpty()) |
| 1291 return; | 1237 return; |
| 1292 | 1238 |
| 1293 // TODO(wjmaclean) This computation is nearly identical to the one in | |
| 1294 // MaxScrollOffset. Find some way to combine these. | |
| 1295 gfx::ScrollOffset current_offset; | 1239 gfx::ScrollOffset current_offset; |
| 1296 for (LayerImpl const* current_layer = this; | 1240 for (LayerImpl const* current_layer = this; |
| 1297 current_layer != scrollbar_clip_layer; | 1241 current_layer != scrollbar_clip_layer->parent(); |
| 1298 current_layer = current_layer->parent()) { | 1242 current_layer = current_layer->parent()) { |
| 1299 DCHECK(current_layer); | 1243 current_offset += current_layer->CurrentScrollOffset(); |
| 1300 const gfx::Transform& layer_transform = current_layer->transform(); | |
| 1301 if (current_layer == page_scale_layer) { | 1244 if (current_layer == page_scale_layer) { |
| 1302 DCHECK(layer_transform.IsIdentity()); | |
| 1303 float scale_factor = layer_tree_impl()->current_page_scale_factor(); | 1245 float scale_factor = layer_tree_impl()->current_page_scale_factor(); |
| 1304 current_offset.Scale(scale_factor); | 1246 current_offset.Scale(scale_factor); |
| 1305 scroll_rect.Scale(scale_factor); | 1247 scroll_rect.Scale(scale_factor); |
| 1306 } else { | |
| 1307 DCHECK(layer_transform.IsScale2d()); | |
| 1308 gfx::Vector2dF layer_scale = layer_transform.Scale2d(); | |
| 1309 DCHECK(layer_scale.x() == layer_scale.y()); | |
| 1310 gfx::ScrollOffset new_offset = ScrollOffsetWithDelta( | |
| 1311 current_layer->scroll_offset(), current_layer->ScrollDelta()); | |
| 1312 new_offset.Scale(layer_scale.x(), layer_scale.y()); | |
| 1313 current_offset += new_offset; | |
| 1314 } | 1248 } |
| 1315 } | 1249 } |
| 1316 // TODO(wjmaclean) Once we move to a model where the two-viewport model is | |
| 1317 // turned on in all builds, remove the next two lines. For now however, the | |
| 1318 // page scale layer may coincide with the clip layer, and so this is | |
| 1319 // necessary. | |
| 1320 if (page_scale_layer == scrollbar_clip_layer) { | |
| 1321 scroll_rect.Scale(layer_tree_impl()->current_page_scale_factor()); | |
| 1322 current_offset.Scale(layer_tree_impl()->current_page_scale_factor()); | |
| 1323 } | |
| 1324 | 1250 |
| 1325 bool scrollbar_needs_animation = false; | 1251 bool scrollbar_needs_animation = false; |
| 1326 scrollbar_needs_animation |= scrollbar_layer->SetVerticalAdjust( | 1252 scrollbar_needs_animation |= scrollbar_layer->SetVerticalAdjust( |
| 1327 scrollbar_clip_layer->bounds_delta().y()); | 1253 scrollbar_clip_layer->bounds_delta().y()); |
| 1328 if (scrollbar_layer->orientation() == HORIZONTAL) { | 1254 if (scrollbar_layer->orientation() == HORIZONTAL) { |
| 1329 float visible_ratio = clip_rect.width() / scroll_rect.width(); | 1255 float visible_ratio = clip_rect.width() / scroll_rect.width(); |
| 1330 scrollbar_needs_animation |= | 1256 scrollbar_needs_animation |= |
| 1331 scrollbar_layer->SetCurrentPos(current_offset.x()); | 1257 scrollbar_layer->SetCurrentPos(current_offset.x()); |
| 1332 scrollbar_needs_animation |= | 1258 scrollbar_needs_animation |= |
| 1333 scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width()); | 1259 scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width()); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 state->SetInteger("layer_id", id()); | 1391 state->SetInteger("layer_id", id()); |
| 1466 MathUtil::AddToTracedValue("bounds", bounds_, state); | 1392 MathUtil::AddToTracedValue("bounds", bounds_, state); |
| 1467 | 1393 |
| 1468 state->SetDouble("opacity", opacity()); | 1394 state->SetDouble("opacity", opacity()); |
| 1469 | 1395 |
| 1470 MathUtil::AddToTracedValue("position", position_, state); | 1396 MathUtil::AddToTracedValue("position", position_, state); |
| 1471 | 1397 |
| 1472 state->SetInteger("draws_content", DrawsContent()); | 1398 state->SetInteger("draws_content", DrawsContent()); |
| 1473 state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes()); | 1399 state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes()); |
| 1474 | 1400 |
| 1475 MathUtil::AddToTracedValue("scroll_offset", scroll_offset_, state); | 1401 MathUtil::AddToTracedValue( |
| 1402 "scroll_offset", scroll_offset_ ? scroll_offset_->Current(IsActive()) |
| 1403 : gfx::ScrollOffset(), |
| 1404 state); |
| 1405 |
| 1476 MathUtil::AddToTracedValue("transform_origin", transform_origin_, state); | 1406 MathUtil::AddToTracedValue("transform_origin", transform_origin_, state); |
| 1477 | 1407 |
| 1478 bool clipped; | 1408 bool clipped; |
| 1479 gfx::QuadF layer_quad = MathUtil::MapQuad( | 1409 gfx::QuadF layer_quad = MathUtil::MapQuad( |
| 1480 screen_space_transform(), | 1410 screen_space_transform(), |
| 1481 gfx::QuadF(gfx::Rect(content_bounds())), | 1411 gfx::QuadF(gfx::Rect(content_bounds())), |
| 1482 &clipped); | 1412 &clipped); |
| 1483 MathUtil::AddToTracedValue("layer_quad", layer_quad, state); | 1413 MathUtil::AddToTracedValue("layer_quad", layer_quad, state); |
| 1484 if (!touch_event_handler_region_.IsEmpty()) { | 1414 if (!touch_event_handler_region_.IsEmpty()) { |
| 1485 state->BeginArray("touch_event_handler_region"); | 1415 state->BeginArray("touch_event_handler_region"); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1603 SetNeedsPushProperties(); | 1533 SetNeedsPushProperties(); |
| 1604 layer_tree_impl()->set_needs_update_draw_properties(); | 1534 layer_tree_impl()->set_needs_update_draw_properties(); |
| 1605 if (should_have_render_surface) { | 1535 if (should_have_render_surface) { |
| 1606 render_surface_ = make_scoped_ptr(new RenderSurfaceImpl(this)); | 1536 render_surface_ = make_scoped_ptr(new RenderSurfaceImpl(this)); |
| 1607 return; | 1537 return; |
| 1608 } | 1538 } |
| 1609 render_surface_.reset(); | 1539 render_surface_.reset(); |
| 1610 } | 1540 } |
| 1611 | 1541 |
| 1612 } // namespace cc | 1542 } // namespace cc |
| OLD | NEW |