diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-18 15:52:54 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-18 15:52:54 +0000 |
commit | 9de65c8b3f17f28ff7edebb63f0922f5734bf55b (patch) | |
tree | 7ec8c5b258e930a9c1c1682f451fc877f640f780 /chrome/renderer | |
parent | cd7bc4ed28abcb9a3652d4e3f6ffa2fe9f503aae (diff) | |
download | chromium_src-9de65c8b3f17f28ff7edebb63f0922f5734bf55b.zip chromium_src-9de65c8b3f17f28ff7edebb63f0922f5734bf55b.tar.gz chromium_src-9de65c8b3f17f28ff7edebb63f0922f5734bf55b.tar.bz2 |
Revert 34951 - Combine ViewHostMsg_{Paint,Scroll}Rect into one IPC.
The combined IPC means that scrolling only requires one transport DIB instead
of two. Previously, we'd use one in the ScrollRect IPC to pass up the pixels
for the exposed region, and then we'd use a second one in the PaintRect IPC to
pass up the pixels for the updated scroll bar rendering. Now all paints are
done using a single transport DIB.
Optimize RenderWidgetHostViewWin::OnPaint to only paint the damaged regions.
This means calling GetUpdateRgn and GetRegionData to enumerate the list of
damage rects. Then only those rects are copied from the backing store.
The same optimization is not done for Linux or Mac yet.
R=brettw
BUG=29591
TEST=none
Review URL: http://codereview.chromium.org/506013
TBR=darin@chromium.org
Review URL: http://codereview.chromium.org/506075
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34953 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/render_widget.cc | 187 | ||||
-rw-r--r-- | chrome/renderer/render_widget.h | 26 |
2 files changed, 130 insertions, 83 deletions
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc index 8a3513c..27955bb 100644 --- a/chrome/renderer/render_widget.cc +++ b/chrome/renderer/render_widget.cc @@ -50,8 +50,9 @@ RenderWidget::RenderWidget(RenderThreadBase* render_thread, bool activatable) render_thread_(render_thread), host_window_(0), current_paint_buf_(NULL), + current_scroll_buf_(NULL), next_paint_flags_(0), - update_reply_pending_(false), + paint_reply_pending_(false), did_show_(false), is_hidden_(false), needs_repainting_on_restore_(false), @@ -78,6 +79,10 @@ RenderWidget::~RenderWidget() { RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); current_paint_buf_ = NULL; } + if (current_scroll_buf_) { + RenderProcess::current()->ReleaseTransportDIB(current_scroll_buf_); + current_scroll_buf_ = NULL; + } RenderProcess::current()->ReleaseProcess(); } @@ -137,7 +142,8 @@ IPC_DEFINE_MESSAGE_MAP(RenderWidget) IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize) IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden) IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored) - IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck) + IPC_MESSAGE_HANDLER(ViewMsg_PaintRect_ACK, OnPaintRectAck) + IPC_MESSAGE_HANDLER(ViewMsg_ScrollRect_ACK, OnScrollRectAck) IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) @@ -252,17 +258,11 @@ void RenderWidget::OnWasRestored(bool needs_repainting) { didInvalidateRect(gfx::Rect(size_.width(), size_.height())); } -void RenderWidget::OnRequestMoveAck() { - DCHECK(pending_window_rect_count_); - pending_window_rect_count_--; -} - -void RenderWidget::OnUpdateRectAck() { - DCHECK(update_reply_pending()); - update_reply_pending_ = false; - - // If we sent an UpdateRect message with a zero-sized bitmap, then we should - // have no current update buf. +void RenderWidget::OnPaintRectAck() { + DCHECK(paint_reply_pending()); + paint_reply_pending_ = false; + // If we sent a PaintRect message with a zero-sized bitmap, then + // we should have no current paint buf. if (current_paint_buf_) { RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); current_paint_buf_ = NULL; @@ -275,6 +275,23 @@ void RenderWidget::OnUpdateRectAck() { CallDoDeferredUpdate(); } +void RenderWidget::OnRequestMoveAck() { + DCHECK(pending_window_rect_count_); + pending_window_rect_count_--; +} + +void RenderWidget::OnScrollRectAck() { + DCHECK(scroll_reply_pending()); + + if (current_scroll_buf_) { + RenderProcess::current()->ReleaseTransportDIB(current_scroll_buf_); + current_scroll_buf_ = NULL; + } + + // Continue scrolling if necessary... + CallDoDeferredUpdate(); +} + void RenderWidget::OnHandleInputEvent(const IPC::Message& message) { void* iter = NULL; @@ -388,17 +405,9 @@ void RenderWidget::PaintDebugBorder(const gfx::Rect& rect, if (!kPaintBorder) return; - // Cycle through these colors to help distinguish new paint rects. - const SkColor colors[] = { - SkColorSetARGB(0x3F, 0xFF, 0, 0), - SkColorSetARGB(0x3F, 0xFF, 0, 0xFF), - SkColorSetARGB(0x3F, 0, 0, 0xFF), - }; - static int color_selector = 0; - SkPaint paint; paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(colors[color_selector++ % arraysize(colors)]); + paint.setColor(SkColorSetARGB(0x3F, 0xFF, 0, 0)); paint.setStrokeWidth(1); SkIRect irect; @@ -417,7 +426,7 @@ void RenderWidget::CallDoDeferredUpdate() { void RenderWidget::DoDeferredUpdate() { if (!webwidget_ || !paint_aggregator_.HasPendingUpdate() || - update_reply_pending()) + paint_reply_pending() || scroll_reply_pending()) return; // Suppress updating when we are hidden. @@ -435,56 +444,86 @@ void RenderWidget::DoDeferredUpdate() { PaintAggregator::PendingUpdate update = paint_aggregator_.GetPendingUpdate(); paint_aggregator_.ClearPendingUpdate(); - gfx::Rect scroll_damage = update.GetScrollDamage(); - gfx::Rect bounds = update.GetPaintBounds().Union(scroll_damage); + if (!update.scroll_rect.IsEmpty()) { + // Optmized scrolling - // Compute a buffer for painting and cache it. - scoped_ptr<skia::PlatformCanvas> canvas( - RenderProcess::current()->GetDrawingCanvas(¤t_paint_buf_, bounds)); - if (!canvas.get()) { - NOTREACHED(); - return; - } + // Compute the region we will expose by scrolling, and paint that into a + // shared memory section. + gfx::Rect damaged_rect = update.GetScrollDamage(); - // We may get back a smaller canvas than we asked for. - // TODO(darin): This seems like it could cause painting problems! - DCHECK_EQ(bounds.width(), canvas->getDevice()->width()); - DCHECK_EQ(bounds.height(), canvas->getDevice()->height()); - bounds.set_width(canvas->getDevice()->width()); - bounds.set_height(canvas->getDevice()->height()); - - HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size()); - - // The scroll damage is just another rectangle to paint and copy. - std::vector<gfx::Rect> copy_rects; - copy_rects.swap(update.paint_rects); - if (!scroll_damage.IsEmpty()) - copy_rects.push_back(scroll_damage); - - // TODO(darin): Re-enable painting multiple damage rects once the - // page-cycler regressions are resolved. See bug 29589. - if (update.scroll_rect.IsEmpty()) { - update.paint_rects.clear(); - update.paint_rects.push_back(bounds); + scoped_ptr<skia::PlatformCanvas> canvas( + RenderProcess::current()->GetDrawingCanvas(¤t_scroll_buf_, + damaged_rect)); + if (!canvas.get()) { + NOTREACHED(); + return; + } + + // We may get back a smaller canvas than we asked for. + damaged_rect.set_width(canvas->getDevice()->width()); + damaged_rect.set_height(canvas->getDevice()->height()); + + // Set these parameters before calling Paint, since that could result in + // further invalidates (uncommon). + ViewHostMsg_ScrollRect_Params params; + params.bitmap_rect = damaged_rect; + params.dx = update.scroll_delta.x(); + params.dy = update.scroll_delta.y(); + params.clip_rect = update.scroll_rect; + params.view_size = size_; + params.plugin_window_moves = plugin_window_moves_; + params.bitmap = current_scroll_buf_->id(); + + plugin_window_moves_.clear(); + + PaintRect(damaged_rect, damaged_rect.origin(), canvas.get()); + Send(new ViewHostMsg_ScrollRect(routing_id_, params)); } - for (size_t i = 0; i < copy_rects.size(); ++i) - PaintRect(copy_rects[i], bounds.origin(), canvas.get()); + if (!update.paint_rects.empty()) { + // Normal painting + + gfx::Rect bounds = update.GetPaintBounds(); + + // Compute a buffer for painting and cache it. + scoped_ptr<skia::PlatformCanvas> canvas( + RenderProcess::current()->GetDrawingCanvas(¤t_paint_buf_, + bounds)); + if (!canvas.get()) { + NOTREACHED(); + return; + } + + // We may get back a smaller canvas than we asked for. + bounds.set_width(canvas->getDevice()->width()); + bounds.set_height(canvas->getDevice()->height()); + + HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size()); + + // TODO(darin): Re-enable painting multiple damage rects once the + // page-cycler regressions are resolved. See bug 29589. + if (update.scroll_rect.IsEmpty()) { + update.paint_rects.clear(); + update.paint_rects.push_back(bounds); + } + + for (size_t i = 0; i < update.paint_rects.size(); ++i) + PaintRect(update.paint_rects[i], bounds.origin(), canvas.get()); - ViewHostMsg_UpdateRect_Params params; - params.bitmap = current_paint_buf_->id(); - params.bitmap_rect = bounds; - params.dx = update.scroll_delta.x(); - params.dy = update.scroll_delta.y(); - params.scroll_rect = update.scroll_rect; - params.copy_rects.swap(copy_rects); // TODO(darin): clip to bounds? - params.view_size = size_; - params.plugin_window_moves.swap(plugin_window_moves_); - params.flags = next_paint_flags_; + ViewHostMsg_PaintRect_Params params; + params.bitmap_rect = bounds; + params.update_rects = update.paint_rects; // TODO(darin): clip to bounds? + params.view_size = size_; + params.plugin_window_moves = plugin_window_moves_; + params.flags = next_paint_flags_; + params.bitmap = current_paint_buf_->id(); - update_reply_pending_ = true; - Send(new ViewHostMsg_UpdateRect(routing_id_, params)); - next_paint_flags_ = 0; + plugin_window_moves_.clear(); + + paint_reply_pending_ = true; + Send(new ViewHostMsg_PaintRect(routing_id_, params)); + next_paint_flags_ = 0; + } UpdateIME(); } @@ -509,7 +548,7 @@ void RenderWidget::didInvalidateRect(const WebRect& rect) { return; if (!paint_aggregator_.HasPendingUpdate()) return; - if (update_reply_pending()) + if (paint_reply_pending() || scroll_reply_pending()) return; // Perform updating asynchronously. This serves two purposes: @@ -538,7 +577,7 @@ void RenderWidget::didScrollRect(int dx, int dy, const WebRect& clip_rect) { return; if (!paint_aggregator_.HasPendingUpdate()) return; - if (update_reply_pending()) + if (paint_reply_pending() || scroll_reply_pending()) return; // Perform updating asynchronously. This serves two purposes: @@ -734,23 +773,23 @@ void RenderWidget::SetBackground(const SkBitmap& background) { } bool RenderWidget::next_paint_is_resize_ack() const { - return ViewHostMsg_UpdateRect_Flags::is_resize_ack(next_paint_flags_); + return ViewHostMsg_PaintRect_Flags::is_resize_ack(next_paint_flags_); } bool RenderWidget::next_paint_is_restore_ack() const { - return ViewHostMsg_UpdateRect_Flags::is_restore_ack(next_paint_flags_); + return ViewHostMsg_PaintRect_Flags::is_restore_ack(next_paint_flags_); } void RenderWidget::set_next_paint_is_resize_ack() { - next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK; + next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_RESIZE_ACK; } void RenderWidget::set_next_paint_is_restore_ack() { - next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_RESTORE_ACK; + next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_RESTORE_ACK; } void RenderWidget::set_next_paint_is_repaint_ack() { - next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK; + next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_REPAINT_ACK; } void RenderWidget::UpdateIME() { diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h index 4cf033e..c25c99a 100644 --- a/chrome/renderer/render_widget.h +++ b/chrome/renderer/render_widget.h @@ -142,7 +142,8 @@ class RenderWidget : public IPC::Channel::Listener, const gfx::Rect& resizer_rect); void OnWasHidden(); void OnWasRestored(bool needs_repainting); - void OnUpdateRectAck(); + void OnPaintRectAck(); + void OnScrollRectAck(); void OnRequestMoveAck(); void OnHandleInputEvent(const IPC::Message& message); void OnMouseCaptureLost(); @@ -166,9 +167,14 @@ class RenderWidget : public IPC::Channel::Listener, bool is_hidden() const { return is_hidden_; } - // True if an UpdateRect_ACK message is pending. - bool update_reply_pending() const { - return update_reply_pending_; + // True if a PaintRect_ACK message is pending. + bool paint_reply_pending() const { + return paint_reply_pending_; + } + + // True if a ScrollRect_ACK message is pending. + bool scroll_reply_pending() const { + return current_scroll_buf_ != NULL; } bool next_paint_is_resize_ack() const; @@ -232,20 +238,22 @@ class RenderWidget : public IPC::Channel::Listener, // The size of the RenderWidget. gfx::Size size_; - // The TransportDIB that is being used to transfer an image to the browser. + // Transport DIBs that are currently in use to transfer an image to the + // browser. TransportDIB* current_paint_buf_; + TransportDIB* current_scroll_buf_; PaintAggregator paint_aggregator_; // The area that must be reserved for drawing the resize corner. gfx::Rect resizer_rect_; - // Flags for the next ViewHostMsg_UpdateRect message. + // Flags for the next ViewHostMsg_PaintRect message. int next_paint_flags_; - // True if we are expecting an UpdateRect_ACK message (i.e., that a - // UpdateRect message has been sent). - bool update_reply_pending_; + // True if we are expecting a PaintRect_ACK message (i.e., that a PaintRect + // message has been sent). + bool paint_reply_pending_; // Set to true if we should ignore RenderWidget::Show calls. bool did_show_; |