Index: gpu/command_buffer/service/gpu_scheduler.cc |
=================================================================== |
--- gpu/command_buffer/service/gpu_scheduler.cc (revision 92876) |
+++ gpu/command_buffer/service/gpu_scheduler.cc (working copy) |
@@ -19,41 +19,37 @@ |
namespace gpu { |
-GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, |
- SurfaceManager* surface_manager, |
- gles2::ContextGroup* group) |
- : command_buffer_(command_buffer), |
- commands_per_update_(100), |
- unscheduled_count_(0), |
-#if defined(OS_MACOSX) || defined(TOUCH_UI) |
- swap_buffers_count_(0), |
- acknowledged_swap_buffers_count_(0), |
-#endif |
- method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
+GpuScheduler* GpuScheduler::Create(CommandBuffer* command_buffer, |
+ SurfaceManager* surface_manager, |
+ gles2::ContextGroup* group) { |
DCHECK(command_buffer); |
- decoder_.reset(gles2::GLES2Decoder::Create(surface_manager, group)); |
- decoder_->set_engine(this); |
+ |
+ gles2::GLES2Decoder* decoder = |
+ gles2::GLES2Decoder::Create(surface_manager, group); |
+ |
+ GpuScheduler* scheduler = new GpuScheduler(command_buffer, |
+ decoder, |
+ NULL); |
+ |
+ decoder->set_engine(scheduler); |
+ |
if (CommandLine::ForCurrentProcess()->HasSwitch( |
switches::kEnableGPUServiceLogging)) { |
- decoder_->set_debug(true); |
+ decoder->set_debug(true); |
} |
+ |
+ return scheduler; |
} |
-GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, |
- gles2::GLES2Decoder* decoder, |
- CommandParser* parser, |
- int commands_per_update) |
- : command_buffer_(command_buffer), |
- commands_per_update_(commands_per_update), |
- unscheduled_count_(0), |
-#if defined(OS_MACOSX) || defined(TOUCH_UI) |
- swap_buffers_count_(0), |
- acknowledged_swap_buffers_count_(0), |
-#endif |
- method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
+GpuScheduler* GpuScheduler::CreateForTests(CommandBuffer* command_buffer, |
+ gles2::GLES2Decoder* decoder, |
+ CommandParser* parser) { |
DCHECK(command_buffer); |
- decoder_.reset(decoder); |
- parser_.reset(parser); |
+ GpuScheduler* scheduler = new GpuScheduler(command_buffer, |
+ decoder, |
+ parser); |
+ |
+ return scheduler; |
} |
GpuScheduler::~GpuScheduler() { |
@@ -82,11 +78,6 @@ |
} |
#endif |
- // Do not limit to a certain number of commands before scheduling another |
- // update when rendering onscreen. |
- if (!surface->IsOffscreen()) |
- commands_per_update_ = INT_MAX; |
- |
// Map the ring buffer and create the parser. |
Buffer ring_buffer = command_buffer_->GetRingBuffer(); |
if (ring_buffer.ptr) { |
@@ -144,29 +135,16 @@ |
} |
#endif |
-void GpuScheduler::PutChanged(bool sync) { |
+void GpuScheduler::PutChanged() { |
TRACE_EVENT1("gpu", "GpuScheduler:PutChanged", "this", this); |
- CommandBuffer::State state = command_buffer_->GetState(); |
- parser_->set_put(state.put_offset); |
- if (sync) |
- ProcessCommands(); |
- else |
- ScheduleProcessCommands(); |
-} |
+ DCHECK(IsScheduled()); |
-void GpuScheduler::ProcessCommands() { |
- TRACE_EVENT1("gpu", "GpuScheduler:ProcessCommands", "this", this); |
CommandBuffer::State state = command_buffer_->GetState(); |
+ parser_->set_put(state.put_offset); |
if (state.error != error::kNoError) |
return; |
- if (unscheduled_count_ > 0) { |
- TRACE_EVENT1("gpu", "EarlyOut_Unscheduled", |
- "unscheduled_count_", unscheduled_count_); |
- return; |
- } |
- |
if (decoder_.get()) { |
if (!decoder_->MakeCurrent()) { |
LOG(ERROR) << "Context lost because MakeCurrent failed."; |
@@ -184,60 +162,30 @@ |
#if defined(OS_MACOSX) || defined(TOUCH_UI) |
// 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) { |
- TRACE_EVENT0("gpu", "EarlyOut_OSX_Throttle"); |
- // Stop doing work on this command buffer. In the GPU process, |
- // receipt of the GpuMsg_AcceleratedSurfaceBuffersSwappedACK |
- // message causes ProcessCommands to be scheduled again. |
- return; |
- } |
+ DCHECK(!do_rate_limiting || |
+ swap_buffers_count_ - acknowledged_swap_buffers_count_ == 0); |
#endif |
- base::TimeTicks start_time = base::TimeTicks::Now(); |
- base::TimeDelta elapsed; |
- bool is_break = false; |
error::Error error = error::kNoError; |
- do { |
- int commands_processed = 0; |
- while (commands_processed < commands_per_update_ && |
- !parser_->IsEmpty()) { |
- error = parser_->ProcessCommand(); |
+ while (!parser_->IsEmpty()) { |
+ error = parser_->ProcessCommand(); |
- // TODO(piman): various classes duplicate various pieces of state, leading |
- // to needlessly complex update logic. It should be possible to simply |
- // share the state across all of them. |
- command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); |
+ // TODO(piman): various classes duplicate various pieces of state, leading |
+ // to needlessly complex update logic. It should be possible to simply |
+ // share the state across all of them. |
+ command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); |
- if (error == error::kWaiting || error == error::kYield) { |
- is_break = true; |
- break; |
- } else if (error::IsError(error)) { |
- command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); |
- command_buffer_->SetParseError(error); |
- return; |
- } |
- |
- if (unscheduled_count_ > 0) { |
- is_break = true; |
- break; |
- } |
- |
- ++commands_processed; |
- if (command_processed_callback_.get()) { |
- command_processed_callback_->Run(); |
- } |
+ if (error::IsError(error)) { |
+ command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); |
+ command_buffer_->SetParseError(error); |
+ return; |
} |
- elapsed = base::TimeTicks::Now() - start_time; |
- } while(!is_break && |
- !parser_->IsEmpty() && |
- elapsed.InMicroseconds() < kMinimumSchedulerQuantumMicros); |
- if (unscheduled_count_ == 0 && |
- error != error::kWaiting && |
- !parser_->IsEmpty()) { |
- ScheduleProcessCommands(); |
+ if (command_processed_callback_.get()) |
+ command_processed_callback_->Run(); |
+ |
+ if (unscheduled_count_ > 0) |
+ return; |
} |
} |
@@ -249,12 +197,8 @@ |
--unscheduled_count_; |
DCHECK_GE(unscheduled_count_, 0); |
- if (unscheduled_count_ == 0) { |
- if (scheduled_callback_.get()) |
- scheduled_callback_->Run(); |
- |
- ScheduleProcessCommands(); |
- } |
+ if (unscheduled_count_ == 0 && scheduled_callback_.get()) |
+ scheduled_callback_->Run(); |
} else { |
++unscheduled_count_; |
} |
@@ -320,10 +264,18 @@ |
set_token_callback_ = callback; |
} |
-void GpuScheduler::ScheduleProcessCommands() { |
- MessageLoop::current()->PostTask( |
- FROM_HERE, |
- method_factory_.NewRunnableMethod(&GpuScheduler::ProcessCommands)); |
+GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, |
+ gles2::GLES2Decoder* decoder, |
+ CommandParser* parser) |
+ : command_buffer_(command_buffer), |
+ decoder_(decoder), |
+ parser_(parser), |
+ unscheduled_count_(0), |
+#if defined(OS_MACOSX) || defined(TOUCH_UI) |
+ swap_buffers_count_(0), |
+ acknowledged_swap_buffers_count_(0), |
+#endif |
+ method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
} |
void GpuScheduler::WillResize(gfx::Size size) { |