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" |
(...skipping 23 matching lines...) Expand all Loading... | |
34 : parent_(NULL), | 34 : parent_(NULL), |
35 scroll_parent_(NULL), | 35 scroll_parent_(NULL), |
36 clip_parent_(NULL), | 36 clip_parent_(NULL), |
37 mask_layer_id_(-1), | 37 mask_layer_id_(-1), |
38 replica_layer_id_(-1), | 38 replica_layer_id_(-1), |
39 layer_id_(id), | 39 layer_id_(id), |
40 layer_tree_impl_(tree_impl), | 40 layer_tree_impl_(tree_impl), |
41 anchor_point_(0.5f, 0.5f), | 41 anchor_point_(0.5f, 0.5f), |
42 anchor_point_z_(0.f), | 42 anchor_point_z_(0.f), |
43 scroll_offset_delegate_(NULL), | 43 scroll_offset_delegate_(NULL), |
44 scrollable_(false), | 44 scroll_clip_layer_(NULL), |
45 should_scroll_on_main_thread_(false), | 45 should_scroll_on_main_thread_(false), |
46 have_wheel_event_handlers_(false), | 46 have_wheel_event_handlers_(false), |
47 user_scrollable_horizontal_(true), | 47 user_scrollable_horizontal_(true), |
48 user_scrollable_vertical_(true), | 48 user_scrollable_vertical_(true), |
49 stacking_order_changed_(false), | 49 stacking_order_changed_(false), |
50 double_sided_(true), | 50 double_sided_(true), |
51 layer_property_changed_(false), | 51 layer_property_changed_(false), |
52 masks_to_bounds_(false), | 52 masks_to_bounds_(false), |
53 contents_opaque_(false), | 53 contents_opaque_(false), |
54 is_root_for_isolated_group_(false), | 54 is_root_for_isolated_group_(false), |
55 preserves_3d_(false), | 55 preserves_3d_(false), |
56 use_parent_backface_visibility_(false), | 56 use_parent_backface_visibility_(false), |
57 draw_checkerboard_for_missing_tiles_(false), | 57 draw_checkerboard_for_missing_tiles_(false), |
58 draws_content_(false), | 58 draws_content_(false), |
59 hide_layer_and_subtree_(false), | 59 hide_layer_and_subtree_(false), |
60 force_render_surface_(false), | 60 force_render_surface_(false), |
61 is_container_for_fixed_position_layers_(false), | 61 is_container_for_fixed_position_layers_(false), |
62 background_color_(0), | 62 background_color_(0), |
63 opacity_(1.0), | 63 opacity_(1.0), |
64 blend_mode_(SkXfermode::kSrcOver_Mode), | 64 blend_mode_(SkXfermode::kSrcOver_Mode), |
65 draw_depth_(0.f), | 65 draw_depth_(0.f), |
66 current_draw_mode_(DRAW_MODE_NONE), | 66 current_draw_mode_(DRAW_MODE_NONE) { |
67 horizontal_scrollbar_layer_(NULL), | |
68 vertical_scrollbar_layer_(NULL) { | |
69 DCHECK_GT(layer_id_, 0); | 67 DCHECK_GT(layer_id_, 0); |
70 DCHECK(layer_tree_impl_); | 68 DCHECK(layer_tree_impl_); |
71 layer_tree_impl_->RegisterLayer(this); | 69 layer_tree_impl_->RegisterLayer(this); |
72 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); | 70 AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar(); |
73 layer_animation_controller_ = | 71 layer_animation_controller_ = |
74 registrar->GetAnimationControllerForId(layer_id_); | 72 registrar->GetAnimationControllerForId(layer_id_); |
75 layer_animation_controller_->AddValueObserver(this); | 73 layer_animation_controller_->AddValueObserver(this); |
76 if (IsActive()) | 74 if (IsActive()) |
77 layer_animation_controller_->set_value_provider(this); | 75 layer_animation_controller_->set_value_provider(this); |
78 } | 76 } |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 | 350 |
353 if (sent_scroll_delta_ == sent_scroll_delta) | 351 if (sent_scroll_delta_ == sent_scroll_delta) |
354 return; | 352 return; |
355 | 353 |
356 sent_scroll_delta_ = sent_scroll_delta; | 354 sent_scroll_delta_ = sent_scroll_delta; |
357 } | 355 } |
358 | 356 |
359 gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { | 357 gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { |
360 DCHECK(scrollable()); | 358 DCHECK(scrollable()); |
361 gfx::Vector2dF min_delta = -scroll_offset_; | 359 gfx::Vector2dF min_delta = -scroll_offset_; |
362 gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_; | 360 gfx::Vector2dF max_delta = MaxScrollOffset() - scroll_offset_; |
363 // Clamp new_delta so that position + delta stays within scroll bounds. | 361 // Clamp new_delta so that position + delta stays within scroll bounds. |
364 gfx::Vector2dF new_delta = (ScrollDelta() + scroll); | 362 gfx::Vector2dF new_delta = (ScrollDelta() + scroll); |
365 new_delta.SetToMax(min_delta); | 363 new_delta.SetToMax(min_delta); |
366 new_delta.SetToMin(max_delta); | 364 new_delta.SetToMin(max_delta); |
367 gfx::Vector2dF unscrolled = | 365 gfx::Vector2dF unscrolled = |
368 ScrollDelta() + scroll - new_delta; | 366 ScrollDelta() + scroll - new_delta; |
369 SetScrollDelta(new_delta); | 367 SetScrollDelta(new_delta); |
368 | |
370 return unscrolled; | 369 return unscrolled; |
371 } | 370 } |
372 | 371 |
372 void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { | |
373 scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id); | |
374 } | |
375 | |
373 void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { | 376 void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { |
374 // Pending tree never has sent scroll deltas | 377 // Pending tree never has sent scroll deltas |
375 DCHECK(layer_tree_impl()->IsActiveTree()); | 378 DCHECK(layer_tree_impl()->IsActiveTree()); |
376 | 379 |
377 // Apply sent scroll deltas to scroll position / scroll delta as if the | 380 // Apply sent scroll deltas to scroll position / scroll delta as if the |
378 // main thread had applied them and then committed those values. | 381 // main thread had applied them and then committed those values. |
379 // | 382 // |
380 // This function should not change the total scroll offset; it just shifts | 383 // This function should not change the total scroll offset; it just shifts |
381 // some of the scroll delta to the scroll offset. Therefore, adjust these | 384 // some of the scroll delta to the scroll offset. Therefore, adjust these |
382 // variables directly rather than calling the scroll offset delegate to | 385 // variables directly rather than calling the scroll offset delegate to |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 if (type == InputHandler::Wheel && have_wheel_event_handlers()) { | 455 if (type == InputHandler::Wheel && have_wheel_event_handlers()) { |
453 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); | 456 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); |
454 return InputHandler::ScrollOnMainThread; | 457 return InputHandler::ScrollOnMainThread; |
455 } | 458 } |
456 | 459 |
457 if (!scrollable()) { | 460 if (!scrollable()) { |
458 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); | 461 TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); |
459 return InputHandler::ScrollIgnored; | 462 return InputHandler::ScrollIgnored; |
460 } | 463 } |
461 | 464 |
462 if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { | 465 gfx::Vector2d max_scroll_offset = MaxScrollOffset(); |
466 if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0) { | |
463 TRACE_EVENT0("cc", | 467 TRACE_EVENT0("cc", |
464 "LayerImpl::tryScroll: Ignored. Technically scrollable," | 468 "LayerImpl::tryScroll: Ignored. Technically scrollable," |
465 " but has no affordance in either direction."); | 469 " but has no affordance in either direction."); |
466 return InputHandler::ScrollIgnored; | 470 return InputHandler::ScrollIgnored; |
467 } | 471 } |
468 | 472 |
469 return InputHandler::ScrollStarted; | 473 return InputHandler::ScrollStarted; |
470 } | 474 } |
471 | 475 |
472 bool LayerImpl::DrawCheckerboardForMissingTiles() const { | 476 bool LayerImpl::DrawCheckerboardForMissingTiles() const { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
524 layer->SetPosition(position_); | 528 layer->SetPosition(position_); |
525 layer->SetIsContainerForFixedPositionLayers( | 529 layer->SetIsContainerForFixedPositionLayers( |
526 is_container_for_fixed_position_layers_); | 530 is_container_for_fixed_position_layers_); |
527 layer->SetFixedContainerSizeDelta(fixed_container_size_delta_); | 531 layer->SetFixedContainerSizeDelta(fixed_container_size_delta_); |
528 layer->SetPositionConstraint(position_constraint_); | 532 layer->SetPositionConstraint(position_constraint_); |
529 layer->SetPreserves3d(preserves_3d()); | 533 layer->SetPreserves3d(preserves_3d()); |
530 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); | 534 layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); |
531 layer->SetSublayerTransform(sublayer_transform_); | 535 layer->SetSublayerTransform(sublayer_transform_); |
532 layer->SetTransform(transform_); | 536 layer->SetTransform(transform_); |
533 | 537 |
534 layer->SetScrollable(scrollable_); | 538 layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() |
539 : Layer::INVALID_ID); | |
535 layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); | 540 layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); |
536 layer->set_user_scrollable_vertical(user_scrollable_vertical_); | 541 layer->set_user_scrollable_vertical(user_scrollable_vertical_); |
537 layer->SetScrollOffsetAndDelta( | 542 layer->SetScrollOffsetAndDelta( |
538 scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta()); | 543 scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta()); |
539 layer->SetSentScrollDelta(gfx::Vector2d()); | 544 layer->SetSentScrollDelta(gfx::Vector2d()); |
540 | 545 |
541 layer->SetMaxScrollOffset(max_scroll_offset_); | |
542 | |
543 LayerImpl* scroll_parent = NULL; | 546 LayerImpl* scroll_parent = NULL; |
544 if (scroll_parent_) | 547 if (scroll_parent_) |
545 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); | 548 scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); |
546 | 549 |
547 layer->SetScrollParent(scroll_parent); | 550 layer->SetScrollParent(scroll_parent); |
548 if (scroll_children_) { | 551 if (scroll_children_) { |
549 std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; | 552 std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; |
550 for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); | 553 for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); |
551 it != scroll_children_->end(); ++it) | 554 it != scroll_children_->end(); ++it) |
552 scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); | 555 scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
605 gfx_transform.matrix().asColMajord(transform); | 608 gfx_transform.matrix().asColMajord(transform); |
606 list = new base::ListValue; | 609 list = new base::ListValue; |
607 for (int i = 0; i < 16; ++i) | 610 for (int i = 0; i < 16; ++i) |
608 list->AppendDouble(transform[i]); | 611 list->AppendDouble(transform[i]); |
609 result->Set("DrawTransform", list); | 612 result->Set("DrawTransform", list); |
610 | 613 |
611 result->SetBoolean("DrawsContent", draws_content_); | 614 result->SetBoolean("DrawsContent", draws_content_); |
612 result->SetDouble("Opacity", opacity()); | 615 result->SetDouble("Opacity", opacity()); |
613 result->SetBoolean("ContentsOpaque", contents_opaque_); | 616 result->SetBoolean("ContentsOpaque", contents_opaque_); |
614 | 617 |
615 if (scrollable_) | 618 if (scrollable()) |
616 result->SetBoolean("Scrollable", scrollable_); | 619 result->SetBoolean("Scrollable", true); |
617 | 620 |
618 if (have_wheel_event_handlers_) | 621 if (have_wheel_event_handlers_) |
619 result->SetBoolean("WheelHandler", have_wheel_event_handlers_); | 622 result->SetBoolean("WheelHandler", have_wheel_event_handlers_); |
620 if (!touch_event_handler_region_.IsEmpty()) { | 623 if (!touch_event_handler_region_.IsEmpty()) { |
621 scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue(); | 624 scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue(); |
622 result->Set("TouchRegion", region.release()); | 625 result->Set("TouchRegion", region.release()); |
623 } | 626 } |
624 | 627 |
625 list = new base::ListValue; | 628 list = new base::ListValue; |
626 for (size_t i = 0; i < children_.size(); ++i) | 629 for (size_t i = 0; i < children_.size(); ++i) |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 bool LayerImpl::IsActive() const { | 717 bool LayerImpl::IsActive() const { |
715 return layer_tree_impl_->IsActiveTree(); | 718 return layer_tree_impl_->IsActiveTree(); |
716 } | 719 } |
717 | 720 |
718 void LayerImpl::SetBounds(gfx::Size bounds) { | 721 void LayerImpl::SetBounds(gfx::Size bounds) { |
719 if (bounds_ == bounds) | 722 if (bounds_ == bounds) |
720 return; | 723 return; |
721 | 724 |
722 bounds_ = bounds; | 725 bounds_ = bounds; |
723 | 726 |
727 ScrollbarParametersDidChange(); | |
724 if (masks_to_bounds()) | 728 if (masks_to_bounds()) |
725 NoteLayerPropertyChangedForSubtree(); | 729 NoteLayerPropertyChangedForSubtree(); |
726 else | 730 else |
727 NoteLayerPropertyChanged(); | 731 NoteLayerPropertyChanged(); |
728 } | 732 } |
729 | 733 |
730 void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { | 734 void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { |
731 int new_layer_id = mask_layer ? mask_layer->id() : -1; | 735 int new_layer_id = mask_layer ? mask_layer->id() : -1; |
732 | 736 |
733 if (mask_layer) { | 737 if (mask_layer) { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
981 float* contents_scale_x, | 985 float* contents_scale_x, |
982 float* contents_scale_y, | 986 float* contents_scale_y, |
983 gfx::Size* content_bounds) { | 987 gfx::Size* content_bounds) { |
984 // Base LayerImpl has all of its content scales and content bounds pushed | 988 // Base LayerImpl has all of its content scales and content bounds pushed |
985 // from its Layer during commit and just reuses those values as-is. | 989 // from its Layer during commit and just reuses those values as-is. |
986 *contents_scale_x = this->contents_scale_x(); | 990 *contents_scale_x = this->contents_scale_x(); |
987 *contents_scale_y = this->contents_scale_y(); | 991 *contents_scale_y = this->contents_scale_y(); |
988 *content_bounds = this->content_bounds(); | 992 *content_bounds = this->content_bounds(); |
989 } | 993 } |
990 | 994 |
991 void LayerImpl::UpdateScrollbarPositions() { | |
992 gfx::Vector2dF current_offset = scroll_offset_ + ScrollDelta(); | |
993 | |
994 gfx::RectF viewport(PointAtOffsetFromOrigin(current_offset), bounds_); | |
995 gfx::SizeF scrollable_size(max_scroll_offset_.x() + bounds_.width(), | |
996 max_scroll_offset_.y() + bounds_.height()); | |
997 if (horizontal_scrollbar_layer_) { | |
998 horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); | |
999 horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); | |
1000 horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio( | |
1001 viewport.width() / scrollable_size.width()); | |
1002 } | |
1003 if (vertical_scrollbar_layer_) { | |
1004 vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); | |
1005 vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); | |
1006 vertical_scrollbar_layer_->SetVisibleToTotalLengthRatio( | |
1007 viewport.height() / scrollable_size.height()); | |
1008 } | |
1009 | |
1010 if (current_offset == last_scroll_offset_) | |
1011 return; | |
1012 last_scroll_offset_ = current_offset; | |
1013 | |
1014 if (scrollbar_animation_controller_) { | |
1015 bool should_animate = scrollbar_animation_controller_->DidScrollUpdate( | |
1016 layer_tree_impl_->CurrentPhysicalTimeTicks()); | |
1017 if (should_animate) | |
1018 layer_tree_impl_->StartScrollbarAnimation(); | |
1019 } | |
1020 | |
1021 // Get the current_offset_.y() value for a sanity-check on scrolling | |
1022 // benchmark metrics. Specifically, we want to make sure | |
1023 // BasicMouseWheelSmoothScrollGesture has proper scroll curves. | |
1024 if (layer_tree_impl()->IsActiveTree()) { | |
1025 TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); | |
1026 } | |
1027 } | |
1028 | |
1029 void LayerImpl::SetScrollOffsetDelegate( | 995 void LayerImpl::SetScrollOffsetDelegate( |
1030 LayerScrollOffsetDelegate* scroll_offset_delegate) { | 996 LayerScrollOffsetDelegate* scroll_offset_delegate) { |
1031 // Having both a scroll parent and a scroll offset delegate is unsupported. | 997 // Having both a scroll parent and a scroll offset delegate is unsupported. |
1032 DCHECK(!scroll_parent_); | 998 DCHECK(!scroll_parent_); |
1033 if (!scroll_offset_delegate && scroll_offset_delegate_) { | 999 if (!scroll_offset_delegate && scroll_offset_delegate_) { |
1034 scroll_delta_ = | 1000 scroll_delta_ = |
1035 scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; | 1001 scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; |
1036 } | 1002 } |
1037 gfx::Vector2dF total_offset = TotalScrollOffset(); | 1003 gfx::Vector2dF total_offset = TotalScrollOffset(); |
1038 scroll_offset_delegate_ = scroll_offset_delegate; | 1004 scroll_offset_delegate_ = scroll_offset_delegate; |
1039 if (scroll_offset_delegate_) { | 1005 if (scroll_offset_delegate_) |
1040 scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); | |
1041 scroll_offset_delegate_->SetTotalScrollOffset(total_offset); | 1006 scroll_offset_delegate_->SetTotalScrollOffset(total_offset); |
1042 } | |
1043 } | 1007 } |
1044 | 1008 |
1045 bool LayerImpl::IsExternalFlingActive() const { | 1009 bool LayerImpl::IsExternalFlingActive() const { |
1046 return scroll_offset_delegate_ && | 1010 return scroll_offset_delegate_ && |
1047 scroll_offset_delegate_->IsExternalFlingActive(); | 1011 scroll_offset_delegate_->IsExternalFlingActive(); |
1048 } | 1012 } |
1049 | 1013 |
1050 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { | 1014 void LayerImpl::SetScrollOffset(gfx::Vector2d scroll_offset) { |
1051 SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); | 1015 SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); |
1052 } | 1016 } |
1053 | 1017 |
1054 void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset, | 1018 void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset, |
1055 gfx::Vector2dF scroll_delta) { | 1019 gfx::Vector2dF scroll_delta) { |
1056 bool changed = false; | 1020 bool changed = false; |
1057 | 1021 |
1022 last_scroll_offset_ = scroll_offset; | |
1023 | |
1058 if (scroll_offset_ != scroll_offset) { | 1024 if (scroll_offset_ != scroll_offset) { |
1059 changed = true; | 1025 changed = true; |
1060 scroll_offset_ = scroll_offset; | 1026 scroll_offset_ = scroll_offset; |
1061 | 1027 |
1062 if (scroll_offset_delegate_) | 1028 if (scroll_offset_delegate_) |
1063 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); | 1029 scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); |
1064 } | 1030 } |
1065 | 1031 |
1066 if (ScrollDelta() != scroll_delta) { | 1032 if (ScrollDelta() != scroll_delta) { |
1067 changed = true; | 1033 changed = true; |
(...skipping 14 matching lines...) Expand all Loading... | |
1082 if (scroll_offset_delegate_) { | 1048 if (scroll_offset_delegate_) { |
1083 scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ + | 1049 scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ + |
1084 scroll_delta); | 1050 scroll_delta); |
1085 } else { | 1051 } else { |
1086 scroll_delta_ = scroll_delta; | 1052 scroll_delta_ = scroll_delta; |
1087 } | 1053 } |
1088 } | 1054 } |
1089 | 1055 |
1090 if (changed) { | 1056 if (changed) { |
1091 NoteLayerPropertyChangedForSubtree(); | 1057 NoteLayerPropertyChangedForSubtree(); |
1092 UpdateScrollbarPositions(); | 1058 ScrollbarParametersDidChange(); |
1093 } | 1059 } |
1094 } | 1060 } |
1095 | 1061 |
1096 gfx::Vector2dF LayerImpl::ScrollDelta() const { | 1062 gfx::Vector2dF LayerImpl::ScrollDelta() const { |
1097 if (scroll_offset_delegate_) | 1063 if (scroll_offset_delegate_) |
1098 return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; | 1064 return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_; |
1099 return scroll_delta_; | 1065 return scroll_delta_; |
1100 } | 1066 } |
1101 | 1067 |
1102 void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { | 1068 void LayerImpl::SetScrollDelta(gfx::Vector2dF scroll_delta) { |
(...skipping 15 matching lines...) Expand all Loading... | |
1118 Region LayerImpl::VisibleContentOpaqueRegion() const { | 1084 Region LayerImpl::VisibleContentOpaqueRegion() const { |
1119 if (contents_opaque()) | 1085 if (contents_opaque()) |
1120 return visible_content_rect(); | 1086 return visible_content_rect(); |
1121 return Region(); | 1087 return Region(); |
1122 } | 1088 } |
1123 | 1089 |
1124 void LayerImpl::DidBeginTracing() {} | 1090 void LayerImpl::DidBeginTracing() {} |
1125 | 1091 |
1126 void LayerImpl::DidLoseOutputSurface() {} | 1092 void LayerImpl::DidLoseOutputSurface() {} |
1127 | 1093 |
1128 void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { | 1094 gfx::Vector2d LayerImpl::MaxScrollOffset() const { |
aelias_OOO_until_Jul13
2014/01/16 03:44:04
Just checking: have you verified this logic also w
wjmaclean
2014/01/16 15:07:32
I'm not sure that I understand what you mean by "i
| |
1129 if (max_scroll_offset_ == max_scroll_offset) | 1095 if (!scroll_clip_layer_) |
1096 return gfx::Vector2d(); | |
1097 | |
1098 LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer(); | |
1099 DCHECK(this != page_scale_layer); | |
1100 DCHECK(scroll_clip_layer_); | |
1101 DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() | |
1102 || IsContainerForFixedPositionLayers()); | |
1103 | |
1104 // TODO(wjmaclean) Find out why Blink sometimes gives us empty bounds on the | |
1105 // scroll layer. | |
1106 // | |
1107 // For now we will use the content layer bounds as a fallback. | |
1108 // It's apparently a known issue that Blink sometimes gives us zero bounds on | |
1109 // the scroll layer, but as the contents layer has no way to directly notify | |
1110 // when its bounds have changed, and since the content layer bounds can be | |
1111 // updated after the scroll layer bounds in a tree sync, it seems better to | |
1112 // only use them as a fall-back. | |
1113 gfx::Size scaled_scroll_bounds(bounds()); | |
1114 if (scaled_scroll_bounds.IsEmpty()) { | |
1115 // TODO(wjmaclean) Should we add some metrics collection here to see how | |
1116 // often we end up with empty scroll bounds, and on which platforms? | |
1117 if (children().size()) | |
1118 scaled_scroll_bounds = children()[0]->bounds(); | |
1119 } | |
1120 | |
1121 float scale_factor = 1.f; | |
1122 LayerImpl const* last_layer = 0; | |
1123 for (LayerImpl const* current_layer = this; | |
1124 current_layer != scroll_clip_layer_->parent(); | |
aelias_OOO_until_Jul13
2014/01/16 19:49:26
As one thing that appears like a bug here, you're
wjmaclean
2014/01/16 20:13:36
I wondered about that ... we can exclude the clip
| |
1125 current_layer = current_layer->parent()) { | |
1126 float current_layer_scale = 1.f; | |
1127 | |
1128 const gfx::Transform& layer_transform = current_layer->transform(); | |
aelias_OOO_until_Jul13
2014/01/16 03:44:04
We don't need to take the other transforms into co
wjmaclean
2014/01/16 15:07:32
You're assuming that this scrolling mechanism is o
aelias_OOO_until_Jul13
2014/01/16 19:49:26
OK, I read this as trying to compensate for CSS sc
| |
1129 if (current_layer == page_scale_layer) { | |
1130 DCHECK(layer_transform.IsIdentity()); | |
1131 current_layer_scale = layer_tree_impl()->total_page_scale_factor(); | |
1132 } else { | |
1133 // TODO(wjmaclean) Should we allow for translation too? | |
1134 if (layer_transform.IsScale()) { | |
1135 gfx::Vector2dF layer_scale = layer_transform.Scale(); | |
1136 // TODO(wjmaclean) Allow for non-isotropic scales. | |
1137 DCHECK(layer_scale.x() == layer_scale.y()); | |
1138 current_layer_scale = layer_scale.x(); | |
1139 } | |
1140 } | |
1141 | |
1142 scale_factor *= current_layer_scale; | |
1143 last_layer = current_layer; | |
1144 } | |
1145 DCHECK(last_layer == scroll_clip_layer_); | |
1146 | |
1147 scaled_scroll_bounds.SetSize( | |
1148 scale_factor * scaled_scroll_bounds.width(), | |
1149 scale_factor * scaled_scroll_bounds.height()); | |
1150 | |
1151 gfx::RectF clip_rect(gfx::PointF(), scroll_clip_layer_->bounds()); | |
1152 if (this == layer_tree_impl()->InnerViewportScrollLayer()) | |
aelias_OOO_until_Jul13
2014/01/16 19:49:26
If we are going to go down the path of generality
wjmaclean
2014/01/16 20:13:36
Yes, we had identified this special case as a weak
aelias_OOO_until_Jul13
2014/01/16 20:36:38
If you try that, you're going to run into the prob
wjmaclean
2014/01/16 20:39:41
Agreed ... I believe that's why it's there for now
| |
1153 clip_rect = | |
1154 gfx::RectF(gfx::PointF(), layer_tree_impl()->ScrollableViewportSize()); | |
1155 gfx::Vector2dF max_offset( | |
1156 scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), | |
1157 scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); | |
1158 // We need the final scroll offset to be in CSS coords. | |
1159 max_offset.Scale(1 / scale_factor); | |
aelias_OOO_until_Jul13
2014/01/16 03:44:04
The old UpdateMaxScrollOffset() logic was simpler
wjmaclean
2014/01/16 15:07:32
Again, I think the more general model we want to s
| |
1160 return gfx::Vector2d(max_offset.x(), max_offset.y()); | |
1161 } | |
1162 | |
1163 gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { | |
1164 gfx::Vector2dF max_offset = MaxScrollOffset(); | |
1165 gfx::Vector2dF old_offset = TotalScrollOffset(); | |
1166 gfx::Vector2dF clamped_offset = old_offset; | |
1167 | |
1168 clamped_offset.SetToMin(max_offset); | |
1169 clamped_offset.SetToMax(gfx::Vector2d()); | |
1170 gfx::Vector2dF delta = clamped_offset - old_offset; | |
1171 if (!delta.IsZero()) | |
1172 ScrollBy(delta); | |
1173 | |
1174 return delta; | |
1175 } | |
1176 | |
1177 void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, | |
1178 LayerImpl* scrollbar_clip_layer) const { | |
1179 DCHECK(scrollbar_layer); | |
1180 LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer(); | |
1181 | |
1182 DCHECK(this != page_scale_layer); | |
1183 DCHECK(scrollbar_clip_layer); | |
1184 DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() | |
1185 || IsContainerForFixedPositionLayers()); | |
1186 gfx::RectF clip_rect(gfx::PointF(), scrollbar_clip_layer->bounds()); | |
1187 | |
1188 // See comment in MaxScrollOffset() regarding the use of the content layer | |
1189 // bounds here. | |
1190 gfx::RectF scroll_rect(gfx::PointF(), bounds()); | |
1191 if (scroll_rect.IsEmpty()) { | |
1192 if (children().size()) | |
1193 scroll_rect = gfx::RectF(children()[0]->bounds()); | |
1194 } | |
1195 | |
1196 if (scroll_rect.size().IsEmpty()) | |
1130 return; | 1197 return; |
1131 max_scroll_offset_ = max_scroll_offset; | |
1132 | 1198 |
1133 if (scroll_offset_delegate_) | 1199 // TODO(wjmaclean) This computation is nearly identical to the one in |
1134 scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); | 1200 // MaxScrollOffset. Find some way to combine these. |
1201 gfx::Vector2dF current_offset; | |
aelias_OOO_until_Jul13
2014/01/16 03:44:04
Likewise, I don't think any scaling is needed here
| |
1202 LayerImpl const* last_layer = 0; | |
1203 for (LayerImpl const* current_layer = this; | |
1204 current_layer != scrollbar_clip_layer->parent(); | |
1205 current_layer = current_layer->parent()) { | |
1206 const gfx::Transform& layer_transform = current_layer->transform(); | |
1207 if (current_layer == page_scale_layer) { | |
1208 DCHECK(layer_transform.IsIdentity()); | |
1209 float scale_factor = layer_tree_impl()->total_page_scale_factor(); | |
1210 current_offset.Scale(scale_factor); | |
1211 scroll_rect.Scale(scale_factor); | |
1212 } else { | |
1213 gfx::Vector2dF new_offset = | |
1214 current_layer->scroll_offset() + current_layer->ScrollDelta(); | |
1215 if (layer_transform.IsScale()) { | |
1216 gfx::Vector2dF layer_scale = layer_transform.Scale(); | |
1217 DCHECK(layer_scale.x() == layer_scale.y()); | |
1218 new_offset.Scale(layer_scale.x(), layer_scale.y()); | |
1219 } | |
1220 current_offset += new_offset; | |
1221 } | |
1222 last_layer = current_layer; | |
1223 } | |
1224 DCHECK(last_layer == scrollbar_clip_layer); | |
1135 | 1225 |
1136 layer_tree_impl()->set_needs_update_draw_properties(); | 1226 scrollbar_layer->SetVerticalAdjust(layer_tree_impl()->VerticalAdjust(this)); |
1137 UpdateScrollbarPositions(); | 1227 if (scrollbar_layer->orientation() == HORIZONTAL) { |
1228 float visible_ratio = clip_rect.width() / scroll_rect.width(); | |
1229 scrollbar_layer->SetCurrentPos(current_offset.x()); | |
1230 scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width()); | |
1231 scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); | |
1232 } else { | |
1233 float visible_ratio = clip_rect.height() / scroll_rect.height(); | |
1234 scrollbar_layer->SetCurrentPos(current_offset.y()); | |
1235 scrollbar_layer->SetMaximum(scroll_rect.height() - clip_rect.height()); | |
1236 scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); | |
1237 } | |
1238 | |
1239 // TODO(wjmaclean) The scrollbar animator for the pinch-zoom scrollbars should | |
1240 // activate for every scroll on the main frame, not just the scrolls that move | |
1241 // the pinch virtual viewport (i.e. trigger from either inner or outer | |
1242 // viewport). | |
1243 if (scrollbar_animation_controller_) { | |
1244 bool should_animate = scrollbar_animation_controller_->DidScrollUpdate( | |
1245 layer_tree_impl_->CurrentPhysicalTimeTicks()); | |
1246 if (should_animate) | |
1247 layer_tree_impl_->StartScrollbarAnimation(); | |
1248 } | |
1138 } | 1249 } |
1139 | 1250 |
1140 void LayerImpl::DidBecomeActive() { | 1251 void LayerImpl::DidBecomeActive() { |
1141 if (layer_tree_impl_->settings().scrollbar_animator == | 1252 if (layer_tree_impl_->settings().scrollbar_animator == |
1142 LayerTreeSettings::NoAnimator) { | 1253 LayerTreeSettings::NoAnimator) { |
1143 return; | 1254 return; |
1144 } | 1255 } |
1145 | 1256 |
1146 bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || | 1257 bool need_scrollbar_animation_controller = scrollable() && scrollbars_; |
1147 vertical_scrollbar_layer_; | |
1148 if (!need_scrollbar_animation_controller) { | 1258 if (!need_scrollbar_animation_controller) { |
1149 scrollbar_animation_controller_.reset(); | 1259 scrollbar_animation_controller_.reset(); |
1150 return; | 1260 return; |
1151 } | 1261 } |
1152 | 1262 |
1153 if (scrollbar_animation_controller_) | 1263 if (scrollbar_animation_controller_) |
1154 return; | 1264 return; |
1155 | 1265 |
1156 switch (layer_tree_impl_->settings().scrollbar_animator) { | 1266 switch (layer_tree_impl_->settings().scrollbar_animator) { |
1157 case LayerTreeSettings::LinearFade: { | 1267 case LayerTreeSettings::LinearFade: { |
(...skipping 12 matching lines...) Expand all Loading... | |
1170 scrollbar_animation_controller_ = | 1280 scrollbar_animation_controller_ = |
1171 ScrollbarAnimationControllerThinning::Create(this) | 1281 ScrollbarAnimationControllerThinning::Create(this) |
1172 .PassAs<ScrollbarAnimationController>(); | 1282 .PassAs<ScrollbarAnimationController>(); |
1173 break; | 1283 break; |
1174 } | 1284 } |
1175 case LayerTreeSettings::NoAnimator: | 1285 case LayerTreeSettings::NoAnimator: |
1176 NOTREACHED(); | 1286 NOTREACHED(); |
1177 break; | 1287 break; |
1178 } | 1288 } |
1179 } | 1289 } |
1180 void LayerImpl::SetHorizontalScrollbarLayer( | 1290 |
1181 ScrollbarLayerImplBase* scrollbar_layer) { | 1291 void LayerImpl::ClearScrollbars() { |
1182 horizontal_scrollbar_layer_ = scrollbar_layer; | 1292 if (!scrollbars_) |
1183 if (horizontal_scrollbar_layer_) | 1293 return; |
1184 horizontal_scrollbar_layer_->set_scroll_layer_id(id()); | 1294 |
1295 scrollbars_.reset(NULL); | |
1185 } | 1296 } |
1186 | 1297 |
1187 void LayerImpl::SetVerticalScrollbarLayer( | 1298 void LayerImpl::AddScrollbar(ScrollbarLayerImplBase* layer) { |
1188 ScrollbarLayerImplBase* scrollbar_layer) { | 1299 DCHECK(layer); |
1189 vertical_scrollbar_layer_ = scrollbar_layer; | 1300 if (!scrollbars_) |
1190 if (vertical_scrollbar_layer_) | 1301 scrollbars_.reset(new ScrollbarSet()); |
1191 vertical_scrollbar_layer_->set_scroll_layer_id(id()); | 1302 |
1303 scrollbars_->insert(layer); | |
1304 } | |
1305 | |
1306 void LayerImpl::RemoveScrollbar(ScrollbarLayerImplBase* layer) { | |
1307 DCHECK(scrollbars_); | |
1308 DCHECK(layer); | |
1309 | |
1310 scrollbars_->erase(layer); | |
1311 if (scrollbars_->empty()) | |
1312 scrollbars_.reset(); | |
1313 } | |
1314 | |
1315 bool LayerImpl::HasScrollbar(ScrollbarOrientation orientation) const { | |
1316 if (!scrollbars_) | |
1317 return false; | |
1318 | |
1319 for (ScrollbarSet::iterator it = scrollbars_->begin(); | |
1320 it != scrollbars_->end(); ++it) | |
1321 if ((*it)->orientation() == orientation) | |
1322 return true; | |
1323 | |
1324 return false; | |
1325 } | |
1326 | |
1327 void LayerImpl::ScrollbarParametersDidChange() { | |
1328 if (!scrollbars_) | |
1329 return; | |
1330 | |
1331 for (ScrollbarSet::iterator it = scrollbars_->begin(); | |
1332 it != scrollbars_->end(); ++it) | |
1333 (*it)->ScrollbarParametersDidChange(); | |
1192 } | 1334 } |
1193 | 1335 |
1194 void LayerImpl::AsValueInto(base::DictionaryValue* state) const { | 1336 void LayerImpl::AsValueInto(base::DictionaryValue* state) const { |
1195 TracedValue::MakeDictIntoImplicitSnapshot(state, LayerTypeAsString(), this); | 1337 TracedValue::MakeDictIntoImplicitSnapshot(state, LayerTypeAsString(), this); |
1196 state->SetInteger("layer_id", id()); | 1338 state->SetInteger("layer_id", id()); |
1197 state->SetString("layer_name", debug_name()); | 1339 state->SetString("layer_name", debug_name()); |
1198 state->Set("bounds", MathUtil::AsValue(bounds()).release()); | 1340 state->Set("bounds", MathUtil::AsValue(bounds()).release()); |
1199 state->SetInteger("draws_content", DrawsContent()); | 1341 state->SetInteger("draws_content", DrawsContent()); |
1200 state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes()); | 1342 state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes()); |
1201 | 1343 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1271 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 1413 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
1272 AsValueInto(state.get()); | 1414 AsValueInto(state.get()); |
1273 return state.PassAs<base::Value>(); | 1415 return state.PassAs<base::Value>(); |
1274 } | 1416 } |
1275 | 1417 |
1276 void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { | 1418 void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { |
1277 benchmark->RunOnLayer(this); | 1419 benchmark->RunOnLayer(this); |
1278 } | 1420 } |
1279 | 1421 |
1280 } // namespace cc | 1422 } // namespace cc |
OLD | NEW |