| OLD | NEW |
| 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 <queue> | 7 #include <queue> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 base::StaticAtomicSequenceNumber g_next_command_buffer_id; | 58 base::StaticAtomicSequenceNumber g_next_command_buffer_id; |
| 59 | 59 |
| 60 template <typename T> | 60 template <typename T> |
| 61 static void RunTaskWithResult(base::Callback<T(void)> task, | 61 static void RunTaskWithResult(base::Callback<T(void)> task, |
| 62 T* result, | 62 T* result, |
| 63 base::WaitableEvent* completion) { | 63 base::WaitableEvent* completion) { |
| 64 *result = task.Run(); | 64 *result = task.Run(); |
| 65 completion->Signal(); | 65 completion->Signal(); |
| 66 } | 66 } |
| 67 | 67 |
| 68 struct ScopedOrderNumberProcessor { | |
| 69 ScopedOrderNumberProcessor(SyncPointOrderData* order_data, uint32_t order_num) | |
| 70 : order_data_(order_data), order_num_(order_num) { | |
| 71 order_data_->BeginProcessingOrderNumber(order_num_); | |
| 72 } | |
| 73 | |
| 74 ~ScopedOrderNumberProcessor() { | |
| 75 order_data_->FinishProcessingOrderNumber(order_num_); | |
| 76 } | |
| 77 | |
| 78 private: | |
| 79 SyncPointOrderData* order_data_; | |
| 80 uint32_t order_num_; | |
| 81 }; | |
| 82 | |
| 83 struct GpuInProcessThreadHolder { | 68 struct GpuInProcessThreadHolder { |
| 84 GpuInProcessThreadHolder() | 69 GpuInProcessThreadHolder() |
| 85 : sync_point_manager(new SyncPointManager(false)), | 70 : sync_point_manager(new SyncPointManager(false)), |
| 86 gpu_thread(new GpuInProcessThread(sync_point_manager.get())) {} | 71 gpu_thread(new GpuInProcessThread(sync_point_manager.get())) {} |
| 87 scoped_ptr<SyncPointManager> sync_point_manager; | 72 scoped_ptr<SyncPointManager> sync_point_manager; |
| 88 scoped_refptr<InProcessCommandBuffer::Service> gpu_thread; | 73 scoped_refptr<InProcessCommandBuffer::Service> gpu_thread; |
| 89 }; | 74 }; |
| 90 | 75 |
| 91 base::LazyInstance<GpuInProcessThreadHolder> g_default_service = | 76 base::LazyInstance<GpuInProcessThreadHolder> g_default_service = |
| 92 LAZY_INSTANCE_INITIALIZER; | 77 LAZY_INSTANCE_INITIALIZER; |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 GetStateFast(); | 490 GetStateFast(); |
| 506 return last_state_.token; | 491 return last_state_.token; |
| 507 } | 492 } |
| 508 | 493 |
| 509 void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset, | 494 void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset, |
| 510 uint32_t order_num) { | 495 uint32_t order_num) { |
| 511 CheckSequencedThread(); | 496 CheckSequencedThread(); |
| 512 ScopedEvent handle_flush(&flush_event_); | 497 ScopedEvent handle_flush(&flush_event_); |
| 513 base::AutoLock lock(command_buffer_lock_); | 498 base::AutoLock lock(command_buffer_lock_); |
| 514 | 499 |
| 500 sync_point_order_data_->BeginProcessingOrderNumber(order_num); |
| 501 command_buffer_->Flush(put_offset); |
| 515 { | 502 { |
| 516 ScopedOrderNumberProcessor scoped_order_num(sync_point_order_data_.get(), | 503 // Update state before signaling the flush event. |
| 517 order_num); | 504 base::AutoLock lock(state_after_last_flush_lock_); |
| 518 command_buffer_->Flush(put_offset); | 505 state_after_last_flush_ = command_buffer_->GetLastState(); |
| 519 { | 506 } |
| 520 // Update state before signaling the flush event. | 507 DCHECK((!error::IsError(state_after_last_flush_.error) && !context_lost_) || |
| 521 base::AutoLock lock(state_after_last_flush_lock_); | 508 (error::IsError(state_after_last_flush_.error) && context_lost_)); |
| 522 state_after_last_flush_ = command_buffer_->GetLastState(); | |
| 523 } | |
| 524 DCHECK((!error::IsError(state_after_last_flush_.error) && !context_lost_) || | |
| 525 (error::IsError(state_after_last_flush_.error) && context_lost_)); | |
| 526 | 509 |
| 527 // Currently the in process command buffer does not support being | 510 // Currently the in process command buffer does not support being descheduled, |
| 528 // descheduled, if it does we would need to back off on calling the finish | 511 // if it does we would need to back off on calling the finish processing |
| 529 // processing number function until the message is rescheduled and finished | 512 // order number function until the message is rescheduled and finished |
| 530 // processing. This DCHECK is to enforce this. | 513 // processing. This DCHECK is to enforce this. |
| 531 DCHECK(context_lost_ || put_offset == state_after_last_flush_.get_offset); | 514 DCHECK(context_lost_ || put_offset == state_after_last_flush_.get_offset); |
| 532 } | 515 sync_point_order_data_->FinishProcessingOrderNumber(order_num); |
| 533 | 516 |
| 534 // If we've processed all pending commands but still have pending queries, | 517 // If we've processed all pending commands but still have pending queries, |
| 535 // pump idle work until the query is passed. | 518 // pump idle work until the query is passed. |
| 536 if (put_offset == state_after_last_flush_.get_offset && | 519 if (put_offset == state_after_last_flush_.get_offset && |
| 537 (gpu_scheduler_->HasMoreIdleWork() || | 520 (gpu_scheduler_->HasMoreIdleWork() || |
| 538 gpu_scheduler_->HasPendingQueries())) { | 521 gpu_scheduler_->HasPendingQueries())) { |
| 539 ScheduleDelayedWorkOnGpuThread(); | 522 ScheduleDelayedWorkOnGpuThread(); |
| 540 } | 523 } |
| 541 } | 524 } |
| 542 | 525 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 internalformat, gpu_memory_buffer->GetFormat())); | 661 internalformat, gpu_memory_buffer->GetFormat())); |
| 679 | 662 |
| 680 // This handle is owned by the GPU thread and must be passed to it or it | 663 // This handle is owned by the GPU thread and must be passed to it or it |
| 681 // will leak. In otherwords, do not early out on error between here and the | 664 // will leak. In otherwords, do not early out on error between here and the |
| 682 // queuing of the CreateImage task below. | 665 // queuing of the CreateImage task below. |
| 683 bool requires_sync_point = false; | 666 bool requires_sync_point = false; |
| 684 gfx::GpuMemoryBufferHandle handle = | 667 gfx::GpuMemoryBufferHandle handle = |
| 685 ShareGpuMemoryBufferToGpuThread(gpu_memory_buffer->GetHandle(), | 668 ShareGpuMemoryBufferToGpuThread(gpu_memory_buffer->GetHandle(), |
| 686 &requires_sync_point); | 669 &requires_sync_point); |
| 687 | 670 |
| 688 SyncPointManager* sync_manager = service_->sync_point_manager(); | 671 QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread, |
| 689 const uint32_t order_num = | 672 base::Unretained(this), |
| 690 sync_point_order_data_->GenerateUnprocessedOrderNumber(sync_manager); | 673 new_id, |
| 674 handle, |
| 675 gfx::Size(width, height), |
| 676 gpu_memory_buffer->GetFormat(), |
| 677 internalformat)); |
| 691 | 678 |
| 692 uint64_t fence_sync = 0; | |
| 693 if (requires_sync_point) { | 679 if (requires_sync_point) { |
| 694 fence_sync = GenerateFenceSyncRelease(); | 680 gpu_memory_buffer_manager_->SetDestructionSyncPoint(gpu_memory_buffer, |
| 695 | 681 InsertSyncPoint()); |
| 696 // Previous fence syncs should be flushed already. | |
| 697 DCHECK_EQ(fence_sync - 1, flushed_fence_sync_release_); | |
| 698 } | |
| 699 | |
| 700 QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread, | |
| 701 base::Unretained(this), new_id, handle, | |
| 702 gfx::Size(width, height), gpu_memory_buffer->GetFormat(), | |
| 703 internalformat, order_num, fence_sync)); | |
| 704 | |
| 705 if (fence_sync) { | |
| 706 flushed_fence_sync_release_ = fence_sync; | |
| 707 SyncToken sync_token(GetNamespaceID(), GetCommandBufferID(), fence_sync); | |
| 708 sync_token.SetVerifyFlush(); | |
| 709 gpu_memory_buffer_manager_->SetDestructionSyncToken(gpu_memory_buffer, | |
| 710 sync_token); | |
| 711 } | 682 } |
| 712 | 683 |
| 713 return new_id; | 684 return new_id; |
| 714 } | 685 } |
| 715 | 686 |
| 716 void InProcessCommandBuffer::CreateImageOnGpuThread( | 687 void InProcessCommandBuffer::CreateImageOnGpuThread( |
| 717 int32 id, | 688 int32 id, |
| 718 const gfx::GpuMemoryBufferHandle& handle, | 689 const gfx::GpuMemoryBufferHandle& handle, |
| 719 const gfx::Size& size, | 690 const gfx::Size& size, |
| 720 gfx::BufferFormat format, | 691 gfx::BufferFormat format, |
| 721 uint32 internalformat, | 692 uint32 internalformat) { |
| 722 uint32_t order_num, | |
| 723 uint64_t fence_sync) { | |
| 724 ScopedOrderNumberProcessor scoped_order_num(sync_point_order_data_.get(), | |
| 725 order_num); | |
| 726 if (!decoder_) | 693 if (!decoder_) |
| 727 return; | 694 return; |
| 728 | 695 |
| 729 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); | 696 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); |
| 730 DCHECK(image_manager); | 697 DCHECK(image_manager); |
| 731 if (image_manager->LookupImage(id)) { | 698 if (image_manager->LookupImage(id)) { |
| 732 LOG(ERROR) << "Image already exists with same ID."; | 699 LOG(ERROR) << "Image already exists with same ID."; |
| 733 return; | 700 return; |
| 734 } | 701 } |
| 735 | 702 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 759 handle, size, format, internalformat, kClientId); | 726 handle, size, format, internalformat, kClientId); |
| 760 if (!image.get()) { | 727 if (!image.get()) { |
| 761 LOG(ERROR) << "Failed to create image for buffer."; | 728 LOG(ERROR) << "Failed to create image for buffer."; |
| 762 return; | 729 return; |
| 763 } | 730 } |
| 764 | 731 |
| 765 image_manager->AddImage(image.get(), id); | 732 image_manager->AddImage(image.get(), id); |
| 766 break; | 733 break; |
| 767 } | 734 } |
| 768 } | 735 } |
| 769 | |
| 770 if (fence_sync) { | |
| 771 sync_point_client_->ReleaseFenceSync(fence_sync); | |
| 772 } | |
| 773 } | 736 } |
| 774 | 737 |
| 775 void InProcessCommandBuffer::DestroyImage(int32 id) { | 738 void InProcessCommandBuffer::DestroyImage(int32 id) { |
| 776 CheckSequencedThread(); | 739 CheckSequencedThread(); |
| 777 | 740 |
| 778 QueueTask(base::Bind(&InProcessCommandBuffer::DestroyImageOnGpuThread, | 741 QueueTask(base::Bind(&InProcessCommandBuffer::DestroyImageOnGpuThread, |
| 779 base::Unretained(this), | 742 base::Unretained(this), |
| 780 id)); | 743 id)); |
| 781 } | 744 } |
| 782 | 745 |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1120 framebuffer_completeness_cache_ = | 1083 framebuffer_completeness_cache_ = |
| 1121 new gpu::gles2::FramebufferCompletenessCache; | 1084 new gpu::gles2::FramebufferCompletenessCache; |
| 1122 return framebuffer_completeness_cache_; | 1085 return framebuffer_completeness_cache_; |
| 1123 } | 1086 } |
| 1124 | 1087 |
| 1125 SyncPointManager* GpuInProcessThread::sync_point_manager() { | 1088 SyncPointManager* GpuInProcessThread::sync_point_manager() { |
| 1126 return sync_point_manager_; | 1089 return sync_point_manager_; |
| 1127 } | 1090 } |
| 1128 | 1091 |
| 1129 } // namespace gpu | 1092 } // namespace gpu |
| OLD | NEW |