Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(448)

Side by Side Diff: cc/layers/layer_impl.cc

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

Powered by Google App Engine
This is Rietveld 408576698