Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: chrome/browser/renderer_host/render_widget_host.cc

Issue 108040: Send array of paint rects and bitmaps as opposed to a Union (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/histogram.h" 7 #include "base/histogram.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"
11 #include "chrome/browser/renderer_host/render_process_host.h" 11 #include "chrome/browser/renderer_host/render_process_host.h"
12 #include "chrome/browser/renderer_host/render_widget_helper.h" 12 #include "chrome/browser/renderer_host/render_widget_helper.h"
13 #include "chrome/browser/renderer_host/render_widget_host_view.h" 13 #include "chrome/browser/renderer_host/render_widget_host_view.h"
14 #include "chrome/common/notification_service.h" 14 #include "chrome/common/notification_service.h"
15 #include "chrome/common/render_messages.h" 15 #include "chrome/common/render_messages.h"
16 #include "skia/ext/platform_canvas.h"
16 #include "views/view.h" 17 #include "views/view.h"
17 #include "webkit/glue/webcursor.h" 18 #include "webkit/glue/webcursor.h"
18 #include "webkit/glue/webtextdirection.h" 19 #include "webkit/glue/webtextdirection.h"
19 20
20 #if defined(OS_WIN) 21 #if defined(OS_WIN)
21 #include "base/gfx/gdi_util.h" 22 #include "base/gfx/gdi_util.h"
22 #include "chrome/app/chrome_dll_resource.h" 23 #include "chrome/app/chrome_dll_resource.h"
23 #endif // defined(OS_WIN) 24 #endif // defined(OS_WIN)
24 25
25 using base::Time; 26 using base::Time;
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags); 491 ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags);
491 if (is_repaint_ack) { 492 if (is_repaint_ack) {
492 repaint_ack_pending_ = false; 493 repaint_ack_pending_ = false;
493 TimeDelta delta = TimeTicks::Now() - repaint_start_time_; 494 TimeDelta delta = TimeTicks::Now() - repaint_start_time_;
494 UMA_HISTOGRAM_TIMES("MPArch.RWH_RepaintDelta", delta); 495 UMA_HISTOGRAM_TIMES("MPArch.RWH_RepaintDelta", delta);
495 } 496 }
496 497
497 DCHECK(!params.bitmap_rect.IsEmpty()); 498 DCHECK(!params.bitmap_rect.IsEmpty());
498 DCHECK(!params.view_size.IsEmpty()); 499 DCHECK(!params.view_size.IsEmpty());
499 500
500 const size_t size = params.bitmap_rect.height() *
501 params.bitmap_rect.width() * 4;
502 TransportDIB* dib = process_->GetTransportDIB(params.bitmap); 501 TransportDIB* dib = process_->GetTransportDIB(params.bitmap);
503 if (dib) { 502 if (dib) {
503 const size_t size = params.bitmap_rect.height() *
504 skia::PlatformCanvas::StrideForWidth(params.bitmap_rect.width());
504 if (dib->size() < size) { 505 if (dib->size() < size) {
505 DLOG(WARNING) << "Transport DIB too small for given rectangle"; 506 DLOG(WARNING) << "Transport DIB too small for given rectangle";
506 process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID); 507 process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID);
507 } else { 508 } else {
508 // Paint the backing store. This will update it with the renderer-supplied 509 // Paint the backing store. This will update it with the
509 // bits. The view will read out of the backing store later to actually 510 // renderer-supplied bits. The view will read out of the backing
510 // draw to the screen. 511 // store later to actually draw to the screen.
511 PaintBackingStoreRect(dib, params.bitmap_rect, params.view_size); 512 PaintBackingStoreRects(dib, params.bitmap_rect, params.paint_rects,
513 params.view_size);
512 } 514 }
513 } 515 }
514 516
515 // ACK early so we can prefetch the next PaintRect if there is a next one. 517 // ACK early so we can prefetch the next PaintRect if there is a next one.
516 // This must be done AFTER we're done painting with the bitmap supplied by the 518 // This must be done AFTER we're done painting with the bitmap supplied by the
517 // renderer. This ACK is a signal to the renderer that the backing store can 519 // renderer. This ACK is a signal to the renderer that the backing store can
518 // be re-used, so the bitmap may be invalid after this call. 520 // be re-used, so the bitmap may be invalid after this call.
519 Send(new ViewMsg_PaintRect_ACK(routing_id_)); 521 Send(new ViewMsg_PaintRect_ACK(routing_id_));
520 522
521 // We don't need to update the view if the view is hidden. We must do this 523 // We don't need to update the view if the view is hidden. We must do this
522 // early return after the ACK is sent, however, or the renderer will not send 524 // early return after the ACK is sent, however, or the renderer will not send
523 // is more data. 525 // is more data.
524 if (is_hidden_) 526 if (is_hidden_)
525 return; 527 return;
526 528
527 // Now paint the view. Watch out: it might be destroyed already. 529 // Now paint the view. Watch out: it might be destroyed already.
528 if (view_) { 530 if (view_) {
529 view_->MovePluginWindows(params.plugin_window_moves); 531 view_->MovePluginWindows(params.plugin_window_moves);
530 view_being_painted_ = true; 532 view_being_painted_ = true;
531 view_->DidPaintRect(params.bitmap_rect); 533 if (params.paint_rects.empty()) {
534 view_->DidPaintRect(params.bitmap_rect);
535 } else {
536 for (size_t i = 0; i < params.paint_rects.size(); ++i)
537 view_->DidPaintRect(params.paint_rects[i]);
538 }
532 view_being_painted_ = false; 539 view_being_painted_ = false;
533 } 540 }
534 541
535 if (paint_observer_.get()) 542 if (paint_observer_.get())
536 paint_observer_->RenderWidgetHostDidPaint(this); 543 paint_observer_->RenderWidgetHostDidPaint(this);
537 544
538 // If we got a resize ack, then perhaps we have another resize to send? 545 // If we got a resize ack, then perhaps we have another resize to send?
539 if (is_resize_ack && view_) { 546 if (is_resize_ack && view_) {
540 gfx::Rect view_bounds = view_->GetViewBounds(); 547 gfx::Rect view_bounds = view_->GetViewBounds();
541 if (current_size_.width() != view_bounds.width() || 548 if (current_size_.width() != view_bounds.width() ||
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 mouse_move_pending_ = false; 619 mouse_move_pending_ = false;
613 620
614 // now, we can send the next mouse move event 621 // now, we can send the next mouse move event
615 if (next_mouse_move_.get()) { 622 if (next_mouse_move_.get()) {
616 DCHECK(next_mouse_move_->type == WebInputEvent::MouseMove); 623 DCHECK(next_mouse_move_->type == WebInputEvent::MouseMove);
617 ForwardMouseEvent(*next_mouse_move_); 624 ForwardMouseEvent(*next_mouse_move_);
618 } 625 }
619 } 626 }
620 627
621 if (WebInputEvent::isKeyboardEventType(type)) { 628 if (WebInputEvent::isKeyboardEventType(type)) {
622 if (key_queue_.size() == 0) { 629 if (key_queue_.empty()) {
623 LOG(ERROR) << "Got a KeyEvent back from the renderer but we " 630 LOG(ERROR) << "Got a KeyEvent back from the renderer but we "
624 << "don't seem to have sent it to the renderer!"; 631 << "don't seem to have sent it to the renderer!";
625 } else if (key_queue_.front().type != type) { 632 } else if (key_queue_.front().type != type) {
626 LOG(ERROR) << "We seem to have a different key type sent from " 633 LOG(ERROR) << "We seem to have a different key type sent from "
627 << "the renderer. (" << key_queue_.front().type << " vs. " 634 << "the renderer. (" << key_queue_.front().type << " vs. "
628 << type << "). Ignoring event."; 635 << type << "). Ignoring event.";
629 } else { 636 } else {
630 bool processed = false; 637 bool processed = false;
631 r = message.ReadBool(&iter, &processed); 638 r = message.ReadBool(&iter, &processed);
632 DCHECK(r); 639 DCHECK(r);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 687
681 view_->ShowPopupWithItems(validated_params.bounds, 688 view_->ShowPopupWithItems(validated_params.bounds,
682 validated_params.item_height, 689 validated_params.item_height,
683 validated_params.selected_item, 690 validated_params.selected_item,
684 validated_params.popup_items); 691 validated_params.popup_items);
685 #else // OS_WIN || OS_LINUX 692 #else // OS_WIN || OS_LINUX
686 NOTREACHED(); 693 NOTREACHED();
687 #endif 694 #endif
688 } 695 }
689 696
690 void RenderWidgetHost::PaintBackingStoreRect(TransportDIB* bitmap, 697 static bool CoversArea(const std::vector<gfx::Rect>& rects,
darin (slow to review) 2009/06/10 17:23:24 nit: please move helper functions to the top of th
MAD 2009/06/10 19:00:13 Done.
691 const gfx::Rect& bitmap_rect, 698 const gfx::Size& size) {
692 const gfx::Size& view_size) { 699 #ifndef NDEBUG
700 // Make sure there are no overlapping rects. That would make the
701 // test below irrelevant. We only do it in the debug build since
702 // this case "should" be covered in the renderer.
703 gfx::Rect view_rect(size.width(), size.height());
704 size_t last_index = rects.size() - 1;
705 for (size_t i = 0; i < last_index; ++i) {
706 DCHECK(view_rect.Contains(rects[i]));
707 for (size_t j = i + 1; i < rects.size(); ++i)
708 DCHECK(!rects[i].Intersects(rects[j]));
709 }
710 DCHECK(view_rect.Contains(rects[last_index]));
711 #endif
712 int target_area = size.height() * size.width();
713 int covered_area = 0;
714 for (size_t i = 0; i < rects.size(); ++i) {
715 covered_area += rects[i].height() * rects[i].width();
716 }
717 return covered_area < target_area;
718 }
719
720 void RenderWidgetHost::PaintBackingStoreRects(
721 TransportDIB* bitmap, const gfx::Rect& bitmap_rect,
722 const std::vector<gfx::Rect>& paint_rects,
723 const gfx::Size& view_size) {
693 // The view may be destroyed already. 724 // The view may be destroyed already.
694 if (!view_) 725 if (!view_)
695 return; 726 return;
696 727
697 if (is_hidden_) { 728 if (is_hidden_) {
698 // Don't bother updating the backing store when we're hidden. Just mark it 729 // Don't bother updating the backing store when we're hidden. Just mark it
699 // as being totally invalid. This will cause a complete repaint when the 730 // as being totally invalid. This will cause a complete repaint when the
700 // view is restored. 731 // view is restored.
701 needs_repainting_on_restore_ = true; 732 needs_repainting_on_restore_ = true;
702 return; 733 return;
703 } 734 }
704 735
705 bool needs_full_paint = false; 736 bool needs_full_paint = false;
706 BackingStore* backing_store = 737 base::ProcessHandle process_handle = process_->process().handle();
707 BackingStoreManager::PrepareBackingStore(this, view_size, 738 if (paint_rects.empty()) {
708 process_->process().handle(), 739 BackingStore* backing_store =
709 bitmap, bitmap_rect, 740 BackingStoreManager::PrepareBackingStore(this, view_size,
710 &needs_full_paint); 741 process_handle, bitmap, bitmap_rect, bitmap_rect,
711 DCHECK(backing_store != NULL); 742 &needs_full_paint);
743 DCHECK(backing_store != NULL);
744 } else {
745 bool checked_coverage = false;
746 // TODO(agl): Reduce the number of X server round trips on Linux.
747 for (size_t i = 0; i < paint_rects.size(); ++i) {
748 BackingStore* backing_store =
749 BackingStoreManager::PrepareBackingStore(this, view_size,
750 process_handle, bitmap, bitmap_rect, paint_rects[i],
751 &needs_full_paint);
752 DCHECK(backing_store != NULL);
753 if (needs_full_paint) {
754 // We should not need a full paint more than once for a given view size
755 DCHECK(!checked_coverage);
756 checked_coverage = true;
757
758 // Before we ask for a full repaint, we check if we already have a
759 // full coverage of the view size in out list of paint_rects
760 if (CoversArea(paint_rects, view_size))
761 break;
762 needs_full_paint = false;
763 }
764 }
765 }
766
712 if (needs_full_paint) { 767 if (needs_full_paint) {
713 repaint_start_time_ = TimeTicks::Now(); 768 repaint_start_time_ = TimeTicks::Now();
714 repaint_ack_pending_ = true; 769 repaint_ack_pending_ = true;
715 Send(new ViewMsg_Repaint(routing_id_, view_size)); 770 Send(new ViewMsg_Repaint(routing_id_, view_size));
716 } 771 }
717 } 772 }
718 773
719 void RenderWidgetHost::ScrollBackingStoreRect(TransportDIB* bitmap, 774 void RenderWidgetHost::ScrollBackingStoreRect(TransportDIB* bitmap,
720 const gfx::Rect& bitmap_rect, 775 const gfx::Rect& bitmap_rect,
721 int dx, int dy, 776 int dx, int dy,
722 const gfx::Rect& clip_rect, 777 const gfx::Rect& clip_rect,
723 const gfx::Size& view_size) { 778 const gfx::Size& view_size) {
724 if (is_hidden_) { 779 if (is_hidden_) {
725 // Don't bother updating the backing store when we're hidden. Just mark it 780 // Don't bother updating the backing store when we're hidden. Just mark it
726 // as being totally invalid. This will cause a complete repaint when the 781 // as being totally invalid. This will cause a complete repaint when the
727 // view is restored. 782 // view is restored.
728 needs_repainting_on_restore_ = true; 783 needs_repainting_on_restore_ = true;
729 return; 784 return;
730 } 785 }
731 786
732 // TODO(darin): do we need to do something else if our backing store is not 787 // TODO(darin): do we need to do something else if our backing store is not
733 // the same size as the advertised view? maybe we just assume there is a 788 // the same size as the advertised view? maybe we just assume there is a
734 // full paint on its way? 789 // full paint on its way?
735 BackingStore* backing_store = BackingStoreManager::Lookup(this); 790 BackingStore* backing_store = BackingStoreManager::Lookup(this);
736 if (!backing_store || (backing_store->size() != view_size)) 791 if (!backing_store || (backing_store->size() != view_size))
737 return; 792 return;
738 backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect, 793 backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect,
739 dx, dy, clip_rect, view_size); 794 dx, dy, clip_rect, view_size);
740 } 795 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698