| 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/native_widget_types.h" | 7 #include "base/gfx/native_widget_types.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/keyboard_codes.h" | 9 #include "base/keyboard_codes.h" |
| 10 #include "chrome/browser/renderer_host/backing_store.h" | 10 #include "chrome/browser/renderer_host/backing_store.h" |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags); | 417 ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags); |
| 418 if (is_repaint_ack) { | 418 if (is_repaint_ack) { |
| 419 repaint_ack_pending_ = false; | 419 repaint_ack_pending_ = false; |
| 420 TimeDelta delta = TimeTicks::Now() - repaint_start_time_; | 420 TimeDelta delta = TimeTicks::Now() - repaint_start_time_; |
| 421 UMA_HISTOGRAM_TIMES(L"MPArch.RWH_RepaintDelta", delta); | 421 UMA_HISTOGRAM_TIMES(L"MPArch.RWH_RepaintDelta", delta); |
| 422 } | 422 } |
| 423 | 423 |
| 424 DCHECK(!params.bitmap_rect.IsEmpty()); | 424 DCHECK(!params.bitmap_rect.IsEmpty()); |
| 425 DCHECK(!params.view_size.IsEmpty()); | 425 DCHECK(!params.view_size.IsEmpty()); |
| 426 | 426 |
| 427 // Paint the backing store. This will update it with the renderer-supplied | 427 const size_t size = params.bitmap_rect.height() * |
| 428 // bits. The view will read out of the backing store later to actually draw | 428 params.bitmap_rect.width() * 4; |
| 429 // to the screen. | 429 TransportDIB* dib = process_->GetTransportDIB(params.bitmap); |
| 430 PaintBackingStoreRect(params.bitmap, params.bitmap_rect, params.view_size); | 430 if (dib) { |
| 431 if (dib->size() < size) { |
| 432 DLOG(WARNING) << "Transport DIB too small for given rectangle"; |
| 433 process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID); |
| 434 } else { |
| 435 // Paint the backing store. This will update it with the renderer-supplied |
| 436 // bits. The view will read out of the backing store later to actually dra
w |
| 437 // to the screen. |
| 438 PaintBackingStoreRect(dib, params.bitmap_rect, params.view_size); |
| 439 } |
| 440 } |
| 431 | 441 |
| 432 // ACK early so we can prefetch the next PaintRect if there is a next one. | 442 // ACK early so we can prefetch the next PaintRect if there is a next one. |
| 433 // This must be done AFTER we're done painting with the bitmap supplied by the | 443 // This must be done AFTER we're done painting with the bitmap supplied by the |
| 434 // renderer. This ACK is a signal to the renderer that the backing store can | 444 // renderer. This ACK is a signal to the renderer that the backing store can |
| 435 // be re-used, so the bitmap may be invalid after this call. | 445 // be re-used, so the bitmap may be invalid after this call. |
| 436 Send(new ViewMsg_PaintRect_ACK(routing_id_)); | 446 Send(new ViewMsg_PaintRect_ACK(routing_id_)); |
| 437 | 447 |
| 438 // We don't need to update the view if the view is hidden. We must do this | 448 // We don't need to update the view if the view is hidden. We must do this |
| 439 // early return after the ACK is sent, however, or the renderer will not send | 449 // early return after the ACK is sent, however, or the renderer will not send |
| 440 // is more data. | 450 // is more data. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 467 TimeDelta delta = TimeTicks::Now() - paint_start; | 477 TimeDelta delta = TimeTicks::Now() - paint_start; |
| 468 UMA_HISTOGRAM_TIMES(L"MPArch.RWH_OnMsgPaintRect", delta); | 478 UMA_HISTOGRAM_TIMES(L"MPArch.RWH_OnMsgPaintRect", delta); |
| 469 } | 479 } |
| 470 | 480 |
| 471 void RenderWidgetHost::OnMsgScrollRect( | 481 void RenderWidgetHost::OnMsgScrollRect( |
| 472 const ViewHostMsg_ScrollRect_Params& params) { | 482 const ViewHostMsg_ScrollRect_Params& params) { |
| 473 TimeTicks scroll_start = TimeTicks::Now(); | 483 TimeTicks scroll_start = TimeTicks::Now(); |
| 474 | 484 |
| 475 DCHECK(!params.view_size.IsEmpty()); | 485 DCHECK(!params.view_size.IsEmpty()); |
| 476 | 486 |
| 477 // Scroll the backing store. | 487 const size_t size = params.bitmap_rect.height() * |
| 478 ScrollBackingStoreRect(params.bitmap, params.bitmap_rect, | 488 params.bitmap_rect.width() * 4; |
| 479 params.dx, params.dy, | 489 TransportDIB* dib = process_->GetTransportDIB(params.bitmap); |
| 480 params.clip_rect, params.view_size); | 490 if (dib) { |
| 491 if (dib->size() < size) { |
| 492 LOG(WARNING) << "Transport DIB too small for given rectangle"; |
| 493 process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID); |
| 494 } else { |
| 495 // Scroll the backing store. |
| 496 ScrollBackingStoreRect(dib, params.bitmap_rect, |
| 497 params.dx, params.dy, |
| 498 params.clip_rect, params.view_size); |
| 499 } |
| 500 } |
| 481 | 501 |
| 482 // ACK early so we can prefetch the next ScrollRect if there is a next one. | 502 // ACK early so we can prefetch the next ScrollRect if there is a next one. |
| 483 // This must be done AFTER we're done painting with the bitmap supplied by the | 503 // This must be done AFTER we're done painting with the bitmap supplied by the |
| 484 // renderer. This ACK is a signal to the renderer that the backing store can | 504 // renderer. This ACK is a signal to the renderer that the backing store can |
| 485 // be re-used, so the bitmap may be invalid after this call. | 505 // be re-used, so the bitmap may be invalid after this call. |
| 486 Send(new ViewMsg_ScrollRect_ACK(routing_id_)); | 506 Send(new ViewMsg_ScrollRect_ACK(routing_id_)); |
| 487 | 507 |
| 488 // We don't need to update the view if the view is hidden. We must do this | 508 // We don't need to update the view if the view is hidden. We must do this |
| 489 // early return after the ACK is sent, however, or the renderer will not send | 509 // early return after the ACK is sent, however, or the renderer will not send |
| 490 // is more data. | 510 // is more data. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 view_->UpdateCursor(cursor); | 574 view_->UpdateCursor(cursor); |
| 555 } | 575 } |
| 556 | 576 |
| 557 void RenderWidgetHost::OnMsgImeUpdateStatus(int control, | 577 void RenderWidgetHost::OnMsgImeUpdateStatus(int control, |
| 558 const gfx::Rect& caret_rect) { | 578 const gfx::Rect& caret_rect) { |
| 559 if (view_) { | 579 if (view_) { |
| 560 view_->IMEUpdateStatus(control, caret_rect); | 580 view_->IMEUpdateStatus(control, caret_rect); |
| 561 } | 581 } |
| 562 } | 582 } |
| 563 | 583 |
| 564 void RenderWidgetHost::PaintBackingStoreRect(BitmapWireData bitmap, | 584 void RenderWidgetHost::PaintBackingStoreRect(TransportDIB* bitmap, |
| 565 const gfx::Rect& bitmap_rect, | 585 const gfx::Rect& bitmap_rect, |
| 566 const gfx::Size& view_size) { | 586 const gfx::Size& view_size) { |
| 567 if (is_hidden_) { | 587 if (is_hidden_) { |
| 568 // Don't bother updating the backing store when we're hidden. Just mark it | 588 // Don't bother updating the backing store when we're hidden. Just mark it |
| 569 // as being totally invalid. This will cause a complete repaint when the | 589 // as being totally invalid. This will cause a complete repaint when the |
| 570 // view is restored. | 590 // view is restored. |
| 571 needs_repainting_on_restore_ = true; | 591 needs_repainting_on_restore_ = true; |
| 572 return; | 592 return; |
| 573 } | 593 } |
| 574 | 594 |
| 575 // We use the view size according to the render view, which may not be | 595 // We use the view size according to the render view, which may not be |
| 576 // quite the same as the size of our window. | 596 // quite the same as the size of our window. |
| 577 gfx::Rect view_rect(0, 0, view_size.width(), view_size.height()); | 597 gfx::Rect view_rect(0, 0, view_size.width(), view_size.height()); |
| 578 | 598 |
| 579 bool needs_full_paint = false; | 599 bool needs_full_paint = false; |
| 580 BackingStore* backing_store = | 600 BackingStore* backing_store = |
| 581 BackingStoreManager::PrepareBackingStore(this, view_rect, | 601 BackingStoreManager::PrepareBackingStore(this, view_rect, |
| 582 process_->process().handle(), | 602 process_->process().handle(), |
| 583 bitmap, bitmap_rect, | 603 bitmap, bitmap_rect, |
| 584 &needs_full_paint); | 604 &needs_full_paint); |
| 585 DCHECK(backing_store != NULL); | 605 DCHECK(backing_store != NULL); |
| 586 if (needs_full_paint) { | 606 if (needs_full_paint) { |
| 587 repaint_start_time_ = TimeTicks::Now(); | 607 repaint_start_time_ = TimeTicks::Now(); |
| 588 repaint_ack_pending_ = true; | 608 repaint_ack_pending_ = true; |
| 589 Send(new ViewMsg_Repaint(routing_id_, view_size)); | 609 Send(new ViewMsg_Repaint(routing_id_, view_size)); |
| 590 } | 610 } |
| 591 } | 611 } |
| 592 | 612 |
| 593 void RenderWidgetHost::ScrollBackingStoreRect(BitmapWireData bitmap, | 613 void RenderWidgetHost::ScrollBackingStoreRect(TransportDIB* bitmap, |
| 594 const gfx::Rect& bitmap_rect, | 614 const gfx::Rect& bitmap_rect, |
| 595 int dx, int dy, | 615 int dx, int dy, |
| 596 const gfx::Rect& clip_rect, | 616 const gfx::Rect& clip_rect, |
| 597 const gfx::Size& view_size) { | 617 const gfx::Size& view_size) { |
| 598 if (is_hidden_) { | 618 if (is_hidden_) { |
| 599 // Don't bother updating the backing store when we're hidden. Just mark it | 619 // Don't bother updating the backing store when we're hidden. Just mark it |
| 600 // as being totally invalid. This will cause a complete repaint when the | 620 // as being totally invalid. This will cause a complete repaint when the |
| 601 // view is restored. | 621 // view is restored. |
| 602 needs_repainting_on_restore_ = true; | 622 needs_repainting_on_restore_ = true; |
| 603 return; | 623 return; |
| 604 } | 624 } |
| 605 | 625 |
| 606 // TODO(darin): do we need to do something else if our backing store is not | 626 // TODO(darin): do we need to do something else if our backing store is not |
| 607 // the same size as the advertised view? maybe we just assume there is a | 627 // the same size as the advertised view? maybe we just assume there is a |
| 608 // full paint on its way? | 628 // full paint on its way? |
| 609 BackingStore* backing_store = BackingStoreManager::Lookup(this); | 629 BackingStore* backing_store = BackingStoreManager::Lookup(this); |
| 610 if (!backing_store || (backing_store->size() != view_size)) | 630 if (!backing_store || (backing_store->size() != view_size)) |
| 611 return; | 631 return; |
| 612 backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect, | 632 backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect, |
| 613 dx, dy, clip_rect, view_size); | 633 dx, dy, clip_rect, view_size); |
| 614 } | 634 } |
| OLD | NEW |