Extract SIGPIPE ignoring code to a common place.
[chromium-blink-merge.git] / content / renderer / gpu / compositor_thread.cc
blob815d1c221b155cab71ddea083fc165e5350bb124
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"
7 #include "base/bind.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;
18 namespace content {
20 //------------------------------------------------------------------------------
22 class CompositorThread::InputHandlerWrapper
23 : public WebKit::WebCompositorInputHandlerClient,
24 public base::RefCountedThreadSafe<InputHandlerWrapper> {
25 public:
26 InputHandlerWrapper(CompositorThread* compositor_thread,
27 int routing_id,
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) {
41 main_loop_->PostTask(
42 FROM_HERE,
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);
66 private:
67 friend class base::RefCountedThreadSafe<InputHandlerWrapper>;
69 virtual ~InputHandlerWrapper() {
70 input_handler_->setClient(NULL);
73 CompositorThread* compositor_thread_;
74 int routing_id_;
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") {
88 filter_ =
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 {
99 return filter_;
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(
108 FROM_HERE,
109 base::Bind(&CompositorThread::AddInputHandlerOnCompositorThread,
110 base::Unretained(this),
111 routing_id,
112 input_handler_id,
113 base::MessageLoopProxy::current(),
114 render_view_impl));
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);
126 if (!input_handler)
127 return;
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);
134 return;
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(
154 int routing_id,
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);
163 return;
166 it->second->input_handler()->handleInputEvent(*input_event);
169 } // namespace content