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

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

Issue 1864723003: Make lost context and error message callbacks on GpuControl go to client (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: errorcallback: nitmissed Created 4 years, 8 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/in_process_command_buffer.h" 5 #include "gpu/command_buffer/service/in_process_command_buffer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <queue> 10 #include <queue>
11 #include <set> 11 #include <set>
12 #include <utility> 12 #include <utility>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/bind_helpers.h" 15 #include "base/bind_helpers.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/location.h" 18 #include "base/location.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/memory/weak_ptr.h" 20 #include "base/memory/weak_ptr.h"
21 #include "base/numerics/safe_conversions.h" 21 #include "base/numerics/safe_conversions.h"
22 #include "base/sequence_checker.h" 22 #include "base/sequence_checker.h"
23 #include "base/single_thread_task_runner.h" 23 #include "base/single_thread_task_runner.h"
24 #include "base/thread_task_runner_handle.h" 24 #include "base/thread_task_runner_handle.h"
25 #include "gpu/command_buffer/client/gpu_control_client.h"
25 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" 26 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
26 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" 27 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
27 #include "gpu/command_buffer/common/sync_token.h" 28 #include "gpu/command_buffer/common/sync_token.h"
28 #include "gpu/command_buffer/common/value_state.h" 29 #include "gpu/command_buffer/common/value_state.h"
29 #include "gpu/command_buffer/service/command_buffer_service.h" 30 #include "gpu/command_buffer/service/command_buffer_service.h"
30 #include "gpu/command_buffer/service/command_executor.h" 31 #include "gpu/command_buffer/service/command_executor.h"
31 #include "gpu/command_buffer/service/context_group.h" 32 #include "gpu/command_buffer/service/context_group.h"
32 #include "gpu/command_buffer/service/gl_context_virtual.h" 33 #include "gpu/command_buffer/service/gl_context_virtual.h"
33 #include "gpu/command_buffer/service/gpu_preferences.h" 34 #include "gpu/command_buffer/service/gpu_preferences.h"
34 #include "gpu/command_buffer/service/image_factory.h" 35 #include "gpu/command_buffer/service/image_factory.h"
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 206 }
206 return program_cache_.get(); 207 return program_cache_.get();
207 } 208 }
208 209
209 InProcessCommandBuffer::InProcessCommandBuffer( 210 InProcessCommandBuffer::InProcessCommandBuffer(
210 const scoped_refptr<Service>& service) 211 const scoped_refptr<Service>& service)
211 : command_buffer_id_( 212 : command_buffer_id_(
212 CommandBufferId::FromUnsafeValue(g_next_command_buffer_id.GetNext())), 213 CommandBufferId::FromUnsafeValue(g_next_command_buffer_id.GetNext())),
213 delayed_work_pending_(false), 214 delayed_work_pending_(false),
214 image_factory_(nullptr), 215 image_factory_(nullptr),
216 gpu_control_client_(nullptr),
217 #if DCHECK_IS_ON()
218 context_lost_(false),
219 #endif
215 last_put_offset_(-1), 220 last_put_offset_(-1),
216 gpu_memory_buffer_manager_(nullptr), 221 gpu_memory_buffer_manager_(nullptr),
217 next_fence_sync_release_(1), 222 next_fence_sync_release_(1),
218 flushed_fence_sync_release_(0), 223 flushed_fence_sync_release_(0),
219 flush_event_(false, false), 224 flush_event_(false, false),
220 service_(GetInitialService(service)), 225 service_(GetInitialService(service)),
221 fence_sync_wait_event_(false, false), 226 fence_sync_wait_event_(false, false),
227 client_thread_weak_ptr_factory_(this),
222 gpu_thread_weak_ptr_factory_(this) { 228 gpu_thread_weak_ptr_factory_(this) {
223 DCHECK(service_.get()); 229 DCHECK(service_.get());
224 next_image_id_.GetNext(); 230 next_image_id_.GetNext();
225 } 231 }
226 232
227 InProcessCommandBuffer::~InProcessCommandBuffer() { 233 InProcessCommandBuffer::~InProcessCommandBuffer() {
228 Destroy(); 234 Destroy();
229 } 235 }
230 236
231 bool InProcessCommandBuffer::MakeCurrent() { 237 bool InProcessCommandBuffer::MakeCurrent() {
232 CheckSequencedThread(); 238 CheckSequencedThread();
233 command_buffer_lock_.AssertAcquired(); 239 command_buffer_lock_.AssertAcquired();
234 240
235 if (error::IsError(command_buffer_->GetLastState().error)) { 241 if (error::IsError(command_buffer_->GetLastState().error)) {
236 DLOG(ERROR) << "MakeCurrent failed because context lost."; 242 DLOG(ERROR) << "MakeCurrent failed because context lost.";
237 return false; 243 return false;
238 } 244 }
239 if (!decoder_->MakeCurrent()) { 245 if (!decoder_->MakeCurrent()) {
240 DLOG(ERROR) << "Context lost because MakeCurrent failed."; 246 DLOG(ERROR) << "Context lost because MakeCurrent failed.";
241 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); 247 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
242 command_buffer_->SetParseError(gpu::error::kLostContext); 248 command_buffer_->SetParseError(gpu::error::kLostContext);
243 return false; 249 return false;
244 } 250 }
245 return true; 251 return true;
246 } 252 }
247 253
248 void InProcessCommandBuffer::PumpCommands() { 254 void InProcessCommandBuffer::PumpCommandsOnGpuThread() {
249 CheckSequencedThread(); 255 CheckSequencedThread();
250 command_buffer_lock_.AssertAcquired(); 256 command_buffer_lock_.AssertAcquired();
251 257
252 if (!MakeCurrent()) 258 if (!MakeCurrent())
253 return; 259 return;
254 260
255 executor_->PutChanged(); 261 executor_->PutChanged();
256 } 262 }
257 263
258 bool InProcessCommandBuffer::GetBufferChanged(int32_t transfer_buffer_id) {
259 CheckSequencedThread();
260 command_buffer_lock_.AssertAcquired();
261 command_buffer_->SetGetBuffer(transfer_buffer_id);
262 return true;
263 }
264
265 bool InProcessCommandBuffer::Initialize( 264 bool InProcessCommandBuffer::Initialize(
266 scoped_refptr<gfx::GLSurface> surface, 265 scoped_refptr<gfx::GLSurface> surface,
267 bool is_offscreen, 266 bool is_offscreen,
268 gfx::AcceleratedWidget window, 267 gfx::AcceleratedWidget window,
269 const gfx::Size& size, 268 const gfx::Size& size,
270 const std::vector<int32_t>& attribs, 269 const std::vector<int32_t>& attribs,
271 gfx::GpuPreference gpu_preference, 270 gfx::GpuPreference gpu_preference,
272 const base::Closure& context_lost_callback,
273 InProcessCommandBuffer* share_group, 271 InProcessCommandBuffer* share_group,
274 GpuMemoryBufferManager* gpu_memory_buffer_manager, 272 GpuMemoryBufferManager* gpu_memory_buffer_manager,
275 ImageFactory* image_factory) { 273 ImageFactory* image_factory) {
276 DCHECK(!share_group || service_.get() == share_group->service_.get()); 274 DCHECK(!share_group || service_.get() == share_group->service_.get());
277 context_lost_callback_ = WrapCallback(context_lost_callback);
278 275
279 if (surface.get()) { 276 if (surface) {
280 // GPU thread must be the same as client thread due to GLSurface not being 277 // GPU thread must be the same as client thread due to GLSurface not being
281 // thread safe. 278 // thread safe.
282 sequence_checker_.reset(new base::SequenceChecker); 279 sequence_checker_.reset(new base::SequenceChecker);
283 surface_ = surface; 280 surface_ = surface;
281 } else {
282 origin_task_runner_ = base::ThreadTaskRunnerHandle::Get();
283 client_thread_weak_ptr_ = client_thread_weak_ptr_factory_.GetWeakPtr();
284 } 284 }
285 285
286 gpu::Capabilities capabilities; 286 gpu::Capabilities capabilities;
287 InitializeOnGpuThreadParams params(is_offscreen, 287 InitializeOnGpuThreadParams params(is_offscreen,
288 window, 288 window,
289 size, 289 size,
290 attribs, 290 attribs,
291 gpu_preference, 291 gpu_preference,
292 &capabilities, 292 &capabilities,
293 share_group, 293 share_group,
(...skipping 27 matching lines...) Expand all
321 321
322 DCHECK(params.size.width() >= 0 && params.size.height() >= 0); 322 DCHECK(params.size.width() >= 0 && params.size.height() >= 0);
323 323
324 TransferBufferManager* manager = new TransferBufferManager(nullptr); 324 TransferBufferManager* manager = new TransferBufferManager(nullptr);
325 transfer_buffer_manager_ = manager; 325 transfer_buffer_manager_ = manager;
326 manager->Initialize(); 326 manager->Initialize();
327 327
328 scoped_ptr<CommandBufferService> command_buffer( 328 scoped_ptr<CommandBufferService> command_buffer(
329 new CommandBufferService(transfer_buffer_manager_.get())); 329 new CommandBufferService(transfer_buffer_manager_.get()));
330 command_buffer->SetPutOffsetChangeCallback(base::Bind( 330 command_buffer->SetPutOffsetChangeCallback(base::Bind(
331 &InProcessCommandBuffer::PumpCommands, gpu_thread_weak_ptr_)); 331 &InProcessCommandBuffer::PumpCommandsOnGpuThread, gpu_thread_weak_ptr_));
332 command_buffer->SetParseErrorCallback(base::Bind( 332 command_buffer->SetParseErrorCallback(base::Bind(
333 &InProcessCommandBuffer::OnContextLost, gpu_thread_weak_ptr_)); 333 &InProcessCommandBuffer::OnContextLostOnGpuThread, gpu_thread_weak_ptr_));
334 334
335 if (!command_buffer->Initialize()) { 335 if (!command_buffer->Initialize()) {
336 LOG(ERROR) << "Could not initialize command buffer."; 336 LOG(ERROR) << "Could not initialize command buffer.";
337 DestroyOnGpuThread(); 337 DestroyOnGpuThread();
338 return false; 338 return false;
339 } 339 }
340 340
341 gl_share_group_ = params.context_group 341 gl_share_group_ = params.context_group
342 ? params.context_group->gl_share_group_ 342 ? params.context_group->gl_share_group_
343 : service_->share_group(); 343 : service_->share_group();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 base::Bind(&InProcessCommandBuffer::WaitFenceSyncOnGpuThread, 448 base::Bind(&InProcessCommandBuffer::WaitFenceSyncOnGpuThread,
449 base::Unretained(this))); 449 base::Unretained(this)));
450 450
451 image_factory_ = params.image_factory; 451 image_factory_ = params.image_factory;
452 452
453 return true; 453 return true;
454 } 454 }
455 455
456 void InProcessCommandBuffer::Destroy() { 456 void InProcessCommandBuffer::Destroy() {
457 CheckSequencedThread(); 457 CheckSequencedThread();
458 458 client_thread_weak_ptr_factory_.InvalidateWeakPtrs();
459 gpu_control_client_ = nullptr;
459 base::WaitableEvent completion(true, false); 460 base::WaitableEvent completion(true, false);
460 bool result = false; 461 bool result = false;
461 base::Callback<bool(void)> destroy_task = base::Bind( 462 base::Callback<bool(void)> destroy_task = base::Bind(
462 &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this)); 463 &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this));
463 QueueTask( 464 QueueTask(
464 base::Bind(&RunTaskWithResult<bool>, destroy_task, &result, &completion)); 465 base::Bind(&RunTaskWithResult<bool>, destroy_task, &result, &completion));
465 completion.Wait(); 466 completion.Wait();
466 } 467 }
467 468
468 bool InProcessCommandBuffer::DestroyOnGpuThread() { 469 bool InProcessCommandBuffer::DestroyOnGpuThread() {
469 CheckSequencedThread(); 470 CheckSequencedThread();
470 gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs(); 471 gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs();
471 command_buffer_.reset(); 472 command_buffer_.reset();
472 // Clean up GL resources if possible. 473 // Clean up GL resources if possible.
473 bool have_context = context_.get() && context_->MakeCurrent(surface_.get()); 474 bool have_context = context_.get() && context_->MakeCurrent(surface_.get());
474 if (decoder_) { 475 if (decoder_) {
475 decoder_->Destroy(have_context); 476 decoder_->Destroy(have_context);
476 decoder_.reset(); 477 decoder_.reset();
477 } 478 }
478 context_ = NULL; 479 context_ = nullptr;
479 surface_ = NULL; 480 surface_ = nullptr;
480 sync_point_client_ = NULL; 481 sync_point_client_ = nullptr;
481 if (sync_point_order_data_) { 482 if (sync_point_order_data_) {
482 sync_point_order_data_->Destroy(); 483 sync_point_order_data_->Destroy();
483 sync_point_order_data_ = nullptr; 484 sync_point_order_data_ = nullptr;
484 } 485 }
485 gl_share_group_ = NULL; 486 gl_share_group_ = nullptr;
486 #if defined(OS_ANDROID) 487 #if defined(OS_ANDROID)
487 stream_texture_manager_.reset(); 488 stream_texture_manager_.reset();
488 #endif 489 #endif
489 490
490 return true; 491 return true;
491 } 492 }
492 493
493 void InProcessCommandBuffer::CheckSequencedThread() { 494 void InProcessCommandBuffer::CheckSequencedThread() {
494 DCHECK(!sequence_checker_ || 495 DCHECK(!sequence_checker_ ||
495 sequence_checker_->CalledOnValidSequencedThread()); 496 sequence_checker_->CalledOnValidSequencedThread());
496 } 497 }
497 498
499 void InProcessCommandBuffer::OnContextLostOnGpuThread() {
500 if (!origin_task_runner_)
501 return OnContextLost(); // Just kidding, we're on the client thread.
502 origin_task_runner_->PostTask(
503 FROM_HERE, base::Bind(&InProcessCommandBuffer::OnContextLost,
504 client_thread_weak_ptr_));
505 }
506
498 void InProcessCommandBuffer::OnContextLost() { 507 void InProcessCommandBuffer::OnContextLost() {
499 CheckSequencedThread(); 508 CheckSequencedThread();
500 if (!context_lost_callback_.is_null()) { 509
501 context_lost_callback_.Run(); 510 #if DCHECK_IS_ON()
502 context_lost_callback_.Reset(); 511 // This method shouldn't be called more than once.
503 } 512 DCHECK(!context_lost_);
513 context_lost_ = true;
514 #endif
515
516 if (gpu_control_client_)
517 gpu_control_client_->OnGpuControlLostContext();
504 } 518 }
505 519
506 CommandBuffer::State InProcessCommandBuffer::GetStateFast() { 520 CommandBuffer::State InProcessCommandBuffer::GetStateFast() {
507 CheckSequencedThread(); 521 CheckSequencedThread();
508 base::AutoLock lock(state_after_last_flush_lock_); 522 base::AutoLock lock(state_after_last_flush_lock_);
509 if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U) 523 if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U)
510 last_state_ = state_after_last_flush_; 524 last_state_ = state_after_last_flush_;
511 return last_state_; 525 return last_state_;
512 } 526 }
513 527
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 561 }
548 562
549 // If we've processed all pending commands but still have pending queries, 563 // If we've processed all pending commands but still have pending queries,
550 // pump idle work until the query is passed. 564 // pump idle work until the query is passed.
551 if (put_offset == state_after_last_flush_.get_offset && 565 if (put_offset == state_after_last_flush_.get_offset &&
552 (executor_->HasMoreIdleWork() || executor_->HasPendingQueries())) { 566 (executor_->HasMoreIdleWork() || executor_->HasPendingQueries())) {
553 ScheduleDelayedWorkOnGpuThread(); 567 ScheduleDelayedWorkOnGpuThread();
554 } 568 }
555 } 569 }
556 570
557 void InProcessCommandBuffer::PerformDelayedWork() { 571 void InProcessCommandBuffer::PerformDelayedWorkOnGpuThread() {
558 CheckSequencedThread(); 572 CheckSequencedThread();
559 delayed_work_pending_ = false; 573 delayed_work_pending_ = false;
560 base::AutoLock lock(command_buffer_lock_); 574 base::AutoLock lock(command_buffer_lock_);
561 if (MakeCurrent()) { 575 if (MakeCurrent()) {
562 executor_->PerformIdleWork(); 576 executor_->PerformIdleWork();
563 executor_->ProcessPendingQueries(); 577 executor_->ProcessPendingQueries();
564 if (executor_->HasMoreIdleWork() || executor_->HasPendingQueries()) { 578 if (executor_->HasMoreIdleWork() || executor_->HasPendingQueries()) {
565 ScheduleDelayedWorkOnGpuThread(); 579 ScheduleDelayedWorkOnGpuThread();
566 } 580 }
567 } 581 }
568 } 582 }
569 583
570 void InProcessCommandBuffer::ScheduleDelayedWorkOnGpuThread() { 584 void InProcessCommandBuffer::ScheduleDelayedWorkOnGpuThread() {
571 CheckSequencedThread(); 585 CheckSequencedThread();
572 if (delayed_work_pending_) 586 if (delayed_work_pending_)
573 return; 587 return;
574 delayed_work_pending_ = true; 588 delayed_work_pending_ = true;
575 service_->ScheduleDelayedWork(base::Bind( 589 service_->ScheduleDelayedWork(
576 &InProcessCommandBuffer::PerformDelayedWork, gpu_thread_weak_ptr_)); 590 base::Bind(&InProcessCommandBuffer::PerformDelayedWorkOnGpuThread,
591 gpu_thread_weak_ptr_));
577 } 592 }
578 593
579 void InProcessCommandBuffer::Flush(int32_t put_offset) { 594 void InProcessCommandBuffer::Flush(int32_t put_offset) {
580 CheckSequencedThread(); 595 CheckSequencedThread();
581 if (last_state_.error != gpu::error::kNoError) 596 if (last_state_.error != gpu::error::kNoError)
582 return; 597 return;
583 598
584 if (last_put_offset_ == put_offset) 599 if (last_put_offset_ == put_offset)
585 return; 600 return;
586 601
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 id); 678 id);
664 679
665 QueueTask(task); 680 QueueTask(task);
666 } 681 }
667 682
668 void InProcessCommandBuffer::DestroyTransferBufferOnGpuThread(int32_t id) { 683 void InProcessCommandBuffer::DestroyTransferBufferOnGpuThread(int32_t id) {
669 base::AutoLock lock(command_buffer_lock_); 684 base::AutoLock lock(command_buffer_lock_);
670 command_buffer_->DestroyTransferBuffer(id); 685 command_buffer_->DestroyTransferBuffer(id);
671 } 686 }
672 687
688 void InProcessCommandBuffer::SetGpuControlClient(GpuControlClient* client) {
689 gpu_control_client_ = client;
690 }
691
673 gpu::Capabilities InProcessCommandBuffer::GetCapabilities() { 692 gpu::Capabilities InProcessCommandBuffer::GetCapabilities() {
674 return capabilities_; 693 return capabilities_;
675 } 694 }
676 695
677 int32_t InProcessCommandBuffer::CreateImage(ClientBuffer buffer, 696 int32_t InProcessCommandBuffer::CreateImage(ClientBuffer buffer,
678 size_t width, 697 size_t width,
679 size_t height, 698 size_t height,
680 unsigned internalformat) { 699 unsigned internalformat) {
681 CheckSequencedThread(); 700 CheckSequencedThread();
682 701
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 framebuffer_completeness_cache_ = 1114 framebuffer_completeness_cache_ =
1096 new gpu::gles2::FramebufferCompletenessCache; 1115 new gpu::gles2::FramebufferCompletenessCache;
1097 return framebuffer_completeness_cache_; 1116 return framebuffer_completeness_cache_;
1098 } 1117 }
1099 1118
1100 SyncPointManager* GpuInProcessThread::sync_point_manager() { 1119 SyncPointManager* GpuInProcessThread::sync_point_manager() {
1101 return sync_point_manager_; 1120 return sync_point_manager_;
1102 } 1121 }
1103 1122
1104 } // namespace gpu 1123 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/in_process_command_buffer.h ('k') | gpu/command_buffer/tests/gl_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698