Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1712)

Unified Diff: content/common/gpu/gpu_command_buffer_stub.cc

Issue 12040049: gpu: Implement idle async pixel transfers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase and prevent starvation Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 7e539969cf33d195c377cdd21083c8369208a50a..306408f1d84e50c3716cafd2b4104d59763d06fe 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -88,8 +88,13 @@ void FastSetActiveURL(const GURL& url, size_t url_hash) {
// The first time polling a fence, delay some extra time to allow other
// stubs to process some work, or else the timing of the fences could
// allow a pattern of alternating fast and slow frames to occur.
-const int64 kHandleMoreWorkPeriodMs = 2;
-const int64 kHandleMoreWorkPeriodBusyMs = 1;
+const int64 kHandleMoreWorkPeriodMicroseconds = 2000;
+const int64 kHandleMoreWorkPeriodBusyMicroseconds = 1000;
+
+// Use a shorter delay when there'ss idle work to be done.
Sami 2013/03/07 16:57:19 Typo: there'ss
reveman 2013/03/07 20:21:04 Done.
+const int64 kHandleMoreIdleWorkPeriodBusyMicroseconds = 100;
+// Prevents idle work from being starved.
+const int64 kMaxTimeSinceIdleMicroseconds = 10000;
} // namespace
@@ -126,6 +131,7 @@ GpuCommandBufferStub::GpuCommandBufferStub(
watchdog_(watchdog),
sync_point_wait_count_(0),
delayed_work_scheduled_(false),
+ is_idle_(false),
active_url_(active_url),
total_gpu_memory_(0) {
active_url_hash_ = base::Hash(active_url.possibly_invalid_spec());
@@ -166,6 +172,8 @@ bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
return false;
}
+ is_idle_ = false;
+
// Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
// here. This is so the reply can be delayed if the scheduler is unscheduled.
bool handled = true;
@@ -211,7 +219,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(kHandleMoreWorkPeriodMicroseconds);
DCHECK(handled);
return handled;
@@ -235,9 +243,28 @@ void GpuCommandBufferStub::PollWork() {
FastSetActiveURL(active_url_, active_url_hash_);
if (decoder_.get() && !MakeCurrent())
return;
- if (scheduler_.get())
- scheduler_->PollUnscheduleFences();
- ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs);
+ int64 delay = kHandleMoreWorkPeriodBusyMicroseconds;
+ if (scheduler_.get()) {
+ bool fences_complete = scheduler_->PollUnscheduleFences();
+ // Perform idle work if all fences are complete.
+ if (fences_complete) {
+ DCHECK(!last_idle_time_.is_null());
+ base::TimeDelta time_since_idle = base::TimeTicks::Now() -
+ last_idle_time_;
+ base::TimeDelta max_time_since_idle =
+ base::TimeDelta::FromMicroseconds(kMaxTimeSinceIdleMicroseconds);
+
+ // Perform some idle work if idle or it's been too long since
+ // last time we were idle.
+ if (is_idle_ || time_since_idle > max_time_since_idle) {
+ last_idle_time_ = base::TimeTicks::Now();
+ // Use idle work period delay when there's more idle work pending.
+ if (scheduler_->PerformIdleWork())
+ delay = kHandleMoreIdleWorkPeriodBusyMicroseconds;
+ }
+ }
+ }
+ ScheduleDelayedWork(delay);
}
bool GpuCommandBufferStub::HasUnprocessedCommands() {
@@ -250,14 +277,26 @@ bool GpuCommandBufferStub::HasUnprocessedCommands() {
}
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));
+ if (!HasMoreWork()) {
+ last_idle_time_ = base::TimeTicks();
+ return;
}
+
+ if (delayed_work_scheduled_)
+ return;
+ delayed_work_scheduled_ = true;
+
+ // Consider the command buffer idle if no messages are received between
+ // now and when PollWork is called.
+ is_idle_ = true;
+ if (last_idle_time_.is_null())
+ last_idle_time_ = base::TimeTicks::Now();
+
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&GpuCommandBufferStub::PollWork,
+ AsWeakPtr()),
+ base::TimeDelta::FromMicroseconds(delay));
}
void GpuCommandBufferStub::OnEcho(const IPC::Message& message) {

Powered by Google App Engine
This is Rietveld 408576698