| 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 |