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

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: Add DCHECKs to ensure idle async uploads are only used with GL_TEXTURE_2D target 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 c74d4377693855de5493f5e1da6fb8536a511d54..26b05e5a0d9bfb11b91fd6da633e2308affbbfc9 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;
+// 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());
@@ -235,8 +239,34 @@ void GpuCommandBufferStub::PollWork() {
FastSetActiveURL(active_url_, active_url_hash_);
if (decoder_.get() && !MakeCurrent())
return;
- if (scheduler_.get())
- scheduler_->PollUnscheduleFences();
+
+ 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(kHandleMoreWorkPeriodBusyMs);
}
@@ -250,14 +280,39 @@ 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;
+
+ // 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();
+
+ // IsScheduled() returns true after passing all unschedule fences
+ // and this is when we can start performing idle work. Idle work
+ // is done synchronously so we can set delay to 0 and instead poll
+ // for more work at the rate idle work is performed. This also ensures
+ // that idle work is done as efficiently as possible without any
+ // unnecessary delays.
+ 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) {
« no previous file with comments | « content/common/gpu/gpu_command_buffer_stub.h ('k') | gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698