diff options
23 files changed, 1032 insertions, 490 deletions
diff --git a/cc/blink/web_layer_impl.cc b/cc/blink/web_layer_impl.cc index 88601b5..56c2af9 100644 --- a/cc/blink/web_layer_impl.cc +++ b/cc/blink/web_layer_impl.cc @@ -345,9 +345,58 @@ bool WebLayerImpl::haveScrollEventHandlers() const { return layer_->have_scroll_event_handlers(); } -void WebLayerImpl::setShouldScrollOnMainThread( - bool should_scroll_on_main_thread) { - layer_->SetShouldScrollOnMainThread(should_scroll_on_main_thread); +static_assert(static_cast<cc::InputHandler::MainThreadScrollingReason>( + blink::WebMainThreadScrollingReason::NotScrollingOnMain) == + cc::InputHandler::NOT_SCROLLING_ON_MAIN, + "InputHandler::MainThreadScrollingReason and " + "WebMainThreadScrollingReason enums must match"); +static_assert(static_cast<cc::InputHandler::MainThreadScrollingReason>( + blink::WebMainThreadScrollingReason:: + HasBackgroundAttachmentFixedObjects) == + cc::InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS, + "InputHandler::MainThreadScrollingReason and " + "WebMainThreadScrollingReason enums must match"); +static_assert(static_cast<cc::InputHandler::MainThreadScrollingReason>( + blink::WebMainThreadScrollingReason:: + HasNonLayerViewportConstrainedObjects) == + cc::InputHandler::HAS_NON_LAYER_VIEWPORT_CONSTRAINED_OBJECTS, + "InputHandler::MainThreadScrollingReason and " + "WebMainThreadScrollingReason enums must match"); +static_assert( + static_cast<cc::InputHandler::MainThreadScrollingReason>( + blink::WebMainThreadScrollingReason::ThreadedScrollingDisabled) == + cc::InputHandler::THREADED_SCROLLING_DISABLED, + "InputHandler::MainThreadScrollingReason and " + "WebMainThreadScrollingReason enums must match"); +static_assert(static_cast<cc::InputHandler::MainThreadScrollingReason>( + blink::WebMainThreadScrollingReason::ScrollBarScrolling) == + cc::InputHandler::SCROLL_BAR_SCROLLING, + "InputHandler::MainThreadScrollingReason and " + "WebMainThreadScrollingReason enums must match"); +static_assert(static_cast<cc::InputHandler::MainThreadScrollingReason>( + blink::WebMainThreadScrollingReason::PageOverlay) == + cc::InputHandler::PAGE_OVERLAY, + "InputHandler::MainThreadScrollingReason and " + "WebMainThreadScrollingReason enums must match"); + +void WebLayerImpl::addMainThreadScrollingReasons( + blink::WebMainThreadScrollingReason::WebMainThreadScrollingReason + main_thread_scrolling_reasons) { + DCHECK(main_thread_scrolling_reasons); + // WebLayerImpl should only know about non-transient scrolling + // reasons. Transient scrolling reasons are computed per hit test. + DCHECK_LE( + main_thread_scrolling_reasons, + static_cast< + blink::WebMainThreadScrollingReason::WebMainThreadScrollingReason>( + cc::InputHandler::MaxNonTransientScrollingReason)); + layer_->AddMainThreadScrollingReasons( + static_cast<cc::InputHandler::MainThreadScrollingReason>( + main_thread_scrolling_reasons)); +} + +void WebLayerImpl::clearMainThreadScrollingReasons() { + layer_->ClearMainThreadScrollingReasons(); } bool WebLayerImpl::shouldScrollOnMainThread() const { diff --git a/cc/blink/web_layer_impl.h b/cc/blink/web_layer_impl.h index 3fd0bcc..482c633 100644 --- a/cc/blink/web_layer_impl.h +++ b/cc/blink/web_layer_impl.h @@ -22,6 +22,7 @@ #include "third_party/WebKit/public/platform/WebDoublePoint.h" #include "third_party/WebKit/public/platform/WebFloatPoint.h" #include "third_party/WebKit/public/platform/WebLayer.h" +#include "third_party/WebKit/public/platform/WebMainThreadScrollingReason.h" #include "third_party/WebKit/public/platform/WebPoint.h" #include "third_party/WebKit/public/platform/WebRect.h" #include "third_party/WebKit/public/platform/WebSize.h" @@ -128,7 +129,10 @@ class WebLayerImpl : public blink::WebLayer { bool haveWheelEventHandlers() const override; void setHaveScrollEventHandlers(bool have_scroll_event_handlers) override; bool haveScrollEventHandlers() const override; - void setShouldScrollOnMainThread(bool scroll_on_main) override; + void addMainThreadScrollingReasons( + blink::WebMainThreadScrollingReason::WebMainThreadScrollingReason + main_thread_scrolling_reasons) override; + void clearMainThreadScrollingReasons() override; bool shouldScrollOnMainThread() const override; void setNonFastScrollableRegion( const blink::WebVector<blink::WebRect>& region) override; diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index f65509f..d26e6a4 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h @@ -77,14 +77,51 @@ class CC_EXPORT InputHandler { public: // Note these are used in a histogram. Do not reorder or delete existing // entries. - enum ScrollStatus { + enum ScrollThread { SCROLL_ON_MAIN_THREAD = 0, - SCROLL_STARTED, + SCROLL_ON_IMPL_THREAD, SCROLL_IGNORED, SCROLL_UNKNOWN, // This must be the last entry. ScrollStatusCount }; + + // Ensure this stays in sync with MainThreadScrollingReason in histograms.xml, + // and that this extends ScrollingCoordinator::MainThreadScrollingReason. + // ScrollingCoordinator::MainThreadScrollingReason contains the flags + // which are associated with a layer. The flags only contained in + // InputHandler::MainThreadScrollingReason are computed for each scroll + // begin. + enum MainThreadScrollingReason { + NOT_SCROLLING_ON_MAIN = 0, + HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS = 1 << 0, + HAS_NON_LAYER_VIEWPORT_CONSTRAINED_OBJECTS = 1 << 1, + THREADED_SCROLLING_DISABLED = 1 << 2, + SCROLL_BAR_SCROLLING = 1 << 3, + PAGE_OVERLAY = 1 << 4, + MaxNonTransientScrollingReason = PAGE_OVERLAY, + NON_FAST_SCROLLABLE_REGION = 1 << 5, + EVENT_HANDLERS = 1 << 6, + FAILED_HIT_TEST = 1 << 7, + NO_SCROLLING_LAYER = 1 << 8, + NOT_SCROLLABLE = 1 << 9, + CONTINUING_MAIN_THREAD_SCROLL = 1 << 10, + NON_INVERTIBLE_TRANSFORM = 1 << 11, + MainThreadScrollingReasonCount = 13 + }; + + struct ScrollStatus { + ScrollStatus() + : thread(SCROLL_ON_IMPL_THREAD), + main_thread_scrolling_reasons(NOT_SCROLLING_ON_MAIN) {} + ScrollStatus(ScrollThread thread, + MainThreadScrollingReason main_thread_scrolling_reasons) + : thread(thread), + main_thread_scrolling_reasons(main_thread_scrolling_reasons) {} + ScrollThread thread; + MainThreadScrollingReason main_thread_scrolling_reasons; + }; + enum ScrollInputType { GESTURE, WHEEL, ANIMATED_WHEEL, NON_BUBBLING_GESTURE }; // Binds a client to this handler to receive notifications. Only one client @@ -181,6 +218,13 @@ class CC_EXPORT InputHandler { DISALLOW_COPY_AND_ASSIGN(InputHandler); }; +inline const InputHandler::MainThreadScrollingReason& operator|=( + InputHandler::MainThreadScrollingReason& a, + InputHandler::MainThreadScrollingReason b) { + return a = static_cast<InputHandler::MainThreadScrollingReason>( + static_cast<unsigned>(a) | static_cast<unsigned>(b)); +} + } // namespace cc #endif // CC_INPUT_INPUT_HANDLER_H_ diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index cc2cbbb..88043a7 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -66,8 +66,8 @@ Layer::Layer(const LayerSettings& settings) property_tree_sequence_number_(-1), element_id_(0), mutable_properties_(kMutablePropertyNone), + main_thread_scrolling_reasons_(InputHandler::NOT_SCROLLING_ON_MAIN), should_flatten_transform_from_property_tree_(false), - should_scroll_on_main_thread_(false), have_wheel_event_handlers_(false), have_scroll_event_handlers_(false), user_scrollable_horizontal_(true), @@ -947,11 +947,21 @@ void Layer::SetUserScrollable(bool horizontal, bool vertical) { SetNeedsCommit(); } -void Layer::SetShouldScrollOnMainThread(bool should_scroll_on_main_thread) { +void Layer::AddMainThreadScrollingReasons( + InputHandler::MainThreadScrollingReason main_thread_scrolling_reasons) { DCHECK(IsPropertyChangeAllowed()); - if (should_scroll_on_main_thread_ == should_scroll_on_main_thread) + DCHECK(main_thread_scrolling_reasons); + if (main_thread_scrolling_reasons_ == main_thread_scrolling_reasons) return; - should_scroll_on_main_thread_ = should_scroll_on_main_thread; + main_thread_scrolling_reasons_ |= main_thread_scrolling_reasons; + SetNeedsCommit(); +} + +void Layer::ClearMainThreadScrollingReasons() { + DCHECK(IsPropertyChangeAllowed()); + if (!main_thread_scrolling_reasons_) + return; + main_thread_scrolling_reasons_ = InputHandler::NOT_SCROLLING_ON_MAIN; SetNeedsCommit(); } @@ -1196,7 +1206,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { DCHECK(!(FilterIsAnimating() && layer->FilterIsAnimatingOnImplOnly())); layer->SetBackgroundFilters(background_filters()); layer->SetMasksToBounds(masks_to_bounds_); - layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); + layer->set_main_thread_scrolling_reasons(main_thread_scrolling_reasons_); layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_); layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); @@ -1467,7 +1477,7 @@ void Layer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto) { // |filters_| and |background_filters_|. See crbug.com/541321. base->set_masks_to_bounds(masks_to_bounds_); - base->set_should_scroll_on_main_thread(should_scroll_on_main_thread_); + base->set_main_thread_scrolling_reasons(main_thread_scrolling_reasons_); base->set_have_wheel_event_handlers(have_wheel_event_handlers_); base->set_have_scroll_event_handlers(have_scroll_event_handlers_); RegionToProto(non_fast_scrollable_region_, @@ -1553,7 +1563,9 @@ void Layer::FromLayerSpecificPropertiesProto( hide_layer_and_subtree_ = base.hide_layer_and_subtree(); has_render_surface_ = base.has_render_surface(); masks_to_bounds_ = base.masks_to_bounds(); - should_scroll_on_main_thread_ = base.should_scroll_on_main_thread(); + main_thread_scrolling_reasons_ = + static_cast<InputHandler::MainThreadScrollingReason>( + base.main_thread_scrolling_reasons()); have_wheel_event_handlers_ = base.have_wheel_event_handlers(); have_scroll_event_handlers_ = base.have_scroll_event_handlers(); non_fast_scrollable_region_ = diff --git a/cc/layers/layer.h b/cc/layers/layer.h index ef5da33..aff32fa 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h @@ -23,6 +23,7 @@ #include "cc/base/region.h" #include "cc/debug/frame_timing_request.h" #include "cc/debug/micro_benchmark.h" +#include "cc/input/input_handler.h" #include "cc/layers/layer_lists.h" #include "cc/layers/layer_position_constraint.h" #include "cc/layers/paint_properties.h" @@ -276,9 +277,11 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, } bool user_scrollable_vertical() const { return user_scrollable_vertical_; } - void SetShouldScrollOnMainThread(bool should_scroll_on_main_thread); + void AddMainThreadScrollingReasons( + InputHandler::MainThreadScrollingReason main_thread_scrolling_reasons); + void ClearMainThreadScrollingReasons(); bool should_scroll_on_main_thread() const { - return should_scroll_on_main_thread_; + return !!main_thread_scrolling_reasons_; } void SetHaveWheelEventHandlers(bool have_wheel_event_handlers); @@ -723,8 +726,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, uint64_t element_id_; uint32_t mutable_properties_; gfx::Vector2dF offset_to_transform_parent_; + InputHandler::MainThreadScrollingReason main_thread_scrolling_reasons_; bool should_flatten_transform_from_property_tree_ : 1; - bool should_scroll_on_main_thread_ : 1; bool have_wheel_event_handlers_ : 1; bool have_scroll_event_handlers_ : 1; bool user_scrollable_horizontal_ : 1; diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index b845968..422de5c 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -57,7 +57,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, layer_tree_impl_(tree_impl), scroll_offset_(scroll_offset), scroll_clip_layer_id_(Layer::INVALID_ID), - should_scroll_on_main_thread_(false), + main_thread_scrolling_reasons_(InputHandler::NOT_SCROLLING_ON_MAIN), have_wheel_event_handlers_(false), have_scroll_event_handlers_(false), scroll_blocks_on_(SCROLL_BLOCKS_ON_NONE), @@ -507,15 +507,24 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( const gfx::PointF& screen_space_point, InputHandler::ScrollInputType type, ScrollBlocksOn effective_block_mode) const { + InputHandler::ScrollStatus scroll_status; + scroll_status.main_thread_scrolling_reasons = + InputHandler::NOT_SCROLLING_ON_MAIN; if (should_scroll_on_main_thread()) { TRACE_EVENT0("cc", "LayerImpl::TryScroll: Failed ShouldScrollOnMainThread"); - return InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.thread = InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.main_thread_scrolling_reasons = + main_thread_scrolling_reasons_; + return scroll_status; } gfx::Transform screen_space_transform = ScreenSpaceTransform(); if (!screen_space_transform.IsInvertible()) { TRACE_EVENT0("cc", "LayerImpl::TryScroll: Ignored NonInvertibleTransform"); - return InputHandler::SCROLL_IGNORED; + scroll_status.thread = InputHandler::SCROLL_IGNORED; + scroll_status.main_thread_scrolling_reasons = + InputHandler::NON_INVERTIBLE_TRANSFORM; + return scroll_status; } if (!non_fast_scrollable_region().IsEmpty()) { @@ -535,26 +544,35 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( gfx::ToRoundedPoint(hit_test_point_in_layer_space))) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed NonFastScrollableRegion"); - return InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.thread = InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.main_thread_scrolling_reasons = + InputHandler::NON_FAST_SCROLLABLE_REGION; + return scroll_status; } } if (have_scroll_event_handlers() && effective_block_mode & SCROLL_BLOCKS_ON_SCROLL_EVENT) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed ScrollEventHandlers"); - return InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.thread = InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.main_thread_scrolling_reasons = InputHandler::EVENT_HANDLERS; + return scroll_status; } if ((type == InputHandler::WHEEL || type == InputHandler::ANIMATED_WHEEL) && have_wheel_event_handlers() && effective_block_mode & SCROLL_BLOCKS_ON_WHEEL_EVENT) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); - return InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.thread = InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.main_thread_scrolling_reasons = InputHandler::EVENT_HANDLERS; + return scroll_status; } if (!scrollable()) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable"); - return InputHandler::SCROLL_IGNORED; + scroll_status.thread = InputHandler::SCROLL_IGNORED; + scroll_status.main_thread_scrolling_reasons = InputHandler::NOT_SCROLLABLE; + return scroll_status; } gfx::ScrollOffset max_scroll_offset = MaxScrollOffset(); @@ -562,10 +580,13 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored. Technically scrollable," " but has no affordance in either direction."); - return InputHandler::SCROLL_IGNORED; + scroll_status.thread = InputHandler::SCROLL_IGNORED; + scroll_status.main_thread_scrolling_reasons = InputHandler::NOT_SCROLLABLE; + return scroll_status; } - return InputHandler::SCROLL_STARTED; + scroll_status.thread = InputHandler::SCROLL_ON_IMPL_THREAD; + return scroll_status; } skia::RefPtr<SkPicture> LayerImpl::GetPicture() { @@ -594,7 +615,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetFilters(filters()); layer->SetBackgroundFilters(background_filters()); layer->SetMasksToBounds(masks_to_bounds_); - layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_); + layer->set_main_thread_scrolling_reasons(main_thread_scrolling_reasons_); layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_); layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_); layer->SetScrollBlocksOn(scroll_blocks_on_); diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 4dca350..48e9529 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -492,11 +492,12 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, void ApplySentScrollDeltasFromAbortedCommit(); - void SetShouldScrollOnMainThread(bool should_scroll_on_main_thread) { - should_scroll_on_main_thread_ = should_scroll_on_main_thread; + void set_main_thread_scrolling_reasons( + InputHandler::MainThreadScrollingReason main_thread_scrolling_reasons) { + main_thread_scrolling_reasons_ = main_thread_scrolling_reasons; } bool should_scroll_on_main_thread() const { - return should_scroll_on_main_thread_; + return !!main_thread_scrolling_reasons_; } void SetHaveWheelEventHandlers(bool have_wheel_event_handlers) { @@ -773,8 +774,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, int scroll_clip_layer_id_; gfx::Vector2dF offset_to_transform_parent_; - - bool should_scroll_on_main_thread_ : 1; + InputHandler::MainThreadScrollingReason main_thread_scrolling_reasons_; bool have_wheel_event_handlers_ : 1; bool have_scroll_event_handlers_ : 1; diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index f73cb25..13bcba1 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc @@ -131,8 +131,8 @@ class LayerSerializationTest : public testing::Test { EXPECT_EQ(src->hide_layer_and_subtree_, dest->hide_layer_and_subtree_); EXPECT_EQ(src->has_render_surface_, dest->has_render_surface_); EXPECT_EQ(src->masks_to_bounds_, dest->masks_to_bounds_); - EXPECT_EQ(src->should_scroll_on_main_thread_, - dest->should_scroll_on_main_thread_); + EXPECT_EQ(src->main_thread_scrolling_reasons_, + dest->main_thread_scrolling_reasons_); EXPECT_EQ(src->have_wheel_event_handlers_, dest->have_wheel_event_handlers_); EXPECT_EQ(src->have_scroll_event_handlers_, @@ -249,7 +249,7 @@ class LayerSerializationTest : public testing::Test { layer->hide_layer_and_subtree_ = false; layer->has_render_surface_ = false; layer->masks_to_bounds_ = true; - layer->should_scroll_on_main_thread_ = false; + layer->main_thread_scrolling_reasons_ = InputHandler::NOT_SCROLLING_ON_MAIN; layer->have_wheel_event_handlers_ = true; layer->have_scroll_event_handlers_ = false; layer->non_fast_scrollable_region_ = Region(gfx::Rect(5, 1, 14, 3)); @@ -299,8 +299,8 @@ class LayerSerializationTest : public testing::Test { layer->hide_layer_and_subtree_ = !layer->hide_layer_and_subtree_; layer->has_render_surface_ = !layer->has_render_surface_; layer->masks_to_bounds_ = !layer->masks_to_bounds_; - layer->should_scroll_on_main_thread_ = - !layer->should_scroll_on_main_thread_; + layer->main_thread_scrolling_reasons_ = + InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS; layer->have_wheel_event_handlers_ = !layer->have_wheel_event_handlers_; layer->have_scroll_event_handlers_ = !layer->have_scroll_event_handlers_; layer->non_fast_scrollable_region_ = Region(gfx::Rect(5, 1, 14, 3)); @@ -967,7 +967,8 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset( gfx::ScrollOffset(10, 10))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetShouldScrollOnMainThread(true)); + EXPECT_SET_NEEDS_COMMIT(1, test_layer->AddMainThreadScrollingReasons( + InputHandler::EVENT_HANDLERS)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNonFastScrollableRegion( Region(gfx::Rect(1, 1, 2, 2)))); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHaveWheelEventHandlers(true)); diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc index aabde35..2e82259 100644 --- a/cc/layers/painted_scrollbar_layer.cc +++ b/cc/layers/painted_scrollbar_layer.cc @@ -50,7 +50,7 @@ PaintedScrollbarLayer::PaintedScrollbarLayer(const LayerSettings& settings, has_thumb_(scrollbar_->HasThumb()), thumb_opacity_(scrollbar_->ThumbOpacity()) { if (!scrollbar_->IsOverlay()) - SetShouldScrollOnMainThread(true); + AddMainThreadScrollingReasons(InputHandler::SCROLL_BAR_SCROLLING); } PaintedScrollbarLayer::~PaintedScrollbarLayer() {} diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index b9fc9ae..e0d7a74 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc @@ -160,9 +160,11 @@ TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { // When the scrollbar is not an overlay scrollbar, the scroll should be // responded to on the main thread as the compositor does not yet implement // scrollbar scrolling. - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - scrollbar_layer_impl->TryScroll( - gfx::PointF(), InputHandler::GESTURE, SCROLL_BLOCKS_ON_NONE)); + InputHandler::ScrollStatus status = scrollbar_layer_impl->TryScroll( + gfx::PointF(), InputHandler::GESTURE, SCROLL_BLOCKS_ON_NONE); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::SCROLL_BAR_SCROLLING, + status.main_thread_scrolling_reasons); // Create and attach an overlay scrollbar. scrollbar.reset(new FakeScrollbar(false, false, true)); @@ -175,9 +177,10 @@ TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { // The user shouldn't be able to drag an overlay scrollbar and the scroll // may be handled in the compositor. - EXPECT_EQ(InputHandler::SCROLL_IGNORED, - scrollbar_layer_impl->TryScroll( - gfx::PointF(), InputHandler::GESTURE, SCROLL_BLOCKS_ON_NONE)); + status = scrollbar_layer_impl->TryScroll(gfx::PointF(), InputHandler::GESTURE, + SCROLL_BLOCKS_ON_NONE); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLABLE, status.main_thread_scrolling_reasons); } TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) { diff --git a/cc/proto/layer.proto b/cc/proto/layer.proto index bc1255d..4c8ba31 100644 --- a/cc/proto/layer.proto +++ b/cc/proto/layer.proto @@ -85,7 +85,7 @@ message BaseLayerProperties { // repeated FilterOperation filters = 12; // repeated FilterOperation background_filters = 13; optional bool masks_to_bounds = 14; - optional bool should_scroll_on_main_thread = 15; + optional uint32 main_thread_scrolling_reasons = 15; optional bool have_wheel_event_handlers = 16; optional bool have_scroll_event_handlers = 17; optional Region non_fast_scrollable_region = 18; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 057228f..2d1321e0 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -140,7 +140,7 @@ enum ScrollThread { MAIN_THREAD, CC_THREAD }; void RecordCompositorSlowScrollMetric(InputHandler::ScrollInputType type, ScrollThread scroll_thread) { - bool scroll_on_main_thread = (scroll_thread == ScrollThread::MAIN_THREAD); + bool scroll_on_main_thread = (scroll_thread == MAIN_THREAD); if (type == InputHandler::WHEEL || type == InputHandler::ANIMATED_WHEEL) { UMA_HISTOGRAM_BOOLEAN("Renderer4.CompositorWheelScrollUpdateThread", scroll_on_main_thread); @@ -548,8 +548,10 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt( active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); bool scroll_on_main_thread = false; + InputHandler::MainThreadScrollingReason main_thread_scrolling_reasons; LayerImpl* test_layer_impl = FindScrollLayerForDeviceViewportPoint( - device_viewport_point, type, layer_impl, &scroll_on_main_thread, NULL); + device_viewport_point, type, layer_impl, &scroll_on_main_thread, nullptr, + &main_thread_scrolling_reasons); if (!test_layer_impl) return false; @@ -2476,8 +2478,12 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( InputHandler::ScrollInputType type, LayerImpl* layer_impl, bool* scroll_on_main_thread, - bool* optional_has_ancestor_scroll_handler) const { + bool* optional_has_ancestor_scroll_handler, + InputHandler::MainThreadScrollingReason* main_thread_scrolling_reasons) + const { DCHECK(scroll_on_main_thread); + DCHECK(main_thread_scrolling_reasons); + *main_thread_scrolling_reasons = InputHandler::NOT_SCROLLING_ON_MAIN; ScrollBlocksOn block_mode = EffectiveScrollBlocksOn(layer_impl); @@ -2488,8 +2494,17 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( // thread. ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type, block_mode); - if (status == SCROLL_ON_MAIN_THREAD) { + if (status.thread == SCROLL_ON_MAIN_THREAD) { + if (layer_impl->should_scroll_on_main_thread()) { + DCHECK(status.main_thread_scrolling_reasons <= + InputHandler::MaxNonTransientScrollingReason); + } else { + DCHECK(status.main_thread_scrolling_reasons > + InputHandler::MaxNonTransientScrollingReason); + } + *scroll_on_main_thread = true; + *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; return NULL; } @@ -2499,9 +2514,19 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( status = scroll_layer_impl->TryScroll(device_viewport_point, type, block_mode); + // If any layer wants to divert the scroll event to the main thread, abort. - if (status == SCROLL_ON_MAIN_THREAD) { + if (status.thread == SCROLL_ON_MAIN_THREAD) { + if (layer_impl->should_scroll_on_main_thread()) { + DCHECK(status.main_thread_scrolling_reasons <= + InputHandler::MaxNonTransientScrollingReason); + } else { + DCHECK(status.main_thread_scrolling_reasons > + InputHandler::MaxNonTransientScrollingReason); + } + *scroll_on_main_thread = true; + *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; return NULL; } @@ -2509,8 +2534,10 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( scroll_layer_impl->have_scroll_event_handlers()) *optional_has_ancestor_scroll_handler = true; - if (status == SCROLL_STARTED && !potentially_scrolling_layer_impl) + if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD && + !potentially_scrolling_layer_impl) { potentially_scrolling_layer_impl = scroll_layer_impl; + } } // Falling back to the root scroll layer ensures generation of root overscroll @@ -2553,9 +2580,14 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( DCHECK(scroll_state); DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); - if (!scrolling_layer_impl) - return SCROLL_IGNORED; - + InputHandler::ScrollStatus scroll_status; + scroll_status.main_thread_scrolling_reasons = NOT_SCROLLING_ON_MAIN; + if (!scrolling_layer_impl) { + scroll_status.thread = SCROLL_IGNORED; + scroll_status.main_thread_scrolling_reasons = NO_SCROLLING_LAYER; + return scroll_status; + } + scroll_status.thread = SCROLL_ON_IMPL_THREAD; ScrollAnimationAbort(scrolling_layer_impl); top_controls_manager_->ScrollBegin(); @@ -2570,12 +2602,12 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( DistributeScrollDelta(scroll_state); client_->RenewTreePriority(); - RecordCompositorSlowScrollMetric(type, ScrollThread::CC_THREAD); + RecordCompositorSlowScrollMetric(type, CC_THREAD); // TODO(lanwei): Will remove this metric in M50 when we have used the new // metrics for one milestone, see https://crbug.com/557787. UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false); - return SCROLL_STARTED; + return scroll_status; } InputHandler::ScrollStatus LayerTreeHostImpl::RootScrollBegin( @@ -2591,6 +2623,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::RootScrollBegin( InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( ScrollState* scroll_state, InputHandler::ScrollInputType type) { + ScrollStatus scroll_status; + scroll_status.main_thread_scrolling_reasons = NOT_SCROLLING_ON_MAIN; TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin"); ClearCurrentlyScrollingLayer(); @@ -2607,22 +2641,29 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( LayerImpl* scroll_layer_impl = active_tree_->FindFirstScrollingLayerThatIsHitByPoint( device_viewport_point); - if (scroll_layer_impl && !HasScrollAncestor(layer_impl, scroll_layer_impl)) - return SCROLL_UNKNOWN; + if (scroll_layer_impl && + !HasScrollAncestor(layer_impl, scroll_layer_impl)) { + scroll_status.thread = SCROLL_UNKNOWN; + scroll_status.main_thread_scrolling_reasons = + InputHandler::FAILED_HIT_TEST; + return scroll_status; + } } bool scroll_on_main_thread = false; LayerImpl* scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( device_viewport_point, type, layer_impl, &scroll_on_main_thread, - &scroll_affects_scroll_handler_); + &scroll_affects_scroll_handler_, + &scroll_status.main_thread_scrolling_reasons); if (scroll_on_main_thread) { - RecordCompositorSlowScrollMetric(type, ScrollThread::MAIN_THREAD); + RecordCompositorSlowScrollMetric(type, MAIN_THREAD); // TODO(lanwei): Will remove this metric in M50 when we have used the new // metrics for one milestone, see https://crbug.com/557787. UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true); - return SCROLL_ON_MAIN_THREAD; + scroll_status.thread = SCROLL_ON_MAIN_THREAD; + return scroll_status; } return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type); @@ -2631,10 +2672,16 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( const gfx::Point& viewport_point, const gfx::Vector2dF& scroll_delta) { + InputHandler::ScrollStatus scroll_status; + scroll_status.main_thread_scrolling_reasons = NOT_SCROLLING_ON_MAIN; if (LayerImpl* layer_impl = CurrentlyScrollingLayer()) { - return ScrollAnimationUpdateTarget(layer_impl, scroll_delta) - ? SCROLL_STARTED - : SCROLL_IGNORED; + if (ScrollAnimationUpdateTarget(layer_impl, scroll_delta)) { + scroll_status.thread = SCROLL_ON_IMPL_THREAD; + } else { + scroll_status.thread = SCROLL_IGNORED; + scroll_status.main_thread_scrolling_reasons = NOT_SCROLLABLE; + } + return scroll_status; } ScrollState scroll_state(0, 0, viewport_point.x(), viewport_point.y(), 0, 0, @@ -2643,9 +2690,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( // that can scroll and set up an animation of its scroll offset. Note that // this does not currently go through the scroll customization and viewport // machinery that ScrollBy uses for non-animated wheel scrolls. - InputHandler::ScrollStatus scroll_status = - ScrollBegin(&scroll_state, ANIMATED_WHEEL); - if (scroll_status == SCROLL_STARTED) { + scroll_status = ScrollBegin(&scroll_state, ANIMATED_WHEEL); + if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { gfx::Vector2dF pending_delta = scroll_delta; for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); layer_impl; layer_impl = NextLayerInScrollOrder(layer_impl)) { @@ -2674,7 +2720,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( ScrollAnimationCreate(layer_impl, target_offset, current_offset); SetNeedsOneBeginImplFrame(); - return SCROLL_STARTED; + return scroll_status; } } scroll_state.set_is_ending(true); @@ -3006,9 +3052,16 @@ void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state) { } InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { - if (!CurrentlyScrollingLayer()) - return SCROLL_IGNORED; - return SCROLL_STARTED; + InputHandler::ScrollStatus scroll_status; + scroll_status.main_thread_scrolling_reasons = + InputHandler::NOT_SCROLLING_ON_MAIN; + if (!CurrentlyScrollingLayer()) { + scroll_status.thread = SCROLL_IGNORED; + scroll_status.main_thread_scrolling_reasons = NO_SCROLLING_LAYER; + } else { + scroll_status.thread = SCROLL_ON_IMPL_THREAD; + } + return scroll_status; } float LayerTreeHostImpl::DeviceSpaceDistanceToLayer( @@ -3036,9 +3089,10 @@ void LayerTreeHostImpl::MouseMoveAt(const gfx::Point& viewport_point) { return; bool scroll_on_main_thread = false; + InputHandler::MainThreadScrollingReason main_thread_scrolling_reasons; LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint( device_viewport_point, InputHandler::GESTURE, layer_impl, - &scroll_on_main_thread, NULL); + &scroll_on_main_thread, NULL, &main_thread_scrolling_reasons); if (scroll_layer_impl == InnerViewportScrollLayer()) scroll_layer_impl = OuterViewportScrollLayer(); if (scroll_on_main_thread || !scroll_layer_impl) diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 6d78c16..1e0f7f6 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -683,7 +683,9 @@ class CC_EXPORT LayerTreeHostImpl InputHandler::ScrollInputType type, LayerImpl* layer_hit_by_point, bool* scroll_on_main_thread, - bool* optional_has_ancestor_scroll_handler) const; + bool* optional_has_ancestor_scroll_handler, + InputHandler::MainThreadScrollingReason* main_thread_scrolling_reason) + const; float DeviceSpaceDistanceToLayer(const gfx::PointF& device_viewport_point, LayerImpl* layer_impl); void StartScrollbarFadeRecursive(LayerImpl* layer); diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 814279e..72a3354 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -621,9 +621,12 @@ TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { host_impl_->SetViewportSize(gfx::Size(50, 50)); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(), InputHandler::WHEEL)); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); @@ -641,9 +644,12 @@ TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) { host_impl_->SetViewportSize(gfx::Size(50, 50)); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + EXPECT_FALSE(host_impl_->IsActivelyScrolling()); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); EXPECT_TRUE(host_impl_->IsActivelyScrolling()); @@ -653,9 +659,11 @@ TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) { TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) { // We should not crash when trying to scroll an empty layer tree. - EXPECT_EQ(InputHandler::SCROLL_IGNORED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NO_SCROLLING_LAYER, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { @@ -672,9 +680,11 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { // We should not crash when trying to scroll after the renderer initialization // fails. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { @@ -683,9 +693,10 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { DrawFrame(); // We should not crash if the tree is replaced while we are scrolling. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->active_tree()->DetachLayerTree(); scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); @@ -709,30 +720,37 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { // With registered event handlers, wheel scrolls don't necessarily // have to go to the main thread. root->SetHaveWheelEventHandlers(true); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); host_impl_->ScrollEnd(EndState().get()); // But typically the scroll-blocks-on mode will require them to. root->SetScrollBlocksOn(SCROLL_BLOCKS_ON_WHEEL_EVENT | SCROLL_BLOCKS_ON_START_TOUCH); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::EVENT_HANDLERS, status.main_thread_scrolling_reasons); // But gesture scrolls can still be handled. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); host_impl_->ScrollEnd(EndState().get()); // And if the handlers go away, wheel scrolls can again be processed // on impl (despite the scroll-blocks-on mode). root->SetHaveWheelEventHandlers(false); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); host_impl_->ScrollEnd(EndState().get()); } @@ -762,9 +780,11 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 10))); // But they don't influence the actual handling of the scroll gestures. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); host_impl_->ScrollEnd(EndState().get()); // It's the union of scroll-blocks-on mode bits across all layers in the @@ -785,36 +805,47 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnScrollEventHandlers) { // With registered scroll handlers, scrolls don't generally have to go // to the main thread. root->SetHaveScrollEventHandlers(true); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + host_impl_->ScrollEnd(EndState().get()); // Even the default scroll blocks on mode doesn't require this. root->SetScrollBlocksOn(SCROLL_BLOCKS_ON_WHEEL_EVENT | SCROLL_BLOCKS_ON_START_TOUCH); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + host_impl_->ScrollEnd(EndState().get()); // But the page can opt in to blocking on scroll event handlers. root->SetScrollBlocksOn(SCROLL_BLOCKS_ON_SCROLL_EVENT); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::EVENT_HANDLERS, status.main_thread_scrolling_reasons); // GESTURE and WHEEL scrolls behave identically in this regard. - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::EVENT_HANDLERS, status.main_thread_scrolling_reasons); // And if the handlers go away, scrolls can again be processed on impl // (despite the scroll-blocks-on mode). root->SetHaveScrollEventHandlers(false); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + host_impl_->ScrollEnd(EndState().get()); } @@ -858,46 +889,66 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnLayerTopology) { RebuildPropertyTrees(); } + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point(10, 10)).get(), InputHandler::GESTURE); // Scroll-blocks-on on a layer affects scrolls that hit that layer. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(), - InputHandler::GESTURE)); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); host_impl_->ScrollEnd(EndState().get()); + child1->SetScrollBlocksOn(SCROLL_BLOCKS_ON_SCROLL_EVENT); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::EVENT_HANDLERS, status.main_thread_scrolling_reasons); // But not those that hit only other layers. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); host_impl_->ScrollEnd(EndState().get()); // It's the union of bits set across the scroll ancestor chain that matters. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + host_impl_->ScrollEnd(EndState().get()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), - InputHandler::WHEEL)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + host_impl_->ScrollEnd(EndState().get()); root->SetScrollBlocksOn(SCROLL_BLOCKS_ON_WHEEL_EVENT); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + host_impl_->ScrollEnd(EndState().get()); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), - InputHandler::WHEEL)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::EVENT_HANDLERS, status.main_thread_scrolling_reasons); + child2->SetScrollBlocksOn(SCROLL_BLOCKS_ON_SCROLL_EVENT); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), - InputHandler::WHEEL)); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::EVENT_HANDLERS, status.main_thread_scrolling_reasons); + + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 25)).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::EVENT_HANDLERS, status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) { @@ -906,15 +957,23 @@ TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) { DrawFrame(); // Ignore the fling since no layer is being scrolled - EXPECT_EQ(InputHandler::SCROLL_IGNORED, host_impl_->FlingScrollBegin()); + InputHandler::ScrollStatus status = host_impl_->FlingScrollBegin(); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NO_SCROLLING_LAYER, + status.main_thread_scrolling_reasons); // Start scrolling a layer - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); // Now the fling should go ahead since we've started scrolling a layer - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + status = host_impl_->FlingScrollBegin(); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) { @@ -923,15 +982,23 @@ TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) { DrawFrame(); // Ignore the fling since no layer is being scrolled - EXPECT_EQ(InputHandler::SCROLL_IGNORED, host_impl_->FlingScrollBegin()); + InputHandler::ScrollStatus status = host_impl_->FlingScrollBegin(); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NO_SCROLLING_LAYER, + status.main_thread_scrolling_reasons); // Start scrolling a layer - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); // Now the fling should go ahead since we've started scrolling a layer - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + status = host_impl_->FlingScrollBegin(); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) { @@ -940,15 +1007,21 @@ TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) { DrawFrame(); LayerImpl* root = host_impl_->active_tree()->root_layer(); - root->SetShouldScrollOnMainThread(true); + root->set_main_thread_scrolling_reasons( + InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS); // Start scrolling a layer - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS, + status.main_thread_scrolling_reasons); // The fling should be ignored since there's no layer being scrolled impl-side - EXPECT_EQ(InputHandler::SCROLL_IGNORED, host_impl_->FlingScrollBegin()); + status = host_impl_->FlingScrollBegin(); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NO_SCROLLING_LAYER, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { @@ -957,14 +1030,20 @@ TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { DrawFrame(); LayerImpl* root = host_impl_->active_tree()->root_layer(); - root->SetShouldScrollOnMainThread(true); + root->set_main_thread_scrolling_reasons( + InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS, + status.main_thread_scrolling_reasons); + + status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { @@ -977,21 +1056,29 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { DrawFrame(); // All scroll types inside the non-fast scrollable region should fail. - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point(25, 25)).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point(25, 25)).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::NON_FAST_SCROLLABLE_REGION, + status.main_thread_scrolling_reasons); EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25), InputHandler::WHEEL)); - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point(25, 25)).get(), - InputHandler::GESTURE)); + + status = host_impl_->ScrollBegin(BeginState(gfx::Point(25, 25)).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::NON_FAST_SCROLLABLE_REGION, + status.main_thread_scrolling_reasons); EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25), InputHandler::GESTURE)); // All scroll types outside this region should succeed. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(), - InputHandler::WHEEL)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75), InputHandler::GESTURE)); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); @@ -1000,9 +1087,12 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { host_impl_->ScrollEnd(EndState().get()); EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75), InputHandler::GESTURE)); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(), - InputHandler::GESTURE)); + + status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(), + InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75), InputHandler::GESTURE)); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); @@ -1024,18 +1114,23 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { // This point would fall into the non-fast scrollable region except that we've // moved the layer down by 25 pixels. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point(40, 10)).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point(40, 10)).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); + EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10), InputHandler::WHEEL)); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 1)).get()); host_impl_->ScrollEnd(EndState().get()); // This point is still inside the non-fast region. - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(), - InputHandler::WHEEL)); + status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::NON_FAST_SCROLLABLE_REGION, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) { @@ -1072,9 +1167,11 @@ TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::GESTURE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); // Trying to scroll to the left/top will not succeed. EXPECT_FALSE( @@ -1145,9 +1242,10 @@ TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) { DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); // Trying to scroll if not user_scrollable_vertical will fail. host_impl_->InnerViewportScrollLayer()->set_user_scrollable_vertical(false); @@ -1180,9 +1278,10 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { DrawFrame(); gfx::Point scroll_position(10, 10); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(scroll_position).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->CurrentScrollOffset()); @@ -1194,9 +1293,10 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { overflow->set_user_scrollable_horizontal(false); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(scroll_position).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset()); @@ -1207,9 +1307,10 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { overflow->set_user_scrollable_vertical(false); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(scroll_position).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset()); @@ -1556,9 +1657,10 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { host_impl_->ScrollEnd(EndState().get()); gfx::Vector2d scroll_delta(0, 10); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -1907,9 +2009,10 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { new LatencyInfoSwapPromise(latency_info)); SetupScrollAndContentsLayers(gfx::Size(100, 100)); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); host_impl_->QueueSwapPromiseForMainThreadScrollUpdate( std::move(swap_promise)); @@ -3036,9 +3139,10 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { } // Scrolling should update metadata immediately. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); { CompositorFrameMetadata metadata = @@ -3669,9 +3773,11 @@ TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { DrawFrame(); // Scroll event is ignored because layer is not scrollable. - EXPECT_EQ(InputHandler::SCROLL_IGNORED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NO_SCROLLING_LAYER, + status.main_thread_scrolling_reasons); EXPECT_FALSE(did_request_redraw_); EXPECT_FALSE(did_request_commit_); } @@ -3817,9 +3923,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->top_controls_manager()->ScrollBegin(); @@ -3860,9 +3967,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) { gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10)); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); // Make the test scroll delta a fractional amount, to verify that the // fixed container size delta is (1) non-zero, and (2) fractional, and @@ -3904,9 +4012,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, outer_scroll->SetDrawsContent(true); host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2dF(0.f, 50.f)).get()); @@ -3926,9 +4035,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, host_impl_->ScrollEnd(EndState().get()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll); host_impl_->ScrollBy( @@ -3979,9 +4089,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) { // not be scaled. host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); // Scroll down, the top controls hiding should expand the viewport size so // the delta should be equal to the scroll distance. @@ -4028,9 +4139,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsDontTriggerCommit) { // Scroll 25px to hide top controls gfx::Vector2dF scroll_delta(0.f, 25.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_FALSE(did_request_commit_); } @@ -4072,9 +4184,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) { gfx::Vector2dF scroll_delta(0.f, 25.f); host_impl_->active_tree()->property_trees()->needs_rebuild = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4232,9 +4345,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) { // Hide the top controls by 25px. gfx::Vector2dF scroll_delta(0.f, 25.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); // scrolling down at the max extents no longer hides the top controls @@ -4259,9 +4373,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) { // Bring the top controls down by 25px. scroll_delta = gfx::Vector2dF(0.f, -25.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4288,9 +4403,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsAspectRatio) { host_impl_->top_controls_manager()->ContentTopOffset()); gfx::Vector2dF scroll_delta(0.f, 25.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4329,9 +4445,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { // Send a gesture scroll that will scroll the outer viewport, make sure the // top controls get scrolled. gfx::Vector2dF scroll_delta(0.f, 15.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(host_impl_->InnerViewportScrollLayer(), @@ -4343,9 +4460,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { host_impl_->top_controls_manager()->ContentTopOffset()); scroll_delta = gfx::Vector2dF(0.f, 50.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(0, host_impl_->top_controls_manager()->ContentTopOffset()); @@ -4360,9 +4478,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { host_impl_->InnerViewportScrollLayer()->SetScrollDelta(inner_viewport_offset); scroll_delta = gfx::Vector2dF(0.f, -65.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(top_controls_height_, @@ -4382,9 +4501,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, layer_size_, layer_size_, layer_size_); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->top_controls_manager()->ScrollBegin(); host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f)); @@ -4397,9 +4517,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, host_impl_->ScrollEnd(EndState().get()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); float scroll_increment_y = -25.f; host_impl_->top_controls_manager()->ScrollBegin(); @@ -4427,9 +4548,10 @@ TEST_F(LayerTreeHostImplTopControlsTest, gfx::ScrollOffset(), host_impl_->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); } TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { @@ -4461,9 +4583,10 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { host_impl_->SetViewportSize(surface_size); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); host_impl_->ScrollEnd(EndState().get()); EXPECT_TRUE(did_request_redraw_); @@ -4481,9 +4604,10 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { host_impl_->SetViewportSize(surface_size); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); host_impl_->ScrollEnd(EndState().get()); EXPECT_TRUE(did_request_redraw_); @@ -4501,9 +4625,12 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { // Scroll event is ignored because the input coordinate is outside the layer // boundaries. - EXPECT_EQ(InputHandler::SCROLL_IGNORED, - host_impl_->ScrollBegin(BeginState(gfx::Point(15, 5)).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point(15, 5)).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NO_SCROLLING_LAYER, + status.main_thread_scrolling_reasons); + EXPECT_FALSE(did_request_redraw_); EXPECT_FALSE(did_request_commit_); } @@ -4527,9 +4654,12 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { // Scroll event is ignored because the scrollable layer is not facing the // viewer and there is nothing scrollable behind it. - EXPECT_EQ(InputHandler::SCROLL_IGNORED, - host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NO_SCROLLING_LAYER, + status.main_thread_scrolling_reasons); + EXPECT_FALSE(did_request_redraw_); EXPECT_FALSE(did_request_commit_); } @@ -4540,7 +4670,8 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { LayerImpl::Create(host_impl_->active_tree(), 3); scoped_ptr<LayerImpl> content_layer = CreateScrollableLayer(1, surface_size, clip_layer.get()); - content_layer->SetShouldScrollOnMainThread(true); + content_layer->set_main_thread_scrolling_reasons( + InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS); content_layer->SetScrollClipLayer(Layer::INVALID_ID); // Note: we can use the same clip layer for both since both calls to @@ -4557,9 +4688,11 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { // Scrolling fails because the content layer is asking to be scrolled on the // main thread. - EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::HAS_BACKGROUND_ATTACHMENT_FIXED_OBJECTS, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { @@ -4585,9 +4718,10 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta = scroll_delta; gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4629,9 +4763,10 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta = scroll_delta; gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4726,9 +4861,10 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta(scroll_delta); gfx::ScrollOffset expected_max_scroll(outer_scroll->MaxScrollOffset()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4777,9 +4913,10 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { DrawFrame(); { gfx::Vector2d scroll_delta(-8, -7); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4837,9 +4974,10 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { DrawFrame(); { gfx::Vector2d scroll_delta(0, -10); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::NON_BUBBLING_GESTURE)); + InputHandler::NON_BUBBLING_GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4862,9 +5000,10 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { // The next time we scroll we should only scroll the parent. scroll_delta = gfx::Vector2d(0, -3); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::NON_BUBBLING_GESTURE)); + InputHandler::NON_BUBBLING_GESTURE) + .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child); @@ -4883,9 +5022,10 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { // After scrolling the parent, another scroll on the opposite direction // should still scroll the child. scroll_delta = gfx::Vector2d(0, 7); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::NON_BUBBLING_GESTURE)); + InputHandler::NON_BUBBLING_GESTURE) + .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); @@ -4906,9 +5046,10 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f); scroll_delta = gfx::Vector2d(0, -2); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(1, 1)).get(), - InputHandler::NON_BUBBLING_GESTURE)); + InputHandler::NON_BUBBLING_GESTURE) + .thread); EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -4952,9 +5093,10 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { DrawFrame(); { gfx::Vector2d scroll_delta(0, 4); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -5007,9 +5149,10 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { // Scrolling should still work even though we did not draw yet. RebuildPropertyTrees(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); } TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { @@ -5027,9 +5170,10 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { // Scroll to the right in screen coordinates with a gesture. gfx::Vector2d gesture_scroll_delta(10, 0); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -5041,9 +5185,10 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { // Reset and scroll down with the wheel. scroll_layer->SetScrollDelta(gfx::Vector2dF()); gfx::Vector2d wheel_scroll_delta(0, 10); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -5088,9 +5233,10 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { { // Scroll down in screen coordinates with a gesture. gfx::Vector2d gesture_scroll_delta(0, 10); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(1, 1)).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -5112,9 +5258,10 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { // Now reset and scroll the same amount horizontally. child_ptr->SetScrollDelta(gfx::Vector2dF()); gfx::Vector2d gesture_scroll_delta(10, 0); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(1, 1)).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -5191,9 +5338,10 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { for (int i = 0; i < 4; ++i) { child_ptr->SetScrollDelta(gfx::Vector2dF()); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(viewport_point).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy( UpdateState(viewport_point, gesture_scroll_deltas[i]).get()); viewport_point += gesture_scroll_deltas[i]; @@ -5225,9 +5373,10 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { // Scroll down in screen coordinates with a gesture. gfx::Vector2d scroll_delta(0, 10); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -5240,9 +5389,10 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { // Reset and scroll down with the wheel. scroll_layer->SetScrollDelta(gfx::Vector2dF()); gfx::Vector2d wheel_scroll_delta(0, 10); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -5394,9 +5544,10 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { gfx::Vector2dF scroll_delta(0.f, 10.f); gfx::ScrollOffset current_offset(7.f, 8.f); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); @@ -5470,9 +5621,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) { EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); // In-bounds scrolling does not affect overscroll. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); scroll_result = host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); EXPECT_TRUE(scroll_result.did_scroll); @@ -5619,9 +5771,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { DrawFrame(); { gfx::Vector2d scroll_delta(0, -10); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::NON_BUBBLING_GESTURE)); + InputHandler::NON_BUBBLING_GESTURE) + .thread); scroll_result = host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_TRUE(scroll_result.did_scroll); @@ -5632,9 +5785,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { // The next time we scroll we should only scroll the parent, but overscroll // should still not reach the root layer. scroll_delta = gfx::Vector2d(0, -30); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::NON_BUBBLING_GESTURE)); + InputHandler::NON_BUBBLING_GESTURE) + .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); scroll_result = @@ -5648,9 +5802,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { // After scrolling the parent, another scroll on the opposite direction // should scroll the child. scroll_delta = gfx::Vector2d(0, 70); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::NON_BUBBLING_GESTURE)); + InputHandler::NON_BUBBLING_GESTURE) + .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer); scroll_result = host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); @@ -5671,9 +5826,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) { DrawFrame(); { gfx::Vector2d scroll_delta(0, 8); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); scroll_result = host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_TRUE(scroll_result.did_scroll); @@ -5707,9 +5863,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) { EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); // Even though the layer can't scroll the overscroll still happens. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); scroll_result = host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); EXPECT_FALSE(scroll_result.did_scroll); @@ -5726,9 +5883,10 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { // Edge glow effect should be applicable only upon reaching Edges // of the content. unnecessary glow effect calls shouldn't be // called while scrolling up without reaching the edge of the content. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); scroll_result = host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get()); EXPECT_TRUE(scroll_result.did_scroll); @@ -5744,10 +5902,12 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { host_impl_->ScrollEnd(EndState().get()); // unusedrootDelta should be subtracted from applied delta so that // unwanted glow effect calls are not called. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::NON_BUBBLING_GESTURE)); - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), + InputHandler::NON_BUBBLING_GESTURE) + .thread); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->FlingScrollBegin().thread); scroll_result = host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2dF(0, 20)).get()); EXPECT_TRUE(scroll_result.did_scroll); @@ -5764,9 +5924,10 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { host_impl_->ScrollEnd(EndState().get()); // TestCase to check kEpsilon, which prevents minute values to trigger // gloweffect without reaching edge. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); scroll_result = host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2dF(-0.12f, 0.1f)).get()); EXPECT_FALSE(scroll_result.did_scroll); @@ -7460,11 +7621,13 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); { - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->FlingScrollBegin().thread); gfx::Vector2d scroll_delta(0, 100); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); @@ -7513,9 +7676,10 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { LayerImpl* grand_child = child->children()[0].get(); gfx::Vector2d scroll_delta(0, -2); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_TRUE( host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()) .did_scroll); @@ -7538,7 +7702,8 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { ExpectNone(*scroll_info, child->id()); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->FlingScrollBegin().thread); EXPECT_FALSE( host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()) .did_scroll); @@ -7581,11 +7746,13 @@ TEST_F(LayerTreeHostImplTest, WheelFlingShouldntBubble) { host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); { - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->FlingScrollBegin().thread); gfx::Vector2d scroll_delta(0, 100); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); @@ -7629,9 +7796,11 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) { DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread); + EXPECT_EQ(InputHandler::FAILED_HIT_TEST, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { @@ -7668,9 +7837,11 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread); + EXPECT_EQ(InputHandler::FAILED_HIT_TEST, + status.main_thread_scrolling_reasons); } TEST_F(LayerTreeHostImplTest, NotScrollInvisibleScroller) { @@ -7698,9 +7869,10 @@ TEST_F(LayerTreeHostImplTest, NotScrollInvisibleScroller) { // // Why SCROLL_STARTED? In this case, it's because we've bubbled out and // started scrolling the inner viewport. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_EQ(2, host_impl_->CurrentlyScrollingLayer()->id()); } @@ -7735,9 +7907,10 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleDescendent) { // We should have scrolled |invisible_scroll_layer| as it was hit and it has // a descendant which is a drawn RSLL member. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id()); } @@ -7789,9 +7962,10 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) { // We should have scrolled |child_scroll| even though it is invisible. // The reason for this is that if the scrolling the scroll would move a layer // that is a drawn RSLL member, then we should accept this hit. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id()); } @@ -7981,9 +8155,10 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); // Scrolling normally should not trigger any forwarding. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_TRUE( host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()) @@ -7997,9 +8172,10 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { // Scrolling with a scroll handler should defer the swap to the main // thread. scroll_layer->SetHaveScrollEventHandlers(true); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_TRUE( host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()) @@ -8080,9 +8256,10 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { BOTH, SHOWN, false); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8154,9 +8331,10 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, WheelUnhandledByTopControls) { LayerImpl* viewport_layer = host_impl_->InnerViewportScrollLayer(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(), viewport_layer->CurrentScrollOffset()); @@ -8187,9 +8365,10 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { BOTH, SHOWN, false); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8264,9 +8443,10 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { gfx::ScrollOffset(0, initial_scroll_offset)); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8334,9 +8514,10 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, gfx::ScrollOffset(0, initial_scroll_offset)); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8402,9 +8583,10 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, false); DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); float offset = 50; @@ -8577,11 +8759,13 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) { // Scrolling the viewport always sets the outer scroll layer as the // currently scrolling layer. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->FlingScrollBegin().thread); EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); gfx::Vector2d scroll_delta(inner_viewport.width() / 2.f, @@ -8597,11 +8781,13 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) { EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset()); // Fling past the inner viewport boundry, make sure outer viewport scrolls. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->FlingScrollBegin().thread); EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); @@ -8638,10 +8824,12 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset()); // Make sure the scroll goes to the inner viewport first. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + InputHandler::GESTURE) + .thread); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->FlingScrollBegin().thread); EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(), InputHandler::GESTURE)); @@ -8695,9 +8883,10 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, scoped_ptr<ScrollAndScaleSet> scroll_info; gfx::Vector2d scroll_delta(0, inner_viewport.height()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_TRUE( host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()) .did_scroll); @@ -8712,7 +8901,8 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll); // The fling have no effect on the currently scrolling layer. - EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin()); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->FlingScrollBegin().thread); EXPECT_FALSE( host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()) .did_scroll); @@ -8756,14 +8946,16 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, DrawFrame(); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->RootScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll); host_impl_->ScrollEnd(EndState().get()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll); host_impl_->ScrollEnd(EndState().get()); } @@ -8784,9 +8976,10 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, // Ensure inner viewport doesn't react to scrolls (test it's unscrollable). EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll->CurrentScrollOffset()); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::GESTURE)); + InputHandler::GESTURE) + .thread); scroll_result = host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get()); EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll->CurrentScrollOffset()); @@ -9089,8 +9282,9 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer(); EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), scrolling_layer); @@ -9113,8 +9307,9 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { EXPECT_TRUE(y > 1 && y < 49); // Update target. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); host_impl_->DidFinishImplFrame(); begin_frame_args.frame_time = @@ -9153,8 +9348,9 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE); // Perform animated scroll. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer(); @@ -9179,9 +9375,10 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { EXPECT_TRUE(y > 1 && y < 49); // Perform instant scroll. - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point(0, y)).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y), InputHandler::WHEEL)); host_impl_->ScrollBy( @@ -9217,8 +9414,9 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE); - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer(); @@ -9240,8 +9438,9 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { EXPECT_TRUE(y > 1 && y < 49); // Update target. - EXPECT_EQ(InputHandler::SCROLL_STARTED, - host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); host_impl_->DidFinishImplFrame(); begin_frame_args.frame_time = @@ -9379,9 +9578,10 @@ TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) { host_impl_->ScrollEnd(EndState().get()); gfx::Vector2dF scroll_delta(0, 5); - EXPECT_EQ(InputHandler::SCROLL_STARTED, + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL)); + InputHandler::WHEEL) + .thread); EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset()); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index ac20d47..6d34140 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc @@ -608,7 +608,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { gfx::Vector2dF(0.5f, 0.5f)); InputHandler::ScrollStatus status = impl->ScrollBegin( BeginState(scroll_point).get(), InputHandler::GESTURE); - EXPECT_EQ(InputHandler::SCROLL_STARTED, status); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); impl->ScrollBy(UpdateState(gfx::Point(), scroll_amount_).get()); LayerImpl* scrolling_layer = impl->CurrentlyScrollingLayer(); CHECK(scrolling_layer); @@ -631,7 +631,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { gfx::Vector2dF(0.5f, 0.5f)); InputHandler::ScrollStatus status = impl->ScrollBegin( BeginState(scroll_point).get(), InputHandler::WHEEL); - EXPECT_EQ(InputHandler::SCROLL_STARTED, status); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); impl->ScrollBy(UpdateState(gfx::Point(), scroll_amount_).get()); impl->ScrollEnd(EndState().get()); @@ -1034,24 +1034,29 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset // Set max_scroll_offset = (100, 100). scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); - EXPECT_EQ( - InputHandler::SCROLL_STARTED, - scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, - SCROLL_BLOCKS_ON_NONE)); + + InputHandler::ScrollStatus status = scroll_layer->TryScroll( + gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, SCROLL_BLOCKS_ON_NONE); + + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); // Set max_scroll_offset = (0, 0). scroll_layer->SetBounds(root->bounds()); - EXPECT_EQ( - InputHandler::SCROLL_IGNORED, - scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, - SCROLL_BLOCKS_ON_NONE)); + status = scroll_layer->TryScroll( + gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, SCROLL_BLOCKS_ON_NONE); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLABLE, + status.main_thread_scrolling_reasons); // Set max_scroll_offset = (-100, -100). scroll_layer->SetBounds(gfx::Size()); - EXPECT_EQ( - InputHandler::SCROLL_IGNORED, - scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, - SCROLL_BLOCKS_ON_NONE)); + status = scroll_layer->TryScroll( + gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, SCROLL_BLOCKS_ON_NONE); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLABLE, + status.main_thread_scrolling_reasons); EndTest(); } @@ -1085,14 +1090,18 @@ class LayerTreeHostScrollTestScrollNonDrawnLayer // Verify that the scroll layer's scroll offset is taken into account when // checking whether the screen space point is inside the non-fast // scrollable region. - EXPECT_EQ( - InputHandler::SCROLL_ON_MAIN_THREAD, - scroll_layer->TryScroll(gfx::PointF(1.f, 1.f), InputHandler::GESTURE, - SCROLL_BLOCKS_ON_NONE)); - EXPECT_EQ( - InputHandler::SCROLL_STARTED, - scroll_layer->TryScroll(gfx::PointF(21.f, 21.f), InputHandler::GESTURE, - SCROLL_BLOCKS_ON_NONE)); + + InputHandler::ScrollStatus status = scroll_layer->TryScroll( + gfx::PointF(1.f, 1.f), InputHandler::GESTURE, SCROLL_BLOCKS_ON_NONE); + EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread); + EXPECT_EQ(InputHandler::NON_FAST_SCROLLABLE_REGION, + status.main_thread_scrolling_reasons); + + status = scroll_layer->TryScroll( + gfx::PointF(21.f, 21.f), InputHandler::GESTURE, SCROLL_BLOCKS_ON_NONE); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::NOT_SCROLLING_ON_MAIN, + status.main_thread_scrolling_reasons); EndTest(); } diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp index 3903651..ccfd74e 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp @@ -344,7 +344,7 @@ void ScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(ScrollableArea* if (!platformSupportsCoordinatedScrollbar) { if (scrollbarGraphicsLayer) { WebLayer* scrollbarLayer = toWebLayer(scrollbarGraphicsLayer); - scrollbarLayer->setShouldScrollOnMainThread(true); + scrollbarLayer->addMainThreadScrollingReasons(WebMainThreadScrollingReason::ScrollBarScrolling); } return; } @@ -399,7 +399,7 @@ bool ScrollingCoordinator::scrollableAreaScrollLayerDidChange(ScrollableArea* sc // to set the WebLayer's scroll position at fractional precision otherwise the // WebLayer's position after snapping to device pixel can be off with regard to // fixed position elements. - if (m_lastMainThreadScrollingReasons & ScrollingCoordinator::HasNonLayerViewportConstrainedObjects) { + if (m_lastMainThreadScrollingReasons & WebMainThreadScrollingReason::HasNonLayerViewportConstrainedObjects) { webLayer->setScrollPositionDouble(DoublePoint(scrollableArea->scrollPosition() - scrollableArea->minimumScrollPosition())); } else { DoublePoint scrollPosition(scrollableArea->scrollPositionDouble() - scrollableArea->minimumScrollPositionDouble()); @@ -714,7 +714,10 @@ void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(MainTh return; if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) { m_lastMainThreadScrollingReasons = reasons; - scrollLayer->setShouldScrollOnMainThread(reasons); + if (reasons) + scrollLayer->addMainThreadScrollingReasons(static_cast<WebMainThreadScrollingReason::WebMainThreadScrollingReason>(reasons)); + else + scrollLayer->clearMainThreadScrollingReasons(); } } @@ -1023,7 +1026,7 @@ MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() co MainThreadScrollingReasons reasons = static_cast<MainThreadScrollingReasons>(0); if (!m_page->settings().threadedScrollingEnabled()) - reasons |= ThreadedScrollingDisabled; + reasons |= WebMainThreadScrollingReason::ThreadedScrollingDisabled; if (!m_page->mainFrame()->isLocalFrame()) return reasons; @@ -1032,7 +1035,7 @@ MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() co return reasons; if (frameView->hasBackgroundAttachmentFixedObjects()) - reasons |= HasBackgroundAttachmentFixedObjects; + reasons |= WebMainThreadScrollingReason::HasBackgroundAttachmentFixedObjects; FrameView::ScrollingReasons scrollingReasons = frameView->scrollingReasons(); const bool mayBeScrolledByInput = (scrollingReasons == FrameView::Scrollable); const bool mayBeScrolledByScript = mayBeScrolledByInput || (scrollingReasons == @@ -1043,7 +1046,7 @@ MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() co // not let this move there path as an optimization, when we have slow-repaint // elements. if (mayBeScrolledByScript && hasVisibleSlowRepaintViewportConstrainedObjects(frameView)) { - reasons |= HasNonLayerViewportConstrainedObjects; + reasons |= WebMainThreadScrollingReason::HasNonLayerViewportConstrainedObjects; } return reasons; @@ -1053,11 +1056,11 @@ String ScrollingCoordinator::mainThreadScrollingReasonsAsText(MainThreadScrollin { StringBuilder stringBuilder; - if (reasons & ScrollingCoordinator::HasBackgroundAttachmentFixedObjects) + if (reasons & WebMainThreadScrollingReason::HasBackgroundAttachmentFixedObjects) stringBuilder.appendLiteral("Has background-attachment:fixed, "); - if (reasons & ScrollingCoordinator::HasNonLayerViewportConstrainedObjects) + if (reasons & WebMainThreadScrollingReason::HasNonLayerViewportConstrainedObjects) stringBuilder.appendLiteral("Has non-layer viewport-constrained objects, "); - if (reasons & ScrollingCoordinator::ThreadedScrollingDisabled) + if (reasons & WebMainThreadScrollingReason::ThreadedScrollingDisabled) stringBuilder.appendLiteral("Threaded scrolling is disabled, "); if (stringBuilder.length()) diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h index 2b55d1f..fd48d40 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h @@ -31,6 +31,7 @@ #include "platform/PlatformWheelEvent.h" #include "platform/geometry/IntRect.h" #include "platform/scroll/ScrollTypes.h" +#include "public/platform/WebMainThreadScrollingReason.h" #include "wtf/Noncopyable.h" #include "wtf/text/WTFString.h" @@ -95,12 +96,6 @@ public: void handleWheelEventPhase(PlatformWheelEventPhase); #endif - enum MainThreadScrollingReasonFlags { - HasBackgroundAttachmentFixedObjects = 1 << 0, - HasNonLayerViewportConstrainedObjects = 1 << 1, - ThreadedScrollingDisabled = 1 << 2 - }; - MainThreadScrollingReasons mainThreadScrollingReasons() const; bool shouldUpdateScrollLayerPositionOnMainThread() const { return mainThreadScrollingReasons() != 0; } diff --git a/third_party/WebKit/Source/web/PageOverlay.cpp b/third_party/WebKit/Source/web/PageOverlay.cpp index d5b1544..0bcd39e 100644 --- a/third_party/WebKit/Source/web/PageOverlay.cpp +++ b/third_party/WebKit/Source/web/PageOverlay.cpp @@ -31,6 +31,7 @@ #include "core/frame/FrameHost.h" #include "core/frame/Settings.h" #include "core/page/Page.h" +#include "core/page/scrolling/ScrollingCoordinator.h" #include "platform/graphics/GraphicsContext.h" #include "platform/graphics/GraphicsLayer.h" #include "platform/graphics/GraphicsLayerClient.h" @@ -84,7 +85,7 @@ void PageOverlay::update() // This is required for contents of overlay to stay in sync with the page while scrolling. WebLayer* platformLayer = m_layer->platformLayer(); - platformLayer->setShouldScrollOnMainThread(true); + platformLayer->addMainThreadScrollingReasons(WebMainThreadScrollingReason::PageOverlay); page->frameHost().visualViewport().containerLayer()->addChild(m_layer.get()); } diff --git a/third_party/WebKit/public/platform/WebLayer.h b/third_party/WebKit/public/platform/WebLayer.h index 6ef2535..0d40182 100644 --- a/third_party/WebKit/public/platform/WebLayer.h +++ b/third_party/WebKit/public/platform/WebLayer.h @@ -32,6 +32,7 @@ #include "WebCompositorAnimation.h" #include "WebDoublePoint.h" #include "WebFloatPoint3D.h" +#include "WebMainThreadScrollingReason.h" #include "WebPoint.h" #include "WebRect.h" #include "WebScrollBlocksOn.h" @@ -207,7 +208,10 @@ public: virtual void setHaveScrollEventHandlers(bool) = 0; virtual bool haveScrollEventHandlers() const = 0; - virtual void setShouldScrollOnMainThread(bool) = 0; + // Indicates that this layer will always scroll on the main thread for the provided reason. + virtual void addMainThreadScrollingReasons(WebMainThreadScrollingReason::WebMainThreadScrollingReason) = 0; + // Indicates that the layer could scroll on the compositor thread. + virtual void clearMainThreadScrollingReasons() = 0; virtual bool shouldScrollOnMainThread() const = 0; virtual void setNonFastScrollableRegion(const WebVector<WebRect>&) = 0; diff --git a/third_party/WebKit/public/platform/WebMainThreadScrollingReason.h b/third_party/WebKit/public/platform/WebMainThreadScrollingReason.h new file mode 100644 index 0000000..7dcae44 --- /dev/null +++ b/third_party/WebKit/public/platform/WebMainThreadScrollingReason.h @@ -0,0 +1,26 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WebMainThreadScrollingReason_h +#define WebMainThreadScrollingReason_h + +#include "WebCommon.h" + +namespace blink { + +// Ensure this stays in sync with InputHandler::MainThreadScrollingReason. +namespace WebMainThreadScrollingReason { +enum WebMainThreadScrollingReason { + NotScrollingOnMain = 0, + HasBackgroundAttachmentFixedObjects = 1 << 0, + HasNonLayerViewportConstrainedObjects = 1 << 1, + ThreadedScrollingDisabled = 1 << 2, + ScrollBarScrolling = 1 << 3, + PageOverlay = 1 << 4 +}; +} // namespace MainThreadScrollingReason + +} // namespace blink + +#endif diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index c5502bf..999559c 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -39212,6 +39212,28 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. </summary> </histogram> +<histogram name="Renderer4.MainThreadGestureScrollReason" + enum="MainThreadScrollingReason"> + <owner>tdresser@chromium.org</owner> + <summary> + Ideally we'd always scroll on the impl thread, but there are a variety of + situations where we need to scroll on main. We should try to drive these + down. For every gesture, we record whether or not the scroll occurred on the + main thread, and if it did, what the reason was. + </summary> +</histogram> + +<histogram name="Renderer4.MainThreadWheelScrollReason" + enum="MainThreadScrollingReason"> + <owner>tdresser@chromium.org</owner> + <summary> + Ideally we'd always scroll on the impl thread, but there are a variety of + situations where we need to scroll on main. We should try to drive these + down. For every wheel tick, we record whether or not the the scroll occurred + on the main thread, and if it did, what the reason was. + </summary> +</histogram> + <histogram name="Renderer4.pixelCountCulled_Draw" units="NormalizedPixels"> <owner>wiltzius@chromium.org</owner> <summary> @@ -51193,8 +51215,8 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. </histogram> <histogram name="TryScroll.SlowScroll" enum="ScrollThread"> - <owner>Please list the metric's owners. Add more owner tags as needed.</owner> - <summary>Whether the scroll is executed on main thread.</summary> + <owner>tdresser@chromium.org</owner> + <summary>Whether a scroll is executed on main thread.</summary> </histogram> <histogram name="UMA.ActualLogUploadInterval" units="minutes"> @@ -69968,6 +69990,22 @@ To add a new entry, add it with any value and run test to compute valid value. <int value="1" label="cache-control: no-store"/> </enum> +<enum name="MainThreadScrollingReason" type="int"> + <int value="0" label="Not scrolling on main"/> + <int value="1" label="Background attachment fixed"/> + <int value="2" label="Non layer viewport constrained"/> + <int value="3" label="Threaded scrolling disabled"/> + <int value="4" label="Scrollbar scrolling"/> + <int value="5" label="Page overlay"/> + <int value="6" label="Non-fast scrollable region"/> + <int value="7" label="Event handlers"/> + <int value="8" label="Failed hit test"/> + <int value="9" label="No scrolling layer"/> + <int value="10" label="Not scrollable"/> + <int value="11" label="Continuing main thread scroll"/> + <int value="12" label="Non-invertible transform"/> +</enum> + <enum name="MakeChromeDefaultResult" type="int"> <int value="0" label="Chrome made default"/> <int value="1" label="Dialog closed without explicit choice"/> diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc index b0b7659..8511af6 100644 --- a/ui/events/blink/input_handler_proxy.cc +++ b/ui/events/blink/input_handler_proxy.cc @@ -359,6 +359,51 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent( return DID_NOT_HANDLE; } +void RecordMainThreadScrollingReasons( + WebInputEvent::Type type, + cc::InputHandler::MainThreadScrollingReason reasons) { + static const char* kGestureHistogramName = + "Renderer4.MainThreadGestureScrollReason"; + static const char* kWheelHistogramName = + "Renderer4.MainThreadWheelScrollReason"; + + DCHECK(type == WebInputEvent::GestureScrollBegin || + type == WebInputEvent::MouseWheel); + + if (type != WebInputEvent::GestureScrollBegin && + type != WebInputEvent::MouseWheel) { + return; + } + + if (reasons == cc::InputHandler::NOT_SCROLLING_ON_MAIN) { + if (type == WebInputEvent::GestureScrollBegin) { + UMA_HISTOGRAM_ENUMERATION( + kGestureHistogramName, cc::InputHandler::NOT_SCROLLING_ON_MAIN, + cc::InputHandler::MainThreadScrollingReasonCount); + } else { + UMA_HISTOGRAM_ENUMERATION( + kWheelHistogramName, cc::InputHandler::NOT_SCROLLING_ON_MAIN, + cc::InputHandler::MainThreadScrollingReasonCount); + } + } + + for (int i = 0; i < cc::InputHandler::MainThreadScrollingReasonCount - 1; + ++i) { + unsigned val = 1 << i; + if (reasons & val) { + if (type == WebInputEvent::GestureScrollBegin) { + UMA_HISTOGRAM_ENUMERATION( + kGestureHistogramName, i + 1, + cc::InputHandler::MainThreadScrollingReasonCount); + } else { + UMA_HISTOGRAM_ENUMERATION( + kWheelHistogramName, i + 1, + cc::InputHandler::MainThreadScrollingReasonCount); + } + } + } +} + bool InputHandlerProxy::ShouldAnimate( const blink::WebMouseWheelEvent& event) const { #if defined(OS_MACOSX) @@ -396,8 +441,12 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollAnimated(gfx::Point(wheel_event.x, wheel_event.y), scroll_delta); - switch (scroll_status) { - case cc::InputHandler::SCROLL_STARTED: + + RecordMainThreadScrollingReasons( + wheel_event.type, scroll_status.main_thread_scrolling_reasons); + + switch (scroll_status.thread) { + case cc::InputHandler::SCROLL_ON_IMPL_THREAD: result = DID_HANDLE; break; case cc::InputHandler::SCROLL_IGNORED: @@ -410,11 +459,14 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( } else { cc::ScrollState scroll_state_begin(0, 0, wheel_event.x, wheel_event.y, 0, 0, true, false, false); - cc::InputHandler::ScrollStatus scroll_status = - input_handler_->ScrollBegin(&scroll_state_begin, - cc::InputHandler::WHEEL); - switch (scroll_status) { - case cc::InputHandler::SCROLL_STARTED: { + cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( + &scroll_state_begin, cc::InputHandler::WHEEL); + + RecordMainThreadScrollingReasons( + wheel_event.type, scroll_status.main_thread_scrolling_reasons); + + switch (scroll_status.thread) { + case cc::InputHandler::SCROLL_ON_IMPL_THREAD: { TRACE_EVENT_INSTANT2("input", "InputHandlerProxy::handle_input wheel scroll", TRACE_EVENT_SCOPE_THREAD, "deltaX", @@ -487,10 +539,14 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin( input_handler_->ScrollBegin(&scroll_state, cc::InputHandler::GESTURE); } UMA_HISTOGRAM_ENUMERATION("Renderer4.CompositorScrollHitTestResult", - scroll_status, + scroll_status.thread, cc::InputHandler::ScrollStatusCount); - switch (scroll_status) { - case cc::InputHandler::SCROLL_STARTED: + + RecordMainThreadScrollingReasons(gesture_event.type, + scroll_status.main_thread_scrolling_reasons); + + switch (scroll_status.thread) { + case cc::InputHandler::SCROLL_ON_IMPL_THREAD: TRACE_EVENT_INSTANT0("input", "InputHandlerProxy::handle_input gesture scroll", TRACE_EVENT_SCOPE_THREAD); @@ -542,8 +598,9 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollEnd( InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart( const WebGestureEvent& gesture_event) { cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); - cc::InputHandler::ScrollStatus scroll_status = - cc::InputHandler::SCROLL_ON_MAIN_THREAD; + cc::InputHandler::ScrollStatus scroll_status; + scroll_status.main_thread_scrolling_reasons = + cc::InputHandler::NOT_SCROLLING_ON_MAIN; switch (gesture_event.sourceDevice) { case blink::WebGestureDeviceTouchpad: if (gesture_event.data.flingStart.targetViewport) { @@ -555,10 +612,13 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart( } break; case blink::WebGestureDeviceTouchscreen: - if (!gesture_scroll_on_impl_thread_) - scroll_status = cc::InputHandler::SCROLL_ON_MAIN_THREAD; - else + if (!gesture_scroll_on_impl_thread_) { + scroll_status.thread = cc::InputHandler::SCROLL_ON_MAIN_THREAD; + scroll_status.main_thread_scrolling_reasons = + cc::InputHandler::CONTINUING_MAIN_THREAD_SCROLL; + } else { scroll_status = input_handler_->FlingScrollBegin(); + } break; case blink::WebGestureDeviceUninitialized: NOTREACHED(); @@ -569,8 +629,8 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart( expect_scroll_update_end_ = false; #endif - switch (scroll_status) { - case cc::InputHandler::SCROLL_STARTED: { + switch (scroll_status.thread) { + case cc::InputHandler::SCROLL_ON_IMPL_THREAD: { if (gesture_event.sourceDevice == blink::WebGestureDeviceTouchpad) { scroll_state.set_is_ending(true); input_handler_->ScrollEnd(&scroll_state); diff --git a/ui/events/blink/input_handler_proxy_unittest.cc b/ui/events/blink/input_handler_proxy_unittest.cc index ccf24f4..3beb7e8 100644 --- a/ui/events/blink/input_handler_proxy_unittest.cc +++ b/ui/events/blink/input_handler_proxy_unittest.cc @@ -242,6 +242,18 @@ WebTouchPoint CreateWebTouchPoint(WebTouchPoint::State state, float x, return point; } +const cc::InputHandler::ScrollStatus kImplThreadScrollState( + cc::InputHandler::SCROLL_ON_IMPL_THREAD, + cc::InputHandler::NOT_SCROLLING_ON_MAIN); + +const cc::InputHandler::ScrollStatus kMainThreadScrollState( + cc::InputHandler::SCROLL_ON_MAIN_THREAD, + cc::InputHandler::EVENT_HANDLERS); + +const cc::InputHandler::ScrollStatus kScrollIgnoredScrollState( + cc::InputHandler::SCROLL_IGNORED, + cc::InputHandler::NOT_SCROLLABLE); + } // namespace class InputHandlerProxyTest @@ -321,7 +333,7 @@ class InputHandlerProxyTest VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = source_device; EXPECT_EQ(expected_disposition_, @@ -330,7 +342,7 @@ class InputHandlerProxyTest VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); gesture_ = @@ -404,7 +416,7 @@ TEST_P(InputHandlerProxyTest, DISABLED_MouseWheelWithPreciseScrollingDeltas) { // Smooth scroll because hasPreciseScrollingDeltas is set to false. wheel.hasPreciseScrollingDeltas = false; EXPECT_CALL(mock_input_handler_, ScrollAnimated(::testing::_, ::testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); VERIFY_AND_RESET_MOCKS(); @@ -412,7 +424,7 @@ TEST_P(InputHandlerProxyTest, DISABLED_MouseWheelWithPreciseScrollingDeltas) { // No smooth scroll because hasPreciseScrollingDeltas is set to true. wheel.hasPreciseScrollingDeltas = true; EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollBy(::testing::_)) .WillOnce(testing::Return(scroll_result_did_scroll_)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); @@ -433,7 +445,7 @@ TEST_P(InputHandlerProxyTest, DISABLED_MouseWheelScrollIgnored) { wheel.type = WebInputEvent::MouseWheel; EXPECT_CALL(mock_input_handler_, ScrollAnimated(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED)); + .WillOnce(testing::Return(kScrollIgnoredScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); VERIFY_AND_RESET_MOCKS(); @@ -445,7 +457,7 @@ TEST_P(InputHandlerProxyTest, GestureScrollStarted) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; EXPECT_EQ(expected_disposition_,input_handler_->HandleInputEvent(gesture_)); @@ -492,7 +504,7 @@ TEST_P(InputHandlerProxyTest, GestureScrollOnMainThread) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); + .WillOnce(testing::Return(kMainThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -524,7 +536,7 @@ TEST_P(InputHandlerProxyTest, GestureScrollIgnored) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED)); + .WillOnce(testing::Return(kScrollIgnoredScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -544,7 +556,7 @@ TEST_P(InputHandlerProxyTest, GestureScrollBeginThatTargetViewport) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, RootScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.data.scrollBegin.targetViewport = true; @@ -640,7 +652,7 @@ TEST_P(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); + .WillOnce(testing::Return(kMainThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -717,7 +729,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingStartedTouchpad) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); @@ -740,7 +752,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingOnMainThreadTouchpad) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); + .WillOnce(testing::Return(kMainThreadScrollState)); gesture_.type = WebInputEvent::GestureFlingStart; gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; @@ -764,7 +776,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingIgnoredTouchpad) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED)); + .WillOnce(testing::Return(kScrollIgnoredScrollState)); gesture_.type = WebInputEvent::GestureFlingStart; gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; @@ -801,7 +813,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) { modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -822,7 +834,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) { // The second call should start scrolling in the -X direction. EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL( mock_input_handler_, ScrollBy(testing::Property(&cc::ScrollState::delta_x, testing::Lt(0)))) @@ -839,7 +851,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) { // rest of the fling can be // transferred to the main thread. EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); + .WillOnce(testing::Return(kMainThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_)).Times(0); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)).Times(0); // Expected wheel fling animation parameters: @@ -907,7 +919,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -926,7 +938,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { // The second call should start scrolling in the -X direction. EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL( mock_input_handler_, ScrollBy(testing::Property(&cc::ScrollState::delta_x, testing::Lt(0)))) @@ -943,7 +955,8 @@ TEST_P(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { // rest of the fling can be // transferred to the main thread. EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); + .WillOnce(testing::Return(kMainThreadScrollState)); + EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_)).Times(0); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)).Times(0); @@ -1007,7 +1020,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); expected_disposition_ = InputHandlerProxy::DID_HANDLE; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1026,7 +1039,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { // Tick the second fling once normally. EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL( mock_input_handler_, ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)))) @@ -1039,7 +1052,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { // Then abort the second fling. EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); + .WillOnce(testing::Return(kMainThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_)).Times(0); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)).Times(0); @@ -1072,7 +1085,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingStartedTouchscreen) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1080,7 +1093,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingStartedTouchscreen) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); gesture_.type = WebInputEvent::GestureFlingStart; @@ -1106,7 +1119,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingOnMainThreadTouchscreen) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); + .WillOnce(testing::Return(kMainThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1133,7 +1146,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; @@ -1145,7 +1158,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) { // Flings ignored by the InputHandler should be dropped, signalling the end // of the touch scroll sequence. EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED)); + .WillOnce(testing::Return(kScrollIgnoredScrollState)); gesture_.type = WebInputEvent::GestureFlingStart; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; @@ -1157,7 +1170,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) { // GestureFlingCancel, as the original GestureFlingStart was dropped. expected_disposition_ = InputHandlerProxy::DID_HANDLE; EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1171,7 +1184,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; @@ -1193,7 +1206,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) { modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); VERIFY_AND_RESET_MOCKS(); @@ -1232,7 +1245,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingWithValidTimestamp) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; @@ -1256,7 +1269,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingWithValidTimestamp) { modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); VERIFY_AND_RESET_MOCKS(); @@ -1288,7 +1301,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingWithInvalidTimestamp) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; @@ -1315,7 +1328,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingWithInvalidTimestamp) { gesture_.modifiers = modifiers; EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); VERIFY_AND_RESET_MOCKS(); @@ -1353,7 +1366,7 @@ TEST_P(InputHandlerProxyTest, GestureScrollOnImplThreadFlagClearedAfterFling) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1378,7 +1391,7 @@ TEST_P(InputHandlerProxyTest, GestureScrollOnImplThreadFlagClearedAfterFling) { modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); // |gesture_scroll_on_impl_thread_| should still be true after @@ -1426,7 +1439,7 @@ TEST_P(InputHandlerProxyTest, VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1448,7 +1461,7 @@ TEST_P(InputHandlerProxyTest, fling_point, fling_global_point, modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); // |gesture_scroll_on_impl_thread_| should still be true after @@ -1461,7 +1474,7 @@ TEST_P(InputHandlerProxyTest, // result, this scroll begin will cancel the previous fling. EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1484,7 +1497,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) { gesture_.data.flingStart.velocityX = fling_delta.x; gesture_.data.flingStart.velocityY = fling_delta.y; EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1498,7 +1511,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) { // The second animate starts scrolling in the positive X and Y directions. EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL( mock_input_handler_, ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Lt(0)))) @@ -1517,7 +1530,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) { overscroll.accumulated_root_overscroll = gfx::Vector2dF(0, 100); overscroll.unused_scroll_delta = gfx::Vector2dF(0, 10); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL( mock_input_handler_, ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Lt(0)))) @@ -1538,7 +1551,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) { // The next call to animate will no longer scroll vertically. EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL( mock_input_handler_, ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Eq(0)))) @@ -1555,7 +1568,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; @@ -1579,7 +1592,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) { modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); VERIFY_AND_RESET_MOCKS(); @@ -1636,7 +1649,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1649,7 +1662,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) { gesture_.data.flingStart.velocityX = fling_delta.x; gesture_.data.flingStart.velocityY = fling_delta.y; EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); VERIFY_AND_RESET_MOCKS(); @@ -1790,7 +1803,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -1811,7 +1824,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) { gesture_.data.flingStart.velocityX = fling_delta.x; gesture_.data.flingStart.velocityY = fling_delta.y; EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); @@ -1842,7 +1855,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) { VERIFY_AND_RESET_MOCKS(); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); gesture_.type = WebInputEvent::GestureScrollBegin; gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; @@ -1866,7 +1879,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) { modifiers); EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); VERIFY_AND_RESET_MOCKS(); @@ -2051,7 +2064,7 @@ TEST_P(InputHandlerProxyTest, NoFlingBoostIfScrollTargetsDifferentLayer) { .WillOnce(testing::Return(false)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); time += dt; gesture_.timeStampSeconds = InSecondsF(time); @@ -2092,7 +2105,7 @@ TEST_P(InputHandlerProxyTest, NoFlingBoostIfScrollDelayed) { time += base::TimeDelta::FromMilliseconds(100); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); Animate(time); VERIFY_AND_RESET_MOCKS(); @@ -2137,7 +2150,7 @@ TEST_P(InputHandlerProxyTest, NoFlingBoostIfNotAnimated) { gesture_.data.scrollUpdate.deltaY = -40; EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_)) .WillOnce(testing::Return(scroll_result_did_scroll_)); EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); @@ -2220,7 +2233,7 @@ TEST_P(InputHandlerProxyTest, NoFlingBoostIfScrollInDifferentDirection) { gesture_.data.scrollUpdate.deltaX = -fling_delta.x; EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollBy(testing::Property(&cc::ScrollState::delta_x, testing::Eq(fling_delta.x)))) @@ -2327,7 +2340,7 @@ TEST_P(InputHandlerProxyTest, FlingBoostTerminatedDuringScrollSequence) { .WillOnce(testing::Return(scroll_result_did_not_scroll_)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); Animate(time); VERIFY_AND_RESET_MOCKS(); @@ -2377,7 +2390,7 @@ TEST_P(InputHandlerProxyTest, DidReceiveInputEvent_ForFling) { gesture_.data.flingStart.velocityY = fling_delta.y; EXPECT_SET_NEEDS_ANIMATE_INPUT(1); EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) - .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); + .WillOnce(testing::Return(kImplThreadScrollState)); EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); EXPECT_EQ(InputHandlerProxy::DID_HANDLE, input_handler_->HandleInputEvent(gesture_)); |