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

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: blimp 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
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),
215 last_put_offset_(-1), 216 last_put_offset_(-1),
216 gpu_memory_buffer_manager_(nullptr), 217 gpu_memory_buffer_manager_(nullptr),
217 next_fence_sync_release_(1), 218 next_fence_sync_release_(1),
218 flushed_fence_sync_release_(0), 219 flushed_fence_sync_release_(0),
219 flush_event_(false, false), 220 flush_event_(false, false),
220 service_(GetInitialService(service)), 221 service_(GetInitialService(service)),
221 fence_sync_wait_event_(false, false), 222 fence_sync_wait_event_(false, false),
223 client_thread_weak_ptr_factory_(this),
222 gpu_thread_weak_ptr_factory_(this) { 224 gpu_thread_weak_ptr_factory_(this) {
223 DCHECK(service_.get()); 225 DCHECK(service_.get());
224 next_image_id_.GetNext(); 226 next_image_id_.GetNext();
225 } 227 }
226 228
227 InProcessCommandBuffer::~InProcessCommandBuffer() { 229 InProcessCommandBuffer::~InProcessCommandBuffer() {
228 Destroy(); 230 Destroy();
229 } 231 }
230 232
231 bool InProcessCommandBuffer::MakeCurrent() { 233 bool InProcessCommandBuffer::MakeCurrent() {
232 CheckSequencedThread(); 234 CheckSequencedThread();
233 command_buffer_lock_.AssertAcquired(); 235 command_buffer_lock_.AssertAcquired();
234 236
235 if (error::IsError(command_buffer_->GetLastState().error)) { 237 if (error::IsError(command_buffer_->GetLastState().error)) {
236 DLOG(ERROR) << "MakeCurrent failed because context lost."; 238 DLOG(ERROR) << "MakeCurrent failed because context lost.";
237 return false; 239 return false;
238 } 240 }
239 if (!decoder_->MakeCurrent()) { 241 if (!decoder_->MakeCurrent()) {
240 DLOG(ERROR) << "Context lost because MakeCurrent failed."; 242 DLOG(ERROR) << "Context lost because MakeCurrent failed.";
241 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); 243 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
242 command_buffer_->SetParseError(gpu::error::kLostContext); 244 command_buffer_->SetParseError(gpu::error::kLostContext);
243 return false; 245 return false;
244 } 246 }
245 return true; 247 return true;
246 } 248 }
247 249
248 void InProcessCommandBuffer::PumpCommands() { 250 void InProcessCommandBuffer::PumpCommandsOnGpuThread() {
249 CheckSequencedThread(); 251 CheckSequencedThread();
250 command_buffer_lock_.AssertAcquired(); 252 command_buffer_lock_.AssertAcquired();
251 253
252 if (!MakeCurrent()) 254 if (!MakeCurrent())
253 return; 255 return;
254 256
255 executor_->PutChanged(); 257 executor_->PutChanged();
256 } 258 }
257 259
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( 260 bool InProcessCommandBuffer::Initialize(
266 scoped_refptr<gfx::GLSurface> surface, 261 scoped_refptr<gfx::GLSurface> surface,
267 bool is_offscreen, 262 bool is_offscreen,
268 gfx::AcceleratedWidget window, 263 gfx::AcceleratedWidget window,
269 const gfx::Size& size, 264 const gfx::Size& size,
270 const std::vector<int32_t>& attribs, 265 const std::vector<int32_t>& attribs,
271 gfx::GpuPreference gpu_preference, 266 gfx::GpuPreference gpu_preference,
272 const base::Closure& context_lost_callback,
273 InProcessCommandBuffer* share_group, 267 InProcessCommandBuffer* share_group,
274 GpuMemoryBufferManager* gpu_memory_buffer_manager, 268 GpuMemoryBufferManager* gpu_memory_buffer_manager,
275 ImageFactory* image_factory) { 269 ImageFactory* image_factory) {
276 DCHECK(!share_group || service_.get() == share_group->service_.get()); 270 DCHECK(!share_group || service_.get() == share_group->service_.get());
277 context_lost_callback_ = WrapCallback(context_lost_callback);
278 271
279 if (surface.get()) { 272 if (surface.get()) {
280 // GPU thread must be the same as client thread due to GLSurface not being 273 // GPU thread must be the same as client thread due to GLSurface not being
281 // thread safe. 274 // thread safe.
282 sequence_checker_.reset(new base::SequenceChecker); 275 sequence_checker_.reset(new base::SequenceChecker);
283 surface_ = surface; 276 surface_ = surface;
284 } 277 }
285 278
279 origin_task_runner_ = base::ThreadTaskRunnerHandle::Get();
280 client_thread_weak_ptr_ = client_thread_weak_ptr_factory_.GetWeakPtr();
281
286 gpu::Capabilities capabilities; 282 gpu::Capabilities capabilities;
287 InitializeOnGpuThreadParams params(is_offscreen, 283 InitializeOnGpuThreadParams params(is_offscreen,
288 window, 284 window,
289 size, 285 size,
290 attribs, 286 attribs,
291 gpu_preference, 287 gpu_preference,
292 &capabilities, 288 &capabilities,
293 share_group, 289 share_group,
294 image_factory); 290 image_factory);
295 291
(...skipping 25 matching lines...) Expand all
321 317
322 DCHECK(params.size.width() >= 0 && params.size.height() >= 0); 318 DCHECK(params.size.width() >= 0 && params.size.height() >= 0);
323 319
324 TransferBufferManager* manager = new TransferBufferManager(nullptr); 320 TransferBufferManager* manager = new TransferBufferManager(nullptr);
325 transfer_buffer_manager_ = manager; 321 transfer_buffer_manager_ = manager;
326 manager->Initialize(); 322 manager->Initialize();
327 323
328 scoped_ptr<CommandBufferService> command_buffer( 324 scoped_ptr<CommandBufferService> command_buffer(
329 new CommandBufferService(transfer_buffer_manager_.get())); 325 new CommandBufferService(transfer_buffer_manager_.get()));
330 command_buffer->SetPutOffsetChangeCallback(base::Bind( 326 command_buffer->SetPutOffsetChangeCallback(base::Bind(
331 &InProcessCommandBuffer::PumpCommands, gpu_thread_weak_ptr_)); 327 &InProcessCommandBuffer::PumpCommandsOnGpuThread, gpu_thread_weak_ptr_));
332 command_buffer->SetParseErrorCallback(base::Bind( 328 command_buffer->SetParseErrorCallback(base::Bind(
333 &InProcessCommandBuffer::OnContextLost, gpu_thread_weak_ptr_)); 329 &InProcessCommandBuffer::OnContextLostOnGpuThread, gpu_thread_weak_ptr_));
334 330
335 if (!command_buffer->Initialize()) { 331 if (!command_buffer->Initialize()) {
336 LOG(ERROR) << "Could not initialize command buffer."; 332 LOG(ERROR) << "Could not initialize command buffer.";
337 DestroyOnGpuThread(); 333 DestroyOnGpuThread();
338 return false; 334 return false;
339 } 335 }
340 336
341 gl_share_group_ = params.context_group 337 gl_share_group_ = params.context_group
342 ? params.context_group->gl_share_group_ 338 ? params.context_group->gl_share_group_
343 : service_->share_group(); 339 : service_->share_group();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 base::Bind(&InProcessCommandBuffer::WaitFenceSyncOnGpuThread, 444 base::Bind(&InProcessCommandBuffer::WaitFenceSyncOnGpuThread,
449 base::Unretained(this))); 445 base::Unretained(this)));
450 446
451 image_factory_ = params.image_factory; 447 image_factory_ = params.image_factory;
452 448
453 return true; 449 return true;
454 } 450 }
455 451
456 void InProcessCommandBuffer::Destroy() { 452 void InProcessCommandBuffer::Destroy() {
457 CheckSequencedThread(); 453 CheckSequencedThread();
458 454 client_thread_weak_ptr_factory_.InvalidateWeakPtrs();
459 base::WaitableEvent completion(true, false); 455 base::WaitableEvent completion(true, false);
460 bool result = false; 456 bool result = false;
461 base::Callback<bool(void)> destroy_task = base::Bind( 457 base::Callback<bool(void)> destroy_task = base::Bind(
462 &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this)); 458 &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this));
463 QueueTask( 459 QueueTask(
464 base::Bind(&RunTaskWithResult<bool>, destroy_task, &result, &completion)); 460 base::Bind(&RunTaskWithResult<bool>, destroy_task, &result, &completion));
465 completion.Wait(); 461 completion.Wait();
466 } 462 }
467 463
468 bool InProcessCommandBuffer::DestroyOnGpuThread() { 464 bool InProcessCommandBuffer::DestroyOnGpuThread() {
469 CheckSequencedThread(); 465 CheckSequencedThread();
470 gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs(); 466 gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs();
471 command_buffer_.reset(); 467 command_buffer_.reset();
472 // Clean up GL resources if possible. 468 // Clean up GL resources if possible.
473 bool have_context = context_.get() && context_->MakeCurrent(surface_.get()); 469 bool have_context = context_.get() && context_->MakeCurrent(surface_.get());
474 if (decoder_) { 470 if (decoder_) {
475 decoder_->Destroy(have_context); 471 decoder_->Destroy(have_context);
476 decoder_.reset(); 472 decoder_.reset();
477 } 473 }
478 context_ = NULL; 474 context_ = nullptr;
479 surface_ = NULL; 475 surface_ = nullptr;
480 sync_point_client_ = NULL; 476 sync_point_client_ = nullptr;
481 if (sync_point_order_data_) { 477 if (sync_point_order_data_) {
482 sync_point_order_data_->Destroy(); 478 sync_point_order_data_->Destroy();
483 sync_point_order_data_ = nullptr; 479 sync_point_order_data_ = nullptr;
484 } 480 }
485 gl_share_group_ = NULL; 481 gl_share_group_ = nullptr;
486 #if defined(OS_ANDROID) 482 #if defined(OS_ANDROID)
487 stream_texture_manager_.reset(); 483 stream_texture_manager_.reset();
488 #endif 484 #endif
489 485
490 return true; 486 return true;
491 } 487 }
492 488
493 void InProcessCommandBuffer::CheckSequencedThread() { 489 void InProcessCommandBuffer::CheckSequencedThread() {
494 DCHECK(!sequence_checker_ || 490 DCHECK(!sequence_checker_ ||
495 sequence_checker_->CalledOnValidSequencedThread()); 491 sequence_checker_->CalledOnValidSequencedThread());
496 } 492 }
497 493
494 void InProcessCommandBuffer::OnContextLostOnGpuThread() {
495 if (!origin_task_runner_ || origin_task_runner_->BelongsToCurrentThread())
496 return OnContextLost();
497 origin_task_runner_->PostTask(
498 FROM_HERE, base::Bind(&InProcessCommandBuffer::OnContextLost,
499 client_thread_weak_ptr_));
500 }
501
498 void InProcessCommandBuffer::OnContextLost() { 502 void InProcessCommandBuffer::OnContextLost() {
499 CheckSequencedThread(); 503 CheckSequencedThread();
500 if (!context_lost_callback_.is_null()) { 504 DCHECK(gpu_control_client_);
501 context_lost_callback_.Run(); 505 gpu_control_client_->OnGpuControlLostContext();
502 context_lost_callback_.Reset(); 506 context_lost_ = true;
503 }
504 } 507 }
505 508
506 CommandBuffer::State InProcessCommandBuffer::GetStateFast() { 509 CommandBuffer::State InProcessCommandBuffer::GetStateFast() {
507 CheckSequencedThread(); 510 CheckSequencedThread();
508 base::AutoLock lock(state_after_last_flush_lock_); 511 base::AutoLock lock(state_after_last_flush_lock_);
509 if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U) 512 if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U)
510 last_state_ = state_after_last_flush_; 513 last_state_ = state_after_last_flush_;
511 return last_state_; 514 return last_state_;
512 } 515 }
513 516
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 550 }
548 551
549 // If we've processed all pending commands but still have pending queries, 552 // If we've processed all pending commands but still have pending queries,
550 // pump idle work until the query is passed. 553 // pump idle work until the query is passed.
551 if (put_offset == state_after_last_flush_.get_offset && 554 if (put_offset == state_after_last_flush_.get_offset &&
552 (executor_->HasMoreIdleWork() || executor_->HasPendingQueries())) { 555 (executor_->HasMoreIdleWork() || executor_->HasPendingQueries())) {
553 ScheduleDelayedWorkOnGpuThread(); 556 ScheduleDelayedWorkOnGpuThread();
554 } 557 }
555 } 558 }
556 559
557 void InProcessCommandBuffer::PerformDelayedWork() { 560 void InProcessCommandBuffer::PerformDelayedWorkOnGpuThread() {
558 CheckSequencedThread(); 561 CheckSequencedThread();
559 delayed_work_pending_ = false; 562 delayed_work_pending_ = false;
560 base::AutoLock lock(command_buffer_lock_); 563 base::AutoLock lock(command_buffer_lock_);
561 if (MakeCurrent()) { 564 if (MakeCurrent()) {
562 executor_->PerformIdleWork(); 565 executor_->PerformIdleWork();
563 executor_->ProcessPendingQueries(); 566 executor_->ProcessPendingQueries();
564 if (executor_->HasMoreIdleWork() || executor_->HasPendingQueries()) { 567 if (executor_->HasMoreIdleWork() || executor_->HasPendingQueries()) {
565 ScheduleDelayedWorkOnGpuThread(); 568 ScheduleDelayedWorkOnGpuThread();
566 } 569 }
567 } 570 }
568 } 571 }
569 572
570 void InProcessCommandBuffer::ScheduleDelayedWorkOnGpuThread() { 573 void InProcessCommandBuffer::ScheduleDelayedWorkOnGpuThread() {
571 CheckSequencedThread(); 574 CheckSequencedThread();
572 if (delayed_work_pending_) 575 if (delayed_work_pending_)
573 return; 576 return;
574 delayed_work_pending_ = true; 577 delayed_work_pending_ = true;
575 service_->ScheduleDelayedWork(base::Bind( 578 service_->ScheduleDelayedWork(
576 &InProcessCommandBuffer::PerformDelayedWork, gpu_thread_weak_ptr_)); 579 base::Bind(&InProcessCommandBuffer::PerformDelayedWorkOnGpuThread,
580 gpu_thread_weak_ptr_));
577 } 581 }
578 582
579 void InProcessCommandBuffer::Flush(int32_t put_offset) { 583 void InProcessCommandBuffer::Flush(int32_t put_offset) {
580 CheckSequencedThread(); 584 CheckSequencedThread();
581 if (last_state_.error != gpu::error::kNoError) 585 if (last_state_.error != gpu::error::kNoError)
582 return; 586 return;
583 587
584 if (last_put_offset_ == put_offset) 588 if (last_put_offset_ == put_offset)
585 return; 589 return;
586 590
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 id); 667 id);
664 668
665 QueueTask(task); 669 QueueTask(task);
666 } 670 }
667 671
668 void InProcessCommandBuffer::DestroyTransferBufferOnGpuThread(int32_t id) { 672 void InProcessCommandBuffer::DestroyTransferBufferOnGpuThread(int32_t id) {
669 base::AutoLock lock(command_buffer_lock_); 673 base::AutoLock lock(command_buffer_lock_);
670 command_buffer_->DestroyTransferBuffer(id); 674 command_buffer_->DestroyTransferBuffer(id);
671 } 675 }
672 676
677 void InProcessCommandBuffer::SetGpuControlClient(GpuControlClient* client) {
678 gpu_control_client_ = client;
679 }
680
673 gpu::Capabilities InProcessCommandBuffer::GetCapabilities() { 681 gpu::Capabilities InProcessCommandBuffer::GetCapabilities() {
674 return capabilities_; 682 return capabilities_;
675 } 683 }
676 684
677 int32_t InProcessCommandBuffer::CreateImage(ClientBuffer buffer, 685 int32_t InProcessCommandBuffer::CreateImage(ClientBuffer buffer,
678 size_t width, 686 size_t width,
679 size_t height, 687 size_t height,
680 unsigned internalformat) { 688 unsigned internalformat) {
681 CheckSequencedThread(); 689 CheckSequencedThread();
682 690
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 framebuffer_completeness_cache_ = 1103 framebuffer_completeness_cache_ =
1096 new gpu::gles2::FramebufferCompletenessCache; 1104 new gpu::gles2::FramebufferCompletenessCache;
1097 return framebuffer_completeness_cache_; 1105 return framebuffer_completeness_cache_;
1098 } 1106 }
1099 1107
1100 SyncPointManager* GpuInProcessThread::sync_point_manager() { 1108 SyncPointManager* GpuInProcessThread::sync_point_manager() {
1101 return sync_point_manager_; 1109 return sync_point_manager_;
1102 } 1110 }
1103 1111
1104 } // namespace gpu 1112 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698