Index: gpu/command_buffer/service/gpu_processor.cc |
=================================================================== |
--- gpu/command_buffer/service/gpu_processor.cc (revision 67289) |
+++ gpu/command_buffer/service/gpu_processor.cc (working copy) |
@@ -16,6 +16,10 @@ |
gles2::ContextGroup* group) |
: command_buffer_(command_buffer), |
commands_per_update_(100), |
+#if defined(OS_MACOSX) |
+ swap_buffers_count_(0), |
+ acknowledged_swap_buffers_count_(0), |
+#endif |
method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
DCHECK(command_buffer); |
decoder_.reset(gles2::GLES2Decoder::Create(group)); |
@@ -28,6 +32,10 @@ |
int commands_per_update) |
: command_buffer_(command_buffer), |
commands_per_update_(commands_per_update), |
+#if defined(OS_MACOSX) |
+ swap_buffers_count_(0), |
+ acknowledged_swap_buffers_count_(0), |
+#endif |
method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
DCHECK(command_buffer); |
decoder_.reset(decoder); |
@@ -87,6 +95,12 @@ |
parser_.reset(); |
} |
+#if defined(OS_MACOSX) |
+namespace { |
+const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; |
+} |
+#endif |
+ |
void GPUProcessor::ProcessCommands() { |
CommandBuffer::State state = command_buffer_->GetState(); |
if (state.error != error::kNoError) |
@@ -102,6 +116,19 @@ |
parser_->set_put(state.put_offset); |
+#if defined(OS_MACOSX) |
+ bool do_rate_limiting = surface_.get() != NULL; |
+ // Don't swamp the browser process with SwapBuffers calls it can't handle. |
+ if (do_rate_limiting && |
+ swap_buffers_count_ - acknowledged_swap_buffers_count_ >= |
+ kMaxOutstandingSwapBuffersCallsPerOnscreenContext) { |
+ // Stop doing work on this command buffer. In the GPU process, |
+ // receipt of the GpuMsg_AcceleratedSurfaceBuffersSwappedACK |
+ // message causes ProcessCommands to be scheduled again. |
+ return; |
+ } |
+#endif |
+ |
int commands_processed = 0; |
while (commands_processed < commands_per_update_ && !parser_->IsEmpty()) { |
error::Error error = parser_->ProcessCommand(); |
@@ -115,12 +142,16 @@ |
command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); |
if (!parser_->IsEmpty()) { |
- MessageLoop::current()->PostTask( |
- FROM_HERE, |
- method_factory_.NewRunnableMethod(&GPUProcessor::ProcessCommands)); |
+ ScheduleProcessCommands(); |
} |
} |
+void GPUProcessor::ScheduleProcessCommands() { |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ method_factory_.NewRunnableMethod(&GPUProcessor::ProcessCommands)); |
+} |
+ |
Buffer GPUProcessor::GetSharedMemoryBuffer(int32 shm_id) { |
return command_buffer_->GetTransferBuffer(shm_id); |
} |