| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/renderer_host/render_widget_host.h" | 5 #include "chrome/browser/renderer_host/render_widget_host.h" |
| 6 | 6 |
| 7 #include "base/gfx/native_widget_types.h" | 7 #include "base/gfx/native_widget_types.h" |
| 8 #include "base/histogram.h" | 8 #include "base/histogram.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/keyboard_codes.h" | 10 #include "base/keyboard_codes.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 | 47 |
| 48 RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, | 48 RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, |
| 49 int routing_id) | 49 int routing_id) |
| 50 : view_(NULL), | 50 : view_(NULL), |
| 51 process_(process), | 51 process_(process), |
| 52 routing_id_(routing_id), | 52 routing_id_(routing_id), |
| 53 is_loading_(false), | 53 is_loading_(false), |
| 54 is_hidden_(false), | 54 is_hidden_(false), |
| 55 repaint_ack_pending_(false), | 55 repaint_ack_pending_(false), |
| 56 resize_ack_pending_(false), | 56 resize_ack_pending_(false), |
| 57 suppress_view_updating_(false), | |
| 58 mouse_move_pending_(false), | 57 mouse_move_pending_(false), |
| 59 needs_repainting_on_restore_(false), | 58 needs_repainting_on_restore_(false), |
| 60 is_unresponsive_(false), | 59 is_unresponsive_(false), |
| 60 in_get_backing_store_(false), |
| 61 view_being_painted_(false), | 61 view_being_painted_(false), |
| 62 text_direction_updated_(false), | 62 text_direction_updated_(false), |
| 63 text_direction_(WEB_TEXT_DIRECTION_LTR), | 63 text_direction_(WEB_TEXT_DIRECTION_LTR), |
| 64 text_direction_canceled_(false) { | 64 text_direction_canceled_(false) { |
| 65 if (routing_id_ == MSG_ROUTING_NONE) | 65 if (routing_id_ == MSG_ROUTING_NONE) |
| 66 routing_id_ = process_->GetNextRoutingID(); | 66 routing_id_ = process_->GetNextRoutingID(); |
| 67 | 67 |
| 68 process_->Attach(this, routing_id_); | 68 process_->Attach(this, routing_id_); |
| 69 // Because the widget initializes as is_hidden_ == false, | 69 // Because the widget initializes as is_hidden_ == false, |
| 70 // tell the process host that we're alive. | 70 // tell the process host that we're alive. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 if (!view_) | 202 if (!view_) |
| 203 return; | 203 return; |
| 204 view_->SetIsLoading(is_loading); | 204 view_->SetIsLoading(is_loading); |
| 205 } | 205 } |
| 206 | 206 |
| 207 BackingStore* RenderWidgetHost::GetBackingStore() { | 207 BackingStore* RenderWidgetHost::GetBackingStore() { |
| 208 // We should not be asked to paint while we are hidden. If we are hidden, | 208 // We should not be asked to paint while we are hidden. If we are hidden, |
| 209 // then it means that our consumer failed to call WasRestored. | 209 // then it means that our consumer failed to call WasRestored. |
| 210 DCHECK(!is_hidden_) << "GetBackingStore called while hidden!"; | 210 DCHECK(!is_hidden_) << "GetBackingStore called while hidden!"; |
| 211 | 211 |
| 212 // We should never be called recursively; this can theoretically lead to |
| 213 // infinite recursion and almost certainly leads to lower performance. |
| 214 DCHECK(!in_get_backing_store_) << "GetBackingStore called recursively!"; |
| 215 in_get_backing_store_ = true; |
| 216 |
| 212 // We might have a cached backing store that we can reuse! | 217 // We might have a cached backing store that we can reuse! |
| 213 BackingStore* backing_store = | 218 BackingStore* backing_store = |
| 214 BackingStoreManager::GetBackingStore(this, current_size_); | 219 BackingStoreManager::GetBackingStore(this, current_size_); |
| 215 // If we fail to find a backing store in the cache, send out a request | 220 // If we fail to find a backing store in the cache, send out a request |
| 216 // to the renderer to paint the view if required. | 221 // to the renderer to paint the view if required. |
| 217 if (!backing_store && !repaint_ack_pending_ && !resize_ack_pending_ && | 222 if (!backing_store && !repaint_ack_pending_ && !resize_ack_pending_ && |
| 218 !view_being_painted_) { | 223 !view_being_painted_) { |
| 219 repaint_start_time_ = TimeTicks::Now(); | 224 repaint_start_time_ = TimeTicks::Now(); |
| 220 repaint_ack_pending_ = true; | 225 repaint_ack_pending_ = true; |
| 221 Send(new ViewMsg_Repaint(routing_id_, current_size_)); | 226 Send(new ViewMsg_Repaint(routing_id_, current_size_)); |
| 222 } | 227 } |
| 223 | 228 |
| 224 // When we have asked the RenderWidget to resize, and we are still waiting on | 229 // When we have asked the RenderWidget to resize, and we are still waiting on |
| 225 // a response, block for a little while to see if we can't get a response | 230 // a response, block for a little while to see if we can't get a response |
| 226 // before returning the old (incorrectly sized) backing store. | 231 // before returning the old (incorrectly sized) backing store. |
| 227 if (resize_ack_pending_ || !backing_store) { | 232 if (resize_ack_pending_ || !backing_store) { |
| 228 IPC::Message msg; | 233 IPC::Message msg; |
| 229 TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS); | 234 TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS); |
| 230 if (process_->WaitForPaintMsg(routing_id_, max_delay, &msg)) { | 235 if (process_->WaitForPaintMsg(routing_id_, max_delay, &msg)) { |
| 231 suppress_view_updating_ = true; | |
| 232 ViewHostMsg_PaintRect::Dispatch( | 236 ViewHostMsg_PaintRect::Dispatch( |
| 233 &msg, this, &RenderWidgetHost::OnMsgPaintRect); | 237 &msg, this, &RenderWidgetHost::OnMsgPaintRect); |
| 234 suppress_view_updating_ = false; | |
| 235 backing_store = BackingStoreManager::GetBackingStore(this, current_size_); | 238 backing_store = BackingStoreManager::GetBackingStore(this, current_size_); |
| 236 } | 239 } |
| 237 } | 240 } |
| 238 | 241 |
| 242 in_get_backing_store_ = false; |
| 239 return backing_store; | 243 return backing_store; |
| 240 } | 244 } |
| 241 | 245 |
| 242 BackingStore* RenderWidgetHost::AllocBackingStore(const gfx::Size& size) { | 246 BackingStore* RenderWidgetHost::AllocBackingStore(const gfx::Size& size) { |
| 243 if (!view_) | 247 if (!view_) |
| 244 return NULL; | 248 return NULL; |
| 245 | 249 |
| 246 return view_->AllocBackingStore(size); | 250 return view_->AllocBackingStore(size); |
| 247 } | 251 } |
| 248 | 252 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 | 503 |
| 500 // We don't need to update the view if the view is hidden. We must do this | 504 // We don't need to update the view if the view is hidden. We must do this |
| 501 // early return after the ACK is sent, however, or the renderer will not send | 505 // early return after the ACK is sent, however, or the renderer will not send |
| 502 // is more data. | 506 // is more data. |
| 503 if (is_hidden_) | 507 if (is_hidden_) |
| 504 return; | 508 return; |
| 505 | 509 |
| 506 // Now paint the view. Watch out: it might be destroyed already. | 510 // Now paint the view. Watch out: it might be destroyed already. |
| 507 if (view_) { | 511 if (view_) { |
| 508 view_->MovePluginWindows(params.plugin_window_moves); | 512 view_->MovePluginWindows(params.plugin_window_moves); |
| 509 if (!suppress_view_updating_) { | 513 view_being_painted_ = true; |
| 510 view_being_painted_ = true; | 514 view_->DidPaintRect(params.bitmap_rect); |
| 511 view_->DidPaintRect(params.bitmap_rect); | 515 view_being_painted_ = false; |
| 512 view_being_painted_ = false; | |
| 513 } | |
| 514 } | 516 } |
| 515 | 517 |
| 516 if (paint_observer_.get()) | 518 if (paint_observer_.get()) |
| 517 paint_observer_->RenderWidgetHostDidPaint(this); | 519 paint_observer_->RenderWidgetHostDidPaint(this); |
| 518 | 520 |
| 519 // If we got a resize ack, then perhaps we have another resize to send? | 521 // If we got a resize ack, then perhaps we have another resize to send? |
| 520 if (is_resize_ack && view_) { | 522 if (is_resize_ack && view_) { |
| 521 gfx::Rect view_bounds = view_->GetViewBounds(); | 523 gfx::Rect view_bounds = view_->GetViewBounds(); |
| 522 if (current_size_.width() != view_bounds.width() || | 524 if (current_size_.width() != view_bounds.width() || |
| 523 current_size_.height() != view_bounds.height()) { | 525 current_size_.height() != view_bounds.height()) { |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 | 693 |
| 692 // TODO(darin): do we need to do something else if our backing store is not | 694 // TODO(darin): do we need to do something else if our backing store is not |
| 693 // the same size as the advertised view? maybe we just assume there is a | 695 // the same size as the advertised view? maybe we just assume there is a |
| 694 // full paint on its way? | 696 // full paint on its way? |
| 695 BackingStore* backing_store = BackingStoreManager::Lookup(this); | 697 BackingStore* backing_store = BackingStoreManager::Lookup(this); |
| 696 if (!backing_store || (backing_store->size() != view_size)) | 698 if (!backing_store || (backing_store->size() != view_size)) |
| 697 return; | 699 return; |
| 698 backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect, | 700 backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect, |
| 699 dx, dy, clip_rect, view_size); | 701 dx, dy, clip_rect, view_size); |
| 700 } | 702 } |
| OLD | NEW |