// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_ #define GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_ #include #include #include "base/atomic_sequence_num.h" #include "base/callback.h" #include "base/compiler_specific.h" #include "base/containers/scoped_ptr_hash_map.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" #include "gpu/command_buffer/client/gpu_control.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/gpu_export.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_widget_types.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gpu_preference.h" namespace base { class SequenceChecker; } namespace gfx { class GLContext; class GLShareGroup; class GLSurface; class Size; } #if defined(OS_ANDROID) namespace gfx { class SurfaceTexture; } namespace gpu { class StreamTextureManagerInProcess; } #endif namespace gpu { class SyncPointManager; class ValueStateMap; namespace gles2 { class GLES2Decoder; class MailboxManager; class ShaderTranslatorCache; class SubscriptionRefSet; } class CommandBufferServiceBase; class GpuMemoryBufferManager; class GpuScheduler; class ImageFactory; class TransferBufferManagerInterface; // This class provides a thread-safe interface to the global GPU service (for // example GPU thread) when being run in single process mode. // However, the behavior for accessing one context (i.e. one instance of this // class) from different client threads is undefined. class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, public GpuControl { public: class Service; explicit InProcessCommandBuffer(const scoped_refptr& service); ~InProcessCommandBuffer() override; // If |surface| is not NULL, use it directly; in this case, the command // buffer gpu thread must be the same as the client thread. Otherwise create // a new GLSurface. bool Initialize(scoped_refptr surface, bool is_offscreen, gfx::AcceleratedWidget window, const gfx::Size& size, const std::vector& attribs, gfx::GpuPreference gpu_preference, const base::Closure& context_lost_callback, InProcessCommandBuffer* share_group, GpuMemoryBufferManager* gpu_memory_buffer_manager, ImageFactory* image_factory); void Destroy(); // CommandBuffer implementation: bool Initialize() override; State GetLastState() override; int32 GetLastToken() override; void Flush(int32 put_offset) override; void OrderingBarrier(int32 put_offset) override; void WaitForTokenInRange(int32 start, int32 end) override; void WaitForGetOffsetInRange(int32 start, int32 end) override; void SetGetBuffer(int32 shm_id) override; scoped_refptr CreateTransferBuffer(size_t size, int32* id) override; void DestroyTransferBuffer(int32 id) override; gpu::error::Error GetLastError() override; // GpuControl implementation: gpu::Capabilities GetCapabilities() override; int32 CreateImage(ClientBuffer buffer, size_t width, size_t height, unsigned internalformat) override; void DestroyImage(int32 id) override; int32 CreateGpuMemoryBufferImage(size_t width, size_t height, unsigned internalformat, unsigned usage) override; uint32 InsertSyncPoint() override; uint32 InsertFutureSyncPoint() override; void RetireSyncPoint(uint32 sync_point) override; void SignalSyncPoint(uint32 sync_point, const base::Closure& callback) override; void SignalQuery(uint32 query_id, const base::Closure& callback) override; void SetSurfaceVisible(bool visible) override; uint32 CreateStreamTexture(uint32 texture_id) override; void SetLock(base::Lock*) override; bool IsGpuChannelLost() override; // The serializer interface to the GPU service (i.e. thread). class Service { public: Service(); virtual ~Service(); virtual void AddRef() const = 0; virtual void Release() const = 0; // Queues a task to run as soon as possible. virtual void ScheduleTask(const base::Closure& task) = 0; // Schedules |callback| to run at an appropriate time for performing idle // work. virtual void ScheduleIdleWork(const base::Closure& task) = 0; virtual bool UseVirtualizedGLContexts() = 0; virtual scoped_refptr shader_translator_cache() = 0; virtual SyncPointManager* sync_point_manager() = 0; scoped_refptr share_group(); scoped_refptr mailbox_manager(); scoped_refptr subscription_ref_set(); scoped_refptr pending_valuebuffer_state(); private: scoped_refptr share_group_; scoped_refptr mailbox_manager_; scoped_refptr subscription_ref_set_; scoped_refptr pending_valuebuffer_state_; }; #if defined(OS_ANDROID) scoped_refptr GetSurfaceTexture( uint32 stream_id); #endif private: struct InitializeOnGpuThreadParams { bool is_offscreen; gfx::AcceleratedWidget window; const gfx::Size& size; const std::vector& attribs; gfx::GpuPreference gpu_preference; gpu::Capabilities* capabilities; // Ouptut. InProcessCommandBuffer* context_group; ImageFactory* image_factory; InitializeOnGpuThreadParams(bool is_offscreen, gfx::AcceleratedWidget window, const gfx::Size& size, const std::vector& attribs, gfx::GpuPreference gpu_preference, gpu::Capabilities* capabilities, InProcessCommandBuffer* share_group, ImageFactory* image_factory) : is_offscreen(is_offscreen), window(window), size(size), attribs(attribs), gpu_preference(gpu_preference), capabilities(capabilities), context_group(share_group), image_factory(image_factory) {} }; bool InitializeOnGpuThread(const InitializeOnGpuThreadParams& params); bool DestroyOnGpuThread(); void FlushOnGpuThread(int32 put_offset); void ScheduleIdleWorkOnGpuThread(); uint32 CreateStreamTextureOnGpuThread(uint32 client_texture_id); bool MakeCurrent(); base::Closure WrapCallback(const base::Closure& callback); State GetStateFast(); void QueueTask(const base::Closure& task) { service_->ScheduleTask(task); } void CheckSequencedThread(); void RetireSyncPointOnGpuThread(uint32 sync_point); void SignalSyncPointOnGpuThread(uint32 sync_point, const base::Closure& callback); bool WaitSyncPointOnGpuThread(uint32 sync_point); void SignalQueryOnGpuThread(unsigned query_id, const base::Closure& callback); void DestroyTransferBufferOnGpuThread(int32 id); void CreateImageOnGpuThread(int32 id, const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, gfx::BufferFormat format, uint32 internalformat); void DestroyImageOnGpuThread(int32 id); void SetGetBufferOnGpuThread(int32 shm_id, base::WaitableEvent* completion); // Callbacks: void OnContextLost(); void OnResizeView(gfx::Size size, float scale_factor); bool GetBufferChanged(int32 transfer_buffer_id); void PumpCommands(); void PerformIdleWork(); // Members accessed on the gpu thread (possibly with the exception of // creation): bool context_lost_; scoped_refptr transfer_buffer_manager_; scoped_ptr gpu_scheduler_; scoped_ptr decoder_; scoped_refptr context_; scoped_refptr surface_; base::Closure context_lost_callback_; bool idle_work_pending_; // Used to throttle PerformIdleWork. ImageFactory* image_factory_; // Members accessed on the client thread: State last_state_; int32 last_put_offset_; gpu::Capabilities capabilities_; GpuMemoryBufferManager* gpu_memory_buffer_manager_; base::AtomicSequenceNumber next_image_id_; // Accessed on both threads: scoped_ptr command_buffer_; base::Lock command_buffer_lock_; base::WaitableEvent flush_event_; scoped_refptr service_; State state_after_last_flush_; base::Lock state_after_last_flush_lock_; scoped_refptr gl_share_group_; #if defined(OS_ANDROID) scoped_ptr stream_texture_manager_; #endif // Only used with explicit scheduling and the gpu thread is the same as // the client thread. scoped_ptr sequence_checker_; base::WeakPtr gpu_thread_weak_ptr_; base::WeakPtrFactory gpu_thread_weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(InProcessCommandBuffer); }; // Default Service class when a null service is used. class GPU_EXPORT GpuInProcessThread : public base::Thread, public NON_EXPORTED_BASE(InProcessCommandBuffer::Service), public base::RefCountedThreadSafe { public: explicit GpuInProcessThread(SyncPointManager* sync_point_manager); void AddRef() const override; void Release() const override; void ScheduleTask(const base::Closure& task) override; void ScheduleIdleWork(const base::Closure& callback) override; bool UseVirtualizedGLContexts() override; scoped_refptr shader_translator_cache() override; SyncPointManager* sync_point_manager() override; private: ~GpuInProcessThread() override; friend class base::RefCountedThreadSafe; SyncPointManager* sync_point_manager_; // Non-owning. scoped_refptr shader_translator_cache_; DISALLOW_COPY_AND_ASSIGN(GpuInProcessThread); }; } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_