Chromium Code Reviews| Index: content/common/gpu/gpu_command_buffer_stub.cc |
| diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc |
| index c74d4377693855de5493f5e1da6fb8536a511d54..3b717e2cc5404015b3731eeadb59f822e369cffc 100644 |
| --- a/content/common/gpu/gpu_command_buffer_stub.cc |
| +++ b/content/common/gpu/gpu_command_buffer_stub.cc |
| @@ -91,6 +91,9 @@ void FastSetActiveURL(const GURL& url, size_t url_hash) { |
| const int64 kHandleMoreWorkPeriodMs = 2; |
| const int64 kHandleMoreWorkPeriodBusyMs = 1; |
|
Sami
2013/03/14 15:18:07
This seems unused now?
reveman
2013/03/14 19:21:47
Oh, thanks for noticing this. Latest patch makes s
|
| +// Prevents idle work from being starved. |
| +const int64 kMaxTimeSinceIdleMs = 10; |
| + |
| } // namespace |
| GpuCommandBufferStub::GpuCommandBufferStub( |
| @@ -126,6 +129,7 @@ GpuCommandBufferStub::GpuCommandBufferStub( |
| watchdog_(watchdog), |
| sync_point_wait_count_(0), |
| delayed_work_scheduled_(false), |
| + previous_messages_processed_(0), |
| active_url_(active_url), |
| total_gpu_memory_(0) { |
| active_url_hash_ = base::Hash(active_url.possibly_invalid_spec()); |
| @@ -211,7 +215,7 @@ bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { |
| IPC_END_MESSAGE_MAP() |
| // Ensure that any delayed work that was created will be handled. |
| - ScheduleDelayedWork(kHandleMoreWorkPeriodMs); |
| + ScheduleDelayedWork(); |
| DCHECK(handled); |
| return handled; |
| @@ -235,9 +239,35 @@ void GpuCommandBufferStub::PollWork() { |
| FastSetActiveURL(active_url_, active_url_hash_); |
| if (decoder_.get() && !MakeCurrent()) |
| return; |
| - if (scheduler_.get()) |
| - scheduler_->PollUnscheduleFences(); |
| - ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs); |
| + |
| + if (scheduler_.get()) { |
| + bool fences_complete = scheduler_->PollUnscheduleFences(); |
| + // Perform idle work if all fences are complete. |
| + if (fences_complete) { |
| + uint64 current_messages_processed = |
| + channel()->gpu_channel_manager()->MessagesProcessed(); |
| + // We're idle when no messages were processed or scheduled. |
| + bool is_idle = |
| + (previous_messages_processed_ == current_messages_processed) && |
| + !channel()->gpu_channel_manager()->HandleMessagesScheduled(); |
| + if (!is_idle && !last_idle_time_.is_null()) { |
| + base::TimeDelta time_since_idle = base::TimeTicks::Now() - |
| + last_idle_time_; |
| + base::TimeDelta max_time_since_idle = |
| + base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs); |
| + |
| + // Force idle when it's been too long since last time we were idle. |
| + if (time_since_idle > max_time_since_idle) |
| + is_idle = true; |
| + } |
| + |
| + if (is_idle) { |
| + last_idle_time_ = base::TimeTicks::Now(); |
| + scheduler_->PerformIdleWork(); |
| + } |
| + } |
| + } |
| + ScheduleDelayedWork(); |
| } |
| bool GpuCommandBufferStub::HasUnprocessedCommands() { |
| @@ -249,15 +279,37 @@ bool GpuCommandBufferStub::HasUnprocessedCommands() { |
| return false; |
| } |
| -void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) { |
| - if (HasMoreWork() && !delayed_work_scheduled_) { |
| - delayed_work_scheduled_ = true; |
| - MessageLoop::current()->PostDelayedTask( |
| - FROM_HERE, |
| - base::Bind(&GpuCommandBufferStub::PollWork, |
| - AsWeakPtr()), |
| - base::TimeDelta::FromMilliseconds(delay)); |
| +void GpuCommandBufferStub::ScheduleDelayedWork() { |
| + if (!HasMoreWork()) { |
| + last_idle_time_ = base::TimeTicks(); |
| + return; |
| } |
| + |
| + if (delayed_work_scheduled_) |
| + return; |
| + delayed_work_scheduled_ = true; |
| + |
| + // Idle when no messages are processed between now and when |
| + // PollWork is called. |
| + previous_messages_processed_ = |
| + channel()->gpu_channel_manager()->MessagesProcessed(); |
| + if (last_idle_time_.is_null()) |
| + last_idle_time_ = base::TimeTicks::Now(); |
| + |
| + int64 delay = kHandleMoreWorkPeriodMs; |
| + // No need for a delay when there's idle work to be done and we're |
|
epenner
2013/03/14 18:23:24
I think I get this, but would help to have "becaus
reveman
2013/03/14 19:21:47
I've updated this comment to make it more clear wh
|
| + // not waiting on unschedule fences. |
|
Sami
2013/03/14 15:18:07
Typo: unschedule
reveman
2013/03/14 19:21:47
It sounds awkward but this is what we currently ca
|
| + if (scheduler_.get() && |
| + scheduler_->IsScheduled() && |
| + scheduler_->HasMoreIdleWork()) { |
| + delay = 0; |
| + } |
| + |
| + MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&GpuCommandBufferStub::PollWork, |
| + AsWeakPtr()), |
| + base::TimeDelta::FromMilliseconds(delay)); |
| } |
| void GpuCommandBufferStub::OnEcho(const IPC::Message& message) { |