OLD | NEW |
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/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "gpu/common/gpu_trace_event.h" | 10 #include "gpu/common/gpu_trace_event.h" |
11 #include "ui/gfx/gl/gl_context.h" | 11 #include "ui/gfx/gl/gl_context.h" |
12 #include "ui/gfx/gl/gl_bindings.h" | 12 #include "ui/gfx/gl/gl_bindings.h" |
13 | 13 |
14 using ::base::SharedMemory; | 14 using ::base::SharedMemory; |
15 | 15 |
16 namespace gpu { | 16 namespace gpu { |
17 | 17 |
18 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, | 18 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, |
19 gles2::ContextGroup* group) | 19 gles2::ContextGroup* group) |
20 : command_buffer_(command_buffer), | 20 : command_buffer_(command_buffer), |
21 commands_per_update_(100), | 21 commands_per_update_(100), |
| 22 unscheduled_count_(0), |
22 #if defined(OS_MACOSX) | 23 #if defined(OS_MACOSX) |
23 swap_buffers_count_(0), | 24 swap_buffers_count_(0), |
24 acknowledged_swap_buffers_count_(0), | 25 acknowledged_swap_buffers_count_(0), |
25 #endif | 26 #endif |
26 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 27 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
27 DCHECK(command_buffer); | 28 DCHECK(command_buffer); |
28 decoder_.reset(gles2::GLES2Decoder::Create(group)); | 29 decoder_.reset(gles2::GLES2Decoder::Create(group)); |
29 decoder_->set_engine(this); | 30 decoder_->set_engine(this); |
30 } | 31 } |
31 | 32 |
32 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, | 33 GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, |
33 gles2::GLES2Decoder* decoder, | 34 gles2::GLES2Decoder* decoder, |
34 CommandParser* parser, | 35 CommandParser* parser, |
35 int commands_per_update) | 36 int commands_per_update) |
36 : command_buffer_(command_buffer), | 37 : command_buffer_(command_buffer), |
37 commands_per_update_(commands_per_update), | 38 commands_per_update_(commands_per_update), |
| 39 unscheduled_count_(0), |
38 #if defined(OS_MACOSX) | 40 #if defined(OS_MACOSX) |
39 swap_buffers_count_(0), | 41 swap_buffers_count_(0), |
40 acknowledged_swap_buffers_count_(0), | 42 acknowledged_swap_buffers_count_(0), |
41 #endif | 43 #endif |
42 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 44 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
43 DCHECK(command_buffer); | 45 DCHECK(command_buffer); |
44 decoder_.reset(decoder); | 46 decoder_.reset(decoder); |
45 parser_.reset(parser); | 47 parser_.reset(parser); |
46 } | 48 } |
47 | 49 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; | 116 const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; |
115 } | 117 } |
116 #endif | 118 #endif |
117 | 119 |
118 void GpuScheduler::ProcessCommands() { | 120 void GpuScheduler::ProcessCommands() { |
119 GPU_TRACE_EVENT0("gpu", "GpuScheduler:ProcessCommands"); | 121 GPU_TRACE_EVENT0("gpu", "GpuScheduler:ProcessCommands"); |
120 CommandBuffer::State state = command_buffer_->GetState(); | 122 CommandBuffer::State state = command_buffer_->GetState(); |
121 if (state.error != error::kNoError) | 123 if (state.error != error::kNoError) |
122 return; | 124 return; |
123 | 125 |
| 126 if (unscheduled_count_ > 0) |
| 127 return; |
| 128 |
124 if (decoder_.get()) { | 129 if (decoder_.get()) { |
125 if (!decoder_->MakeCurrent()) { | 130 if (!decoder_->MakeCurrent()) { |
126 LOG(ERROR) << "Context lost because MakeCurrent failed."; | 131 LOG(ERROR) << "Context lost because MakeCurrent failed."; |
127 command_buffer_->SetParseError(error::kLostContext); | 132 command_buffer_->SetParseError(error::kLostContext); |
128 return; | 133 return; |
129 } | 134 } |
130 } | 135 } |
131 | 136 |
132 parser_->set_put(state.put_offset); | 137 parser_->set_put(state.put_offset); |
133 | 138 |
(...skipping 16 matching lines...) Expand all Loading... |
150 !parser_->IsEmpty()) { | 155 !parser_->IsEmpty()) { |
151 error = parser_->ProcessCommand(); | 156 error = parser_->ProcessCommand(); |
152 | 157 |
153 if (error == error::kWaiting || error == error::kYield) { | 158 if (error == error::kWaiting || error == error::kYield) { |
154 break; | 159 break; |
155 } else if (error::IsError(error)) { | 160 } else if (error::IsError(error)) { |
156 command_buffer_->SetParseError(error); | 161 command_buffer_->SetParseError(error); |
157 return; | 162 return; |
158 } | 163 } |
159 | 164 |
| 165 if (unscheduled_count_ > 0) |
| 166 break; |
| 167 |
160 ++commands_processed; | 168 ++commands_processed; |
161 if (command_processed_callback_.get()) { | 169 if (command_processed_callback_.get()) { |
162 command_processed_callback_->Run(); | 170 command_processed_callback_->Run(); |
163 } | 171 } |
164 } | 172 } |
165 | 173 |
166 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); | 174 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); |
167 | 175 |
168 if (error != error::kWaiting && !parser_->IsEmpty()) { | 176 if (unscheduled_count_ == 0 && |
| 177 error != error::kWaiting && |
| 178 !parser_->IsEmpty()) { |
169 ScheduleProcessCommands(); | 179 ScheduleProcessCommands(); |
170 } | 180 } |
171 } | 181 } |
172 | 182 |
173 void GpuScheduler::ScheduleProcessCommands() { | 183 void GpuScheduler::SetScheduled(bool scheduled) { |
174 MessageLoop::current()->PostTask( | 184 if (scheduled) { |
175 FROM_HERE, | 185 --unscheduled_count_; |
176 method_factory_.NewRunnableMethod(&GpuScheduler::ProcessCommands)); | 186 DCHECK_GE(unscheduled_count_, 0); |
| 187 |
| 188 if (unscheduled_count_ == 0) |
| 189 ScheduleProcessCommands(); |
| 190 } else { |
| 191 ++unscheduled_count_; |
| 192 } |
177 } | 193 } |
178 | 194 |
179 Buffer GpuScheduler::GetSharedMemoryBuffer(int32 shm_id) { | 195 Buffer GpuScheduler::GetSharedMemoryBuffer(int32 shm_id) { |
180 return command_buffer_->GetTransferBuffer(shm_id); | 196 return command_buffer_->GetTransferBuffer(shm_id); |
181 } | 197 } |
182 | 198 |
183 void GpuScheduler::set_token(int32 token) { | 199 void GpuScheduler::set_token(int32 token) { |
184 command_buffer_->SetToken(token); | 200 command_buffer_->SetToken(token); |
185 } | 201 } |
186 | 202 |
(...skipping 23 matching lines...) Expand all Loading... |
210 decoder_->SetSwapBuffersCallback( | 226 decoder_->SetSwapBuffersCallback( |
211 NewCallback(this, | 227 NewCallback(this, |
212 &GpuScheduler::WillSwapBuffers)); | 228 &GpuScheduler::WillSwapBuffers)); |
213 } | 229 } |
214 | 230 |
215 void GpuScheduler::SetCommandProcessedCallback( | 231 void GpuScheduler::SetCommandProcessedCallback( |
216 Callback0::Type* callback) { | 232 Callback0::Type* callback) { |
217 command_processed_callback_.reset(callback); | 233 command_processed_callback_.reset(callback); |
218 } | 234 } |
219 | 235 |
| 236 void GpuScheduler::ScheduleProcessCommands() { |
| 237 MessageLoop::current()->PostTask( |
| 238 FROM_HERE, |
| 239 method_factory_.NewRunnableMethod(&GpuScheduler::ProcessCommands)); |
| 240 } |
| 241 |
220 } // namespace gpu | 242 } // namespace gpu |
OLD | NEW |