Commit 7a1ec28a authored by jamesr@chromium.org's avatar jamesr@chromium.org

Implement active wheel fling transfer via WebCompositorInputHandlerClient

There are cases where we'll process a GestureFlingStart event on the
compositor thread, initiate a wheel fling, and then later determine that
we can't process the rest of the animation on the compositor thread. One
example of where this could happen is if the page registers a mousewheel
JS event listener while the fling is in progress.  In this case, we need
to transfer the animation to the WebView to process so it can generate
the correct events.

This implements the transfer as a call out via the
WebCompositorInputHandlerClient. I think this is a reasonable place to
put the interface, since it's intimately related with the input
processing stream.

BUG=don't have handy, but there is one
TEST=wheel fling on CrOS should work with --enable-threaded-compositing


Review URL: http://codereview.chromium.org/9802006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129487 0039d316-1c4b-4281-b951-d872f2087c98
parent 10c5623f
...@@ -7,9 +7,10 @@ ...@@ -7,9 +7,10 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/debug/trace_event.h" #include "base/debug/trace_event.h"
#include "content/renderer/gpu/input_event_filter.h" #include "content/renderer/gpu/input_event_filter.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositor.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebActiveWheelFlingParameters.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositorClient.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositorInputHandlerClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositorInputHandler.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositorInputHandler.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
using WebKit::WebCompositorInputHandler; using WebKit::WebCompositorInputHandler;
using WebKit::WebInputEvent; using WebKit::WebInputEvent;
...@@ -17,17 +18,30 @@ using WebKit::WebInputEvent; ...@@ -17,17 +18,30 @@ using WebKit::WebInputEvent;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class CompositorThread::InputHandlerWrapper class CompositorThread::InputHandlerWrapper
: public WebKit::WebCompositorClient { : public WebKit::WebCompositorInputHandlerClient,
public base::RefCountedThreadSafe<InputHandlerWrapper> {
public: public:
InputHandlerWrapper(CompositorThread* compositor_thread, InputHandlerWrapper(CompositorThread* compositor_thread,
int routing_id, int routing_id,
WebKit::WebCompositorInputHandler* input_handler) WebKit::WebCompositorInputHandler* input_handler,
scoped_refptr<base::MessageLoopProxy> main_loop,
const base::WeakPtr<RenderViewImpl>& render_view_impl)
: compositor_thread_(compositor_thread), : compositor_thread_(compositor_thread),
routing_id_(routing_id), routing_id_(routing_id),
input_handler_(input_handler) { input_handler_(input_handler),
main_loop_(main_loop),
render_view_impl_(render_view_impl) {
input_handler_->setClient(this); input_handler_->setClient(this);
} }
virtual void transferActiveWheelFlingAnimation(
const WebKit::WebActiveWheelFlingParameters& params) {
main_loop_->PostTask(
FROM_HERE,
base::Bind(&RenderViewImpl::TransferActiveWheelFlingAnimation,
render_view_impl_, params));
}
virtual ~InputHandlerWrapper() { virtual ~InputHandlerWrapper() {
input_handler_->setClient(NULL); input_handler_->setClient(NULL);
} }
...@@ -37,7 +51,7 @@ class CompositorThread::InputHandlerWrapper ...@@ -37,7 +51,7 @@ class CompositorThread::InputHandlerWrapper
return input_handler_; return input_handler_;
} }
// WebCompositorClient methods: // WebCompositorInputHandlerClient methods:
virtual void willShutdown() { virtual void willShutdown() {
compositor_thread_->RemoveInputHandler(routing_id_); compositor_thread_->RemoveInputHandler(routing_id_);
...@@ -55,6 +69,10 @@ class CompositorThread::InputHandlerWrapper ...@@ -55,6 +69,10 @@ class CompositorThread::InputHandlerWrapper
CompositorThread* compositor_thread_; CompositorThread* compositor_thread_;
int routing_id_; int routing_id_;
WebKit::WebCompositorInputHandler* input_handler_; WebKit::WebCompositorInputHandler* input_handler_;
scoped_refptr<base::MessageLoopProxy> main_loop_;
// Can only be accessed on the main thread.
base::WeakPtr<RenderViewImpl> render_view_impl_;
DISALLOW_COPY_AND_ASSIGN(InputHandlerWrapper); DISALLOW_COPY_AND_ASSIGN(InputHandlerWrapper);
}; };
...@@ -77,14 +95,27 @@ IPC::ChannelProxy::MessageFilter* CompositorThread::GetMessageFilter() const { ...@@ -77,14 +95,27 @@ IPC::ChannelProxy::MessageFilter* CompositorThread::GetMessageFilter() const {
return filter_; return filter_;
} }
void CompositorThread::AddInputHandler(int routing_id, int input_handler_id) { void CompositorThread::AddInputHandler(
if (thread_.message_loop() != MessageLoop::current()) { int routing_id, int input_handler_id,
thread_.message_loop()->PostTask( const base::WeakPtr<RenderViewImpl>& render_view_impl) {
FROM_HERE, DCHECK_NE(thread_.message_loop(), MessageLoop::current());
base::Bind(&CompositorThread::AddInputHandler, base::Unretained(this),
routing_id, input_handler_id)); thread_.message_loop()->PostTask(
return; FROM_HERE,
} base::Bind(&CompositorThread::AddInputHandlerOnCompositorThread,
base::Unretained(this),
routing_id,
input_handler_id,
base::MessageLoopProxy::current(),
render_view_impl));
}
void CompositorThread::AddInputHandlerOnCompositorThread(
int routing_id, int input_handler_id,
scoped_refptr<base::MessageLoopProxy> main_loop,
const base::WeakPtr<RenderViewImpl>& render_view_impl) {
DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
WebCompositorInputHandler* input_handler = WebCompositorInputHandler* input_handler =
WebCompositorInputHandler::fromIdentifier(input_handler_id); WebCompositorInputHandler::fromIdentifier(input_handler_id);
...@@ -102,11 +133,12 @@ void CompositorThread::AddInputHandler(int routing_id, int input_handler_id) { ...@@ -102,11 +133,12 @@ void CompositorThread::AddInputHandler(int routing_id, int input_handler_id) {
TRACE_EVENT0("CompositorThread::AddInputHandler", "AddingRoute"); TRACE_EVENT0("CompositorThread::AddInputHandler", "AddingRoute");
filter_->AddRoute(routing_id); filter_->AddRoute(routing_id);
input_handlers_[routing_id] = input_handlers_[routing_id] =
make_linked_ptr(new InputHandlerWrapper(this, routing_id, input_handler)); make_scoped_refptr(new InputHandlerWrapper(this,
routing_id, input_handler, main_loop, render_view_impl));
} }
void CompositorThread::RemoveInputHandler(int routing_id) { void CompositorThread::RemoveInputHandler(int routing_id) {
DCHECK(thread_.message_loop() == MessageLoop::current()); DCHECK_EQ(MessageLoop::current(), thread_.message_loop());
TRACE_EVENT0("CompositorThread::RemoveInputHandler", "RemovingRoute"); TRACE_EVENT0("CompositorThread::RemoveInputHandler", "RemovingRoute");
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
#include <map> #include <map>
#include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/renderer/render_view_impl.h"
#include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_channel_proxy.h"
#include "webkit/glue/webthread_impl.h" #include "webkit/glue/webthread_impl.h"
...@@ -31,8 +33,10 @@ class CompositorThread { ...@@ -31,8 +33,10 @@ class CompositorThread {
// to the compositor's thread. // to the compositor's thread.
IPC::ChannelProxy::MessageFilter* GetMessageFilter() const; IPC::ChannelProxy::MessageFilter* GetMessageFilter() const;
// Callable from the main thread or the compositor's thread. // Callable from the main thread only.
void AddInputHandler(int routing_id, int input_handler_id); void AddInputHandler(int routing_id,
int input_handler_id,
const base::WeakPtr<RenderViewImpl>& render_view_impl);
webkit_glue::WebThreadImpl* GetWebThread() { return &thread_; } webkit_glue::WebThreadImpl* GetWebThread() { return &thread_; }
...@@ -44,11 +48,18 @@ class CompositorThread { ...@@ -44,11 +48,18 @@ class CompositorThread {
void HandleInputEvent(int routing_id, void HandleInputEvent(int routing_id,
const WebKit::WebInputEvent* input_event); const WebKit::WebInputEvent* input_event);
// Called from the compositor's thread.
void AddInputHandlerOnCompositorThread(
int routing_id,
int input_handler_id,
scoped_refptr<base::MessageLoopProxy> main_loop,
const base::WeakPtr<RenderViewImpl>& render_view_impl);
class InputHandlerWrapper; class InputHandlerWrapper;
friend class InputHandlerWrapper; friend class InputHandlerWrapper;
typedef std::map<int, // routing_id typedef std::map<int, // routing_id
linked_ptr<InputHandlerWrapper> > InputHandlerMap; scoped_refptr<InputHandlerWrapper> > InputHandlerMap;
InputHandlerMap input_handlers_; InputHandlerMap input_handlers_;
webkit_glue::WebThreadImpl thread_; webkit_glue::WebThreadImpl thread_;
......
...@@ -714,6 +714,12 @@ bool RenderViewImpl::GetPluginInfo(const GURL& url, ...@@ -714,6 +714,12 @@ bool RenderViewImpl::GetPluginInfo(const GURL& url,
return found; return found;
} }
void RenderViewImpl::TransferActiveWheelFlingAnimation(
const WebKit::WebActiveWheelFlingParameters& params) {
if (webview())
webview()->transferActiveWheelFlingAnimation(params);
}
bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) { bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL; WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
if (main_frame) if (main_frame)
...@@ -2070,6 +2076,16 @@ bool RenderViewImpl::isPointerLocked() { ...@@ -2070,6 +2076,16 @@ bool RenderViewImpl::isPointerLocked() {
webwidget_mouse_lock_target_.get()); webwidget_mouse_lock_target_.get());
} }
void RenderViewImpl::didActivateCompositor(int input_handler_identifier) {
CompositorThread* compositor_thread =
RenderThreadImpl::current()->compositor_thread();
if (compositor_thread)
compositor_thread->AddInputHandler(
routing_id_, input_handler_identifier, AsWeakPtr());
RenderWidget::didActivateCompositor(input_handler_identifier);
}
// WebKit::WebFrameClient ----------------------------------------------------- // WebKit::WebFrameClient -----------------------------------------------------
WebPlugin* RenderViewImpl::createPlugin(WebFrame* frame, WebPlugin* RenderViewImpl::createPlugin(WebFrame* frame,
......
...@@ -136,6 +136,7 @@ class WebTouchEvent; ...@@ -136,6 +136,7 @@ class WebTouchEvent;
class WebURLLoader; class WebURLLoader;
class WebURLRequest; class WebURLRequest;
class WebUserMediaClient; class WebUserMediaClient;
struct WebActiveWheelFlingParameters;
struct WebFileChooserParams; struct WebFileChooserParams;
struct WebFindOptions; struct WebFindOptions;
struct WebMediaPlayerAction; struct WebMediaPlayerAction;
...@@ -325,6 +326,9 @@ class RenderViewImpl : public RenderWidget, ...@@ -325,6 +326,9 @@ class RenderViewImpl : public RenderWidget,
webkit::WebPluginInfo* plugin_info, webkit::WebPluginInfo* plugin_info,
std::string* actual_mime_type); std::string* actual_mime_type);
void TransferActiveWheelFlingAnimation(
const WebKit::WebActiveWheelFlingParameters& params);
// IPC::Channel::Listener implementation ------------------------------------- // IPC::Channel::Listener implementation -------------------------------------
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
...@@ -341,6 +345,7 @@ class RenderViewImpl : public RenderWidget, ...@@ -341,6 +345,7 @@ class RenderViewImpl : public RenderWidget,
virtual bool requestPointerLock(); virtual bool requestPointerLock();
virtual void requestPointerUnlock(); virtual void requestPointerUnlock();
virtual bool isPointerLocked(); virtual bool isPointerLocked();
virtual void didActivateCompositor(int input_handler_identifier);
// WebKit::WebViewClient implementation -------------------------------------- // WebKit::WebViewClient implementation --------------------------------------
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "content/common/swapped_out_messages.h" #include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "content/renderer/gpu/compositor_thread.h"
#include "content/renderer/render_process.h" #include "content/renderer/render_process.h"
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_webkitplatformsupport_impl.h" #include "content/renderer/renderer_webkitplatformsupport_impl.h"
...@@ -1079,11 +1078,6 @@ void RenderWidget::didAutoResize(const WebSize& new_size) { ...@@ -1079,11 +1078,6 @@ void RenderWidget::didAutoResize(const WebSize& new_size) {
void RenderWidget::didActivateCompositor(int input_handler_identifier) { void RenderWidget::didActivateCompositor(int input_handler_identifier) {
TRACE_EVENT0("gpu", "RenderWidget::didActivateCompositor"); TRACE_EVENT0("gpu", "RenderWidget::didActivateCompositor");
CompositorThread* compositor_thread =
RenderThreadImpl::current()->compositor_thread();
if (compositor_thread)
compositor_thread->AddInputHandler(routing_id_, input_handler_identifier);
if (!is_accelerated_compositing_active_) { if (!is_accelerated_compositing_active_) {
// When not in accelerated compositing mode, in certain cases (e.g. waiting // When not in accelerated compositing mode, in certain cases (e.g. waiting
// for a resize or if no backing store) the RenderWidgetHost is blocking the // for a resize or if no backing store) the RenderWidgetHost is blocking the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment