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

Side by Side Diff: gpu/command_buffer/service/gpu_scheduler.cc

Issue 7058035: WebGraphicsContext3DCommandBufferImpl cleanup, Canvas2D thottling fix, GpuScheduler fix. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tests and feedback Created 9 years, 6 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 unified diff | Download patch | Annotate | Revision Log
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/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/time.h"
12 #include "ui/gfx/gl/gl_context.h" 13 #include "ui/gfx/gl/gl_context.h"
13 #include "ui/gfx/gl/gl_bindings.h" 14 #include "ui/gfx/gl/gl_bindings.h"
14 #include "ui/gfx/gl/gl_surface.h" 15 #include "ui/gfx/gl/gl_surface.h"
15 #include "ui/gfx/gl/gl_switches.h" 16 #include "ui/gfx/gl/gl_switches.h"
16 17
17 using ::base::SharedMemory; 18 using ::base::SharedMemory;
18 19
20 namespace {
21 const int kMinimumSchedulerQuantumMicros = 2000;
22 } // namespace
23
19 namespace gpu { 24 namespace gpu {
20 25
21 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, 26 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer,
22 SurfaceManager* surface_manager, 27 SurfaceManager* surface_manager,
23 gles2::ContextGroup* group) 28 gles2::ContextGroup* group)
24 : command_buffer_(command_buffer), 29 : command_buffer_(command_buffer),
25 commands_per_update_(100), 30 commands_per_update_(100),
26 unscheduled_count_(0), 31 unscheduled_count_(0),
27 #if defined(OS_MACOSX) 32 #if defined(OS_MACOSX)
28 swap_buffers_count_(0), 33 swap_buffers_count_(0),
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 parser_.reset(); 134 parser_.reset();
130 } 135 }
131 136
132 #if defined(OS_MACOSX) 137 #if defined(OS_MACOSX)
133 namespace { 138 namespace {
134 const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; 139 const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1;
135 } 140 }
136 #endif 141 #endif
137 142
138 void GpuScheduler::PutChanged(bool sync) { 143 void GpuScheduler::PutChanged(bool sync) {
144 TRACE_EVENT0("gpu", "GpuScheduler:PutChanged");
139 CommandBuffer::State state = command_buffer_->GetState(); 145 CommandBuffer::State state = command_buffer_->GetState();
140 parser_->set_put(state.put_offset); 146 parser_->set_put(state.put_offset);
141 147
142 if (sync) 148 if (sync)
143 ProcessCommands(); 149 ProcessCommands();
144 else 150 else
145 ScheduleProcessCommands(); 151 ScheduleProcessCommands();
146 } 152 }
147 153
148 void GpuScheduler::ProcessCommands() { 154 void GpuScheduler::ProcessCommands() {
149 TRACE_EVENT0("gpu", "GpuScheduler:ProcessCommands"); 155 TRACE_EVENT0("gpu", "GpuScheduler:ProcessCommands");
150 CommandBuffer::State state = command_buffer_->GetState(); 156 CommandBuffer::State state = command_buffer_->GetState();
151 if (state.error != error::kNoError) 157 if (state.error != error::kNoError)
152 return; 158 return;
153 159
154 if (unscheduled_count_ > 0) 160 if (unscheduled_count_ > 0) {
161 TRACE_EVENT1("gpu", "EarlyOut_Unscheduled",
162 "unscheduled_count_", unscheduled_count_);
155 return; 163 return;
164 }
156 165
157 if (decoder_.get()) { 166 if (decoder_.get()) {
158 if (!decoder_->MakeCurrent()) { 167 if (!decoder_->MakeCurrent()) {
159 LOG(ERROR) << "Context lost because MakeCurrent failed."; 168 LOG(ERROR) << "Context lost because MakeCurrent failed.";
160 command_buffer_->SetParseError(error::kLostContext); 169 command_buffer_->SetParseError(error::kLostContext);
161 return; 170 return;
162 } 171 }
163 } 172 }
164 173
165 #if defined(OS_MACOSX) 174 #if defined(OS_MACOSX)
166 bool do_rate_limiting = surface_.get() != NULL; 175 bool do_rate_limiting = surface_.get() != NULL;
167 // Don't swamp the browser process with SwapBuffers calls it can't handle. 176 // Don't swamp the browser process with SwapBuffers calls it can't handle.
168 if (do_rate_limiting && 177 if (do_rate_limiting &&
169 swap_buffers_count_ - acknowledged_swap_buffers_count_ >= 178 swap_buffers_count_ - acknowledged_swap_buffers_count_ >=
170 kMaxOutstandingSwapBuffersCallsPerOnscreenContext) { 179 kMaxOutstandingSwapBuffersCallsPerOnscreenContext) {
171 // Stop doing work on this command buffer. In the GPU process, 180 // Stop doing work on this command buffer. In the GPU process,
172 // receipt of the GpuMsg_AcceleratedSurfaceBuffersSwappedACK 181 // receipt of the GpuMsg_AcceleratedSurfaceBuffersSwappedACK
173 // message causes ProcessCommands to be scheduled again. 182 // message causes ProcessCommands to be scheduled again.
174 return; 183 return;
175 } 184 }
176 #endif 185 #endif
177 186
187 base::TimeTicks start_time = base::TimeTicks::Now();
188 base::TimeDelta elapsed;
189 bool is_break = false;
178 error::Error error = error::kNoError; 190 error::Error error = error::kNoError;
179 int commands_processed = 0; 191 do {
180 while (commands_processed < commands_per_update_ && 192 int commands_processed = 0;
181 !parser_->IsEmpty()) { 193 while (commands_processed < commands_per_update_ &&
182 error = parser_->ProcessCommand(); 194 !parser_->IsEmpty()) {
195 error = parser_->ProcessCommand();
183 196
184 // TODO(piman): various classes duplicate various pieces of state, leading 197 // TODO(piman): various classes duplicate various pieces of state, leading
185 // to needlessly complex update logic. It should be possible to simply share 198 // to needlessly complex update logic. It should be possible to simply
186 // the state across all of them. 199 // share the state across all of them.
187 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); 200 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get()));
188 201
189 if (error == error::kWaiting || error == error::kYield) { 202 if (error == error::kWaiting || error == error::kYield) {
190 break; 203 is_break = true;
191 } else if (error::IsError(error)) { 204 break;
192 command_buffer_->SetParseError(error); 205 } else if (error::IsError(error)) {
193 return; 206 command_buffer_->SetParseError(error);
207 return;
208 }
209
210 if (unscheduled_count_ > 0) {
211 is_break = true;
212 break;
213 }
214
215 ++commands_processed;
216 if (command_processed_callback_.get()) {
217 command_processed_callback_->Run();
218 }
194 } 219 }
195 220 elapsed = base::TimeTicks::Now() - start_time;
196 if (unscheduled_count_ > 0) 221 } while(!is_break &&
197 break; 222 !parser_->IsEmpty() &&
198 223 elapsed.InMicroseconds() < kMinimumSchedulerQuantumMicros);
199 ++commands_processed;
200 if (command_processed_callback_.get()) {
201 command_processed_callback_->Run();
202 }
203 }
204 224
205 if (unscheduled_count_ == 0 && 225 if (unscheduled_count_ == 0 &&
206 error != error::kWaiting && 226 error != error::kWaiting &&
207 !parser_->IsEmpty()) { 227 !parser_->IsEmpty()) {
208 ScheduleProcessCommands(); 228 ScheduleProcessCommands();
209 } 229 }
210 } 230 }
211 231
212 void GpuScheduler::SetScheduled(bool scheduled) { 232 void GpuScheduler::SetScheduled(bool scheduled) {
233 TRACE_EVENT2("gpu", "GpuScheduler:SetScheduled", "scheduled", scheduled,
234 "unscheduled_count_", unscheduled_count_);
213 if (scheduled) { 235 if (scheduled) {
214 --unscheduled_count_; 236 --unscheduled_count_;
215 DCHECK_GE(unscheduled_count_, 0); 237 DCHECK_GE(unscheduled_count_, 0);
216 238
217 if (unscheduled_count_ == 0) { 239 if (unscheduled_count_ == 0) {
218 if (scheduled_callback_.get()) 240 if (scheduled_callback_.get())
219 scheduled_callback_->Run(); 241 scheduled_callback_->Run();
220 242
221 ScheduleProcessCommands(); 243 ScheduleProcessCommands();
222 } 244 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 command_processed_callback_.reset(callback); 296 command_processed_callback_.reset(callback);
275 } 297 }
276 298
277 void GpuScheduler::ScheduleProcessCommands() { 299 void GpuScheduler::ScheduleProcessCommands() {
278 MessageLoop::current()->PostTask( 300 MessageLoop::current()->PostTask(
279 FROM_HERE, 301 FROM_HERE,
280 method_factory_.NewRunnableMethod(&GpuScheduler::ProcessCommands)); 302 method_factory_.NewRunnableMethod(&GpuScheduler::ProcessCommands));
281 } 303 }
282 304
283 } // namespace gpu 305 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698