| 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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 14 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/memory/weak_ptr.h" | 16 #include "base/memory/weak_ptr.h" |
| 17 #include "base/sequence_checker.h" | 17 #include "base/sequence_checker.h" |
| 18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 19 #include "base/thread_task_runner_handle.h" | 19 #include "base/thread_task_runner_handle.h" |
| 20 #include "base/threading/thread.h" | |
| 21 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" | 20 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" |
| 22 #include "gpu/command_buffer/common/value_state.h" | 21 #include "gpu/command_buffer/common/value_state.h" |
| 23 #include "gpu/command_buffer/service/command_buffer_service.h" | 22 #include "gpu/command_buffer/service/command_buffer_service.h" |
| 24 #include "gpu/command_buffer/service/context_group.h" | 23 #include "gpu/command_buffer/service/context_group.h" |
| 25 #include "gpu/command_buffer/service/gl_context_virtual.h" | 24 #include "gpu/command_buffer/service/gl_context_virtual.h" |
| 26 #include "gpu/command_buffer/service/gpu_scheduler.h" | 25 #include "gpu/command_buffer/service/gpu_scheduler.h" |
| 27 #include "gpu/command_buffer/service/image_factory.h" | 26 #include "gpu/command_buffer/service/image_factory.h" |
| 28 #include "gpu/command_buffer/service/image_manager.h" | 27 #include "gpu/command_buffer/service/image_manager.h" |
| 29 #include "gpu/command_buffer/service/mailbox_manager.h" | 28 #include "gpu/command_buffer/service/mailbox_manager.h" |
| 30 #include "gpu/command_buffer/service/memory_tracking.h" | 29 #include "gpu/command_buffer/service/memory_tracking.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 53 namespace { | 52 namespace { |
| 54 | 53 |
| 55 template <typename T> | 54 template <typename T> |
| 56 static void RunTaskWithResult(base::Callback<T(void)> task, | 55 static void RunTaskWithResult(base::Callback<T(void)> task, |
| 57 T* result, | 56 T* result, |
| 58 base::WaitableEvent* completion) { | 57 base::WaitableEvent* completion) { |
| 59 *result = task.Run(); | 58 *result = task.Run(); |
| 60 completion->Signal(); | 59 completion->Signal(); |
| 61 } | 60 } |
| 62 | 61 |
| 63 class GpuInProcessThread | |
| 64 : public base::Thread, | |
| 65 public InProcessCommandBuffer::Service, | |
| 66 public base::RefCountedThreadSafe<GpuInProcessThread> { | |
| 67 public: | |
| 68 GpuInProcessThread(); | |
| 69 | |
| 70 void AddRef() const override { | |
| 71 base::RefCountedThreadSafe<GpuInProcessThread>::AddRef(); | |
| 72 } | |
| 73 void Release() const override { | |
| 74 base::RefCountedThreadSafe<GpuInProcessThread>::Release(); | |
| 75 } | |
| 76 | |
| 77 void ScheduleTask(const base::Closure& task) override; | |
| 78 void ScheduleIdleWork(const base::Closure& callback) override; | |
| 79 bool UseVirtualizedGLContexts() override { return false; } | |
| 80 scoped_refptr<gles2::ShaderTranslatorCache> shader_translator_cache() | |
| 81 override; | |
| 82 | |
| 83 private: | |
| 84 ~GpuInProcessThread() override; | |
| 85 friend class base::RefCountedThreadSafe<GpuInProcessThread>; | |
| 86 | |
| 87 scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_; | |
| 88 DISALLOW_COPY_AND_ASSIGN(GpuInProcessThread); | |
| 89 }; | |
| 90 | |
| 91 GpuInProcessThread::GpuInProcessThread() : base::Thread("GpuThread") { | |
| 92 Start(); | |
| 93 } | |
| 94 | |
| 95 GpuInProcessThread::~GpuInProcessThread() { | |
| 96 Stop(); | |
| 97 } | |
| 98 | |
| 99 void GpuInProcessThread::ScheduleTask(const base::Closure& task) { | |
| 100 task_runner()->PostTask(FROM_HERE, task); | |
| 101 } | |
| 102 | |
| 103 void GpuInProcessThread::ScheduleIdleWork(const base::Closure& callback) { | |
| 104 // Match delay with GpuCommandBufferStub. | |
| 105 task_runner()->PostDelayedTask(FROM_HERE, callback, | |
| 106 base::TimeDelta::FromMilliseconds(2)); | |
| 107 } | |
| 108 | |
| 109 scoped_refptr<gles2::ShaderTranslatorCache> | |
| 110 GpuInProcessThread::shader_translator_cache() { | |
| 111 if (!shader_translator_cache_.get()) | |
| 112 shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache; | |
| 113 return shader_translator_cache_; | |
| 114 } | |
| 115 | |
| 116 struct GpuInProcessThreadHolder { | 62 struct GpuInProcessThreadHolder { |
| 117 GpuInProcessThreadHolder() : gpu_thread(new GpuInProcessThread) {} | 63 GpuInProcessThreadHolder() |
| 64 : sync_point_manager(new SyncPointManager(false)), |
| 65 gpu_thread(new GpuInProcessThread(sync_point_manager.get())) {} |
| 66 scoped_ptr<SyncPointManager> sync_point_manager; |
| 118 scoped_refptr<InProcessCommandBuffer::Service> gpu_thread; | 67 scoped_refptr<InProcessCommandBuffer::Service> gpu_thread; |
| 119 }; | 68 }; |
| 120 | 69 |
| 121 base::LazyInstance<GpuInProcessThreadHolder> g_default_service = | 70 base::LazyInstance<GpuInProcessThreadHolder> g_default_service = |
| 122 LAZY_INSTANCE_INITIALIZER; | 71 LAZY_INSTANCE_INITIALIZER; |
| 123 | 72 |
| 124 class ScopedEvent { | 73 class ScopedEvent { |
| 125 public: | 74 public: |
| 126 explicit ScopedEvent(base::WaitableEvent* event) : event_(event) {} | 75 explicit ScopedEvent(base::WaitableEvent* event) : event_(event) {} |
| 127 ~ScopedEvent() { event_->Signal(); } | 76 ~ScopedEvent() { event_->Signal(); } |
| 128 | 77 |
| 129 private: | 78 private: |
| 130 base::WaitableEvent* event_; | 79 base::WaitableEvent* event_; |
| 131 }; | 80 }; |
| 132 | 81 |
| 133 // This wrapper adds the WaitSyncPoint which allows waiting on a sync point | |
| 134 // on the service thread, implemented using a condition variable. | |
| 135 struct SyncPointManagerWrapper { | |
| 136 SyncPointManagerWrapper() : manager(SyncPointManager::Create(true)) {} | |
| 137 const scoped_refptr<SyncPointManager> manager; | |
| 138 }; | |
| 139 | |
| 140 base::LazyInstance<SyncPointManagerWrapper> g_sync_point_manager = | |
| 141 LAZY_INSTANCE_INITIALIZER; | |
| 142 | |
| 143 base::SharedMemoryHandle ShareToGpuThread( | 82 base::SharedMemoryHandle ShareToGpuThread( |
| 144 base::SharedMemoryHandle source_handle) { | 83 base::SharedMemoryHandle source_handle) { |
| 145 return base::SharedMemory::DuplicateHandle(source_handle); | 84 return base::SharedMemory::DuplicateHandle(source_handle); |
| 146 } | 85 } |
| 147 | 86 |
| 148 gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuThread( | 87 gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuThread( |
| 149 const gfx::GpuMemoryBufferHandle& source_handle, | 88 const gfx::GpuMemoryBufferHandle& source_handle, |
| 150 bool* requires_sync_point) { | 89 bool* requires_sync_point) { |
| 151 switch (source_handle.type) { | 90 switch (source_handle.type) { |
| 152 case gfx::SHARED_MEMORY_BUFFER: { | 91 case gfx::SHARED_MEMORY_BUFFER: { |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 gfx::Size(width, height), | 716 gfx::Size(width, height), |
| 778 gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat(internalformat), | 717 gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat(internalformat), |
| 779 gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage))); | 718 gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage))); |
| 780 if (!buffer) | 719 if (!buffer) |
| 781 return -1; | 720 return -1; |
| 782 | 721 |
| 783 return CreateImage(buffer->AsClientBuffer(), width, height, internalformat); | 722 return CreateImage(buffer->AsClientBuffer(), width, height, internalformat); |
| 784 } | 723 } |
| 785 | 724 |
| 786 uint32 InProcessCommandBuffer::InsertSyncPoint() { | 725 uint32 InProcessCommandBuffer::InsertSyncPoint() { |
| 787 uint32 sync_point = g_sync_point_manager.Get().manager->GenerateSyncPoint(); | 726 uint32 sync_point = service_->sync_point_manager()->GenerateSyncPoint(); |
| 788 QueueTask(base::Bind(&InProcessCommandBuffer::RetireSyncPointOnGpuThread, | 727 QueueTask(base::Bind(&InProcessCommandBuffer::RetireSyncPointOnGpuThread, |
| 789 base::Unretained(this), | 728 base::Unretained(this), |
| 790 sync_point)); | 729 sync_point)); |
| 791 return sync_point; | 730 return sync_point; |
| 792 } | 731 } |
| 793 | 732 |
| 794 uint32 InProcessCommandBuffer::InsertFutureSyncPoint() { | 733 uint32 InProcessCommandBuffer::InsertFutureSyncPoint() { |
| 795 return g_sync_point_manager.Get().manager->GenerateSyncPoint(); | 734 return service_->sync_point_manager()->GenerateSyncPoint(); |
| 796 } | 735 } |
| 797 | 736 |
| 798 void InProcessCommandBuffer::RetireSyncPoint(uint32 sync_point) { | 737 void InProcessCommandBuffer::RetireSyncPoint(uint32 sync_point) { |
| 799 QueueTask(base::Bind(&InProcessCommandBuffer::RetireSyncPointOnGpuThread, | 738 QueueTask(base::Bind(&InProcessCommandBuffer::RetireSyncPointOnGpuThread, |
| 800 base::Unretained(this), | 739 base::Unretained(this), |
| 801 sync_point)); | 740 sync_point)); |
| 802 } | 741 } |
| 803 | 742 |
| 804 void InProcessCommandBuffer::RetireSyncPointOnGpuThread(uint32 sync_point) { | 743 void InProcessCommandBuffer::RetireSyncPointOnGpuThread(uint32 sync_point) { |
| 805 gles2::MailboxManager* mailbox_manager = | 744 gles2::MailboxManager* mailbox_manager = |
| 806 decoder_->GetContextGroup()->mailbox_manager(); | 745 decoder_->GetContextGroup()->mailbox_manager(); |
| 807 if (mailbox_manager->UsesSync()) { | 746 if (mailbox_manager->UsesSync()) { |
| 808 bool make_current_success = false; | 747 bool make_current_success = false; |
| 809 { | 748 { |
| 810 base::AutoLock lock(command_buffer_lock_); | 749 base::AutoLock lock(command_buffer_lock_); |
| 811 make_current_success = MakeCurrent(); | 750 make_current_success = MakeCurrent(); |
| 812 } | 751 } |
| 813 if (make_current_success) | 752 if (make_current_success) |
| 814 mailbox_manager->PushTextureUpdates(sync_point); | 753 mailbox_manager->PushTextureUpdates(sync_point); |
| 815 } | 754 } |
| 816 g_sync_point_manager.Get().manager->RetireSyncPoint(sync_point); | 755 service_->sync_point_manager()->RetireSyncPoint(sync_point); |
| 817 } | 756 } |
| 818 | 757 |
| 819 void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point, | 758 void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point, |
| 820 const base::Closure& callback) { | 759 const base::Closure& callback) { |
| 821 CheckSequencedThread(); | 760 CheckSequencedThread(); |
| 822 QueueTask(base::Bind(&InProcessCommandBuffer::SignalSyncPointOnGpuThread, | 761 QueueTask(base::Bind(&InProcessCommandBuffer::SignalSyncPointOnGpuThread, |
| 823 base::Unretained(this), | 762 base::Unretained(this), |
| 824 sync_point, | 763 sync_point, |
| 825 WrapCallback(callback))); | 764 WrapCallback(callback))); |
| 826 } | 765 } |
| 827 | 766 |
| 828 bool InProcessCommandBuffer::WaitSyncPointOnGpuThread(unsigned sync_point) { | 767 bool InProcessCommandBuffer::WaitSyncPointOnGpuThread(unsigned sync_point) { |
| 829 g_sync_point_manager.Get().manager->ThreadedWaitSyncPoint(sync_point); | 768 service_->sync_point_manager()->WaitSyncPoint(sync_point); |
| 830 gles2::MailboxManager* mailbox_manager = | 769 gles2::MailboxManager* mailbox_manager = |
| 831 decoder_->GetContextGroup()->mailbox_manager(); | 770 decoder_->GetContextGroup()->mailbox_manager(); |
| 832 mailbox_manager->PullTextureUpdates(sync_point); | 771 mailbox_manager->PullTextureUpdates(sync_point); |
| 833 return true; | 772 return true; |
| 834 } | 773 } |
| 835 | 774 |
| 836 void InProcessCommandBuffer::SignalSyncPointOnGpuThread( | 775 void InProcessCommandBuffer::SignalSyncPointOnGpuThread( |
| 837 unsigned sync_point, | 776 unsigned sync_point, |
| 838 const base::Closure& callback) { | 777 const base::Closure& callback) { |
| 839 g_sync_point_manager.Get().manager->AddSyncPointCallback(sync_point, | 778 service_->sync_point_manager()->AddSyncPointCallback(sync_point, callback); |
| 840 callback); | |
| 841 } | 779 } |
| 842 | 780 |
| 843 void InProcessCommandBuffer::SignalQuery(unsigned query_id, | 781 void InProcessCommandBuffer::SignalQuery(unsigned query_id, |
| 844 const base::Closure& callback) { | 782 const base::Closure& callback) { |
| 845 CheckSequencedThread(); | 783 CheckSequencedThread(); |
| 846 QueueTask(base::Bind(&InProcessCommandBuffer::SignalQueryOnGpuThread, | 784 QueueTask(base::Bind(&InProcessCommandBuffer::SignalQueryOnGpuThread, |
| 847 base::Unretained(this), | 785 base::Unretained(this), |
| 848 query_id, | 786 query_id, |
| 849 WrapCallback(callback))); | 787 WrapCallback(callback))); |
| 850 } | 788 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 } | 881 } |
| 944 | 882 |
| 945 #if defined(OS_ANDROID) | 883 #if defined(OS_ANDROID) |
| 946 scoped_refptr<gfx::SurfaceTexture> | 884 scoped_refptr<gfx::SurfaceTexture> |
| 947 InProcessCommandBuffer::GetSurfaceTexture(uint32 stream_id) { | 885 InProcessCommandBuffer::GetSurfaceTexture(uint32 stream_id) { |
| 948 DCHECK(stream_texture_manager_); | 886 DCHECK(stream_texture_manager_); |
| 949 return stream_texture_manager_->GetSurfaceTexture(stream_id); | 887 return stream_texture_manager_->GetSurfaceTexture(stream_id); |
| 950 } | 888 } |
| 951 #endif | 889 #endif |
| 952 | 890 |
| 891 GpuInProcessThread::GpuInProcessThread(SyncPointManager* sync_point_manager) |
| 892 : base::Thread("GpuThread"), sync_point_manager_(sync_point_manager) { |
| 893 Start(); |
| 894 } |
| 895 |
| 896 GpuInProcessThread::~GpuInProcessThread() { |
| 897 Stop(); |
| 898 } |
| 899 |
| 900 void GpuInProcessThread::AddRef() const { |
| 901 base::RefCountedThreadSafe<GpuInProcessThread>::AddRef(); |
| 902 } |
| 903 void GpuInProcessThread::Release() const { |
| 904 base::RefCountedThreadSafe<GpuInProcessThread>::Release(); |
| 905 } |
| 906 |
| 907 void GpuInProcessThread::ScheduleTask(const base::Closure& task) { |
| 908 task_runner()->PostTask(FROM_HERE, task); |
| 909 } |
| 910 |
| 911 void GpuInProcessThread::ScheduleIdleWork(const base::Closure& callback) { |
| 912 // Match delay with GpuCommandBufferStub. |
| 913 task_runner()->PostDelayedTask(FROM_HERE, callback, |
| 914 base::TimeDelta::FromMilliseconds(2)); |
| 915 } |
| 916 |
| 917 bool GpuInProcessThread::UseVirtualizedGLContexts() { |
| 918 return false; |
| 919 } |
| 920 |
| 921 scoped_refptr<gles2::ShaderTranslatorCache> |
| 922 GpuInProcessThread::shader_translator_cache() { |
| 923 if (!shader_translator_cache_.get()) |
| 924 shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache; |
| 925 return shader_translator_cache_; |
| 926 } |
| 927 |
| 928 SyncPointManager* GpuInProcessThread::sync_point_manager() { |
| 929 return sync_point_manager_; |
| 930 } |
| 931 |
| 953 } // namespace gpu | 932 } // namespace gpu |
| OLD | NEW |