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 |