diff options
author | mad@chromium.org <mad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-15 13:58:30 +0000 |
---|---|---|
committer | mad@chromium.org <mad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-15 13:58:30 +0000 |
commit | c2d1d3bdc97218d7bb123fb2623347632fdc4ee5 (patch) | |
tree | 62f47d49aec7a0f57a41d04bc272daf76cccf0cf /chrome/browser/renderer_host/render_widget_host.cc | |
parent | 1149bde26565fa08c3e14103ec5b02c00db82cf9 (diff) | |
download | chromium_src-c2d1d3bdc97218d7bb123fb2623347632fdc4ee5.zip chromium_src-c2d1d3bdc97218d7bb123fb2623347632fdc4ee5.tar.gz chromium_src-c2d1d3bdc97218d7bb123fb2623347632fdc4ee5.tar.bz2 |
This is to thest the page cycler performance without the resize corner, to see if these paint optimizations are worth it.
I will revert these changes as needed... You may revert them yourself if they cause you trouble before I get to revert them.
I have tested these changes on two different linux configuration, but there are more code paths that I couldn't verify myself, though agl gave me the OK anyway.
These changes have already been reviewed here:
http://codereview.chromium.org/108040
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18383 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host/render_widget_host.cc')
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host.cc | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index fccd45d..c6d7142 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -14,6 +14,7 @@ #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/common/notification_service.h" #include "chrome/common/render_messages.h" +#include "skia/ext/platform_canvas.h" #include "views/view.h" #include "webkit/glue/webcursor.h" #include "webkit/glue/webtextdirection.h" @@ -41,6 +42,32 @@ static const int kPaintMsgTimeoutMS = 40; // How long to wait before we consider a renderer hung. static const int kHungRendererDelayMs = 20000; +// Helper function to confirm if a set of rects completely cover a given area. +// The caller already know that all the rects are contained within the area, +// and they shold not overlap either, so all we need to do is compare the areas. +static bool CoversArea(const std::vector<gfx::Rect>& rects, + const gfx::Size& size) { +#ifndef NDEBUG + // Make sure there are no overlapping rects. That would make the + // test below irrelevant. We only do it in the debug build since + // this case "should" be covered in the renderer. + gfx::Rect view_rect(size.width(), size.height()); + size_t last_index = rects.size() - 1; + for (size_t i = 0; i < last_index; ++i) { + DCHECK(view_rect.Contains(rects[i])); + for (size_t j = i + 1; j < rects.size(); ++j) + DCHECK(!rects[i].Intersects(rects[j])); + } + DCHECK(view_rect.Contains(rects[last_index])); +#endif + int target_area = size.height() * size.width(); + int covered_area = 0; + for (size_t i = 0; i < rects.size(); ++i) { + covered_area += rects[i].height() * rects[i].width(); + } + return covered_area < target_area; +} + /////////////////////////////////////////////////////////////////////////////// // RenderWidgetHost @@ -502,18 +529,19 @@ void RenderWidgetHost::OnMsgPaintRect( DCHECK(!params.bitmap_rect.IsEmpty()); DCHECK(!params.view_size.IsEmpty()); - const size_t size = params.bitmap_rect.height() * - params.bitmap_rect.width() * 4; TransportDIB* dib = process_->GetTransportDIB(params.bitmap); if (dib) { + const size_t size = params.bitmap_rect.height() * + skia::PlatformCanvas::StrideForWidth(params.bitmap_rect.width()); if (dib->size() < size) { DLOG(WARNING) << "Transport DIB too small for given rectangle"; process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID); } else { - // Paint the backing store. This will update it with the renderer-supplied - // bits. The view will read out of the backing store later to actually - // draw to the screen. - PaintBackingStoreRect(dib, params.bitmap_rect, params.view_size); + // Paint the backing store. This will update it with the + // renderer-supplied bits. The view will read out of the backing + // store later to actually draw to the screen. + PaintBackingStoreRects(dib, params.bitmap_rect, params.paint_rects, + params.view_size); } } @@ -533,7 +561,12 @@ void RenderWidgetHost::OnMsgPaintRect( if (view_) { view_->MovePluginWindows(params.plugin_window_moves); view_being_painted_ = true; - view_->DidPaintRect(params.bitmap_rect); + if (params.paint_rects.empty()) { + view_->DidPaintRect(params.bitmap_rect); + } else { + for (size_t i = 0; i < params.paint_rects.size(); ++i) + view_->DidPaintRect(params.paint_rects[i]); + } view_being_painted_ = false; } @@ -624,7 +657,7 @@ void RenderWidgetHost::OnMsgInputEventAck(const IPC::Message& message) { } if (WebInputEvent::isKeyboardEventType(type)) { - if (key_queue_.size() == 0) { + if (key_queue_.empty()) { LOG(ERROR) << "Got a KeyEvent back from the renderer but we " << "don't seem to have sent it to the renderer!"; } else if (key_queue_.front().type != type) { @@ -692,9 +725,10 @@ void RenderWidgetHost::OnMsgShowPopup(const IPC::Message& message) { #endif } -void RenderWidgetHost::PaintBackingStoreRect(TransportDIB* bitmap, - const gfx::Rect& bitmap_rect, - const gfx::Size& view_size) { +void RenderWidgetHost::PaintBackingStoreRects( + TransportDIB* bitmap, const gfx::Rect& bitmap_rect, + const std::vector<gfx::Rect>& paint_rects, + const gfx::Size& view_size) { // The view may be destroyed already. if (!view_) return; @@ -708,12 +742,36 @@ void RenderWidgetHost::PaintBackingStoreRect(TransportDIB* bitmap, } bool needs_full_paint = false; - BackingStore* backing_store = - BackingStoreManager::PrepareBackingStore(this, view_size, - process_->process().handle(), - bitmap, bitmap_rect, - &needs_full_paint); - DCHECK(backing_store != NULL); + base::ProcessHandle process_handle = process_->process().handle(); + if (paint_rects.empty()) { + BackingStore* backing_store = + BackingStoreManager::PrepareBackingStore(this, view_size, + process_handle, bitmap, bitmap_rect, bitmap_rect, + &needs_full_paint); + DCHECK(backing_store != NULL); + } else { + bool checked_coverage = false; + // TODO(agl): Reduce the number of X server round trips on Linux. + for (size_t i = 0; i < paint_rects.size(); ++i) { + BackingStore* backing_store = + BackingStoreManager::PrepareBackingStore(this, view_size, + process_handle, bitmap, bitmap_rect, paint_rects[i], + &needs_full_paint); + DCHECK(backing_store != NULL); + if (needs_full_paint) { + // We should not need a full paint more than once for a given view size + DCHECK(!checked_coverage); + checked_coverage = true; + + // Before we ask for a full repaint, we check if we already have a + // full coverage of the view size in out list of paint_rects + if (CoversArea(paint_rects, view_size)) + break; + needs_full_paint = false; + } + } + } + if (needs_full_paint) { repaint_start_time_ = TimeTicks::Now(); repaint_ack_pending_ = true; |