diff options
author | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-01 20:24:16 +0000 |
---|---|---|
committer | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-01 20:24:16 +0000 |
commit | a9e8b391a900c2a28b07a61848c3383bc4c56979 (patch) | |
tree | 05178e0b0ee0b221b1108c8e715a3bfc4945236d /chrome/browser/renderer_host | |
parent | 6aeac834d9b08d597aee48a01a1661b715aac354 (diff) | |
download | chromium_src-a9e8b391a900c2a28b07a61848c3383bc4c56979.zip chromium_src-a9e8b391a900c2a28b07a61848c3383bc4c56979.tar.gz chromium_src-a9e8b391a900c2a28b07a61848c3383bc4c56979.tar.bz2 |
Add ViewMsg_DoneUsingBitmap message.
ViewMsg_UpdateRect_ACK messages sent from the browser to the
renderer currently tell the renderer both that it can start
rendering the next update and that the TransportDIB that it
previously sent to the browser is now available for reuse.
This change adds a new ViewMsg_DoneUsingBitmap message for
communicating the latter piece of information. We currently
always send ViewMsg_DoneUsingBitmap immediately before
sending ViewMsg_UpdateRect_ACK, so no functional changes are
intended from this change.
This is preparatory work for an optimization where we defer
copying updates to the backing store, instead copying them
directly from the TransportDIB to the widget -- if we get
repeated updates for the same region, we can avoid copying
all but the final update to the backing store entirely.
BUG=none
TEST=tried it on GTK; sent to trybots. will do some testing on other platforms too
Review URL: http://codereview.chromium.org/3506007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61225 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
15 files changed, 106 insertions, 45 deletions
diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h index 53d0288..3977c07 100644 --- a/chrome/browser/renderer_host/backing_store.h +++ b/chrome/browser/renderer_host/backing_store.h @@ -42,16 +42,21 @@ class BackingStore { // the backingstore to be painted from the bitmap. // // The value placed into |*painted_synchronously| indicates if the paint was - // completed synchronously and the TransportDIB can be freed. False means that - // the backing store may still be using the transport DIB and it will manage - // notifying the RenderWidgetHost that it's done with it via - // DonePaintingToBackingStore(). + // completed synchronously and the renderer can begin generating another + // update. If the paint is being done asynchronously, the backing store will + // call DonePaintingToBackingStore() when finished. + // + // |*done_copying_bitmap| is set to true if the browser is done using + // the TransportDIB and to false otherwise. In the false case, the backing + // store will manage notifying the RenderWidgetHost that it's done with it via + // DoneCopyingBitmapToBackingStore(). virtual void PaintToBackingStore( RenderProcessHost* process, TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously) = 0; + bool* painted_synchronously, + bool* done_copying_bitmap) = 0; // Extracts the gives subset of the backing store and copies it to the given // PlatformCanvas. The PlatformCanvas should not be initialized. This function diff --git a/chrome/browser/renderer_host/backing_store_mac.h b/chrome/browser/renderer_host/backing_store_mac.h index 0c1e4a7..0c1df14 100644 --- a/chrome/browser/renderer_host/backing_store_mac.h +++ b/chrome/browser/renderer_host/backing_store_mac.h @@ -29,7 +29,8 @@ class BackingStoreMac : public BackingStore { TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously); + bool* painted_synchronously, + bool* done_copying_bitmap); virtual bool CopyFromBackingStore(const gfx::Rect& rect, skia::PlatformCanvas* output); virtual void ScrollBackingStore(int dx, int dy, diff --git a/chrome/browser/renderer_host/backing_store_mac.mm b/chrome/browser/renderer_host/backing_store_mac.mm index f793395..d7156ea 100644 --- a/chrome/browser/renderer_host/backing_store_mac.mm +++ b/chrome/browser/renderer_host/backing_store_mac.mm @@ -56,10 +56,12 @@ void BackingStoreMac::PaintToBackingStore( TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously) { + bool* painted_synchronously, + bool* done_copying_bitmap) { // Our paints are always synchronous and the caller can free the TransportDIB, // even on failure. *painted_synchronously = true; + *done_copying_bitmap = true; DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap())); diff --git a/chrome/browser/renderer_host/backing_store_manager.cc b/chrome/browser/renderer_host/backing_store_manager.cc index 4325f31..9b7cfa2 100644 --- a/chrome/browser/renderer_host/backing_store_manager.cc +++ b/chrome/browser/renderer_host/backing_store_manager.cc @@ -197,9 +197,11 @@ void BackingStoreManager::PrepareBackingStore( const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* needs_full_paint, - bool* painted_synchronously) { + bool* painted_synchronously, + bool* done_copying_bitmap) { // Default to declaring we're done using the transport DIB so it can be freed. *painted_synchronously = true; + *done_copying_bitmap = true; BackingStore* backing_store = GetBackingStore(host, backing_store_size); if (!backing_store) { @@ -217,9 +219,12 @@ void BackingStoreManager::PrepareBackingStore( backing_store = CreateBackingStore(host, backing_store_size); } - backing_store->PaintToBackingStore(host->process(), bitmap, - bitmap_rect, copy_rects, - painted_synchronously); + backing_store->PaintToBackingStore(host->process(), + bitmap, + bitmap_rect, + copy_rects, + painted_synchronously, + done_copying_bitmap); } // static diff --git a/chrome/browser/renderer_host/backing_store_manager.h b/chrome/browser/renderer_host/backing_store_manager.h index 1ab78cc..38f6574 100644 --- a/chrome/browser/renderer_host/backing_store_manager.h +++ b/chrome/browser/renderer_host/backing_store_manager.h @@ -44,10 +44,10 @@ class BackingStoreManager { // Set if we need to send out a request to paint the view // to the renderer. // painted_synchronously - // Will be set by the function if the request was processed synchronously, - // and the bitmap is done being used. False means that the backing store - // will paint the bitmap at a later time and that the TransportDIB can't be - // freed (it will be the backing store's job to free it later). + // Will be set by the function if the request was processed synchronously. + // done_copying_bitmap + // False means that the backing store is still using the TransportDIB and it + // can't be freed (it will be the backing store's job to free it later). static void PrepareBackingStore( RenderWidgetHost* host, const gfx::Size& backing_store_size, @@ -55,7 +55,8 @@ class BackingStoreManager { const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* needs_full_paint, - bool* painted_synchronously); + bool* painted_synchronously, + bool* done_copying_bitmap); // Returns a matching backing store for the host. // Returns NULL if we fail to find one. diff --git a/chrome/browser/renderer_host/backing_store_proxy.cc b/chrome/browser/renderer_host/backing_store_proxy.cc index ba3538b..40c5636 100644 --- a/chrome/browser/renderer_host/backing_store_proxy.cc +++ b/chrome/browser/renderer_host/backing_store_proxy.cc @@ -23,7 +23,8 @@ BackingStoreProxy::BackingStoreProxy(RenderWidgetHost* widget, : BackingStore(widget, size), process_shim_(process_shim), routing_id_(routing_id), - waiting_for_paint_ack_(false) { + waiting_for_paint_ack_(false), + current_bitmap_(TransportDIB::Id()) { process_shim_->AddRoute(routing_id_, this); } @@ -36,7 +37,8 @@ void BackingStoreProxy::PaintToBackingStore( TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously) { + bool* painted_synchronously, + bool* done_copying_bitmap) { DCHECK(!waiting_for_paint_ack_); base::ProcessId process_id; @@ -49,12 +51,17 @@ void BackingStoreProxy::PaintToBackingStore( if (process_shim_->Send(new GpuMsg_PaintToBackingStore( routing_id_, process_id, bitmap, bitmap_rect, copy_rects))) { // Message sent successfully, so the caller can not destroy the - // TransportDIB. OnDonePaintingToBackingStore will free it later. + // TransportDIB. DoneCopyingBitmapToBackingStore will release it later, and + // DonePaintingToBackingStore will let the renderer know that it can send us + // the next update. *painted_synchronously = false; + *done_copying_bitmap = false; waiting_for_paint_ack_ = true; + current_bitmap_ = bitmap; } else { // On error, we're done with the TransportDIB and the caller can free it. *painted_synchronously = true; + *done_copying_bitmap = true; } } @@ -96,6 +103,8 @@ void BackingStoreProxy::OnChannelError() { void BackingStoreProxy::OnPaintToBackingStoreACK() { DCHECK(waiting_for_paint_ack_); + render_widget_host()->DoneCopyingBitmapToBackingStore(current_bitmap_); render_widget_host()->DonePaintingToBackingStore(); waiting_for_paint_ack_ = false; + current_bitmap_ = TransportDIB::Id(); } diff --git a/chrome/browser/renderer_host/backing_store_proxy.h b/chrome/browser/renderer_host/backing_store_proxy.h index 610f7ef..0976b58 100644 --- a/chrome/browser/renderer_host/backing_store_proxy.h +++ b/chrome/browser/renderer_host/backing_store_proxy.h @@ -12,6 +12,7 @@ class GpuProcessHostUIShim; +// This class proxies renderer updates to the GPU process. class BackingStoreProxy : public BackingStore, public IPC::Channel::Listener { public: @@ -24,7 +25,8 @@ class BackingStoreProxy : public BackingStore, TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously); + bool* painted_synchronously, + bool* done_copying_bitmap); virtual bool CopyFromBackingStore(const gfx::Rect& rect, skia::PlatformCanvas* output); virtual void ScrollBackingStore(int dx, int dy, @@ -45,9 +47,12 @@ class BackingStoreProxy : public BackingStore, // Set to true when we're waiting for the GPU process to do a paint and send // back a "done" message. In this case, the renderer will be waiting for our - // message that we're done using the backing store. + // message that we're done using the bitmap. bool waiting_for_paint_ack_; + // Bitmap currently being used by the GPU process. + TransportDIB::Id current_bitmap_; + DISALLOW_COPY_AND_ASSIGN(BackingStoreProxy); }; diff --git a/chrome/browser/renderer_host/backing_store_win.cc b/chrome/browser/renderer_host/backing_store_win.cc index 94d9cbf..b13d652 100644 --- a/chrome/browser/renderer_host/backing_store_win.cc +++ b/chrome/browser/renderer_host/backing_store_win.cc @@ -69,7 +69,8 @@ void CallStretchDIBits(HDC hdc, int dest_x, int dest_y, int dest_w, int dest_h, } // namespace -BackingStoreWin::BackingStoreWin(RenderWidgetHost* widget, const gfx::Size& size) +BackingStoreWin::BackingStoreWin(RenderWidgetHost* widget, + const gfx::Size& size) : BackingStore(widget, size), backing_store_dib_(NULL), original_bitmap_(NULL) { @@ -117,10 +118,12 @@ void BackingStoreWin::PaintToBackingStore( TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously) { + bool* painted_synchronously, + bool* done_copying_bitmap) { // Our paints are always synchronous and the TransportDIB can be freed when // we're done (even on error). *painted_synchronously = true; + *done_copying_bitmap = true; if (!backing_store_dib_) { backing_store_dib_ = CreateDIB(hdc_, size().width(), diff --git a/chrome/browser/renderer_host/backing_store_win.h b/chrome/browser/renderer_host/backing_store_win.h index 221e0aa..4ea1480 100644 --- a/chrome/browser/renderer_host/backing_store_win.h +++ b/chrome/browser/renderer_host/backing_store_win.h @@ -27,7 +27,8 @@ class BackingStoreWin : public BackingStore { TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously); + bool* painted_synchronously, + bool* done_copying_bitmap); virtual bool CopyFromBackingStore(const gfx::Rect& rect, skia::PlatformCanvas* output); virtual void ScrollBackingStore(int dx, int dy, diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc index f2704c8..a7750ae4 100644 --- a/chrome/browser/renderer_host/backing_store_x.cc +++ b/chrome/browser/renderer_host/backing_store_x.cc @@ -161,10 +161,12 @@ void BackingStoreX::PaintToBackingStore( TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously) { + bool* painted_synchronously, + bool* done_copying_bitmap) { // Our paints are always synchronous and the caller can free the TransportDIB // when we're done, even on error. *painted_synchronously = true; + *done_copying_bitmap = true; if (!display_) return; diff --git a/chrome/browser/renderer_host/backing_store_x.h b/chrome/browser/renderer_host/backing_store_x.h index 283c19f..816d520 100644 --- a/chrome/browser/renderer_host/backing_store_x.h +++ b/chrome/browser/renderer_host/backing_store_x.h @@ -54,7 +54,8 @@ class BackingStoreX : public BackingStore { TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously); + bool* painted_synchronously, + bool* done_copying_bitmap); virtual bool CopyFromBackingStore(const gfx::Rect& rect, skia::PlatformCanvas* output); virtual void ScrollBackingStore(int dx, int dy, diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index 20aafd3..027528e0 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -370,6 +370,11 @@ BackingStore* RenderWidgetHost::AllocBackingStore(const gfx::Size& size) { return view_->AllocBackingStore(size); } +void RenderWidgetHost::DoneCopyingBitmapToBackingStore( + TransportDIB::Id bitmap) { + Send(new ViewMsg_DoneUsingBitmap(routing_id(), bitmap)); +} + void RenderWidgetHost::DonePaintingToBackingStore() { Send(new ViewMsg_UpdateRect_ACK(routing_id())); } @@ -792,6 +797,7 @@ void RenderWidgetHost::OnMsgUpdateRect( DCHECK(!params.view_size.IsEmpty()); bool painted_synchronously = true; // Default to sending a paint ACK below. + bool done_copying_bitmap = true; if (!is_gpu_rendering_active_) { const size_t size = params.bitmap_rect.height() * params.bitmap_rect.width() * 4; @@ -814,20 +820,25 @@ void RenderWidgetHost::OnMsgUpdateRect( // 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(params.bitmap, params.bitmap_rect, - params.copy_rects, params.view_size, - &painted_synchronously); + PaintBackingStoreRect(params.bitmap, + params.bitmap_rect, + params.copy_rects, + params.view_size, + &painted_synchronously, + &done_copying_bitmap); } } } - // ACK early so we can prefetch the next PaintRect if there is a next one. - // This must be done AFTER we're done painting with the bitmap supplied by the - // renderer. This ACK is a signal to the renderer that the backing store can - // be re-used, so the bitmap may be invalid after this call. If the backing - // store is painting asynchronously, it will manage issuing this IPC. + // Tell the renderer that the bitmap can be re-used, so the bitmap may be + // invalid after this call. If the backing store is still using the bitmap, it + // will manage issuing this IPC. + if (done_copying_bitmap) + DoneCopyingBitmapToBackingStore(params.bitmap); + + // ACK early so we can prefetch the next UpdateRect if there is a next one. if (painted_synchronously) - Send(new ViewMsg_UpdateRect_ACK(routing_id_)); + DonePaintingToBackingStore(); // We don't need to update the view if the view is hidden. We must do this // early return after the ACK is sent, however, or the renderer will not send @@ -1083,10 +1094,12 @@ void RenderWidgetHost::PaintBackingStoreRect( const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, const gfx::Size& view_size, - bool* painted_synchronously) { + bool* painted_synchronously, + bool* done_copying_bitmap) { // On failure, we need to be sure our caller knows we're done with the // backing store. *painted_synchronously = true; + *done_copying_bitmap = true; // The view may be destroyed already. if (!view_) @@ -1101,9 +1114,14 @@ void RenderWidgetHost::PaintBackingStoreRect( } bool needs_full_paint = false; - BackingStoreManager::PrepareBackingStore(this, view_size, bitmap, bitmap_rect, - copy_rects, &needs_full_paint, - painted_synchronously); + BackingStoreManager::PrepareBackingStore(this, + view_size, + bitmap, + bitmap_rect, + copy_rects, + &needs_full_paint, + painted_synchronously, + done_copying_bitmap); if (needs_full_paint) { repaint_start_time_ = TimeTicks::Now(); repaint_ack_pending_ = true; diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index 0e5fa4a..91215d6 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -238,9 +238,14 @@ class RenderWidgetHost : public IPC::Channel::Listener, // (for example, if we don't currently have a RenderWidgetHostView.) BackingStore* AllocBackingStore(const gfx::Size& size); - // When a backing store does asynchronous painting, it will call this function - // when it is done with the DIB. We will then forward a message to the - // renderer to send another paint. + // When a backing store is copying a TransportDIB asynchronously, it calls + // this function when it is done using it. We then send a message to the + // renderer letting it know that the bitmap can be reused. + void DoneCopyingBitmapToBackingStore(TransportDIB::Id bitmap); + + // When a backing store does asynchronous painting, it calls this function + // when it is done painting. We then send a message to the renderer to send + // another update. void DonePaintingToBackingStore(); // GPU accelerated version of GetBackingStore function. This will @@ -526,7 +531,8 @@ class RenderWidgetHost : public IPC::Channel::Listener, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, const gfx::Size& view_size, - bool* painted_synchronously); + bool* painted_synchronously, + bool* done_copying_bitmap); // Scrolls the given |clip_rect| in the backing by the given dx/dy amount. The // |dib| and its corresponding location |bitmap_rect| in the backing store diff --git a/chrome/browser/renderer_host/test/test_backing_store.cc b/chrome/browser/renderer_host/test/test_backing_store.cc index d90c7fd..8e2a9b8 100644 --- a/chrome/browser/renderer_host/test/test_backing_store.cc +++ b/chrome/browser/renderer_host/test/test_backing_store.cc @@ -17,7 +17,8 @@ void TestBackingStore::PaintToBackingStore( TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously) { + bool* painted_synchronously, + bool* done_copying_bitmap) { } bool TestBackingStore::CopyFromBackingStore(const gfx::Rect& rect, diff --git a/chrome/browser/renderer_host/test/test_backing_store.h b/chrome/browser/renderer_host/test/test_backing_store.h index f9db76e..ee5ffce 100644 --- a/chrome/browser/renderer_host/test/test_backing_store.h +++ b/chrome/browser/renderer_host/test/test_backing_store.h @@ -19,7 +19,8 @@ class TestBackingStore : public BackingStore { TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, - bool* painted_synchronously); + bool* painted_synchronously, + bool* done_copying_bitmap); virtual bool CopyFromBackingStore(const gfx::Rect& rect, skia::PlatformCanvas* output); virtual void ScrollBackingStore(int dx, int dy, |