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

Unified Diff: gpu/command_buffer/service/gpu_scheduler.cc

Issue 8387008: GpuScheduler can unschedule a command buffer until the GPU has made progress up to a fence. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 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
« no previous file with comments | « gpu/command_buffer/service/gpu_scheduler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/command_buffer/service/gpu_scheduler.cc
===================================================================
--- gpu/command_buffer/service/gpu_scheduler.cc (revision 106933)
+++ gpu/command_buffer/service/gpu_scheduler.cc (working copy)
@@ -4,6 +4,7 @@
#include "gpu/command_buffer/service/gpu_scheduler.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
@@ -18,6 +19,9 @@
using ::base::SharedMemory;
namespace gpu {
+namespace {
+const uint64 kPollFencePeriod = 1;
+}
GpuScheduler::GpuScheduler(CommandBuffer* command_buffer,
gles2::GLES2Decoder* decoder,
@@ -55,9 +59,45 @@
parser_->set_put(state.put_offset);
if (state.error != error::kNoError)
return;
+glGenFencesNV = NULL;
apatrick_chromium 2011/10/25 00:44:24 glFinish code path tested scientifically. Poor per
+ // Check that the GPU has passed all fences.
+ if (!unschedule_fences_.empty()) {
+ if (glGenFencesNV) {
+ while (!unschedule_fences_.empty()) {
+ if (glTestFenceNV(unschedule_fences_.front().fence)) {
+ glDeleteFencesNV(1, &unschedule_fences_.front().fence);
+ unschedule_fences_.front().task.Run();
+ unschedule_fences_.pop();
+ } else {
+ SetScheduled(false);
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&GpuScheduler::SetScheduled, AsWeakPtr(), true),
+ kPollFencePeriod);
+ return;
+ }
+ }
+ } else {
+ // Hopefully no recent drivers don't support GL_NV_fence and this will
+ // not happen in practice.
+ glFinish();
+ while (!unschedule_fences_.empty()) {
+ unschedule_fences_.front().task.Run();
+ unschedule_fences_.pop();
+ }
+ }
+ }
+
+ // One of the unschedule fence tasks might have unscheduled us.
+ if (!IsScheduled())
+ return;
+
error::Error error = error::kNoError;
while (!parser_->IsEmpty()) {
+ DCHECK(IsScheduled());
+ DCHECK(unschedule_fences_.empty());
+
error = parser_->ProcessCommand();
// TODO(piman): various classes duplicate various pieces of state, leading
@@ -127,4 +167,35 @@
command_processed_callback_.reset(callback);
}
+void GpuScheduler::DeferToFence(base::Closure task) {
+ UnscheduleFence fence;
+
+ // What if either of these GL calls fails? TestFenceNV will return true and
+ // PutChanged will treat the fence as having been crossed and thereby not
+ // poll indefinately. See spec:
+ // http://www.opengl.org/registry/specs/NV/fence.txt
+ //
+ // What should happen if TestFenceNV is called for a name before SetFenceNV
+ // is called?
+ // We generate an INVALID_OPERATION error, and return TRUE.
+ // This follows the semantics for texture object names before
+ // they are bound, in that they acquire their state upon binding.
+ // We will arbitrarily return TRUE for consistency.
+ if (glGenFencesNV) {
+ glGenFencesNV(1, &fence.fence);
+ glSetFenceNV(fence.fence, GL_ALL_COMPLETED_NV);
+ glFlush();
+ }
+
+ fence.task = task;
+
+ unschedule_fences_.push(fence);
+}
+
+GpuScheduler::UnscheduleFence::UnscheduleFence() : fence(0) {
+}
+
+GpuScheduler::UnscheduleFence::~UnscheduleFence() {
+}
+
} // namespace gpu
« no previous file with comments | « gpu/command_buffer/service/gpu_scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698