Index: chrome/browser/renderer_host/render_widget_host_view_mac.mm |
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm |
index 60cc85e16acb98d45899c4b1ac3e2c6eaea67409..5834ef6b0615f0fbaae9feb1c1051ff5d683cf4f 100644 |
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm |
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm |
@@ -948,9 +948,50 @@ void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( |
// taken if a plugin is removed, but the RWHVMac itself stays alive. |
} |
+namespace { |
+class DidDestroySurfaceSender : public Task { |
+ public: |
+ DidDestroySurfaceSender( |
+ int renderer_id, |
+ int32 renderer_route_id) |
+ : renderer_id_(renderer_id), |
+ renderer_route_id_(renderer_route_id) { |
+ } |
+ |
+ void Run() { |
+ GpuProcessHost::Get()->Send( |
+ new GpuMsg_DidDestroySurface( |
+ renderer_id_, renderer_route_id_)); |
+ } |
+ |
+ private: |
+ int renderer_id_; |
+ int32 renderer_route_id_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DidDestroySurfaceSender); |
+}; |
+} // anonymous namespace |
+ |
// This is called by AcceleratedPluginView's -dealloc. |
void RenderWidgetHostViewMac::DeallocFakePluginWindowHandle( |
gfx::PluginWindowHandle window) { |
+ // When a browser window with a GPUProcessor is closed, the render process |
+ // will attempt to finish all GL commands. It will busy-wait on the GPU |
+ // process until the command queue is empty. If a paint is pending, the GPU |
+ // process won't process any GL commands until the browser sends a paint ack, |
+ // but since the browser window is already closed, it will never arrive. |
+ // To break this infinite loop, the browser tells the GPU process that the |
+ // surface became invalid, which causes the GPU process to not wait for paint |
+ // acks. |
+ if (render_widget_host_ && |
+ plugin_container_manager_.IsRootContainer(window)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ new DidDestroySurfaceSender( |
+ render_widget_host_->process()->id(), |
+ render_widget_host_->routing_id())); |
+ } |
+ |
plugin_container_manager_.DestroyFakePluginWindowHandle(window); |
} |