1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/gpu/compositor_thread.h"
8 #include "base/debug/trace_event.h"
9 #include "content/renderer/gpu/input_event_filter.h"
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebActiveWheelFlingParameters.h"
11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositorInputHandlerClient.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositorInputHandler.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
15 using WebKit::WebCompositorInputHandler
;
16 using WebKit::WebInputEvent
;
20 //------------------------------------------------------------------------------
22 class CompositorThread::InputHandlerWrapper
23 : public WebKit::WebCompositorInputHandlerClient
,
24 public base::RefCountedThreadSafe
<InputHandlerWrapper
> {
26 InputHandlerWrapper(CompositorThread
* compositor_thread
,
28 WebKit::WebCompositorInputHandler
* input_handler
,
29 scoped_refptr
<base::MessageLoopProxy
> main_loop
,
30 const base::WeakPtr
<RenderViewImpl
>& render_view_impl
)
31 : compositor_thread_(compositor_thread
),
32 routing_id_(routing_id
),
33 input_handler_(input_handler
),
34 main_loop_(main_loop
),
35 render_view_impl_(render_view_impl
) {
36 input_handler_
->setClient(this);
39 virtual void transferActiveWheelFlingAnimation(
40 const WebKit::WebActiveWheelFlingParameters
& params
) {
43 base::Bind(&RenderViewImpl::TransferActiveWheelFlingAnimation
,
44 render_view_impl_
, params
));
47 int routing_id() const { return routing_id_
; }
48 WebKit::WebCompositorInputHandler
* input_handler() const {
49 return input_handler_
;
52 // WebCompositorInputHandlerClient methods:
54 virtual void willShutdown() {
55 compositor_thread_
->RemoveInputHandler(routing_id_
);
58 virtual void didHandleInputEvent() {
59 compositor_thread_
->filter_
->DidHandleInputEvent();
62 virtual void didNotHandleInputEvent(bool send_to_widget
) {
63 compositor_thread_
->filter_
->DidNotHandleInputEvent(send_to_widget
);
67 friend class base::RefCountedThreadSafe
<InputHandlerWrapper
>;
69 virtual ~InputHandlerWrapper() {
70 input_handler_
->setClient(NULL
);
73 CompositorThread
* compositor_thread_
;
75 WebKit::WebCompositorInputHandler
* input_handler_
;
76 scoped_refptr
<base::MessageLoopProxy
> main_loop_
;
78 // Can only be accessed on the main thread.
79 base::WeakPtr
<RenderViewImpl
> render_view_impl_
;
81 DISALLOW_COPY_AND_ASSIGN(InputHandlerWrapper
);
84 //------------------------------------------------------------------------------
86 CompositorThread::CompositorThread(IPC::Listener
* main_listener
)
87 : thread_("Compositor") {
89 new InputEventFilter(main_listener
,
90 thread_
.message_loop()->message_loop_proxy(),
91 base::Bind(&CompositorThread::HandleInputEvent
,
92 base::Unretained(this)));
95 CompositorThread::~CompositorThread() {
98 IPC::ChannelProxy::MessageFilter
* CompositorThread::GetMessageFilter() const {
102 void CompositorThread::AddInputHandler(
103 int routing_id
, int input_handler_id
,
104 const base::WeakPtr
<RenderViewImpl
>& render_view_impl
) {
105 DCHECK_NE(thread_
.message_loop(), MessageLoop::current());
107 thread_
.message_loop()->PostTask(
109 base::Bind(&CompositorThread::AddInputHandlerOnCompositorThread
,
110 base::Unretained(this),
113 base::MessageLoopProxy::current(),
117 void CompositorThread::AddInputHandlerOnCompositorThread(
118 int routing_id
, int input_handler_id
,
119 scoped_refptr
<base::MessageLoopProxy
> main_loop
,
120 const base::WeakPtr
<RenderViewImpl
>& render_view_impl
) {
122 DCHECK_EQ(thread_
.message_loop(), MessageLoop::current());
124 WebCompositorInputHandler
* input_handler
=
125 WebCompositorInputHandler::fromIdentifier(input_handler_id
);
129 if (input_handlers_
.count(routing_id
) != 0) {
130 // It's valid to call AddInputHandler() for the same routing id with the
131 // same input_handler many times, but it's not valid to change the
132 // input_handler for a route.
133 DCHECK_EQ(input_handlers_
[routing_id
]->input_handler(), input_handler
);
137 TRACE_EVENT0("CompositorThread::AddInputHandler", "AddingRoute");
138 filter_
->AddRoute(routing_id
);
139 input_handlers_
[routing_id
] =
140 make_scoped_refptr(new InputHandlerWrapper(this,
141 routing_id
, input_handler
, main_loop
, render_view_impl
));
144 void CompositorThread::RemoveInputHandler(int routing_id
) {
145 DCHECK_EQ(MessageLoop::current(), thread_
.message_loop());
147 TRACE_EVENT0("CompositorThread::RemoveInputHandler", "RemovingRoute");
149 filter_
->RemoveRoute(routing_id
);
150 input_handlers_
.erase(routing_id
);
153 void CompositorThread::HandleInputEvent(
155 const WebInputEvent
* input_event
) {
156 DCHECK_EQ(MessageLoop::current(), thread_
.message_loop());
158 InputHandlerMap::iterator it
= input_handlers_
.find(routing_id
);
159 if (it
== input_handlers_
.end()) {
160 TRACE_EVENT0("CompositorThread::HandleInputEvent", "NoInputHandlerFound");
161 // Oops, we no longer have an interested input handler..
162 filter_
->DidNotHandleInputEvent(true);
166 it
->second
->input_handler()->handleInputEvent(*input_event
);
169 } // namespace content