summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc35
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.h8
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.cc55
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.h2
-rw-r--r--content/common/view_messages.h4
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/port/browser/render_widget_host_view_port.h7
-rw-r--r--content/port/browser/smooth_scroll_gesture.h33
-rw-r--r--content/renderer/gpu/gpu_benchmarking_extension.cc42
-rw-r--r--content/renderer/render_widget.cc4
-rw-r--r--content/renderer/render_widget.h4
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();