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/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "cc/animation/animation_registrar.h" | 10 #include "cc/animation/animation_registrar.h" |
11 #include "cc/animation/scrollbar_animation_controller.h" | 11 #include "cc/animation/scrollbar_animation_controller.h" |
12 #include "cc/animation/scrollbar_animation_controller_linear_fade.h" | 12 #include "cc/animation/scrollbar_animation_controller_linear_fade.h" |
13 #include "cc/animation/scrollbar_animation_controller_thinning.h" | 13 #include "cc/animation/scrollbar_animation_controller_thinning.h" |
14 #include "cc/base/math_util.h" | 14 #include "cc/base/math_util.h" |
15 #include "cc/debug/debug_colors.h" | 15 #include "cc/debug/debug_colors.h" |
16 #include "cc/debug/layer_tree_debug_state.h" | 16 #include "cc/debug/layer_tree_debug_state.h" |
17 #include "cc/debug/micro_benchmark_impl.h" | 17 #include "cc/debug/micro_benchmark_impl.h" |
18 #include "cc/debug/traced_value.h" | 18 #include "cc/debug/traced_value.h" |
19 #include "cc/input/layer_scroll_offset_delegate.h" | 19 #include "cc/input/layer_scroll_offset_delegate.h" |
20 #include "cc/layers/layer_utils.h" | 20 #include "cc/layers/layer_utils.h" |
21 #include "cc/layers/painted_scrollbar_layer_impl.h" | 21 #include "cc/layers/painted_scrollbar_layer_impl.h" |
22 #include "cc/layers/quad_sink.h" | 22 #include "cc/layers/quad_sink.h" |
23 #include "cc/output/copy_output_request.h" | 23 #include "cc/output/copy_output_request.h" |
24 #include "cc/quads/debug_border_draw_quad.h" | 24 #include "cc/quads/debug_border_draw_quad.h" |
25 #include "cc/trees/layer_tree_host_common.h" | 25 #include "cc/trees/layer_tree_host_common.h" |
26 #include "cc/trees/layer_tree_impl.h" | 26 #include "cc/trees/layer_tree_impl.h" |
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/box_f.h" | 29 #include "ui/gfx/box_f.h" |
30 #include "ui/gfx/geometry/vector2d_conversions.h" | |
31 #include "ui/gfx/point_conversions.h" | 30 #include "ui/gfx/point_conversions.h" |
32 #include "ui/gfx/quad_f.h" | 31 #include "ui/gfx/quad_f.h" |
33 #include "ui/gfx/rect_conversions.h" | 32 #include "ui/gfx/rect_conversions.h" |
34 | 33 |
35 namespace cc { | 34 namespace cc { |
36 LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) | 35 LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) |
37 : parent_(NULL), | 36 : parent_(NULL), |
38 scroll_parent_(NULL), | 37 scroll_parent_(NULL), |
39 clip_parent_(NULL), | 38 clip_parent_(NULL), |
40 mask_layer_id_(-1), | 39 mask_layer_id_(-1), |
41 replica_layer_id_(-1), | 40 replica_layer_id_(-1), |
42 layer_id_(id), | 41 layer_id_(id), |
43 layer_tree_impl_(tree_impl), | 42 layer_tree_impl_(tree_impl), |
44 anchor_point_(0.5f, 0.5f), | 43 anchor_point_(0.5f, 0.5f), |
45 anchor_point_z_(0.f), | 44 anchor_point_z_(0.f), |
46 scroll_offset_delegate_(NULL), | 45 scroll_offset_delegate_(NULL), |
47 scroll_clip_layer_(NULL), | 46 scrollable_(false), |
48 should_scroll_on_main_thread_(false), | 47 should_scroll_on_main_thread_(false), |
49 have_wheel_event_handlers_(false), | 48 have_wheel_event_handlers_(false), |
50 user_scrollable_horizontal_(true), | 49 user_scrollable_horizontal_(true), |
51 user_scrollable_vertical_(true), | 50 user_scrollable_vertical_(true), |
52 stacking_order_changed_(false), | 51 stacking_order_changed_(false), |
53 double_sided_(true), | 52 double_sided_(true), |
54 layer_property_changed_(false), | 53 layer_property_changed_(false), |
55 masks_to_bounds_(false), | 54 masks_to_bounds_(false), |
56 contents_opaque_(false), | 55 contents_opaque_(false), |
57 is_root_for_isolated_group_(false), | 56 is_root_for_isolated_group_(false), |
58 preserves_3d_(false), | 57 preserves_3d_(false), |
59 use_parent_backface_visibility_(false), | 58 use_parent_backface_visibility_(false), |
60 draw_checkerboard_for_missing_tiles_(false), | 59 draw_checkerboard_for_missing_tiles_(false), |
61 draws_content_(false), | 60 draws_content_(false), |
62 hide_layer_and_subtree_(false), | 61 hide_layer_and_subtree_(false), |
63 force_render_surface_(false), | 62 force_render_surface_(false), |
64 is_container_for_fixed_position_layers_(false), | 63 is_container_for_fixed_position_layers_(false), |
65 background_color_(0), | 64 background_color_(0), |
66 opacity_(1.0), | 65 opacity_(1.0), |
67 blend_mode_(SkXfermode::kSrcOver_Mode), | 66 blend_mode_(SkXfermode::kSrcOver_Mode), |
68 draw_depth_(0.f), | 67 draw_depth_(0.f), |
69 needs_push_properties_(false), | 68 needs_push_properties_(false), |
70 num_dependents_need_push_properties_(0), | 69 num_dependents_need_push_properties_(0), |
71 current_draw_mode_(DRAW_MODE_NONE) { | 70 current_draw_mode_(DRAW_MODE_NONE), |
| 71 horizontal_scrollbar_layer_(NULL), |
| 72 vertical_scrollbar_layer_(NULL) { |
72 DCHECK_GT(layer_id_, 0); | 73 DCHECK_GT(layer_id_, 0); |
73 DCHECK(layer_tree_impl_); | 74 DCHECK(layer_tree_impl_); |
74 layer_tree_impl_->RegisterLayer(this); | 75 layer_tree_impl_->RegisterLayer(this); |
75 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); | 76 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); |
76 layer_animation_controller_ = | 77 layer_animation_controller_ = |
77 registrar->GetAnimationControllerForId(layer_id_); | 78 registrar->GetAnimationControllerForId(layer_id_); |
78 layer_animation_controller_->AddValueObserver(this); | 79 layer_animation_controller_->AddValueObserver(this); |
79 if (IsActive()) | 80 if (IsActive()) |
80 layer_animation_controller_->set_value_provider(this); | 81 layer_animation_controller_->set_value_provider(this); |
81 SetNeedsPushProperties(); | 82 SetNeedsPushProperties(); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 | 374 |
374 if (sent_scroll_delta_ == sent_scroll_delta) | 375 if (sent_scroll_delta_ == sent_scroll_delta) |
375 return; | 376 return; |
376 | 377 |
377 sent_scroll_delta_ = sent_scroll_delta; | 378 sent_scroll_delta_ = sent_scroll_delta; |
378 } | 379 } |
379 | 380 |
380 gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { | 381 gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { |
381 DCHECK(scrollable()); | 382 DCHECK(scrollable()); |
382 gfx::Vector2dF min_delta = -scroll_offset_; | 383 gfx::Vector2dF min_delta = -scroll_offset_; |
383 gfx::Vector2dF max_delta = MaxScrollOffset() - scroll_offset_; | 384 gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_; |
384 // Clamp new_delta so that position + delta stays within scroll bounds. | 385 // Clamp new_delta so that position + delta stays within scroll bounds. |
385 gfx::Vector2dF new_delta = (ScrollDelta() + scroll); | 386 gfx::Vector2dF new_delta = (ScrollDelta() + scroll); |
386 new_delta.SetToMax(min_delta); | 387 new_delta.SetToMax(min_delta); |
387 new_delta.SetToMin(max_delta); | 388 new_delta.SetToMin(max_delta); |
388 gfx::Vector2dF unscrolled = | 389 gfx::Vector2dF unscrolled = |
389 ScrollDelta() + scroll - new_delta; | 390 ScrollDelta() + scroll - new_delta; |
390 SetScrollDelta(new_delta); | 391 SetScrollDelta(new_delta); |
391 | |
392 return unscrolled; | 392 return unscrolled; |
393 } | 393 } |
394 | 394 |
395 void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { | |
396 scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id); | |
397 } | |
398 | |
399 void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { | 395 void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { |
400 // Pending tree never has sent scroll deltas | 396 // Pending tree never has sent scroll deltas |
401 DCHECK(layer_tree_impl()->IsActiveTree()); | 397 DCHECK(layer_tree_impl()->IsActiveTree()); |
402 | 398 |
403 // Apply sent scroll deltas to scroll position / scroll delta as if the | 399 // Apply sent scroll deltas to scroll position / scroll delta as if the |
404 // main thread had applied them and then committed those values. | 400 // main thread had applied them and then committed those values. |
405 // | 401 // |
406 // This function should not change the total scroll offset; it just shifts | 402 // This function should not change the total scroll offset; it just shifts |
407 // some of the scroll delta to the scroll offset. Therefore, adjust these | 403 // some of the scroll delta to the scroll offset. Therefore, adjust these |
408 // variables directly rather than calling the scroll offset delegate to | 404 // variables directly rather than calling the scroll offset delegate to |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 if (type == InputHandler::Wheel && have_wheel_event_handlers()) { | 474 if (type == InputHandler::Wheel && have_wheel_event_handlers()) { |
479 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); | 475 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); |
480 return InputHandler::ScrollOnMainThread; | 476 return InputHandler::ScrollOnMainThread; |
481 } | 477 } |
482 | 478 |
483 if (!scrollable()) { | 479 if (!scrollable()) { |
484 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); | 480 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); |
485 return InputHandler::ScrollIgnored; | 481 return InputHandler::ScrollIgnored; |
486 } | 482 } |
487 | 483 |
488 gfx::Vector2d max_scroll_offset = MaxScrollOffset(); | 484 if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { |
489 if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0) { | |
490 TRACE_EVENT0("cc", | 485 TRACE_EVENT0("cc", |
491 "LayerImpl::tryScroll: Ignored. Technically scrollable," | 486 "LayerImpl::tryScroll: Ignored. Technically scrollable," |
492 " but has no affordance in either direction."); | 487 " but has no affordance in either direction."); |
493 return InputHandler::ScrollIgnored; | 488 return InputHandler::ScrollIgnored; |
494 } | 489 } |
495 | 490 |
496 return InputHandler::ScrollStarted; | 491 return InputHandler::ScrollStarted; |
497 } | 492 } |
498 | 493 |
499 bool LayerImpl::DrawCheckerboardForMissingTiles() const { | 494 bool LayerImpl::DrawCheckerboardForMissingTiles() const { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 layer->SetPosition(position_); | 545 layer->SetPosition(position_); |
551 layer->SetIsContainerForFixedPositionLayers( | 546 layer->SetIsContainerForFixedPositionLayers( |
552 is_container_for_fixed_position_layers_); | 547 is_container_for_fixed_position_layers_); |
553 layer->SetFixedContainerSizeDelta(fixed_container_size_delta_); | 548 layer->SetFixedContainerSizeDelta(fixed_container_size_delta_); |
554 layer->SetPositionConstraint(position_constraint_); | 549 layer->SetPositionConstraint(position_constraint_); |
555 layer->SetPreserves3d(preserves_3d()); | 550 layer->SetPreserves3d(preserves_3d()); |
556 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); | 551 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); |
557 layer->SetSublayerTransform(sublayer_transform_); | 552 layer->SetSublayerTransform(sublayer_transform_); |
558 layer->SetTransform(transform_); | 553 layer->SetTransform(transform_); |
559 | 554 |
560 layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() | 555 layer->SetScrollable(scrollable_); |
561 : Layer::INVALID_ID); | |
562 layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); | 556 layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); |
563 layer->set_user_scrollable_vertical(user_scrollable_vertical_); | 557 layer->set_user_scrollable_vertical(user_scrollable_vertical_); |
564 layer->SetScrollOffsetAndDelta( | 558 layer->SetScrollOffsetAndDelta( |
565 scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta()); | 559 scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta()); |
566 layer->SetSentScrollDelta(gfx::Vector2d()); | 560 layer->SetSentScrollDelta(gfx::Vector2d()); |
567 | 561 |
| 562 layer->SetMaxScrollOffset(max_scroll_offset_); |
| 563 |
568 LayerImpl* scroll_parent = NULL; | 564 LayerImpl* scroll_parent = NULL; |
569 if (scroll_parent_) | 565 if (scroll_parent_) |
570 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); | 566 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); |
571 | 567 |
572 layer->SetScrollParent(scroll_parent); | 568 layer->SetScrollParent(scroll_parent); |
573 if (scroll_children_) { | 569 if (scroll_children_) { |
574 std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; | 570 std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; |
575 for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); | 571 for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); |
576 it != scroll_children_->end(); ++it) | 572 it != scroll_children_->end(); ++it) |
577 scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); | 573 scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 gfx_transform.matrix().asColMajord(transform); | 627 gfx_transform.matrix().asColMajord(transform); |
632 list = new base::ListValue; | 628 list = new base::ListValue; |
633 for (int i = 0; i < 16; ++i) | 629 for (int i = 0; i < 16; ++i) |
634 list->AppendDouble(transform[i]); | 630 list->AppendDouble(transform[i]); |
635 result->Set("DrawTransform", list); | 631 result->Set("DrawTransform", list); |
636 | 632 |
637 result->SetBoolean("DrawsContent", draws_content_); | 633 result->SetBoolean("DrawsContent", draws_content_); |
638 result->SetDouble("Opacity", opacity()); | 634 result->SetDouble("Opacity", opacity()); |
639 result->SetBoolean("ContentsOpaque", contents_opaque_); | 635 result->SetBoolean("ContentsOpaque", contents_opaque_); |
640 | 636 |
641 if (scrollable()) | 637 if (scrollable_) |
642 result->SetBoolean("Scrollable", true); | 638 result->SetBoolean("Scrollable", scrollable_); |
643 | 639 |
644 if (have_wheel_event_handlers_) | 640 if (have_wheel_event_handlers_) |
645 result->SetBoolean("WheelHandler", have_wheel_event_handlers_); | 641 result->SetBoolean("WheelHandler", have_wheel_event_handlers_); |
646 if (!touch_event_handler_region_.IsEmpty()) { | 642 if (!touch_event_handler_region_.IsEmpty()) { |
647 scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue(); | 643 scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue(); |
648 result->Set("TouchRegion", region.release()); | 644 result->Set("TouchRegion", region.release()); |
649 } | 645 } |
650 | 646 |
651 list = new base::ListValue; | 647 list = new base::ListValue; |
652 for (size_t i = 0; i < children_.size(); ++i) | 648 for (size_t i = 0; i < children_.size(); ++i) |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 bool LayerImpl::IsActive() const { | 750 bool LayerImpl::IsActive() const { |
755 return layer_tree_impl_->IsActiveTree(); | 751 return layer_tree_impl_->IsActiveTree(); |
756 } | 752 } |
757 | 753 |
758 void LayerImpl::SetBounds(gfx::Size bounds) { | 754 void LayerImpl::SetBounds(gfx::Size bounds) { |
759 if (bounds_ == bounds) | 755 if (bounds_ == bounds) |
760 return; | 756 return; |
761 | 757 |
762 bounds_ = bounds; | 758 bounds_ = bounds; |
763 | 759 |
764 ScrollbarParametersDidChange(); | |
765 if (masks_to_bounds()) | 760 if (masks_to_bounds()) |
766 NoteLayerPropertyChangedForSubtree(); | 761 NoteLayerPropertyChangedForSubtree(); |
767 else | 762 else |
768 NoteLayerPropertyChanged(); | 763 NoteLayerPropertyChanged(); |
769 } | 764 } |
770 | 765 |
771 void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { | 766 void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { |
772 int new_layer_id = mask_layer ? mask_layer->id() : -1; | 767 int new_layer_id = mask_layer ? mask_layer->id() : -1; |
773 | 768 |
774 if (mask_layer) { | 769 if (mask_layer) { |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 float* contents_scale_x, | 1023 float* contents_scale_x, |
1029 float* contents_scale_y, | 1024 float* contents_scale_y, |
1030 gfx::Size* content_bounds) { | 1025 gfx::Size* content_bounds) { |
1031 // Base LayerImpl has all of its content scales and content bounds pushed | 1026 // Base LayerImpl has all of its content scales and content bounds pushed |
1032 // from its Layer during commit and just reuses those values as-is. | 1027 // from its Layer during commit and just reuses those values as-is. |
1033 *contents_scale_x = this->contents_scale_x(); | 1028 *contents_scale_x = this->contents_scale_x(); |
1034 *contents_scale_y = this->contents_scale_y(); | 1029 *contents_scale_y = this->contents_scale_y(); |
1035 *content_bounds = this->content_bounds(); | 1030 *content_bounds = this->content_bounds(); |
1036 } | 1031 } |
1037 | 1032 |
| 1033 void LayerImpl::UpdateScrollbarPositions() { |
| 1034 gfx::Vector2dF current_offset = scroll_offset_ + ScrollDelta(); |
| 1035 |
| 1036 gfx::RectF viewport(PointAtOffsetFromOrigin(current_offset), bounds_); |
| 1037 gfx::SizeF scrollable_size(max_scroll_offset_.x() + bounds_.width(), |
| 1038 max_scroll_offset_.y() + bounds_.height()); |
| 1039 if (horizontal_scrollbar_layer_) { |
| 1040 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); |
| 1041 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); |
| 1042 horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio( |
| 1043 viewport.width() / scrollable_size.width()); |
| 1044 } |
| 1045 if (vertical_scrollbar_layer_) { |
| 1046 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); |
| 1047 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); |
| 1048 vertical_scrollbar_layer_->SetVisibleToTotalLengthRatio( |
| 1049 viewport.height() / scrollable_size.height()); |
| 1050 } |
| 1051 |
| 1052 if (current_offset == last_scroll_offset_) |
| 1053 return; |
| 1054 last_scroll_offset_ = current_offset; |
| 1055 |
| 1056 if (scrollbar_animation_controller_) { |
| 1057 bool should_animate = scrollbar_animation_controller_->DidScrollUpdate( |
| 1058 layer_tree_impl_->CurrentPhysicalTimeTicks()); |
| 1059 if (should_animate) |
| 1060 layer_tree_impl_->StartScrollbarAnimation(); |
| 1061 } |
| 1062 |
| 1063 // Get the current_offset_.y() value for a sanity-check on scrolling |
| 1064 // benchmark metrics. Specifically, we want to make sure |
| 1065 // BasicMouseWheelSmoothScrollGesture has proper scroll curves. |
| 1066 if (layer_tree_impl()->IsActiveTree()) { |
| 1067 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); |
| 1068 } |
| 1069 } |
| 1070 |
1038 void LayerImpl::SetScrollOffsetDelegate( | 1071 void LayerImpl::SetScrollOffsetDelegate( |
1039 LayerScrollOffsetDelegate* scroll_offset_delegate) { | 1072 LayerScrollOffsetDelegate* scroll_offset_delegate) { |
1040 // Having both a scroll parent and a scroll offset delegate is unsupported. | 1073 // Having both a scroll parent and a scroll offset delegate is unsupported. |
1041 DCHECK(!scroll_parent_); | 1074 DCHECK(!scroll_parent_); |
1042 if (!scroll_offset_delegate && scroll_offset_delegate_) { | 1075 if (!scroll_offset_delegate && scroll_offset_delegate_) { |
1043 scroll_delta_ = | 1076 scroll_delta_ = |
1044 scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; | 1077 scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; |
1045 } | 1078 } |
1046 gfx::Vector2dF total_offset = TotalScrollOffset(); | 1079 gfx::Vector2dF total_offset = TotalScrollOffset(); |
1047 scroll_offset_delegate_ = scroll_offset_delegate; | 1080 scroll_offset_delegate_ = scroll_offset_delegate; |
1048 if (scroll_offset_delegate_) | 1081 if (scroll_offset_delegate_) { |
| 1082 scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); |
1049 scroll_offset_delegate_->SetTotalScrollOffset(total_offset); | 1083 scroll_offset_delegate_->SetTotalScrollOffset(total_offset); |
| 1084 } |
1050 } | 1085 } |
1051 | 1086 |
1052 bool LayerImpl::IsExternalFlingActive() const { | 1087 bool LayerImpl::IsExternalFlingActive() const { |
1053 return scroll_offset_delegate_ && | 1088 return scroll_offset_delegate_ && |
1054 scroll_offset_delegate_->IsExternalFlingActive(); | 1089 scroll_offset_delegate_->IsExternalFlingActive(); |
1055 } | 1090 } |
1056 | 1091 |
1057 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { | 1092 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { |
1058 SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); | 1093 SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); |
1059 } | 1094 } |
1060 | 1095 |
1061 void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset, | 1096 void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset, |
1062 const gfx::Vector2dF& scroll_delta) { | 1097 const gfx::Vector2dF& scroll_delta) { |
1063 bool changed = false; | 1098 bool changed = false; |
1064 | 1099 |
1065 last_scroll_offset_ = scroll_offset; | |
1066 | |
1067 if (scroll_offset_ != scroll_offset) { | 1100 if (scroll_offset_ != scroll_offset) { |
1068 changed = true; | 1101 changed = true; |
1069 scroll_offset_ = scroll_offset; | 1102 scroll_offset_ = scroll_offset; |
1070 | 1103 |
1071 if (scroll_offset_delegate_) | 1104 if (scroll_offset_delegate_) |
1072 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); | 1105 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); |
1073 } | 1106 } |
1074 | 1107 |
1075 if (ScrollDelta() != scroll_delta) { | 1108 if (ScrollDelta() != scroll_delta) { |
1076 changed = true; | 1109 changed = true; |
(...skipping 14 matching lines...) Expand all Loading... |
1091 if (scroll_offset_delegate_) { | 1124 if (scroll_offset_delegate_) { |
1092 scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ + | 1125 scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ + |
1093 scroll_delta); | 1126 scroll_delta); |
1094 } else { | 1127 } else { |
1095 scroll_delta_ = scroll_delta; | 1128 scroll_delta_ = scroll_delta; |
1096 } | 1129 } |
1097 } | 1130 } |
1098 | 1131 |
1099 if (changed) { | 1132 if (changed) { |
1100 NoteLayerPropertyChangedForSubtree(); | 1133 NoteLayerPropertyChangedForSubtree(); |
1101 ScrollbarParametersDidChange(); | 1134 UpdateScrollbarPositions(); |
1102 } | 1135 } |
1103 } | 1136 } |
1104 | 1137 |
1105 gfx::Vector2dF LayerImpl::ScrollDelta() const { | 1138 gfx::Vector2dF LayerImpl::ScrollDelta() const { |
1106 if (scroll_offset_delegate_) | 1139 if (scroll_offset_delegate_) |
1107 return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; | 1140 return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; |
1108 return scroll_delta_; | 1141 return scroll_delta_; |
1109 } | 1142 } |
1110 | 1143 |
1111 void LayerImpl::SetScrollDelta(const gfx::Vector2dF& scroll_delta) { | 1144 void LayerImpl::SetScrollDelta(const gfx::Vector2dF& scroll_delta) { |
(...skipping 15 matching lines...) Expand all Loading... |
1127 Region LayerImpl::VisibleContentOpaqueRegion() const { | 1160 Region LayerImpl::VisibleContentOpaqueRegion() const { |
1128 if (contents_opaque()) | 1161 if (contents_opaque()) |
1129 return visible_content_rect(); | 1162 return visible_content_rect(); |
1130 return Region(); | 1163 return Region(); |
1131 } | 1164 } |
1132 | 1165 |
1133 void LayerImpl::DidBeginTracing() {} | 1166 void LayerImpl::DidBeginTracing() {} |
1134 | 1167 |
1135 void LayerImpl::ReleaseResources() {} | 1168 void LayerImpl::ReleaseResources() {} |
1136 | 1169 |
1137 gfx::Vector2d LayerImpl::MaxScrollOffset() const { | 1170 void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { |
1138 if (!scroll_clip_layer_ || bounds().IsEmpty()) | 1171 if (max_scroll_offset_ == max_scroll_offset) |
1139 return gfx::Vector2d(); | 1172 return; |
| 1173 max_scroll_offset_ = max_scroll_offset; |
1140 | 1174 |
1141 LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer(); | 1175 if (scroll_offset_delegate_) |
1142 DCHECK(this != page_scale_layer); | 1176 scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); |
1143 DCHECK(scroll_clip_layer_); | |
1144 DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || | |
1145 IsContainerForFixedPositionLayers()); | |
1146 | |
1147 gfx::Size scaled_scroll_bounds(bounds()); | |
1148 | |
1149 float scale_factor = 1.f; | |
1150 for (LayerImpl const* current_layer = this; | |
1151 current_layer != scroll_clip_layer_; | |
1152 current_layer = current_layer->parent()) { | |
1153 DCHECK(current_layer); | |
1154 float current_layer_scale = 1.f; | |
1155 | |
1156 const gfx::Transform& layer_transform = current_layer->transform(); | |
1157 if (current_layer == page_scale_layer) { | |
1158 DCHECK(layer_transform.IsIdentity()); | |
1159 current_layer_scale = layer_tree_impl()->total_page_scale_factor(); | |
1160 } else { | |
1161 // TODO(wjmaclean) Should we allow for translation too? | |
1162 DCHECK(layer_transform.IsScale2d()); | |
1163 gfx::Vector2dF layer_scale = layer_transform.Scale2d(); | |
1164 // TODO(wjmaclean) Allow for non-isotropic scales. | |
1165 DCHECK(layer_scale.x() == layer_scale.y()); | |
1166 current_layer_scale = layer_scale.x(); | |
1167 } | |
1168 | |
1169 scale_factor *= current_layer_scale; | |
1170 } | |
1171 // TODO(wjmaclean) Once we move to a model where the two-viewport model is | |
1172 // turned on in all builds, remove the next two lines. For now however, the | |
1173 // page scale layer may coincide with the clip layer, and so this is | |
1174 // necessary. | |
1175 if (page_scale_layer == scroll_clip_layer_) | |
1176 scale_factor *= layer_tree_impl()->total_page_scale_factor(); | |
1177 | |
1178 scaled_scroll_bounds.SetSize( | |
1179 scale_factor * scaled_scroll_bounds.width(), | |
1180 scale_factor * scaled_scroll_bounds.height()); | |
1181 | |
1182 gfx::RectF clip_rect(gfx::PointF(), scroll_clip_layer_->bounds()); | |
1183 if (this == layer_tree_impl()->InnerViewportScrollLayer()) | |
1184 clip_rect = | |
1185 gfx::RectF(gfx::PointF(), layer_tree_impl()->ScrollableViewportSize()); | |
1186 gfx::Vector2dF max_offset( | |
1187 scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), | |
1188 scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); | |
1189 // We need the final scroll offset to be in CSS coords. | |
1190 max_offset.Scale(1 / scale_factor); | |
1191 max_offset.SetToMax(gfx::Vector2dF()); | |
1192 return gfx::ToFlooredVector2d(max_offset); | |
1193 } | |
1194 | |
1195 gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { | |
1196 gfx::Vector2dF max_offset = MaxScrollOffset(); | |
1197 gfx::Vector2dF old_offset = TotalScrollOffset(); | |
1198 gfx::Vector2dF clamped_offset = old_offset; | |
1199 | |
1200 clamped_offset.SetToMin(max_offset); | |
1201 clamped_offset.SetToMax(gfx::Vector2d()); | |
1202 gfx::Vector2dF delta = clamped_offset - old_offset; | |
1203 if (!delta.IsZero()) | |
1204 ScrollBy(delta); | |
1205 | |
1206 return delta; | |
1207 } | |
1208 | |
1209 void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, | |
1210 LayerImpl* scrollbar_clip_layer) const { | |
1211 DCHECK(scrollbar_layer); | |
1212 LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer(); | |
1213 | |
1214 DCHECK(this != page_scale_layer); | |
1215 DCHECK(scrollbar_clip_layer); | |
1216 DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() | |
1217 || IsContainerForFixedPositionLayers()); | |
1218 gfx::RectF clip_rect(gfx::PointF(), scrollbar_clip_layer->bounds()); | |
1219 | |
1220 // See comment in MaxScrollOffset() regarding the use of the content layer | |
1221 // bounds here. | |
1222 gfx::RectF scroll_rect(gfx::PointF(), bounds()); | |
1223 | |
1224 if (scroll_rect.size().IsEmpty()) | |
1225 return; | |
1226 | |
1227 // TODO(wjmaclean) This computation is nearly identical to the one in | |
1228 // MaxScrollOffset. Find some way to combine these. | |
1229 gfx::Vector2dF current_offset; | |
1230 for (LayerImpl const* current_layer = this; | |
1231 current_layer != scrollbar_clip_layer; | |
1232 current_layer = current_layer->parent()) { | |
1233 DCHECK(current_layer); | |
1234 const gfx::Transform& layer_transform = current_layer->transform(); | |
1235 if (current_layer == page_scale_layer) { | |
1236 DCHECK(layer_transform.IsIdentity()); | |
1237 float scale_factor = layer_tree_impl()->total_page_scale_factor(); | |
1238 current_offset.Scale(scale_factor); | |
1239 scroll_rect.Scale(scale_factor); | |
1240 } else { | |
1241 DCHECK(layer_transform.IsScale2d()); | |
1242 gfx::Vector2dF layer_scale = layer_transform.Scale2d(); | |
1243 DCHECK(layer_scale.x() == layer_scale.y()); | |
1244 gfx::Vector2dF new_offset = | |
1245 current_layer->scroll_offset() + current_layer->ScrollDelta(); | |
1246 new_offset.Scale(layer_scale.x(), layer_scale.y()); | |
1247 current_offset += new_offset; | |
1248 } | |
1249 } | |
1250 // TODO(wjmaclean) Once we move to a model where the two-viewport model is | |
1251 // turned on in all builds, remove the next two lines. For now however, the | |
1252 // page scale layer may coincide with the clip layer, and so this is | |
1253 // necessary. | |
1254 if (page_scale_layer == scrollbar_clip_layer) | |
1255 scroll_rect.Scale(layer_tree_impl()->total_page_scale_factor()); | |
1256 | |
1257 scrollbar_layer->SetVerticalAdjust(layer_tree_impl()->VerticalAdjust(this)); | |
1258 if (scrollbar_layer->orientation() == HORIZONTAL) { | |
1259 float visible_ratio = clip_rect.width() / scroll_rect.width(); | |
1260 scrollbar_layer->SetCurrentPos(current_offset.x()); | |
1261 scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width()); | |
1262 scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); | |
1263 } else { | |
1264 float visible_ratio = clip_rect.height() / scroll_rect.height(); | |
1265 scrollbar_layer->SetCurrentPos(current_offset.y()); | |
1266 scrollbar_layer->SetMaximum(scroll_rect.height() - clip_rect.height()); | |
1267 scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); | |
1268 } | |
1269 | 1177 |
1270 layer_tree_impl()->set_needs_update_draw_properties(); | 1178 layer_tree_impl()->set_needs_update_draw_properties(); |
1271 // TODO(wjmaclean) Should the rest of this function be deleted? | 1179 UpdateScrollbarPositions(); |
1272 // TODO(wjmaclean) The scrollbar animator for the pinch-zoom scrollbars should | 1180 SetNeedsPushProperties(); |
1273 // activate for every scroll on the main frame, not just the scrolls that move | |
1274 // the pinch virtual viewport (i.e. trigger from either inner or outer | |
1275 // viewport). | |
1276 if (scrollbar_animation_controller_) { | |
1277 bool should_animate = scrollbar_animation_controller_->DidScrollUpdate( | |
1278 layer_tree_impl_->CurrentPhysicalTimeTicks()); | |
1279 if (should_animate) | |
1280 layer_tree_impl_->StartScrollbarAnimation(); | |
1281 } | |
1282 } | 1181 } |
1283 | 1182 |
1284 void LayerImpl::DidBecomeActive() { | 1183 void LayerImpl::DidBecomeActive() { |
1285 if (layer_tree_impl_->settings().scrollbar_animator == | 1184 if (layer_tree_impl_->settings().scrollbar_animator == |
1286 LayerTreeSettings::NoAnimator) { | 1185 LayerTreeSettings::NoAnimator) { |
1287 return; | 1186 return; |
1288 } | 1187 } |
1289 | 1188 |
1290 bool need_scrollbar_animation_controller = scrollable() && scrollbars_; | 1189 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || |
| 1190 vertical_scrollbar_layer_; |
1291 if (!need_scrollbar_animation_controller) { | 1191 if (!need_scrollbar_animation_controller) { |
1292 scrollbar_animation_controller_.reset(); | 1192 scrollbar_animation_controller_.reset(); |
1293 return; | 1193 return; |
1294 } | 1194 } |
1295 | 1195 |
1296 if (scrollbar_animation_controller_) | 1196 if (scrollbar_animation_controller_) |
1297 return; | 1197 return; |
1298 | 1198 |
1299 switch (layer_tree_impl_->settings().scrollbar_animator) { | 1199 switch (layer_tree_impl_->settings().scrollbar_animator) { |
1300 case LayerTreeSettings::LinearFade: { | 1200 case LayerTreeSettings::LinearFade: { |
(...skipping 13 matching lines...) Expand all Loading... |
1314 ScrollbarAnimationControllerThinning::Create(this) | 1214 ScrollbarAnimationControllerThinning::Create(this) |
1315 .PassAs<ScrollbarAnimationController>(); | 1215 .PassAs<ScrollbarAnimationController>(); |
1316 break; | 1216 break; |
1317 } | 1217 } |
1318 case LayerTreeSettings::NoAnimator: | 1218 case LayerTreeSettings::NoAnimator: |
1319 NOTREACHED(); | 1219 NOTREACHED(); |
1320 break; | 1220 break; |
1321 } | 1221 } |
1322 } | 1222 } |
1323 | 1223 |
1324 void LayerImpl::ClearScrollbars() { | 1224 void LayerImpl::SetHorizontalScrollbarLayer( |
1325 if (!scrollbars_) | 1225 ScrollbarLayerImplBase* scrollbar_layer) { |
1326 return; | 1226 horizontal_scrollbar_layer_ = scrollbar_layer; |
1327 | 1227 if (horizontal_scrollbar_layer_) |
1328 scrollbars_.reset(NULL); | 1228 horizontal_scrollbar_layer_->set_scroll_layer_id(id()); |
1329 } | 1229 } |
1330 | 1230 |
1331 void LayerImpl::AddScrollbar(ScrollbarLayerImplBase* layer) { | 1231 void LayerImpl::SetVerticalScrollbarLayer( |
1332 DCHECK(layer); | 1232 ScrollbarLayerImplBase* scrollbar_layer) { |
1333 DCHECK(!scrollbars_ || scrollbars_->find(layer) == scrollbars_->end()); | 1233 vertical_scrollbar_layer_ = scrollbar_layer; |
1334 if (!scrollbars_) | 1234 if (vertical_scrollbar_layer_) |
1335 scrollbars_.reset(new ScrollbarSet()); | 1235 vertical_scrollbar_layer_->set_scroll_layer_id(id()); |
1336 | |
1337 scrollbars_->insert(layer); | |
1338 } | |
1339 | |
1340 void LayerImpl::RemoveScrollbar(ScrollbarLayerImplBase* layer) { | |
1341 DCHECK(scrollbars_); | |
1342 DCHECK(layer); | |
1343 DCHECK(scrollbars_->find(layer) != scrollbars_->end()); | |
1344 | |
1345 scrollbars_->erase(layer); | |
1346 if (scrollbars_->empty()) | |
1347 scrollbars_.reset(); | |
1348 } | |
1349 | |
1350 bool LayerImpl::HasScrollbar(ScrollbarOrientation orientation) const { | |
1351 if (!scrollbars_) | |
1352 return false; | |
1353 | |
1354 for (ScrollbarSet::iterator it = scrollbars_->begin(); | |
1355 it != scrollbars_->end(); ++it) | |
1356 if ((*it)->orientation() == orientation) | |
1357 return true; | |
1358 | |
1359 return false; | |
1360 } | |
1361 | |
1362 void LayerImpl::ScrollbarParametersDidChange() { | |
1363 if (!scrollbars_) | |
1364 return; | |
1365 | |
1366 for (ScrollbarSet::iterator it = scrollbars_->begin(); | |
1367 it != scrollbars_->end(); ++it) | |
1368 (*it)->ScrollbarParametersDidChange(); | |
1369 } | 1236 } |
1370 | 1237 |
1371 void LayerImpl::SetNeedsPushProperties() { | 1238 void LayerImpl::SetNeedsPushProperties() { |
1372 if (needs_push_properties_) | 1239 if (needs_push_properties_) |
1373 return; | 1240 return; |
1374 if (!parent_should_know_need_push_properties() && parent_) | 1241 if (!parent_should_know_need_push_properties() && parent_) |
1375 parent_->AddDependentNeedsPushProperties(); | 1242 parent_->AddDependentNeedsPushProperties(); |
1376 needs_push_properties_ = true; | 1243 needs_push_properties_ = true; |
1377 } | 1244 } |
1378 | 1245 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1472 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 1339 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
1473 AsValueInto(state.get()); | 1340 AsValueInto(state.get()); |
1474 return state.PassAs<base::Value>(); | 1341 return state.PassAs<base::Value>(); |
1475 } | 1342 } |
1476 | 1343 |
1477 void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { | 1344 void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { |
1478 benchmark->RunOnLayer(this); | 1345 benchmark->RunOnLayer(this); |
1479 } | 1346 } |
1480 | 1347 |
1481 } // namespace cc | 1348 } // namespace cc |
OLD | NEW |