| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/gdi_util.h" | 7 #include "base/gfx/native_widget_types.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "chrome/app/chrome_dll_resource.h" | |
| 10 #include "chrome/browser/renderer_host/backing_store.h" | 9 #include "chrome/browser/renderer_host/backing_store.h" |
| 11 #include "chrome/browser/renderer_host/render_process_host.h" | 10 #include "chrome/browser/renderer_host/render_process_host.h" |
| 12 #include "chrome/browser/renderer_host/render_widget_helper.h" | 11 #include "chrome/browser/renderer_host/render_widget_helper.h" |
| 13 #include "chrome/browser/renderer_host/render_widget_host_view.h" | 12 #include "chrome/browser/renderer_host/render_widget_host_view.h" |
| 14 #include "chrome/common/notification_service.h" | 13 #include "chrome/common/notification_service.h" |
| 15 #include "chrome/common/win_util.h" | |
| 16 #include "chrome/views/view.h" | 14 #include "chrome/views/view.h" |
| 17 #include "webkit/glue/webcursor.h" | 15 #include "webkit/glue/webcursor.h" |
| 18 #include "webkit/glue/webinputevent.h" | 16 #include "webkit/glue/webinputevent.h" |
| 19 | 17 |
| 18 #if defined(OS_WIN) |
| 19 #include "base/gfx/gdi_util.h" |
| 20 #include "chrome/app/chrome_dll_resource.h" |
| 21 #include "chrome/common/win_util.h" |
| 22 #endif // defined(OS_WIN) |
| 23 |
| 20 using base::Time; | 24 using base::Time; |
| 21 using base::TimeDelta; | 25 using base::TimeDelta; |
| 22 using base::TimeTicks; | 26 using base::TimeTicks; |
| 23 | 27 |
| 24 // How long to (synchronously) wait for the renderer to respond with a | 28 // How long to (synchronously) wait for the renderer to respond with a |
| 25 // PaintRect message, when our backing-store is invalid, before giving up and | 29 // PaintRect message, when our backing-store is invalid, before giving up and |
| 26 // returning a null or incorrectly sized backing-store from GetBackingStore. | 30 // returning a null or incorrectly sized backing-store from GetBackingStore. |
| 27 // This timeout impacts the "choppiness" of our window resize perf. | 31 // This timeout impacts the "choppiness" of our window resize perf. |
| 28 static const int kPaintMsgTimeoutMS = 40; | 32 static const int kPaintMsgTimeoutMS = 40; |
| 29 | 33 |
| 30 // How long to wait before we consider a renderer hung. | 34 // How long to wait before we consider a renderer hung. |
| 31 static const int kHungRendererDelayMs = 20000; | 35 static const int kHungRendererDelayMs = 20000; |
| 32 | 36 |
| 33 /////////////////////////////////////////////////////////////////////////////// | 37 /////////////////////////////////////////////////////////////////////////////// |
| 34 // RenderWidgetHost | 38 // RenderWidgetHost |
| 35 | 39 |
| 36 RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, | 40 RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, |
| 37 int routing_id) | 41 int routing_id) |
| 38 : process_(process), | 42 : view_(NULL), |
| 43 process_(process), |
| 39 routing_id_(routing_id), | 44 routing_id_(routing_id), |
| 40 resize_ack_pending_(false), | |
| 41 mouse_move_pending_(false), | |
| 42 view_(NULL), | |
| 43 is_loading_(false), | 45 is_loading_(false), |
| 44 is_hidden_(false), | 46 is_hidden_(false), |
| 47 repaint_ack_pending_(false), |
| 48 resize_ack_pending_(false), |
| 45 suppress_view_updating_(false), | 49 suppress_view_updating_(false), |
| 50 mouse_move_pending_(false), |
| 46 needs_repainting_on_restore_(false), | 51 needs_repainting_on_restore_(false), |
| 47 is_unresponsive_(false), | 52 is_unresponsive_(false), |
| 48 view_being_painted_(false), | 53 view_being_painted_(false) { |
| 49 repaint_ack_pending_(false) { | |
| 50 if (routing_id_ == MSG_ROUTING_NONE) | 54 if (routing_id_ == MSG_ROUTING_NONE) |
| 51 routing_id_ = process_->GetNextRoutingID(); | 55 routing_id_ = process_->GetNextRoutingID(); |
| 52 | 56 |
| 53 process_->Attach(this, routing_id_); | 57 process_->Attach(this, routing_id_); |
| 54 // Because the widget initializes as is_hidden_ == false, | 58 // Because the widget initializes as is_hidden_ == false, |
| 55 // tell the process host that we're alive. | 59 // tell the process host that we're alive. |
| 56 process_->WidgetRestored(); | 60 process_->WidgetRestored(); |
| 57 } | 61 } |
| 58 | 62 |
| 59 RenderWidgetHost::~RenderWidgetHost() { | 63 RenderWidgetHost::~RenderWidgetHost() { |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 | 274 |
| 271 ForwardInputEvent(mouse_event, sizeof(WebMouseEvent)); | 275 ForwardInputEvent(mouse_event, sizeof(WebMouseEvent)); |
| 272 } | 276 } |
| 273 | 277 |
| 274 void RenderWidgetHost::ForwardWheelEvent( | 278 void RenderWidgetHost::ForwardWheelEvent( |
| 275 const WebMouseWheelEvent& wheel_event) { | 279 const WebMouseWheelEvent& wheel_event) { |
| 276 ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent)); | 280 ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent)); |
| 277 } | 281 } |
| 278 | 282 |
| 279 void RenderWidgetHost::ForwardKeyboardEvent(const WebKeyboardEvent& key_event) { | 283 void RenderWidgetHost::ForwardKeyboardEvent(const WebKeyboardEvent& key_event) { |
| 284 #if defined(OS_WIN) |
| 280 if (key_event.type == WebKeyboardEvent::CHAR && | 285 if (key_event.type == WebKeyboardEvent::CHAR && |
| 281 (key_event.key_code == VK_RETURN || key_event.key_code == VK_SPACE)) | 286 (key_event.key_code == VK_RETURN || key_event.key_code == VK_SPACE)) |
| 282 OnEnterOrSpace(); | 287 OnEnterOrSpace(); |
| 288 #else |
| 289 // TODO(port): we don't have portable keyboard codes yet |
| 290 // Maybe use keyboard_codes.h if we stick with it |
| 291 NOTIMPLEMENTED(); |
| 292 #endif |
| 283 | 293 |
| 284 ForwardInputEvent(key_event, sizeof(WebKeyboardEvent)); | 294 ForwardInputEvent(key_event, sizeof(WebKeyboardEvent)); |
| 285 } | 295 } |
| 286 | 296 |
| 287 void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event, | 297 void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event, |
| 288 int event_size) { | 298 int event_size) { |
| 289 if (!process_->channel()) | 299 if (!process_->channel()) |
| 290 return; | 300 return; |
| 291 | 301 |
| 292 IPC::Message* message = new ViewMsg_HandleInputEvent(routing_id_); | 302 IPC::Message* message = new ViewMsg_HandleInputEvent(routing_id_); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 } | 411 } |
| 402 | 412 |
| 403 bool is_repaint_ack = | 413 bool is_repaint_ack = |
| 404 ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags); | 414 ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags); |
| 405 if (is_repaint_ack) { | 415 if (is_repaint_ack) { |
| 406 repaint_ack_pending_ = false; | 416 repaint_ack_pending_ = false; |
| 407 TimeDelta delta = TimeTicks::Now() - repaint_start_time_; | 417 TimeDelta delta = TimeTicks::Now() - repaint_start_time_; |
| 408 UMA_HISTOGRAM_TIMES(L"MPArch.RWH_RepaintDelta", delta); | 418 UMA_HISTOGRAM_TIMES(L"MPArch.RWH_RepaintDelta", delta); |
| 409 } | 419 } |
| 410 | 420 |
| 411 DCHECK(params.bitmap); | |
| 412 DCHECK(!params.bitmap_rect.IsEmpty()); | 421 DCHECK(!params.bitmap_rect.IsEmpty()); |
| 413 DCHECK(!params.view_size.IsEmpty()); | 422 DCHECK(!params.view_size.IsEmpty()); |
| 414 | 423 |
| 415 // Paint the backing store. This will update it with the renderer-supplied | 424 // Paint the backing store. This will update it with the renderer-supplied |
| 416 // bits. The view will read out of the backing store later to actually draw | 425 // bits. The view will read out of the backing store later to actually draw |
| 417 // to the screen. | 426 // to the screen. |
| 418 PaintBackingStoreRect(params.bitmap, params.bitmap_rect, params.view_size); | 427 PaintBackingStoreRect(params.bitmap, params.bitmap_rect, params.view_size); |
| 419 | 428 |
| 420 // ACK early so we can prefetch the next PaintRect if there is a next one. | 429 // ACK early so we can prefetch the next PaintRect if there is a next one. |
| 421 // This must be done AFTER we're done painting with the bitmap supplied by the | 430 // This must be done AFTER we're done painting with the bitmap supplied by the |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 view_->UpdateCursor(cursor); | 549 view_->UpdateCursor(cursor); |
| 541 } | 550 } |
| 542 | 551 |
| 543 void RenderWidgetHost::OnMsgImeUpdateStatus(ViewHostMsg_ImeControl control, | 552 void RenderWidgetHost::OnMsgImeUpdateStatus(ViewHostMsg_ImeControl control, |
| 544 const gfx::Rect& caret_rect) { | 553 const gfx::Rect& caret_rect) { |
| 545 if (view_) { | 554 if (view_) { |
| 546 view_->IMEUpdateStatus(control, caret_rect); | 555 view_->IMEUpdateStatus(control, caret_rect); |
| 547 } | 556 } |
| 548 } | 557 } |
| 549 | 558 |
| 550 void RenderWidgetHost::PaintBackingStoreRect(HANDLE bitmap, | 559 void RenderWidgetHost::PaintBackingStoreRect(BitmapWireData bitmap, |
| 551 const gfx::Rect& bitmap_rect, | 560 const gfx::Rect& bitmap_rect, |
| 552 const gfx::Size& view_size) { | 561 const gfx::Size& view_size) { |
| 553 if (is_hidden_) { | 562 if (is_hidden_) { |
| 554 // Don't bother updating the backing store when we're hidden. Just mark it | 563 // Don't bother updating the backing store when we're hidden. Just mark it |
| 555 // as being totally invalid. This will cause a complete repaint when the | 564 // as being totally invalid. This will cause a complete repaint when the |
| 556 // view is restored. | 565 // view is restored. |
| 557 needs_repainting_on_restore_ = true; | 566 needs_repainting_on_restore_ = true; |
| 558 return; | 567 return; |
| 559 } | 568 } |
| 560 | 569 |
| 561 // We use the view size according to the render view, which may not be | 570 // We use the view size according to the render view, which may not be |
| 562 // quite the same as the size of our window. | 571 // quite the same as the size of our window. |
| 563 gfx::Rect view_rect(0, 0, view_size.width(), view_size.height()); | 572 gfx::Rect view_rect(0, 0, view_size.width(), view_size.height()); |
| 564 | 573 |
| 565 bool needs_full_paint = false; | 574 bool needs_full_paint = false; |
| 566 BackingStore* backing_store = | 575 BackingStore* backing_store = |
| 567 BackingStoreManager::PrepareBackingStore(this, view_rect, | 576 BackingStoreManager::PrepareBackingStore(this, view_rect, |
| 568 process_->process().handle(), | 577 process_->process().handle(), |
| 569 bitmap, bitmap_rect, | 578 bitmap, bitmap_rect, |
| 570 &needs_full_paint); | 579 &needs_full_paint); |
| 571 DCHECK(backing_store != NULL); | 580 DCHECK(backing_store != NULL); |
| 572 if (needs_full_paint) { | 581 if (needs_full_paint) { |
| 573 repaint_start_time_ = TimeTicks::Now(); | 582 repaint_start_time_ = TimeTicks::Now(); |
| 574 repaint_ack_pending_ = true; | 583 repaint_ack_pending_ = true; |
| 575 Send(new ViewMsg_Repaint(routing_id_, view_size)); | 584 Send(new ViewMsg_Repaint(routing_id_, view_size)); |
| 576 } | 585 } |
| 577 } | 586 } |
| 578 | 587 |
| 579 void RenderWidgetHost::ScrollBackingStoreRect(HANDLE bitmap, | 588 void RenderWidgetHost::ScrollBackingStoreRect(BitmapWireData bitmap, |
| 580 const gfx::Rect& bitmap_rect, | 589 const gfx::Rect& bitmap_rect, |
| 581 int dx, int dy, | 590 int dx, int dy, |
| 582 const gfx::Rect& clip_rect, | 591 const gfx::Rect& clip_rect, |
| 583 const gfx::Size& view_size) { | 592 const gfx::Size& view_size) { |
| 584 if (is_hidden_) { | 593 if (is_hidden_) { |
| 585 // Don't bother updating the backing store when we're hidden. Just mark it | 594 // Don't bother updating the backing store when we're hidden. Just mark it |
| 586 // as being totally invalid. This will cause a complete repaint when the | 595 // as being totally invalid. This will cause a complete repaint when the |
| 587 // view is restored. | 596 // view is restored. |
| 588 needs_repainting_on_restore_ = true; | 597 needs_repainting_on_restore_ = true; |
| 589 return; | 598 return; |
| 590 } | 599 } |
| 591 | 600 |
| 592 // TODO(darin): do we need to do something else if our backing store is not | 601 // TODO(darin): do we need to do something else if our backing store is not |
| 593 // the same size as the advertised view? maybe we just assume there is a | 602 // the same size as the advertised view? maybe we just assume there is a |
| 594 // full paint on its way? | 603 // full paint on its way? |
| 595 BackingStore* backing_store = BackingStoreManager::Lookup(this); | 604 BackingStore* backing_store = BackingStoreManager::Lookup(this); |
| 596 if (!backing_store || (backing_store->size() != view_size)) | 605 if (!backing_store || (backing_store->size() != view_size)) |
| 597 return; | 606 return; |
| 598 backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect, | 607 backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect, |
| 599 dx, dy, clip_rect, view_size); | 608 dx, dy, clip_rect, view_size); |
| 600 } | 609 } |
| OLD | NEW |