diff options
19 files changed, 148 insertions, 61 deletions
diff --git a/app/surface/transport_dib.h b/app/surface/transport_dib.h index 6606c2b..2f439e6 100644 --- a/app/surface/transport_dib.h +++ b/app/surface/transport_dib.h @@ -63,6 +63,10 @@ class TransportDIB { return other.sequence_num < sequence_num; } + bool operator==(const HandleAndSequenceNum& other) const { + return !(*this < other) && !(other < *this); + } + HANDLE handle; uint32 sequence_num; }; 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, diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 13a475c..a35d911 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -177,6 +177,11 @@ IPC_BEGIN_MESSAGES(View) gfx::Size /* page_size */, gfx::Size /* desired_size */) + // Sent when the backing store is finished using a TransportDIB received from + // the renderer via a ViewHostMsg_UpdateRect message. + IPC_MESSAGE_ROUTED1(ViewMsg_DoneUsingBitmap, + TransportDIB::Id /* bitmap */) + // Tells the render view that a ViewHostMsg_UpdateRect message was processed. // This signals the render view that it can send another UpdateRect message. IPC_MESSAGE_ROUTED0(ViewMsg_UpdateRect_ACK) diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc index f5a7ebe..3293589 100644 --- a/chrome/renderer/render_widget.cc +++ b/chrome/renderer/render_widget.cc @@ -4,6 +4,8 @@ #include "chrome/renderer/render_widget.h" +#include <utility> + #include "app/surface/transport_dib.h" #include "base/command_line.h" #include "base/logging.h" @@ -61,7 +63,6 @@ RenderWidget::RenderWidget(RenderThreadBase* render_thread, opener_id_(MSG_ROUTING_NONE), render_thread_(render_thread), host_window_(0), - current_paint_buf_(NULL), next_paint_flags_(0), update_reply_pending_(false), did_show_(false), @@ -82,9 +83,9 @@ RenderWidget::RenderWidget(RenderThreadBase* render_thread, RenderWidget::~RenderWidget() { DCHECK(!webwidget_) << "Leaking our WebWidget!"; - if (current_paint_buf_) { - RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); - current_paint_buf_ = NULL; + for (TransportDIBMap::iterator it = current_paint_bufs_.begin(); + it != current_paint_bufs_.end(); ++it) { + RenderProcess::current()->ReleaseTransportDIB(it->second); } RenderProcess::current()->ReleaseProcess(); } @@ -169,6 +170,7 @@ 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_DoneUsingBitmap, OnDoneUsingBitmap) IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck) IPC_MESSAGE_HANDLER(ViewMsg_CreateVideo_ACK, OnCreateVideoAck) IPC_MESSAGE_HANDLER(ViewMsg_UpdateVideo_ACK, OnUpdateVideoAck) @@ -299,17 +301,27 @@ void RenderWidget::OnRequestMoveAck() { pending_window_rect_count_--; } +void RenderWidget::OnDoneUsingBitmap(TransportDIB::Id id) { + // If we sent an UpdateRect message with a zero-sized bitmap, then we should + // get an empty bitmap in response. + // TODO(derat): Don't send the "done using bitmap" message at all in this + // case. + if (id == TransportDIB::Id()) + return; + + TransportDIBMap::iterator it = current_paint_bufs_.find(id); + if (it != current_paint_bufs_.end()) { + RenderProcess::current()->ReleaseTransportDIB(it->second); + current_paint_bufs_.erase(it); + return; + } + NOTREACHED() << "Browser returned unexpected TransportDIB to renderer"; +} + 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 paint buffer. - if (current_paint_buf_) { - RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); - current_paint_buf_ = NULL; - } - // Notify subclasses. DidFlushPaint(); @@ -515,18 +527,19 @@ void RenderWidget::DoDeferredUpdate() { !is_gpu_rendering_active_ && GetBitmapForOptimizedPluginPaint(bounds, &dib, &optimized_copy_location, &optimized_copy_rect)) { + current_paint_bufs_.insert(std::make_pair(dib->id(), dib)); bounds = optimized_copy_location; copy_rects.push_back(optimized_copy_rect); dib_id = dib->id(); } else if (!is_gpu_rendering_active_) { // Compute a buffer for painting and cache it. scoped_ptr<skia::PlatformCanvas> canvas( - RenderProcess::current()->GetDrawingCanvas(¤t_paint_buf_, - bounds)); + RenderProcess::current()->GetDrawingCanvas(&dib, bounds)); if (!canvas.get()) { NOTREACHED(); return; } + current_paint_bufs_.insert(std::make_pair(dib->id(), dib)); // We may get back a smaller canvas than we asked for. // TODO(darin): This seems like it could cause painting problems! @@ -552,7 +565,7 @@ void RenderWidget::DoDeferredUpdate() { for (size_t i = 0; i < copy_rects.size(); ++i) PaintRect(copy_rects[i], bounds.origin(), canvas.get()); - dib_id = current_paint_buf_->id(); + dib_id = dib->id(); } else { // Accelerated compositing path // Begin painting. bool finish = next_paint_is_resize_ack(); diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h index 47bdf38..8aede6c 100644 --- a/chrome/renderer/render_widget.h +++ b/chrome/renderer/render_widget.h @@ -6,6 +6,7 @@ #define CHROME_RENDERER_RENDER_WIDGET_H_ #pragma once +#include <map> #include <vector> #include "app/surface/transport_dib.h" @@ -129,6 +130,8 @@ class RenderWidget : public IPC::Channel::Listener, // without ref-counting is an error. friend class base::RefCounted<RenderWidget>; + typedef std::map<TransportDIB::Id, TransportDIB*> TransportDIBMap; + RenderWidget(RenderThreadBase* render_thread, WebKit::WebPopupType popup_type); virtual ~RenderWidget(); @@ -171,6 +174,7 @@ class RenderWidget : public IPC::Channel::Listener, const gfx::Rect& resizer_rect); virtual void OnWasHidden(); virtual void OnWasRestored(bool needs_repainting); + void OnDoneUsingBitmap(TransportDIB::Id id); void OnUpdateRectAck(); void OnCreateVideoAck(int32 video_id); void OnUpdateVideoAck(int32 video_id); @@ -288,8 +292,8 @@ 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. - TransportDIB* current_paint_buf_; + // TransportDIBs currently being used to transfer images to the browser. + TransportDIBMap current_paint_bufs_; PaintAggregator paint_aggregator_; |