OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/mus/gles2/command_buffer_local.h" | 5 #include "components/mus/gles2/command_buffer_local.h" |
6 | 6 |
| 7 #include "base/atomic_sequence_num.h" |
7 #include "base/bind.h" | 8 #include "base/bind.h" |
8 #include "base/memory/shared_memory.h" | 9 #include "base/memory/shared_memory.h" |
9 #include "components/mus/gles2/command_buffer_local_client.h" | 10 #include "components/mus/gles2/command_buffer_local_client.h" |
10 #include "components/mus/gles2/gpu_memory_tracker.h" | 11 #include "components/mus/gles2/gpu_memory_tracker.h" |
11 #include "components/mus/gles2/mojo_gpu_memory_buffer.h" | 12 #include "components/mus/gles2/mojo_gpu_memory_buffer.h" |
| 13 #include "gpu/command_buffer/common/sync_token.h" |
12 #include "gpu/command_buffer/service/command_buffer_service.h" | 14 #include "gpu/command_buffer/service/command_buffer_service.h" |
13 #include "gpu/command_buffer/service/context_group.h" | 15 #include "gpu/command_buffer/service/context_group.h" |
14 #include "gpu/command_buffer/service/gpu_scheduler.h" | 16 #include "gpu/command_buffer/service/gpu_scheduler.h" |
15 #include "gpu/command_buffer/service/image_factory.h" | 17 #include "gpu/command_buffer/service/image_factory.h" |
16 #include "gpu/command_buffer/service/image_manager.h" | 18 #include "gpu/command_buffer/service/image_manager.h" |
17 #include "gpu/command_buffer/service/memory_tracking.h" | 19 #include "gpu/command_buffer/service/memory_tracking.h" |
18 #include "gpu/command_buffer/service/shader_translator_cache.h" | 20 #include "gpu/command_buffer/service/shader_translator_cache.h" |
19 #include "gpu/command_buffer/service/transfer_buffer_manager.h" | 21 #include "gpu/command_buffer/service/transfer_buffer_manager.h" |
20 #include "gpu/command_buffer/service/valuebuffer_manager.h" | 22 #include "gpu/command_buffer/service/valuebuffer_manager.h" |
21 #include "ui/gfx/buffer_format_util.h" | 23 #include "ui/gfx/buffer_format_util.h" |
22 #include "ui/gfx/vsync_provider.h" | 24 #include "ui/gfx/vsync_provider.h" |
23 #include "ui/gl/gl_context.h" | 25 #include "ui/gl/gl_context.h" |
24 #include "ui/gl/gl_image_shared_memory.h" | 26 #include "ui/gl/gl_image_shared_memory.h" |
25 #include "ui/gl/gl_surface.h" | 27 #include "ui/gl/gl_surface.h" |
26 | 28 |
27 namespace mus { | 29 namespace mus { |
28 | 30 |
| 31 namespace { |
| 32 |
| 33 base::StaticAtomicSequenceNumber g_next_command_buffer_id; |
| 34 |
| 35 } |
| 36 |
29 const unsigned int GL_READ_WRITE_CHROMIUM = 0x78F2; | 37 const unsigned int GL_READ_WRITE_CHROMIUM = 0x78F2; |
30 | 38 |
31 CommandBufferLocal::CommandBufferLocal(CommandBufferLocalClient* client, | 39 CommandBufferLocal::CommandBufferLocal(CommandBufferLocalClient* client, |
32 gfx::AcceleratedWidget widget, | 40 gfx::AcceleratedWidget widget, |
33 const scoped_refptr<GpuState>& gpu_state) | 41 const scoped_refptr<GpuState>& gpu_state) |
34 : widget_(widget), | 42 : command_buffer_id_(g_next_command_buffer_id.GetNext()), |
| 43 widget_(widget), |
35 gpu_state_(gpu_state), | 44 gpu_state_(gpu_state), |
36 client_(client), | 45 client_(client), |
37 next_fence_sync_release_(1), | 46 next_fence_sync_release_(1), |
38 weak_factory_(this) {} | 47 weak_factory_(this) {} |
39 | 48 |
40 CommandBufferLocal::~CommandBufferLocal() { | 49 CommandBufferLocal::~CommandBufferLocal() { |
41 command_buffer_.reset(); | 50 command_buffer_.reset(); |
42 if (decoder_.get()) { | 51 if (decoder_.get()) { |
43 bool have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get()); | 52 bool have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get()); |
44 decoder_->Destroy(have_context); | 53 decoder_->Destroy(have_context); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 nullptr, bind_generates_resource); | 92 nullptr, bind_generates_resource); |
84 | 93 |
85 command_buffer_.reset( | 94 command_buffer_.reset( |
86 new gpu::CommandBufferService(context_group->transfer_buffer_manager())); | 95 new gpu::CommandBufferService(context_group->transfer_buffer_manager())); |
87 bool result = command_buffer_->Initialize(); | 96 bool result = command_buffer_->Initialize(); |
88 DCHECK(result); | 97 DCHECK(result); |
89 | 98 |
90 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group.get())); | 99 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group.get())); |
91 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), decoder_.get(), | 100 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), decoder_.get(), |
92 decoder_.get())); | 101 decoder_.get())); |
| 102 sync_point_order_data_ = gpu::SyncPointOrderData::Create(); |
| 103 sync_point_client_ = gpu_state_->sync_point_manager()->CreateSyncPointClient( |
| 104 sync_point_order_data_, GetNamespaceID(), GetCommandBufferID()); |
93 decoder_->set_engine(scheduler_.get()); | 105 decoder_->set_engine(scheduler_.get()); |
94 decoder_->SetWaitSyncPointCallback( | 106 decoder_->SetWaitSyncPointCallback( |
95 base::Bind(&CommandBufferLocal::OnWaitSyncPoint, base::Unretained(this))); | 107 base::Bind(&CommandBufferLocal::OnWaitSyncPoint, base::Unretained(this))); |
96 decoder_->SetFenceSyncReleaseCallback(base::Bind( | 108 decoder_->SetFenceSyncReleaseCallback(base::Bind( |
97 &CommandBufferLocal::OnFenceSyncRelease, base::Unretained(this))); | 109 &CommandBufferLocal::OnFenceSyncRelease, base::Unretained(this))); |
98 decoder_->SetWaitFenceSyncCallback( | 110 decoder_->SetWaitFenceSyncCallback( |
99 base::Bind(&CommandBufferLocal::OnWaitFenceSync, base::Unretained(this))); | 111 base::Bind(&CommandBufferLocal::OnWaitFenceSync, base::Unretained(this))); |
100 | 112 |
101 gpu::gles2::DisallowedFeatures disallowed_features; | 113 gpu::gles2::DisallowedFeatures disallowed_features; |
102 | 114 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 void CommandBufferLocal::SetLock(base::Lock* lock) { | 219 void CommandBufferLocal::SetLock(base::Lock* lock) { |
208 NOTIMPLEMENTED(); | 220 NOTIMPLEMENTED(); |
209 } | 221 } |
210 | 222 |
211 bool CommandBufferLocal::IsGpuChannelLost() { | 223 bool CommandBufferLocal::IsGpuChannelLost() { |
212 // This is only possible for out-of-process command buffers. | 224 // This is only possible for out-of-process command buffers. |
213 return false; | 225 return false; |
214 } | 226 } |
215 | 227 |
216 gpu::CommandBufferNamespace CommandBufferLocal::GetNamespaceID() const { | 228 gpu::CommandBufferNamespace CommandBufferLocal::GetNamespaceID() const { |
217 NOTIMPLEMENTED(); | 229 return gpu::CommandBufferNamespace::MOJO_LOCAL; |
218 return gpu::CommandBufferNamespace::INVALID; | |
219 } | 230 } |
220 | 231 |
221 uint64_t CommandBufferLocal::GetCommandBufferID() const { | 232 uint64_t CommandBufferLocal::GetCommandBufferID() const { |
222 NOTIMPLEMENTED(); | 233 return command_buffer_id_; |
223 return 0; | |
224 } | 234 } |
225 | 235 |
226 uint64_t CommandBufferLocal::GenerateFenceSyncRelease() { | 236 uint64_t CommandBufferLocal::GenerateFenceSyncRelease() { |
227 return next_fence_sync_release_++; | 237 return next_fence_sync_release_++; |
228 } | 238 } |
229 | 239 |
230 bool CommandBufferLocal::IsFenceSyncRelease(uint64_t release) { | 240 bool CommandBufferLocal::IsFenceSyncRelease(uint64_t release) { |
231 return release > 0 && release < next_fence_sync_release_; | 241 return release > 0 && release < next_fence_sync_release_; |
232 } | 242 } |
233 | 243 |
234 bool CommandBufferLocal::IsFenceSyncFlushed(uint64_t release) { | 244 bool CommandBufferLocal::IsFenceSyncFlushed(uint64_t release) { |
235 return IsFenceSyncRelease(release); | 245 return IsFenceSyncRelease(release); |
236 } | 246 } |
237 | 247 |
238 void CommandBufferLocal::SignalSyncToken(const gpu::SyncToken& sync_token, | 248 void CommandBufferLocal::SignalSyncToken(const gpu::SyncToken& sync_token, |
239 const base::Closure& callback) { | 249 const base::Closure& callback) { |
240 // TODO(dyen) | 250 // TODO(dyen) |
241 NOTIMPLEMENTED(); | 251 NOTIMPLEMENTED(); |
242 } | 252 } |
243 | 253 |
244 bool CommandBufferLocal::IsFenceSyncFlushReceived(uint64_t release) { | 254 bool CommandBufferLocal::IsFenceSyncFlushReceived(uint64_t release) { |
245 return IsFenceSyncRelease(release); | 255 return IsFenceSyncRelease(release); |
246 } | 256 } |
247 | 257 |
248 bool CommandBufferLocal::CanWaitUnverifiedSyncToken( | 258 bool CommandBufferLocal::CanWaitUnverifiedSyncToken( |
249 const gpu::SyncToken* sync_token) { | 259 const gpu::SyncToken* sync_token) { |
250 // All sync tokens must be flushed before being waited on. | 260 // Right now, MOJO_LOCAL is only used by trusted code, so it is safe to wait |
251 return false; | 261 // on a sync token in MOJO_LOCAL command buffer. |
| 262 return sync_token->namespace_id() == gpu::CommandBufferNamespace::MOJO_LOCAL; |
252 } | 263 } |
253 | 264 |
254 void CommandBufferLocal::PumpCommands() { | 265 void CommandBufferLocal::PumpCommands() { |
255 if (!decoder_->MakeCurrent()) { | 266 if (!decoder_->MakeCurrent()) { |
256 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); | 267 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); |
257 command_buffer_->SetParseError(::gpu::error::kLostContext); | 268 command_buffer_->SetParseError(::gpu::error::kLostContext); |
258 return; | 269 return; |
259 } | 270 } |
| 271 gpu::SyncPointManager* sync_point_manager = gpu_state_->sync_point_manager(); |
| 272 const uint32_t order_num = sync_point_order_data_ |
| 273 ->GenerateUnprocessedOrderNumber(sync_point_manager); |
| 274 sync_point_order_data_->BeginProcessingOrderNumber(order_num); |
260 scheduler_->PutChanged(); | 275 scheduler_->PutChanged(); |
| 276 sync_point_order_data_->FinishProcessingOrderNumber(order_num); |
261 } | 277 } |
262 | 278 |
263 void CommandBufferLocal::OnUpdateVSyncParameters( | 279 void CommandBufferLocal::OnUpdateVSyncParameters( |
264 const base::TimeTicks timebase, | 280 const base::TimeTicks timebase, |
265 const base::TimeDelta interval) { | 281 const base::TimeDelta interval) { |
266 if (client_) | 282 if (client_) |
267 client_->UpdateVSyncParameters(timebase.ToInternalValue(), | 283 client_->UpdateVSyncParameters(timebase.ToInternalValue(), |
268 interval.ToInternalValue()); | 284 interval.ToInternalValue()); |
269 } | 285 } |
270 | 286 |
271 bool CommandBufferLocal::OnWaitSyncPoint(uint32_t sync_point) { | 287 bool CommandBufferLocal::OnWaitSyncPoint(uint32_t sync_point) { |
272 if (!sync_point) | 288 if (!sync_point) |
273 return true; | 289 return true; |
274 | 290 |
275 bool context_changed = false; | 291 if (gpu_state_->sync_point_manager()->IsSyncPointRetired(sync_point)) |
276 while (!gpu_state_->sync_point_manager()->IsSyncPointRetired(sync_point)) { | 292 return true; |
| 293 |
| 294 do { |
277 gpu_state_->command_buffer_task_runner()->RunOneTask(); | 295 gpu_state_->command_buffer_task_runner()->RunOneTask(); |
278 context_changed = true; | 296 } while (!gpu_state_->sync_point_manager()->IsSyncPointRetired(sync_point)); |
279 } | |
280 | 297 |
281 // RunOneTask() changes the current GL context, so we have to recover it. | 298 // RunOneTask() changes the current GL context, so we have to recover it. |
282 if (context_changed) { | 299 if (!decoder_->MakeCurrent()) { |
283 if (!decoder_->MakeCurrent()) { | 300 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); |
284 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); | 301 command_buffer_->SetParseError(::gpu::error::kLostContext); |
285 command_buffer_->SetParseError(::gpu::error::kLostContext); | |
286 } | |
287 } | 302 } |
288 return true; | 303 return true; |
289 } | 304 } |
290 | 305 |
291 void CommandBufferLocal::OnFenceSyncRelease(uint64_t release) { | 306 void CommandBufferLocal::OnFenceSyncRelease(uint64_t release) { |
292 // TODO(dyen): Implement once CommandBufferID has been figured out and | 307 if (!sync_point_client_->client_state()->IsFenceSyncReleased(release)) |
293 // we have a SyncPointClient. It would probably look like what is commented | 308 sync_point_client_->ReleaseFenceSync(release); |
294 // out below: | |
295 // if (!sync_point_client_->client_state()->IsFenceSyncReleased(release)) | |
296 // sync_point_client_->ReleaseFenceSync(release); | |
297 NOTIMPLEMENTED(); | |
298 } | 309 } |
299 | 310 |
300 bool CommandBufferLocal::OnWaitFenceSync( | 311 bool CommandBufferLocal::OnWaitFenceSync( |
301 gpu::CommandBufferNamespace namespace_id, | 312 gpu::CommandBufferNamespace namespace_id, |
302 uint64_t command_buffer_id, | 313 uint64_t command_buffer_id, |
303 uint64_t release) { | 314 uint64_t release) { |
304 gpu::SyncPointManager* sync_point_manager = gpu_state_->sync_point_manager(); | 315 gpu::SyncPointManager* sync_point_manager = gpu_state_->sync_point_manager(); |
305 DCHECK(sync_point_manager); | 316 DCHECK(sync_point_manager); |
306 | 317 |
307 scoped_refptr<gpu::SyncPointClientState> release_state = | 318 scoped_refptr<gpu::SyncPointClientState> release_state = |
308 sync_point_manager->GetSyncPointClientState(namespace_id, | 319 sync_point_manager->GetSyncPointClientState(namespace_id, |
309 command_buffer_id); | 320 command_buffer_id); |
310 | 321 |
311 if (!release_state) | 322 if (!release_state) |
312 return true; | 323 return true; |
313 | 324 |
314 if (release_state->IsFenceSyncReleased(release)) | 325 if (release_state->IsFenceSyncReleased(release)) |
315 return true; | 326 return true; |
316 | 327 |
317 // TODO(dyen): Implement once CommandBufferID has been figured out and | 328 do { |
318 // we have a SyncPointClient. It would probably look like what is commented | 329 gpu_state_->command_buffer_task_runner()->RunOneTask(); |
319 // out below: | 330 } while (!release_state->IsFenceSyncReleased(release)); |
320 // scheduler_->SetScheduled(false); | 331 |
321 // sync_point_client_->Wait( | 332 // RunOneTask() changes the current GL context, so we have to recover it. |
322 // release_state.get(), | 333 if (!decoder_->MakeCurrent()) { |
323 // release, | 334 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); |
324 // base::Bind(&CommandBufferLocal::OnSyncPointRetired, | 335 command_buffer_->SetParseError(::gpu::error::kLostContext); |
325 // weak_factory_.GetWeakPtr())); | 336 } |
326 NOTIMPLEMENTED(); | 337 return true; |
327 return scheduler_->scheduled(); | |
328 } | 338 } |
329 | 339 |
330 void CommandBufferLocal::OnParseError() { | 340 void CommandBufferLocal::OnParseError() { |
331 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); | 341 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); |
332 OnContextLost(state.context_lost_reason); | 342 OnContextLost(state.context_lost_reason); |
333 } | 343 } |
334 | 344 |
335 void CommandBufferLocal::OnContextLost(uint32_t reason) { | 345 void CommandBufferLocal::OnContextLost(uint32_t reason) { |
336 if (client_) | 346 if (client_) |
337 client_->DidLoseContext(); | 347 client_->DidLoseContext(); |
338 } | 348 } |
339 | 349 |
340 } // namespace mus | 350 } // namespace mus |
OLD | NEW |