From 5c4ad75aeff603b729ff8096fde829d3929f642b Mon Sep 17 00:00:00 2001 From: "apatrick@chromium.org" Date: Wed, 10 Apr 2013 22:04:36 +0000 Subject: GPU process "unschedule fences" have a timeout. If the GPU process has waited for more than a given amount of time for a fence to complete, treat it as completed. This is because, when the D3D device is lost, some drivers will never complete the underlying queries and never detect the device lost. By forcing through subsequent rendering, either the driver sometimes detects the device lost and recovers or a subsequent drawing call hangs allowing the GPU watchdog thread to terminate the GPU process. Review URL: https://chromiumcodereview.appspot.com/13093015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@193471 0039d316-1c4b-4281-b951-d872f2087c98 --- gpu/command_buffer/service/gpu_scheduler.cc | 16 +++++++++++++--- gpu/command_buffer/service/gpu_scheduler.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'gpu') diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc index 29ea7fd..8a70255 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -24,6 +24,7 @@ namespace gpu { namespace { const int64 kRescheduleTimeOutDelay = 1000; +const int64 kUnscheduleFenceTimeOutDelay = 10000; } GpuScheduler::GpuScheduler( @@ -233,8 +234,14 @@ bool GpuScheduler::PollUnscheduleFences() { return true; if (unschedule_fences_.front()->fence.get()) { + base::Time now = base::Time::Now(); + base::TimeDelta timeout = + base::TimeDelta::FromMilliseconds(kUnscheduleFenceTimeOutDelay); + while (!unschedule_fences_.empty()) { - if (unschedule_fences_.front()->fence->HasCompleted()) { + const UnscheduleFence& fence = *unschedule_fences_.front(); + if (fence.fence->HasCompleted() || + now - fence.issue_time > timeout) { unschedule_fences_.front()->task.Run(); unschedule_fences_.pop(); SetScheduled(true); @@ -291,8 +298,11 @@ void GpuScheduler::RescheduleTimeOut() { rescheduled_count_ = new_count; } -GpuScheduler::UnscheduleFence::UnscheduleFence( - gfx::GLFence* fence_, base::Closure task_): fence(fence_), task(task_) { +GpuScheduler::UnscheduleFence::UnscheduleFence(gfx::GLFence* fence_, + base::Closure task_) + : fence(fence_), + issue_time(base::Time::Now()), + task(task_) { } GpuScheduler::UnscheduleFence::~UnscheduleFence() { diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h index bda7ac1..bc8510a 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -147,6 +147,7 @@ class GPU_EXPORT GpuScheduler ~UnscheduleFence(); scoped_ptr fence; + base::Time issue_time; base::Closure task; }; std::queue > unschedule_fences_; -- cgit v1.1