| 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/ipc/in_process_command_buffer.h" | 5 #include "gpu/ipc/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> |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 static void RunTaskWithResult(base::Callback<T(void)> task, | 70 static void RunTaskWithResult(base::Callback<T(void)> task, |
| 71 T* result, | 71 T* result, |
| 72 base::WaitableEvent* completion) { | 72 base::WaitableEvent* completion) { |
| 73 *result = task.Run(); | 73 *result = task.Run(); |
| 74 completion->Signal(); | 74 completion->Signal(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 class GpuInProcessThreadHolder : public base::Thread { | 77 class GpuInProcessThreadHolder : public base::Thread { |
| 78 public: | 78 public: |
| 79 GpuInProcessThreadHolder() | 79 GpuInProcessThreadHolder() |
| 80 : base::Thread("GpuThread"), | 80 : base::Thread("GpuThread"), sync_point_manager_(new SyncPointManager()) { |
| 81 sync_point_manager_(new SyncPointManager(false)) { | |
| 82 Start(); | 81 Start(); |
| 83 } | 82 } |
| 84 | 83 |
| 85 ~GpuInProcessThreadHolder() override { Stop(); } | 84 ~GpuInProcessThreadHolder() override { Stop(); } |
| 86 | 85 |
| 87 const scoped_refptr<InProcessCommandBuffer::Service>& GetGpuThreadService() { | 86 const scoped_refptr<InProcessCommandBuffer::Service>& GetGpuThreadService() { |
| 88 if (!gpu_thread_service_) { | 87 if (!gpu_thread_service_) { |
| 89 gpu_thread_service_ = new GpuInProcessThreadService( | 88 gpu_thread_service_ = new GpuInProcessThreadService( |
| 90 task_runner(), sync_point_manager_.get(), nullptr, nullptr); | 89 task_runner(), sync_point_manager_.get(), nullptr, nullptr); |
| 91 } | 90 } |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 } | 341 } |
| 343 } | 342 } |
| 344 | 343 |
| 345 if (!surface_.get()) { | 344 if (!surface_.get()) { |
| 346 LOG(ERROR) << "Could not create GLSurface."; | 345 LOG(ERROR) << "Could not create GLSurface."; |
| 347 DestroyOnGpuThread(); | 346 DestroyOnGpuThread(); |
| 348 return false; | 347 return false; |
| 349 } | 348 } |
| 350 | 349 |
| 351 sync_point_order_data_ = SyncPointOrderData::Create(); | 350 sync_point_order_data_ = SyncPointOrderData::Create(); |
| 352 sync_point_client_ = service_->sync_point_manager()->CreateSyncPointClient( | 351 sync_point_client_ = base::MakeUnique<SyncPointClient>( |
| 353 sync_point_order_data_, GetNamespaceID(), GetCommandBufferID()); | 352 service_->sync_point_manager(), sync_point_order_data_, GetNamespaceID(), |
| 353 GetCommandBufferID()); |
| 354 | 354 |
| 355 if (service_->UseVirtualizedGLContexts() || | 355 if (service_->UseVirtualizedGLContexts() || |
| 356 decoder_->GetContextGroup() | 356 decoder_->GetContextGroup() |
| 357 ->feature_info() | 357 ->feature_info() |
| 358 ->workarounds() | 358 ->workarounds() |
| 359 .use_virtualized_gl_contexts) { | 359 .use_virtualized_gl_contexts) { |
| 360 context_ = gl_share_group_->GetSharedContext(surface_.get()); | 360 context_ = gl_share_group_->GetSharedContext(surface_.get()); |
| 361 if (!context_.get()) { | 361 if (!context_.get()) { |
| 362 context_ = gl::init::CreateGLContext( | 362 context_ = gl::init::CreateGLContext( |
| 363 gl_share_group_.get(), surface_.get(), | 363 gl_share_group_.get(), surface_.get(), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 disallowed_features, params.attribs)) { | 410 disallowed_features, params.attribs)) { |
| 411 LOG(ERROR) << "Could not initialize decoder."; | 411 LOG(ERROR) << "Could not initialize decoder."; |
| 412 DestroyOnGpuThread(); | 412 DestroyOnGpuThread(); |
| 413 return false; | 413 return false; |
| 414 } | 414 } |
| 415 *params.capabilities = decoder_->GetCapabilities(); | 415 *params.capabilities = decoder_->GetCapabilities(); |
| 416 | 416 |
| 417 decoder_->SetFenceSyncReleaseCallback( | 417 decoder_->SetFenceSyncReleaseCallback( |
| 418 base::Bind(&InProcessCommandBuffer::FenceSyncReleaseOnGpuThread, | 418 base::Bind(&InProcessCommandBuffer::FenceSyncReleaseOnGpuThread, |
| 419 base::Unretained(this))); | 419 base::Unretained(this))); |
| 420 decoder_->SetWaitFenceSyncCallback( | 420 decoder_->SetWaitSyncTokenCallback( |
| 421 base::Bind(&InProcessCommandBuffer::WaitFenceSyncOnGpuThread, | 421 base::Bind(&InProcessCommandBuffer::WaitSyncTokenOnGpuThread, |
| 422 base::Unretained(this))); | 422 base::Unretained(this))); |
| 423 decoder_->SetDescheduleUntilFinishedCallback( | 423 decoder_->SetDescheduleUntilFinishedCallback( |
| 424 base::Bind(&InProcessCommandBuffer::DescheduleUntilFinishedOnGpuThread, | 424 base::Bind(&InProcessCommandBuffer::DescheduleUntilFinishedOnGpuThread, |
| 425 base::Unretained(this))); | 425 base::Unretained(this))); |
| 426 decoder_->SetRescheduleAfterFinishedCallback( | 426 decoder_->SetRescheduleAfterFinishedCallback( |
| 427 base::Bind(&InProcessCommandBuffer::RescheduleAfterFinishedOnGpuThread, | 427 base::Bind(&InProcessCommandBuffer::RescheduleAfterFinishedOnGpuThread, |
| 428 base::Unretained(this))); | 428 base::Unretained(this))); |
| 429 | 429 |
| 430 image_factory_ = params.image_factory; | 430 image_factory_ = params.image_factory; |
| 431 | 431 |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 if (!image.get()) { | 794 if (!image.get()) { |
| 795 LOG(ERROR) << "Failed to create image for buffer."; | 795 LOG(ERROR) << "Failed to create image for buffer."; |
| 796 return; | 796 return; |
| 797 } | 797 } |
| 798 | 798 |
| 799 image_manager->AddImage(image.get(), id); | 799 image_manager->AddImage(image.get(), id); |
| 800 break; | 800 break; |
| 801 } | 801 } |
| 802 } | 802 } |
| 803 | 803 |
| 804 if (fence_sync) { | 804 if (fence_sync) |
| 805 sync_point_client_->ReleaseFenceSync(fence_sync); | 805 sync_point_client_->ReleaseFenceSync(fence_sync); |
| 806 } | |
| 807 } | 806 } |
| 808 | 807 |
| 809 void InProcessCommandBuffer::DestroyImage(int32_t id) { | 808 void InProcessCommandBuffer::DestroyImage(int32_t id) { |
| 810 CheckSequencedThread(); | 809 CheckSequencedThread(); |
| 811 | 810 |
| 812 QueueTask(false, base::Bind(&InProcessCommandBuffer::DestroyImageOnGpuThread, | 811 QueueTask(false, base::Bind(&InProcessCommandBuffer::DestroyImageOnGpuThread, |
| 813 base::Unretained(this), id)); | 812 base::Unretained(this), id)); |
| 814 } | 813 } |
| 815 | 814 |
| 816 void InProcessCommandBuffer::DestroyImageOnGpuThread(int32_t id) { | 815 void InProcessCommandBuffer::DestroyImageOnGpuThread(int32_t id) { |
| 817 if (!decoder_) | 816 if (!decoder_) |
| 818 return; | 817 return; |
| 819 | 818 |
| 820 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); | 819 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); |
| 821 DCHECK(image_manager); | 820 DCHECK(image_manager); |
| 822 if (!image_manager->LookupImage(id)) { | 821 if (!image_manager->LookupImage(id)) { |
| 823 LOG(ERROR) << "Image with ID doesn't exist."; | 822 LOG(ERROR) << "Image with ID doesn't exist."; |
| 824 return; | 823 return; |
| 825 } | 824 } |
| 826 | 825 |
| 827 image_manager->RemoveImage(id); | 826 image_manager->RemoveImage(id); |
| 828 } | 827 } |
| 829 | 828 |
| 830 void InProcessCommandBuffer::FenceSyncReleaseOnGpuThread(uint64_t release) { | 829 void InProcessCommandBuffer::FenceSyncReleaseOnGpuThread(uint64_t release) { |
| 831 DCHECK(!sync_point_client_->client_state()->IsFenceSyncReleased(release)); | 830 SyncToken sync_token(GetNamespaceID(), GetExtraCommandBufferData(), |
| 831 GetCommandBufferID(), release); |
| 832 |
| 832 gles2::MailboxManager* mailbox_manager = | 833 gles2::MailboxManager* mailbox_manager = |
| 833 decoder_->GetContextGroup()->mailbox_manager(); | 834 decoder_->GetContextGroup()->mailbox_manager(); |
| 834 if (mailbox_manager->UsesSync()) { | 835 mailbox_manager->PushTextureUpdates(sync_token); |
| 835 SyncToken sync_token(GetNamespaceID(), GetExtraCommandBufferData(), | |
| 836 GetCommandBufferID(), release); | |
| 837 mailbox_manager->PushTextureUpdates(sync_token); | |
| 838 } | |
| 839 | 836 |
| 840 sync_point_client_->ReleaseFenceSync(release); | 837 sync_point_client_->ReleaseFenceSync(release); |
| 841 } | 838 } |
| 842 | 839 |
| 843 bool InProcessCommandBuffer::WaitFenceSyncOnGpuThread( | 840 bool InProcessCommandBuffer::WaitSyncTokenOnGpuThread( |
| 844 gpu::CommandBufferNamespace namespace_id, | 841 const SyncToken& sync_token) { |
| 845 gpu::CommandBufferId command_buffer_id, | |
| 846 uint64_t release) { | |
| 847 DCHECK(!waiting_for_sync_point_); | 842 DCHECK(!waiting_for_sync_point_); |
| 848 gpu::SyncPointManager* sync_point_manager = service_->sync_point_manager(); | 843 gpu::SyncPointManager* sync_point_manager = service_->sync_point_manager(); |
| 849 DCHECK(sync_point_manager); | 844 DCHECK(sync_point_manager); |
| 850 | 845 |
| 851 scoped_refptr<gpu::SyncPointClientState> release_state = | 846 gles2::MailboxManager* mailbox_manager = |
| 852 sync_point_manager->GetSyncPointClientState(namespace_id, | 847 decoder_->GetContextGroup()->mailbox_manager(); |
| 853 command_buffer_id); | 848 DCHECK(mailbox_manager); |
| 854 | |
| 855 if (!release_state) | |
| 856 return true; | |
| 857 | 849 |
| 858 if (service_->BlockThreadOnWaitSyncToken()) { | 850 if (service_->BlockThreadOnWaitSyncToken()) { |
| 859 if (!release_state->IsFenceSyncReleased(release)) { | 851 // Wait if sync point wait is valid. |
| 860 // Use waitable event which is signalled when the release fence is | 852 if (sync_point_client_->Wait( |
| 861 // released. | 853 sync_token, |
| 862 sync_point_client_->Wait( | 854 base::Bind(&base::WaitableEvent::Signal, |
| 863 release_state.get(), release, | 855 base::Unretained(&fence_sync_wait_event_)))) { |
| 864 base::Bind(&base::WaitableEvent::Signal, | |
| 865 base::Unretained(&fence_sync_wait_event_))); | |
| 866 fence_sync_wait_event_.Wait(); | 856 fence_sync_wait_event_.Wait(); |
| 867 } | 857 } |
| 868 | 858 |
| 869 gles2::MailboxManager* mailbox_manager = | |
| 870 decoder_->GetContextGroup()->mailbox_manager(); | |
| 871 SyncToken sync_token(namespace_id, 0, command_buffer_id, release); | |
| 872 mailbox_manager->PullTextureUpdates(sync_token); | 859 mailbox_manager->PullTextureUpdates(sync_token); |
| 873 return true; | 860 return false; |
| 874 } | 861 } |
| 875 | 862 |
| 876 if (release_state->IsFenceSyncReleased(release)) { | 863 waiting_for_sync_point_ = sync_point_client_->Wait( |
| 877 gles2::MailboxManager* mailbox_manager = | 864 sync_token, |
| 878 decoder_->GetContextGroup()->mailbox_manager(); | 865 base::Bind(&InProcessCommandBuffer::OnWaitSyncTokenCompleted, |
| 879 SyncToken sync_token(namespace_id, 0, command_buffer_id, release); | 866 gpu_thread_weak_ptr_factory_.GetWeakPtr(), sync_token)); |
| 867 if (!waiting_for_sync_point_) { |
| 880 mailbox_manager->PullTextureUpdates(sync_token); | 868 mailbox_manager->PullTextureUpdates(sync_token); |
| 881 return true; | 869 return false; |
| 882 } | 870 } |
| 883 | 871 |
| 884 waiting_for_sync_point_ = true; | |
| 885 sync_point_client_->Wait( | |
| 886 release_state.get(), release, | |
| 887 base::Bind(&InProcessCommandBuffer::OnWaitFenceSyncCompleted, | |
| 888 gpu_thread_weak_ptr_factory_.GetWeakPtr(), namespace_id, | |
| 889 command_buffer_id, release)); | |
| 890 | |
| 891 if (!waiting_for_sync_point_) | |
| 892 return true; | |
| 893 | |
| 894 executor_->SetScheduled(false); | 872 executor_->SetScheduled(false); |
| 895 return false; | 873 return true; |
| 896 } | 874 } |
| 897 | 875 |
| 898 void InProcessCommandBuffer::OnWaitFenceSyncCompleted( | 876 void InProcessCommandBuffer::OnWaitSyncTokenCompleted( |
| 899 CommandBufferNamespace namespace_id, | 877 const SyncToken& sync_token) { |
| 900 CommandBufferId command_buffer_id, | |
| 901 uint64_t release) { | |
| 902 DCHECK(waiting_for_sync_point_); | 878 DCHECK(waiting_for_sync_point_); |
| 903 gles2::MailboxManager* mailbox_manager = | 879 gles2::MailboxManager* mailbox_manager = |
| 904 decoder_->GetContextGroup()->mailbox_manager(); | 880 decoder_->GetContextGroup()->mailbox_manager(); |
| 905 SyncToken sync_token(namespace_id, 0, command_buffer_id, release); | |
| 906 mailbox_manager->PullTextureUpdates(sync_token); | 881 mailbox_manager->PullTextureUpdates(sync_token); |
| 907 waiting_for_sync_point_ = false; | 882 waiting_for_sync_point_ = false; |
| 908 executor_->SetScheduled(true); | 883 executor_->SetScheduled(true); |
| 909 QueueTask(false, base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, | 884 QueueTask(false, base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, |
| 910 gpu_thread_weak_ptr_, last_put_offset_)); | 885 gpu_thread_weak_ptr_, last_put_offset_)); |
| 911 } | 886 } |
| 912 | 887 |
| 913 void InProcessCommandBuffer::DescheduleUntilFinishedOnGpuThread() { | 888 void InProcessCommandBuffer::DescheduleUntilFinishedOnGpuThread() { |
| 914 if (!service_->BlockThreadOnWaitSyncToken()) { | 889 if (!service_->BlockThreadOnWaitSyncToken()) { |
| 915 DCHECK(executor_->scheduled()); | 890 DCHECK(executor_->scheduled()); |
| 916 DCHECK(executor_->HasPollingWork()); | 891 DCHECK(executor_->HasPollingWork()); |
| 917 | 892 |
| 918 executor_->SetScheduled(false); | 893 executor_->SetScheduled(false); |
| 919 } | 894 } |
| 920 } | 895 } |
| 921 | 896 |
| 922 void InProcessCommandBuffer::RescheduleAfterFinishedOnGpuThread() { | 897 void InProcessCommandBuffer::RescheduleAfterFinishedOnGpuThread() { |
| 923 if (!service_->BlockThreadOnWaitSyncToken()) { | 898 if (!service_->BlockThreadOnWaitSyncToken()) { |
| 924 DCHECK(!executor_->scheduled()); | 899 DCHECK(!executor_->scheduled()); |
| 925 | 900 |
| 926 executor_->SetScheduled(true); | 901 executor_->SetScheduled(true); |
| 927 ProcessTasksOnGpuThread(); | 902 ProcessTasksOnGpuThread(); |
| 928 } | 903 } |
| 929 } | 904 } |
| 930 | 905 |
| 931 void InProcessCommandBuffer::SignalSyncTokenOnGpuThread( | 906 void InProcessCommandBuffer::SignalSyncTokenOnGpuThread( |
| 932 const SyncToken& sync_token, | 907 const SyncToken& sync_token, |
| 933 const base::Closure& callback) { | 908 const base::Closure& callback) { |
| 934 gpu::SyncPointManager* sync_point_manager = service_->sync_point_manager(); | 909 if (!sync_point_client_->Wait(sync_token, WrapCallback(callback))) |
| 935 DCHECK(sync_point_manager); | |
| 936 | |
| 937 scoped_refptr<gpu::SyncPointClientState> release_state = | |
| 938 sync_point_manager->GetSyncPointClientState( | |
| 939 sync_token.namespace_id(), sync_token.command_buffer_id()); | |
| 940 | |
| 941 if (!release_state) { | |
| 942 callback.Run(); | 910 callback.Run(); |
| 943 return; | |
| 944 } | |
| 945 | |
| 946 sync_point_client_->WaitOutOfOrder( | |
| 947 release_state.get(), sync_token.release_count(), WrapCallback(callback)); | |
| 948 } | 911 } |
| 949 | 912 |
| 950 void InProcessCommandBuffer::SignalQuery(unsigned query_id, | 913 void InProcessCommandBuffer::SignalQuery(unsigned query_id, |
| 951 const base::Closure& callback) { | 914 const base::Closure& callback) { |
| 952 CheckSequencedThread(); | 915 CheckSequencedThread(); |
| 953 QueueTask(false, base::Bind(&InProcessCommandBuffer::SignalQueryOnGpuThread, | 916 QueueTask(false, base::Bind(&InProcessCommandBuffer::SignalQueryOnGpuThread, |
| 954 base::Unretained(this), query_id, | 917 base::Unretained(this), query_id, |
| 955 WrapCallback(callback))); | 918 WrapCallback(callback))); |
| 956 } | 919 } |
| 957 | 920 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 return wrapped_callback; | 1119 return wrapped_callback; |
| 1157 } | 1120 } |
| 1158 | 1121 |
| 1159 InProcessCommandBuffer::GpuTask::GpuTask(const base::Closure& callback, | 1122 InProcessCommandBuffer::GpuTask::GpuTask(const base::Closure& callback, |
| 1160 uint32_t order_number) | 1123 uint32_t order_number) |
| 1161 : callback(callback), order_number(order_number) {} | 1124 : callback(callback), order_number(order_number) {} |
| 1162 | 1125 |
| 1163 InProcessCommandBuffer::GpuTask::~GpuTask() {} | 1126 InProcessCommandBuffer::GpuTask::~GpuTask() {} |
| 1164 | 1127 |
| 1165 } // namespace gpu | 1128 } // namespace gpu |
| OLD | NEW |