OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/render_widget.h" | 5 #include "content/renderer/render_widget.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
14 #include "content/common/content_switches.h" | 14 #include "content/common/content_switches.h" |
| 15 #include "content/common/swapped_out_messages.h" |
15 #include "content/common/view_messages.h" | 16 #include "content/common/view_messages.h" |
16 #include "content/renderer/render_process.h" | 17 #include "content/renderer/render_process.h" |
17 #include "content/renderer/render_thread.h" | 18 #include "content/renderer/render_thread.h" |
18 #include "content/renderer/renderer_webkitclient_impl.h" | 19 #include "content/renderer/renderer_webkitclient_impl.h" |
19 #include "ipc/ipc_sync_message.h" | 20 #include "ipc/ipc_sync_message.h" |
20 #include "skia/ext/platform_canvas.h" | 21 #include "skia/ext/platform_canvas.h" |
21 #include "third_party/skia/include/core/SkShader.h" | 22 #include "third_party/skia/include/core/SkShader.h" |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" |
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h" | 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 host_window_(0), | 68 host_window_(0), |
68 current_paint_buf_(NULL), | 69 current_paint_buf_(NULL), |
69 next_paint_flags_(0), | 70 next_paint_flags_(0), |
70 update_reply_pending_(false), | 71 update_reply_pending_(false), |
71 did_show_(false), | 72 did_show_(false), |
72 is_hidden_(false), | 73 is_hidden_(false), |
73 needs_repainting_on_restore_(false), | 74 needs_repainting_on_restore_(false), |
74 has_focus_(false), | 75 has_focus_(false), |
75 handling_input_event_(false), | 76 handling_input_event_(false), |
76 closing_(false), | 77 closing_(false), |
| 78 is_swapped_out_(false), |
77 input_method_is_active_(false), | 79 input_method_is_active_(false), |
78 text_input_type_(WebKit::WebTextInputTypeNone), | 80 text_input_type_(WebKit::WebTextInputTypeNone), |
79 popup_type_(popup_type), | 81 popup_type_(popup_type), |
80 pending_window_rect_count_(0), | 82 pending_window_rect_count_(0), |
81 suppress_next_char_events_(false), | 83 suppress_next_char_events_(false), |
82 is_accelerated_compositing_active_(false), | 84 is_accelerated_compositing_active_(false), |
83 animation_update_pending_(false), | 85 animation_update_pending_(false), |
84 animation_task_posted_(false) { | 86 animation_task_posted_(false) { |
85 RenderProcess::current()->AddRefProcess(); | 87 RenderProcess::current()->AddRefProcess(); |
86 DCHECK(render_thread_); | 88 DCHECK(render_thread_); |
87 } | 89 } |
88 | 90 |
89 RenderWidget::~RenderWidget() { | 91 RenderWidget::~RenderWidget() { |
90 DCHECK(!webwidget_) << "Leaking our WebWidget!"; | 92 DCHECK(!webwidget_) << "Leaking our WebWidget!"; |
91 if (current_paint_buf_) { | 93 if (current_paint_buf_) { |
92 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); | 94 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); |
93 current_paint_buf_ = NULL; | 95 current_paint_buf_ = NULL; |
94 } | 96 } |
95 RenderProcess::current()->ReleaseProcess(); | 97 // If we are swapped out, we have released already. |
| 98 if (!is_swapped_out_) |
| 99 RenderProcess::current()->ReleaseProcess(); |
96 } | 100 } |
97 | 101 |
98 // static | 102 // static |
99 RenderWidget* RenderWidget::Create(int32 opener_id, | 103 RenderWidget* RenderWidget::Create(int32 opener_id, |
100 RenderThreadBase* render_thread, | 104 RenderThreadBase* render_thread, |
101 WebKit::WebPopupType popup_type) { | 105 WebKit::WebPopupType popup_type) { |
102 DCHECK(opener_id != MSG_ROUTING_NONE); | 106 DCHECK(opener_id != MSG_ROUTING_NONE); |
103 scoped_refptr<RenderWidget> widget(new RenderWidget(render_thread, | 107 scoped_refptr<RenderWidget> widget(new RenderWidget(render_thread, |
104 popup_type)); | 108 popup_type)); |
105 widget->Init(opener_id); // adds reference | 109 widget->Init(opener_id); // adds reference |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 void RenderWidget::CompleteInit(gfx::NativeViewId parent_hwnd, | 157 void RenderWidget::CompleteInit(gfx::NativeViewId parent_hwnd, |
154 gfx::PluginWindowHandle compositing_surface) { | 158 gfx::PluginWindowHandle compositing_surface) { |
155 DCHECK(routing_id_ != MSG_ROUTING_NONE); | 159 DCHECK(routing_id_ != MSG_ROUTING_NONE); |
156 | 160 |
157 host_window_ = parent_hwnd; | 161 host_window_ = parent_hwnd; |
158 compositing_surface_ = compositing_surface; | 162 compositing_surface_ = compositing_surface; |
159 | 163 |
160 Send(new ViewHostMsg_RenderViewReady(routing_id_)); | 164 Send(new ViewHostMsg_RenderViewReady(routing_id_)); |
161 } | 165 } |
162 | 166 |
| 167 void RenderWidget::SetSwappedOut(bool is_swapped_out) { |
| 168 // We should only toggle between states. |
| 169 DCHECK(is_swapped_out_ != is_swapped_out); |
| 170 is_swapped_out_ = is_swapped_out; |
| 171 |
| 172 // If we are swapping out, we will call ReleaseProcess, allowing the process |
| 173 // to exit if all of its RenderViews are swapped out. We wait until the |
| 174 // WasSwappedOut call to do this, to avoid showing the sad tab. |
| 175 // If we are swapping in, we call AddRefProcess to prevent the process from |
| 176 // exiting. |
| 177 if (!is_swapped_out) |
| 178 RenderProcess::current()->AddRefProcess(); |
| 179 } |
| 180 |
163 bool RenderWidget::OnMessageReceived(const IPC::Message& message) { | 181 bool RenderWidget::OnMessageReceived(const IPC::Message& message) { |
164 bool handled = true; | 182 bool handled = true; |
165 IPC_BEGIN_MESSAGE_MAP(RenderWidget, message) | 183 IPC_BEGIN_MESSAGE_MAP(RenderWidget, message) |
166 IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose) | 184 IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose) |
167 IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck) | 185 IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck) |
168 IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize) | 186 IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize) |
169 IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden) | 187 IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden) |
170 IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored) | 188 IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored) |
| 189 IPC_MESSAGE_HANDLER(ViewMsg_WasSwappedOut, OnWasSwappedOut) |
171 IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck) | 190 IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck) |
172 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) | 191 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) |
173 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) | 192 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) |
174 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) | 193 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) |
175 IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive) | 194 IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive) |
176 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) | 195 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) |
177 IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) | 196 IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) |
178 IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize) | 197 IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize) |
179 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) | 198 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) |
180 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) | 199 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) |
181 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) | 200 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) |
182 IPC_MESSAGE_UNHANDLED(handled = false) | 201 IPC_MESSAGE_UNHANDLED(handled = false) |
183 IPC_END_MESSAGE_MAP() | 202 IPC_END_MESSAGE_MAP() |
184 return handled; | 203 return handled; |
185 } | 204 } |
186 | 205 |
187 bool RenderWidget::Send(IPC::Message* message) { | 206 bool RenderWidget::Send(IPC::Message* message) { |
188 // Don't send any messages after the browser has told us to close. | 207 // Don't send any messages after the browser has told us to close, and filter |
189 if (closing_) { | 208 // most outgoing messages while swapped out. |
| 209 if ((is_swapped_out_ && |
| 210 !content::SwappedOutMessages::CanSendWhileSwappedOut(message)) || |
| 211 closing_) { |
190 delete message; | 212 delete message; |
191 return false; | 213 return false; |
192 } | 214 } |
193 | 215 |
194 // If given a messsage without a routing ID, then assign our routing ID. | 216 // If given a messsage without a routing ID, then assign our routing ID. |
195 if (message->routing_id() == MSG_ROUTING_NONE) | 217 if (message->routing_id() == MSG_ROUTING_NONE) |
196 message->set_routing_id(routing_id_); | 218 message->set_routing_id(routing_id_); |
197 | 219 |
198 return render_thread_->Send(message); | 220 return render_thread_->Send(message); |
199 } | 221 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 set_next_paint_is_restore_ack(); | 314 set_next_paint_is_restore_ack(); |
293 | 315 |
294 // Generate a full repaint. | 316 // Generate a full repaint. |
295 if (!is_accelerated_compositing_active_) { | 317 if (!is_accelerated_compositing_active_) { |
296 didInvalidateRect(gfx::Rect(size_.width(), size_.height())); | 318 didInvalidateRect(gfx::Rect(size_.width(), size_.height())); |
297 } else { | 319 } else { |
298 scheduleComposite(); | 320 scheduleComposite(); |
299 } | 321 } |
300 } | 322 } |
301 | 323 |
| 324 void RenderWidget::OnWasSwappedOut() { |
| 325 // If we have been swapped out and no one else is using this process, |
| 326 // it's safe to exit now. If we get swapped back in, we will call |
| 327 // AddRefProcess in SetSwappedOut. |
| 328 if (is_swapped_out_) |
| 329 RenderProcess::current()->ReleaseProcess(); |
| 330 } |
| 331 |
302 void RenderWidget::OnRequestMoveAck() { | 332 void RenderWidget::OnRequestMoveAck() { |
303 DCHECK(pending_window_rect_count_); | 333 DCHECK(pending_window_rect_count_); |
304 pending_window_rect_count_--; | 334 pending_window_rect_count_--; |
305 } | 335 } |
306 | 336 |
307 void RenderWidget::OnUpdateRectAck() { | 337 void RenderWidget::OnUpdateRectAck() { |
308 TRACE_EVENT0("renderer", "RenderWidget::OnUpdateRectAck"); | 338 TRACE_EVENT0("renderer", "RenderWidget::OnUpdateRectAck"); |
309 DCHECK(update_reply_pending()); | 339 DCHECK(update_reply_pending()); |
310 update_reply_pending_ = false; | 340 update_reply_pending_ = false; |
311 | 341 |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 | 1185 |
1156 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { | 1186 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { |
1157 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); | 1187 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); |
1158 i != plugin_window_moves_.end(); ++i) { | 1188 i != plugin_window_moves_.end(); ++i) { |
1159 if (i->window == window) { | 1189 if (i->window == window) { |
1160 plugin_window_moves_.erase(i); | 1190 plugin_window_moves_.erase(i); |
1161 break; | 1191 break; |
1162 } | 1192 } |
1163 } | 1193 } |
1164 } | 1194 } |
OLD | NEW |