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