Index: gpu/command_buffer/service/gpu_scheduler.cc |
diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc |
index 151ff9afd8d4978563ec1451d9eea368b8cf5d60..5fa9ceb3fd917c63e764051fb2e78e4efc668c4a 100644 |
--- a/gpu/command_buffer/service/gpu_scheduler.cc |
+++ b/gpu/command_buffer/service/gpu_scheduler.cc |
@@ -9,6 +9,7 @@ |
#include "base/compiler_specific.h" |
#include "base/debug/trace_event.h" |
#include "base/message_loop.h" |
+#include "base/time.h" |
#include "ui/gfx/gl/gl_context.h" |
#include "ui/gfx/gl/gl_bindings.h" |
#include "ui/gfx/gl/gl_surface.h" |
@@ -136,6 +137,7 @@ const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; |
#endif |
void GpuScheduler::PutChanged(bool sync) { |
+ TRACE_EVENT0("gpu", "GpuScheduler:PutChanged"); |
CommandBuffer::State state = command_buffer_->GetState(); |
parser_->set_put(state.put_offset); |
@@ -151,8 +153,11 @@ void GpuScheduler::ProcessCommands() { |
if (state.error != error::kNoError) |
return; |
- if (unscheduled_count_ > 0) |
+ if (unscheduled_count_ > 0) { |
+ TRACE_EVENT1("gpu", "EarlyOut_Unscheduled", |
+ "unscheduled_count_", unscheduled_count_); |
return; |
+ } |
if (decoder_.get()) { |
if (!decoder_->MakeCurrent()) { |
@@ -175,32 +180,43 @@ void GpuScheduler::ProcessCommands() { |
} |
#endif |
+ base::TimeTicks start_time = base::TimeTicks::Now(); |
+ base::TimeDelta elapsed; |
+ bool is_break = false; |
error::Error error = error::kNoError; |
- int commands_processed = 0; |
- while (commands_processed < commands_per_update_ && |
- !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())); |
- |
- if (error == error::kWaiting || error == error::kYield) { |
- break; |
- } else if (error::IsError(error)) { |
- command_buffer_->SetParseError(error); |
- return; |
+ do { |
+ int commands_processed = 0; |
+ while (commands_processed < commands_per_update_ && |
+ !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())); |
+ |
+ if (error == error::kWaiting || error == error::kYield) { |
+ is_break = true; |
+ break; |
+ } else if (error::IsError(error)) { |
+ 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 (unscheduled_count_ > 0) |
- break; |
- |
- ++commands_processed; |
- if (command_processed_callback_.get()) { |
- command_processed_callback_->Run(); |
- } |
- } |
+ elapsed = base::TimeTicks::Now() - start_time; |
+ } while(!is_break && |
+ !parser_->IsEmpty() && |
+ elapsed.InMicroseconds() < kMinimumSchedulerQuantumMicros); |
if (unscheduled_count_ == 0 && |
error != error::kWaiting && |
@@ -210,6 +226,8 @@ void GpuScheduler::ProcessCommands() { |
} |
void GpuScheduler::SetScheduled(bool scheduled) { |
+ TRACE_EVENT2("gpu", "GpuScheduler:SetScheduled", "scheduled", scheduled, |
+ "unscheduled_count_", unscheduled_count_); |
if (scheduled) { |
--unscheduled_count_; |
DCHECK_GE(unscheduled_count_, 0); |