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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 } | 969 } |
1007 | 970 |
1008 bool InProcessCommandBuffer::IsFenceSyncReleased(uint64_t release) { | 971 bool InProcessCommandBuffer::IsFenceSyncReleased(uint64_t release) { |
1009 return release <= GetLastState().release_count; | 972 return release <= GetLastState().release_count; |
1010 } | 973 } |
1011 | 974 |
1012 void InProcessCommandBuffer::SignalSyncToken(const SyncToken& sync_token, | 975 void InProcessCommandBuffer::SignalSyncToken(const SyncToken& sync_token, |
1013 const base::Closure& callback) { | 976 const base::Closure& callback) { |
1014 CheckSequencedThread(); | 977 CheckSequencedThread(); |
1015 QueueTask( | 978 QueueTask( |
1016 true, | 979 false, |
1017 base::Bind(&InProcessCommandBuffer::SignalSyncTokenOnGpuThread, | 980 base::Bind(&InProcessCommandBuffer::SignalSyncTokenOnGpuThread, |
1018 base::Unretained(this), sync_token, WrapCallback(callback))); | 981 base::Unretained(this), sync_token, WrapCallback(callback))); |
1019 } | 982 } |
1020 | 983 |
1021 bool InProcessCommandBuffer::CanWaitUnverifiedSyncToken( | 984 bool InProcessCommandBuffer::CanWaitUnverifiedSyncToken( |
1022 const SyncToken* sync_token) { | 985 const SyncToken* sync_token) { |
1023 return sync_token->namespace_id() == GetNamespaceID(); | 986 return sync_token->namespace_id() == GetNamespaceID(); |
1024 } | 987 } |
1025 | 988 |
1026 #if defined(OS_WIN) | 989 #if defined(OS_WIN) |
(...skipping 129 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 |