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

Side by Side 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, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gpu/command_buffer/service/gpu_scheduler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/gpu_scheduler.h" 5 #include "gpu/command_buffer/service/gpu_scheduler.h"
6 6
7 #include "base/bind.h"
7 #include "base/callback.h" 8 #include "base/callback.h"
8 #include "base/command_line.h" 9 #include "base/command_line.h"
9 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
10 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
11 #include "base/message_loop.h" 12 #include "base/message_loop.h"
12 #include "base/time.h" 13 #include "base/time.h"
13 #include "ui/gfx/gl/gl_context.h" 14 #include "ui/gfx/gl/gl_context.h"
14 #include "ui/gfx/gl/gl_bindings.h" 15 #include "ui/gfx/gl/gl_bindings.h"
15 #include "ui/gfx/gl/gl_surface.h" 16 #include "ui/gfx/gl/gl_surface.h"
16 #include "ui/gfx/gl/gl_switches.h" 17 #include "ui/gfx/gl/gl_switches.h"
17 18
18 using ::base::SharedMemory; 19 using ::base::SharedMemory;
19 20
20 namespace gpu { 21 namespace gpu {
22 namespace {
23 const uint64 kPollFencePeriod = 1;
24 }
21 25
22 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, 26 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer,
23 gles2::GLES2Decoder* decoder, 27 gles2::GLES2Decoder* decoder,
24 CommandParser* parser) 28 CommandParser* parser)
25 : command_buffer_(command_buffer), 29 : command_buffer_(command_buffer),
26 decoder_(decoder), 30 decoder_(decoder),
27 parser_(parser), 31 parser_(parser),
28 unscheduled_count_(0) { 32 unscheduled_count_(0) {
29 // Map the ring buffer and create the parser. 33 // Map the ring buffer and create the parser.
30 if (!parser) { 34 if (!parser) {
(...skipping 17 matching lines...) Expand all
48 52
49 void GpuScheduler::PutChanged() { 53 void GpuScheduler::PutChanged() {
50 TRACE_EVENT1("gpu", "GpuScheduler:PutChanged", "this", this); 54 TRACE_EVENT1("gpu", "GpuScheduler:PutChanged", "this", this);
51 55
52 DCHECK(IsScheduled()); 56 DCHECK(IsScheduled());
53 57
54 CommandBuffer::State state = command_buffer_->GetState(); 58 CommandBuffer::State state = command_buffer_->GetState();
55 parser_->set_put(state.put_offset); 59 parser_->set_put(state.put_offset);
56 if (state.error != error::kNoError) 60 if (state.error != error::kNoError)
57 return; 61 return;
62 glGenFencesNV = NULL;
apatrick_chromium 2011/10/25 00:44:24 glFinish code path tested scientifically. Poor per
63 // Check that the GPU has passed all fences.
64 if (!unschedule_fences_.empty()) {
65 if (glGenFencesNV) {
66 while (!unschedule_fences_.empty()) {
67 if (glTestFenceNV(unschedule_fences_.front().fence)) {
68 glDeleteFencesNV(1, &unschedule_fences_.front().fence);
69 unschedule_fences_.front().task.Run();
70 unschedule_fences_.pop();
71 } else {
72 SetScheduled(false);
73 MessageLoop::current()->PostDelayedTask(
74 FROM_HERE,
75 base::Bind(&GpuScheduler::SetScheduled, AsWeakPtr(), true),
76 kPollFencePeriod);
77 return;
78 }
79 }
80 } else {
81 // Hopefully no recent drivers don't support GL_NV_fence and this will
82 // not happen in practice.
83 glFinish();
84
85 while (!unschedule_fences_.empty()) {
86 unschedule_fences_.front().task.Run();
87 unschedule_fences_.pop();
88 }
89 }
90 }
91
92 // One of the unschedule fence tasks might have unscheduled us.
93 if (!IsScheduled())
94 return;
58 95
59 error::Error error = error::kNoError; 96 error::Error error = error::kNoError;
60 while (!parser_->IsEmpty()) { 97 while (!parser_->IsEmpty()) {
98 DCHECK(IsScheduled());
99 DCHECK(unschedule_fences_.empty());
100
61 error = parser_->ProcessCommand(); 101 error = parser_->ProcessCommand();
62 102
63 // TODO(piman): various classes duplicate various pieces of state, leading 103 // TODO(piman): various classes duplicate various pieces of state, leading
64 // to needlessly complex update logic. It should be possible to simply 104 // to needlessly complex update logic. It should be possible to simply
65 // share the state across all of them. 105 // share the state across all of them.
66 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); 106 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get()));
67 107
68 if (error::IsError(error)) { 108 if (error::IsError(error)) {
69 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); 109 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
70 command_buffer_->SetParseError(error); 110 command_buffer_->SetParseError(error);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 160
121 int32 GpuScheduler::GetGetOffset() { 161 int32 GpuScheduler::GetGetOffset() {
122 return parser_->get(); 162 return parser_->get();
123 } 163 }
124 164
125 void GpuScheduler::SetCommandProcessedCallback( 165 void GpuScheduler::SetCommandProcessedCallback(
126 Callback0::Type* callback) { 166 Callback0::Type* callback) {
127 command_processed_callback_.reset(callback); 167 command_processed_callback_.reset(callback);
128 } 168 }
129 169
170 void GpuScheduler::DeferToFence(base::Closure task) {
171 UnscheduleFence fence;
172
173 // What if either of these GL calls fails? TestFenceNV will return true and
174 // PutChanged will treat the fence as having been crossed and thereby not
175 // poll indefinately. See spec:
176 // http://www.opengl.org/registry/specs/NV/fence.txt
177 //
178 // What should happen if TestFenceNV is called for a name before SetFenceNV
179 // is called?
180 // We generate an INVALID_OPERATION error, and return TRUE.
181 // This follows the semantics for texture object names before
182 // they are bound, in that they acquire their state upon binding.
183 // We will arbitrarily return TRUE for consistency.
184 if (glGenFencesNV) {
185 glGenFencesNV(1, &fence.fence);
186 glSetFenceNV(fence.fence, GL_ALL_COMPLETED_NV);
187 glFlush();
188 }
189
190 fence.task = task;
191
192 unschedule_fences_.push(fence);
193 }
194
195 GpuScheduler::UnscheduleFence::UnscheduleFence() : fence(0) {
196 }
197
198 GpuScheduler::UnscheduleFence::~UnscheduleFence() {
199 }
200
130 } // namespace gpu 201 } // namespace gpu
OLDNEW
« 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