Chromium Code Reviews| 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/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 host_window_(0), | 67 host_window_(0), |
| 68 current_paint_buf_(NULL), | 68 current_paint_buf_(NULL), |
| 69 next_paint_flags_(0), | 69 next_paint_flags_(0), |
| 70 update_reply_pending_(false), | 70 update_reply_pending_(false), |
| 71 did_show_(false), | 71 did_show_(false), |
| 72 is_hidden_(false), | 72 is_hidden_(false), |
| 73 needs_repainting_on_restore_(false), | 73 needs_repainting_on_restore_(false), |
| 74 has_focus_(false), | 74 has_focus_(false), |
| 75 handling_input_event_(false), | 75 handling_input_event_(false), |
| 76 closing_(false), | 76 closing_(false), |
| 77 is_swapped_out_(false), | |
| 77 input_method_is_active_(false), | 78 input_method_is_active_(false), |
| 78 text_input_type_(WebKit::WebTextInputTypeNone), | 79 text_input_type_(WebKit::WebTextInputTypeNone), |
| 79 popup_type_(popup_type), | 80 popup_type_(popup_type), |
| 80 pending_window_rect_count_(0), | 81 pending_window_rect_count_(0), |
| 81 suppress_next_char_events_(false), | 82 suppress_next_char_events_(false), |
| 82 is_accelerated_compositing_active_(false), | 83 is_accelerated_compositing_active_(false), |
| 83 animation_update_pending_(false), | 84 animation_update_pending_(false), |
| 84 animation_task_posted_(false) { | 85 animation_task_posted_(false) { |
| 85 RenderProcess::current()->AddRefProcess(); | 86 RenderProcess::current()->AddRefProcess(); |
| 86 DCHECK(render_thread_); | 87 DCHECK(render_thread_); |
| 87 } | 88 } |
| 88 | 89 |
| 89 RenderWidget::~RenderWidget() { | 90 RenderWidget::~RenderWidget() { |
| 90 DCHECK(!webwidget_) << "Leaking our WebWidget!"; | 91 DCHECK(!webwidget_) << "Leaking our WebWidget!"; |
| 91 if (current_paint_buf_) { | 92 if (current_paint_buf_) { |
| 92 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); | 93 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); |
| 93 current_paint_buf_ = NULL; | 94 current_paint_buf_ = NULL; |
| 94 } | 95 } |
| 95 RenderProcess::current()->ReleaseProcess(); | 96 // If we are swapped out, we have released already. |
| 97 if (!is_swapped_out_) | |
| 98 RenderProcess::current()->ReleaseProcess(); | |
| 96 } | 99 } |
| 97 | 100 |
| 98 // static | 101 // static |
| 99 RenderWidget* RenderWidget::Create(int32 opener_id, | 102 RenderWidget* RenderWidget::Create(int32 opener_id, |
| 100 RenderThreadBase* render_thread, | 103 RenderThreadBase* render_thread, |
| 101 WebKit::WebPopupType popup_type) { | 104 WebKit::WebPopupType popup_type) { |
| 102 DCHECK(opener_id != MSG_ROUTING_NONE); | 105 DCHECK(opener_id != MSG_ROUTING_NONE); |
| 103 scoped_refptr<RenderWidget> widget(new RenderWidget(render_thread, | 106 scoped_refptr<RenderWidget> widget(new RenderWidget(render_thread, |
| 104 popup_type)); | 107 popup_type)); |
| 105 widget->Init(opener_id); // adds reference | 108 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, | 156 void RenderWidget::CompleteInit(gfx::NativeViewId parent_hwnd, |
| 154 gfx::PluginWindowHandle compositing_surface) { | 157 gfx::PluginWindowHandle compositing_surface) { |
| 155 DCHECK(routing_id_ != MSG_ROUTING_NONE); | 158 DCHECK(routing_id_ != MSG_ROUTING_NONE); |
| 156 | 159 |
| 157 host_window_ = parent_hwnd; | 160 host_window_ = parent_hwnd; |
| 158 compositing_surface_ = compositing_surface; | 161 compositing_surface_ = compositing_surface; |
| 159 | 162 |
| 160 Send(new ViewHostMsg_RenderViewReady(routing_id_)); | 163 Send(new ViewHostMsg_RenderViewReady(routing_id_)); |
| 161 } | 164 } |
| 162 | 165 |
| 166 void RenderWidget::SetSwappedOut(bool is_swapped_out) { | |
| 167 // We should only toggle between states. | |
| 168 DCHECK(is_swapped_out_ != is_swapped_out); | |
| 169 is_swapped_out_ = is_swapped_out; | |
| 170 | |
| 171 // If we are swapping out, we will call ReleaseProcess, allowing the process | |
| 172 // to exit if all of its RenderViews are swapped out. We wait until the | |
| 173 // WasSwappedOut call to do this, to avoid showing the sad tab. | |
| 174 // If we are swapping in, we call AddRefProcess to prevent the process from | |
| 175 // exiting. | |
| 176 if (!is_swapped_out) | |
| 177 RenderProcess::current()->AddRefProcess(); | |
| 178 } | |
| 179 | |
| 163 bool RenderWidget::OnMessageReceived(const IPC::Message& message) { | 180 bool RenderWidget::OnMessageReceived(const IPC::Message& message) { |
| 164 bool handled = true; | 181 bool handled = true; |
| 165 IPC_BEGIN_MESSAGE_MAP(RenderWidget, message) | 182 IPC_BEGIN_MESSAGE_MAP(RenderWidget, message) |
| 166 IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose) | 183 IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose) |
| 167 IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck) | 184 IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck) |
| 168 IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize) | 185 IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize) |
| 169 IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden) | 186 IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden) |
| 170 IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored) | 187 IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored) |
| 188 IPC_MESSAGE_HANDLER(ViewMsg_WasSwappedOut, OnWasSwappedOut) | |
| 171 IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck) | 189 IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck) |
| 172 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) | 190 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) |
| 173 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) | 191 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) |
| 174 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) | 192 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) |
| 175 IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive) | 193 IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive) |
| 176 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) | 194 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) |
| 177 IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) | 195 IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) |
| 178 IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize) | 196 IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize) |
| 179 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) | 197 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) |
| 180 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) | 198 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) |
| 181 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) | 199 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) |
| 182 IPC_MESSAGE_UNHANDLED(handled = false) | 200 IPC_MESSAGE_UNHANDLED(handled = false) |
| 183 IPC_END_MESSAGE_MAP() | 201 IPC_END_MESSAGE_MAP() |
| 184 return handled; | 202 return handled; |
| 185 } | 203 } |
| 186 | 204 |
| 205 bool RenderWidget::CanSendWhileSwappedOut(IPC::Message* message) { | |
|
Matt Perry
2011/05/05 17:06:50
It's a shame that these message lists are duplicat
Charlie Reis
2011/05/10 20:15:09
The lists aren't identical, but it does seem like
Matt Perry
2011/05/10 20:26:32
Oh interesting. There are some messages that you w
Charlie Reis
2011/05/10 20:35:23
Yes-- there are several messages that the renderer
Charlie Reis
2011/05/10 23:17:56
Fixed in the new patch set. I abstract it out to
| |
| 206 // We filter out most IPC messages when swapped out. However, some are | |
| 207 // important (e.g., ACKs) for keeping the browser and renderer state | |
| 208 // consistent in case we later return to this renderer. | |
| 209 switch (message->type()) { | |
| 210 case ViewHostMsg_HandleInputEvent_ACK::ID: | |
| 211 case ViewHostMsg_PaintAtSize_ACK::ID: | |
| 212 case ViewHostMsg_UpdateRect::ID: | |
| 213 return true; | |
| 214 default: | |
| 215 break; | |
| 216 } | |
| 217 return false; | |
| 218 } | |
| 219 | |
| 187 bool RenderWidget::Send(IPC::Message* message) { | 220 bool RenderWidget::Send(IPC::Message* message) { |
| 188 // Don't send any messages after the browser has told us to close. | 221 // Don't send any messages after the browser has told us to close, and filter |
| 189 if (closing_) { | 222 // most outgoing messages while swapped out. |
| 223 if (closing_ || (is_swapped_out_ && !CanSendWhileSwappedOut(message))) { | |
| 190 delete message; | 224 delete message; |
| 191 return false; | 225 return false; |
| 192 } | 226 } |
| 193 | 227 |
| 194 // If given a messsage without a routing ID, then assign our routing ID. | 228 // If given a messsage without a routing ID, then assign our routing ID. |
| 195 if (message->routing_id() == MSG_ROUTING_NONE) | 229 if (message->routing_id() == MSG_ROUTING_NONE) |
| 196 message->set_routing_id(routing_id_); | 230 message->set_routing_id(routing_id_); |
| 197 | 231 |
| 198 return render_thread_->Send(message); | 232 return render_thread_->Send(message); |
| 199 } | 233 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 set_next_paint_is_restore_ack(); | 326 set_next_paint_is_restore_ack(); |
| 293 | 327 |
| 294 // Generate a full repaint. | 328 // Generate a full repaint. |
| 295 if (!is_accelerated_compositing_active_) { | 329 if (!is_accelerated_compositing_active_) { |
| 296 didInvalidateRect(gfx::Rect(size_.width(), size_.height())); | 330 didInvalidateRect(gfx::Rect(size_.width(), size_.height())); |
| 297 } else { | 331 } else { |
| 298 scheduleComposite(); | 332 scheduleComposite(); |
| 299 } | 333 } |
| 300 } | 334 } |
| 301 | 335 |
| 336 void RenderWidget::OnWasSwappedOut() { | |
| 337 // If we have been swapped out and no one else is using this process, | |
| 338 // it's safe to exit now. If we get swapped back in, we will call | |
| 339 // AddRefProcess in SetSwappedOut. | |
| 340 if (is_swapped_out_) | |
| 341 RenderProcess::current()->ReleaseProcess(); | |
| 342 } | |
| 343 | |
| 302 void RenderWidget::OnRequestMoveAck() { | 344 void RenderWidget::OnRequestMoveAck() { |
| 303 DCHECK(pending_window_rect_count_); | 345 DCHECK(pending_window_rect_count_); |
| 304 pending_window_rect_count_--; | 346 pending_window_rect_count_--; |
| 305 } | 347 } |
| 306 | 348 |
| 307 void RenderWidget::OnUpdateRectAck() { | 349 void RenderWidget::OnUpdateRectAck() { |
| 308 GPU_TRACE_EVENT0("renderer", "RenderWidget::OnUpdateRectAck"); | 350 GPU_TRACE_EVENT0("renderer", "RenderWidget::OnUpdateRectAck"); |
| 309 DCHECK(update_reply_pending()); | 351 DCHECK(update_reply_pending()); |
| 310 update_reply_pending_ = false; | 352 update_reply_pending_ = false; |
| 311 | 353 |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1155 | 1197 |
| 1156 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { | 1198 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { |
| 1157 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); | 1199 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); |
| 1158 i != plugin_window_moves_.end(); ++i) { | 1200 i != plugin_window_moves_.end(); ++i) { |
| 1159 if (i->window == window) { | 1201 if (i->window == window) { |
| 1160 plugin_window_moves_.erase(i); | 1202 plugin_window_moves_.erase(i); |
| 1161 break; | 1203 break; |
| 1162 } | 1204 } |
| 1163 } | 1205 } |
| 1164 } | 1206 } |
| OLD | NEW |