diff options
-rw-r--r-- | content/browser/renderer_host/render_widget_host_impl.cc | 35 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_impl.h | 8 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_base.cc | 55 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_base.h | 2 | ||||
-rw-r--r-- | content/common/view_messages.h | 4 | ||||
-rw-r--r-- | content/content_browser.gypi | 2 | ||||
-rw-r--r-- | content/port/browser/render_widget_host_view_port.h | 7 | ||||
-rw-r--r-- | content/port/browser/smooth_scroll_gesture.h | 33 | ||||
-rw-r--r-- | content/renderer/gpu/gpu_benchmarking_extension.cc | 42 | ||||
-rw-r--r-- | content/renderer/render_widget.cc | 4 | ||||
-rw-r--r-- | content/renderer/render_widget.h | 4 |
11 files changed, 194 insertions, 2 deletions
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 795614f..e8b5dcb 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -29,6 +29,7 @@ #include "content/common/gpu/gpu_messages.h" #include "content/common/view_messages.h" #include "content/port/browser/render_widget_host_view_port.h" +#include "content/port/browser/smooth_scroll_gesture.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -74,6 +75,9 @@ static const int kPaintMsgTimeoutMS = 50; // How long to wait before we consider a renderer hung. static const int kHungRendererDelayMs = 30000; +// How many milliseconds apart synthetic scroll messages should be sent. +static const int kSyntheticScrollMessageIntervalMs = 8; + // Returns |true| if the two wheel events should be coalesced. bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event, const WebMouseWheelEvent& new_event) { @@ -280,6 +284,7 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnMsgUpdateRect) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateIsDelayed, OnMsgUpdateIsDelayed) IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnMsgInputEventAck) + IPC_MESSAGE_HANDLER(ViewHostMsg_BeginSmoothScroll, OnMsgBeginSmoothScroll) IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnMsgFocus) IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur) IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeNumTouchEvents, @@ -1473,6 +1478,36 @@ void RenderWidgetHostImpl::OnMsgInputEventAck(WebInputEvent::Type event_type, Details<int>(&type)); } +void RenderWidgetHostImpl::OnMsgBeginSmoothScroll( + bool scroll_down, bool scroll_far) { + if (!view_) + return; + active_smooth_scroll_gesture_.reset( + view_->CreateSmoothScrollGesture(scroll_down, scroll_far)); + TickActiveSmoothScrollGesture(); +} + +void RenderWidgetHostImpl::TickActiveSmoothScrollGesture() { + if (!active_smooth_scroll_gesture_.get()) + return; + + TimeTicks now = TimeTicks::HighResNow(); + + // Post the next tick right away so it is regular. + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture, + weak_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs)); + + + bool active = active_smooth_scroll_gesture_->ForwardInputEvents(now, this); + if (!active) { + active_smooth_scroll_gesture_.reset(); + // TODO(nduca): send "smooth scroll done" event to RenderWidget. + } +} + void RenderWidgetHostImpl::ProcessWheelAck(bool processed) { mouse_wheel_pending_ = false; diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index d01780f..00438bc 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h @@ -49,6 +49,7 @@ namespace content { class RenderWidgetHostDelegate; class RenderWidgetHostViewPort; +class SmoothScrollGesture; class TapSuppressionController; // This implements the RenderWidgetHost interface that is exposed to @@ -490,6 +491,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, void OnMsgUpdateIsDelayed(); void OnMsgInputEventAck(WebKit::WebInputEvent::Type event_type, bool processed); + void OnMsgBeginSmoothScroll(bool scroll_down, bool scroll_far); virtual void OnMsgFocus(); virtual void OnMsgBlur(); void OnMsgDidChangeNumTouchEvents(int count); @@ -581,6 +583,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, // which may get in recursive loops). void DelayedAutoResized(); + // Called periodically to advance the active scroll gesture after being + // initiated by OnMsgBeginSmoothScroll. + void TickActiveSmoothScrollGesture(); + // Our delegate, which wants to know mainly about keyboard events. RenderWidgetHostDelegate* delegate_; @@ -758,6 +764,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, scoped_ptr<TapSuppressionController> tap_suppression_controller_; + scoped_ptr<SmoothScrollGesture> active_smooth_scroll_gesture_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl); }; diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 8fee3f1..1a6e8cd 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/port/browser/smooth_scroll_gesture.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" #include "ui/gfx/display.h" #include "ui/gfx/screen.h" @@ -20,6 +21,12 @@ namespace content { +// How long a smooth scroll gesture should run when it is a near scroll. +static const double kDurationOfNearScrollGestureSec = 0.15; + +// How long a smooth scroll gesture should run when it is a far scroll. +static const double kDurationOfFarScrollGestureSec = 0.5; + // static RenderWidgetHostViewPort* RenderWidgetHostViewPort::FromRWHV( RenderWidgetHostView* rwhv) { @@ -112,4 +119,52 @@ void RenderWidgetHostViewBase::UpdateScreenInfo() { } } +class BasicMouseWheelSmoothScrollGesture + : public SmoothScrollGesture { + public: + BasicMouseWheelSmoothScrollGesture(bool scroll_down, bool scroll_far) + : start_time_(base::TimeTicks::HighResNow()), + scroll_down_(scroll_down), + scroll_far_(scroll_far) { } + + virtual bool ForwardInputEvents(base::TimeTicks now, + RenderWidgetHost* host) OVERRIDE { + double duration_in_seconds; + if (scroll_far_) + duration_in_seconds = kDurationOfFarScrollGestureSec; + else + duration_in_seconds = kDurationOfNearScrollGestureSec; + + if (now - start_time_ > base::TimeDelta::FromSeconds(duration_in_seconds)) + return false; + + WebKit::WebMouseWheelEvent event; + event.type = WebKit::WebInputEvent::MouseWheel; + // TODO(nduca): Figure out plausible value. + event.deltaY = scroll_down_ ? -10 : 10; + event.wheelTicksY = scroll_down_ ? 1 : -1; + event.modifiers = 0; + + // TODO(nduca): Figure out plausible x and y values. + event.globalX = 0; + event.globalY = 0; + event.x = 0; + event.y = 0; + event.windowX = event.x; + event.windowY = event.y; + host->ForwardWheelEvent(event); + return true; + } + + private: + base::TimeTicks start_time_; + bool scroll_down_; + bool scroll_far_; +}; + +SmoothScrollGesture* RenderWidgetHostViewBase::CreateSmoothScrollGesture( + bool scroll_down, bool scroll_far) { + return new BasicMouseWheelSmoothScrollGesture(scroll_down, scroll_far); +} + } // namespace content diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 6172814..a0a3d71 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h @@ -58,6 +58,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase virtual WebKit::WebPopupType GetPopupType() OVERRIDE; virtual BrowserAccessibilityManager* GetBrowserAccessibilityManager() const OVERRIDE; + virtual SmoothScrollGesture* CreateSmoothScrollGesture( + bool scroll_down, bool scroll_far) OVERRIDE; void SetBrowserAccessibilityManager(BrowserAccessibilityManager* manager); diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 61f4d2f..22855bc 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -1555,6 +1555,10 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_HandleInputEvent_ACK, WebKit::WebInputEvent::Type, bool /* processed */) +IPC_MESSAGE_ROUTED2(ViewHostMsg_BeginSmoothScroll, + bool /* scroll_down */, + bool /* scroll_far */) + IPC_MESSAGE_ROUTED0(ViewHostMsg_Focus) IPC_MESSAGE_ROUTED0(ViewHostMsg_Blur) diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 9d31619..b556808 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -28,6 +28,7 @@ 'sources': [ 'port/browser/render_view_host_delegate_view.h', 'port/browser/render_widget_host_view_port.h', + 'port/browser/smooth_scroll_gesture.h', 'public/browser/access_token_store.h', 'public/browser/android/content_view_core.h', 'public/browser/android/devtools_server.h', @@ -1000,4 +1001,3 @@ }], ], } - diff --git a/content/port/browser/render_widget_host_view_port.h b/content/port/browser/render_widget_host_view_port.h index adc2f35..2c31ac0 100644 --- a/content/port/browser/render_widget_host_view_port.h +++ b/content/port/browser/render_widget_host_view_port.h @@ -40,6 +40,8 @@ struct WebScreenInfo; namespace content { +class SmoothScrollGesture; + // This is the larger RenderWidgetHostView interface exposed only // within content/ and to embedders looking to port to new platforms. // RenderWidgetHostView class hierarchy described in render_widget_host_view.h. @@ -248,6 +250,11 @@ class CONTENT_EXPORT RenderWidgetHostViewPort : public RenderWidgetHostView { virtual void ProcessTouchAck(WebKit::WebInputEvent::Type type, bool processed) = 0; + // Asks the view to create a smooth scroll gesture that will be used to + // simulate a user-initiated scroll. + virtual SmoothScrollGesture* CreateSmoothScrollGesture( + bool scroll_down, bool scroll_far) = 0; + virtual void SetHasHorizontalScrollbar(bool has_horizontal_scrollbar) = 0; virtual void SetScrollOffsetPinning( bool is_pinned_to_left, bool is_pinned_to_right) = 0; diff --git a/content/port/browser/smooth_scroll_gesture.h b/content/port/browser/smooth_scroll_gesture.h new file mode 100644 index 0000000..6d6672c --- /dev/null +++ b/content/port/browser/smooth_scroll_gesture.h @@ -0,0 +1,33 @@ +// Copyright (c) 2012 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 CONTENT_PORT_BROWSER_SMOOTH_SCROLL_GESTURE_H_ +#define CONTENT_PORT_BROWSER_SMOOTH_SCROLL_GESTURE_H_ + +#include "base/time.h" + +namespace content { + +class RenderWidgetHost; + +// This is a base class representing a single scroll gesture. These gestures are +// paired with the rendering benchmarking system to (automatically) measure how +// smoothnly chrome is responding to user input. +class SmoothScrollGesture { + public: + virtual ~SmoothScrollGesture() {} + + // When called, the gesture should compute its state at the provided timestamp + // and send the right input events to the provided RenderWidgetHost to + // simulate the gesture having run up to that point in time. + // + // This function should return true until the gesture is over. A false return + // value will stop ticking the gesture and clean it up. + virtual bool ForwardInputEvents(base::TimeTicks now, + RenderWidgetHost* host) = 0; +}; + +} // namespace content + +#endif // CONTENT_PORT_BROWSER_SMOOTH_SCROLL_GESTURE_H_ diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc index e912840..8590e11 100644 --- a/content/renderer/gpu/gpu_benchmarking_extension.cc +++ b/content/renderer/gpu/gpu_benchmarking_extension.cc @@ -3,10 +3,11 @@ // found in the LICENSE file. #include "content/renderer/gpu/gpu_benchmarking_extension.h" - +#include "content/renderer/render_view_impl.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebRenderingStats.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "v8/include/v8.h" using WebKit::WebFrame; @@ -15,6 +16,9 @@ using WebKit::WebView; const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking"; +using WebKit::WebFrame; +using WebKit::WebView; + namespace content { class GpuBenchmarkingWrapper : public v8::Extension { @@ -30,12 +34,25 @@ class GpuBenchmarkingWrapper : public v8::Extension { "chrome.gpuBenchmarking.renderingStats = function() {" " native function GetRenderingStats();" " return GetRenderingStats();" + "};" + "chrome.gpuBenchmarking.beginSmoothScrollDown = " + " function(scroll_far) {" + " scroll_far = scroll_far || false;" + " native function BeginSmoothScroll();" + " return BeginSmoothScroll(true, scroll_far);" + "};" + "chrome.gpuBenchmarking.beginSmoothScrollUp = function(scroll_far) {" + " scroll_far = scroll_far || false;" + " native function BeginSmoothScroll();" + " return BeginSmoothScroll(false, scroll_far);" "};") {} virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( v8::Handle<v8::String> name) { if (name->Equals(v8::String::New("GetRenderingStats"))) return v8::FunctionTemplate::New(GetRenderingStats); + if (name->Equals(v8::String::New("BeginSmoothScroll"))) + return v8::FunctionTemplate::New(BeginSmoothScroll); return v8::Handle<v8::FunctionTemplate>(); } @@ -63,6 +80,29 @@ class GpuBenchmarkingWrapper : public v8::Extension { v8::ReadOnly); return stats_object; } + + static v8::Handle<v8::Value> BeginSmoothScroll(const v8::Arguments& args) { + WebFrame* web_frame = WebFrame::frameForEnteredContext(); + if (!web_frame) + return v8::Undefined(); + + WebView* web_view = web_frame->view(); + if (!web_view) + return v8::Undefined(); + + RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view); + if (!render_view_impl) + return v8::Undefined(); + + if (args.Length() != 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean()) + return v8::False(); + + bool scroll_down = args[0]->BooleanValue(); + bool scroll_far = args[1]->BooleanValue(); + + render_view_impl->BeginSmoothScroll(scroll_down, scroll_far); + return v8::True(); + } }; v8::Extension* GpuBenchmarkingExtension::Get() { diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 3bdf5b1..80cfd7f 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -1769,6 +1769,10 @@ void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { } } +void RenderWidget::BeginSmoothScroll(bool down, bool scroll_far) { + Send(new ViewHostMsg_BeginSmoothScroll(routing_id_, down, scroll_far)); +} + bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) { return false; } diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 8c2700d..c8bea54 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h @@ -152,6 +152,10 @@ class CONTENT_EXPORT RenderWidget // pending moves don't try to reference it. void CleanupWindowInPluginMoves(gfx::PluginWindowHandle window); + // Directs the host to begin a smooth scroll. This scroll should have the same + // performance characteristics as a user-initiated scroll. + void BeginSmoothScroll(bool scroll_down, bool scroll_far); + // Close the underlying WebWidget. virtual void Close(); |