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