summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-22 23:33:58 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-22 23:33:58 +0000
commitb2e52d1a5a76e19512cd90402a09e0ae108b4c6e (patch)
tree32e080da6511a891b6e179af8f435c4266501c0b /gpu
parentd5bc2ed4baad44064d6158bc952e239001e95be1 (diff)
downloadchromium_src-b2e52d1a5a76e19512cd90402a09e0ae108b4c6e.zip
chromium_src-b2e52d1a5a76e19512cd90402a09e0ae108b4c6e.tar.gz
chromium_src-b2e52d1a5a76e19512cd90402a09e0ae108b4c6e.tar.bz2
Mac: Don't hang gpu process if a tab that shares its renderer process with other tabs and that has accelerated content and outstanding paints.
The problem was that the renderer process busy-waits on the GPU process to flush all gpu commands on close, and the GPU process waits with processing commands from the renderer until a paint ack arrives from the browser. But since the window is already closed, no paint acks are sent any more. The fix is to let the browser tell the GPU process when a window is closed, and then let the GPU process not wait for paint acks if the corresponding window has already been closed. Closed windows are identified by (renderer process id, render view routing id). Identifying closed windows by either surface id or gpu channel stub routing id does not work, because they are both created on the GPU side and sent to the browser asynchronously, so it's possible that a browser tab is closed before the ID arrives from the GPU process – in that case, it can't send the "window closed" message even though the GPU process is already in a state where it needs this event. BUG=67170 TEST= 1.) Go to http://www.chromeexperiments.com/detail/body-browser/?f=webgl , click "Launch Experiment", wait until everything is loaded, close popup. %cpu of gpu process and renderer process should go to 0 2.) Go to http://www.chromeexperiments.com/detail/body-browser/?f=webgl , click "Launch Experiment", wait until the bar on the left is loaded but the body isn't yet, close popup. %cpu of gpu process and renderer process should go to 0, but it might take a few seconds until the %cpu in the renderer go down (the site decides to parse the XHR data that gets flushed on widget close) 3.) Go to http://www.chromeexperiments.com/detail/nine-point-five/?f=webgl , click "Launch Experiment", wait until everything is loaded, close popup. %cpu of gpu process and renderer process should go to 0 4.) Go to http://www.chromeexperiments.com/detail/nine-point-five/?f=webgl , click "Launch Experiment", close popup immediately after the background color changed to light grey. %cpu of gpu process and renderer process should go to 0 5.) Go to http://www.chromeexperiments.com/detail/nine-point-five/?f=webgl , click "Launch Experiment", close popup immediately. %cpu of gpu process and renderer process should go to 0 Review URL: http://codereview.chromium.org/6076005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70000 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/service/gpu_processor.h2
-rw-r--r--gpu/command_buffer/service/gpu_processor_mac.cc12
2 files changed, 14 insertions, 0 deletions
diff --git a/gpu/command_buffer/service/gpu_processor.h b/gpu/command_buffer/service/gpu_processor.h
index 9d30f980..a143bad 100644
--- a/gpu/command_buffer/service/gpu_processor.h
+++ b/gpu/command_buffer/service/gpu_processor.h
@@ -97,6 +97,8 @@ class GPUProcessor : public CommandBufferEngine {
uint64 swap_buffers_count() const;
void set_acknowledged_swap_buffers_count(
uint64 acknowledged_swap_buffers_count);
+
+ void DidDestroySurface();
#endif
// Sets a callback that is called when a glResizeCHROMIUM command
diff --git a/gpu/command_buffer/service/gpu_processor_mac.cc b/gpu/command_buffer/service/gpu_processor_mac.cc
index 63a894d..4d9ba18 100644
--- a/gpu/command_buffer/service/gpu_processor_mac.cc
+++ b/gpu/command_buffer/service/gpu_processor_mac.cc
@@ -108,6 +108,18 @@ void GPUProcessor::set_acknowledged_swap_buffers_count(
acknowledged_swap_buffers_count_ = acknowledged_swap_buffers_count;
}
+void GPUProcessor::DidDestroySurface() {
+ // 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.
+ surface_.reset();
+}
+
void GPUProcessor::WillSwapBuffers() {
DCHECK(decoder_.get());
DCHECK(decoder_->GetGLContext());