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 |