Home | History | Annotate | Download | only in client
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
      6 #define CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/atomic_sequence_num.h"
     12 #include "base/containers/hash_tables.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "base/process/process.h"
     17 #include "base/synchronization/lock.h"
     18 #include "content/common/content_export.h"
     19 #include "content/common/gpu/gpu_process_launch_causes.h"
     20 #include "content/common/gpu/gpu_result_codes.h"
     21 #include "content/common/message_router.h"
     22 #include "gpu/config/gpu_info.h"
     23 #include "ipc/ipc_channel_handle.h"
     24 #include "ipc/ipc_sync_channel.h"
     25 #include "ipc/message_filter.h"
     26 #include "ui/gfx/gpu_memory_buffer.h"
     27 #include "ui/gfx/native_widget_types.h"
     28 #include "ui/gfx/size.h"
     29 #include "ui/gl/gpu_preference.h"
     30 
     31 class GURL;
     32 class TransportTextureService;
     33 struct GPUCreateCommandBufferConfig;
     34 
     35 namespace base {
     36 class MessageLoop;
     37 class MessageLoopProxy;
     38 class WaitableEvent;
     39 }
     40 
     41 namespace IPC {
     42 class SyncMessageFilter;
     43 }
     44 
     45 namespace media {
     46 class VideoDecodeAccelerator;
     47 class VideoEncodeAccelerator;
     48 }
     49 
     50 namespace content {
     51 class CommandBufferProxyImpl;
     52 class GpuChannelHost;
     53 
     54 struct GpuListenerInfo {
     55   GpuListenerInfo();
     56   ~GpuListenerInfo();
     57 
     58   base::WeakPtr<IPC::Listener> listener;
     59   scoped_refptr<base::MessageLoopProxy> loop;
     60 };
     61 
     62 class CONTENT_EXPORT GpuChannelHostFactory {
     63  public:
     64   typedef base::Callback<void(const gfx::Size)> CreateImageCallback;
     65 
     66   virtual ~GpuChannelHostFactory() {}
     67 
     68   virtual bool IsMainThread() = 0;
     69   virtual base::MessageLoop* GetMainLoop() = 0;
     70   virtual scoped_refptr<base::MessageLoopProxy> GetIOLoopProxy() = 0;
     71   virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(size_t size) = 0;
     72   virtual CreateCommandBufferResult CreateViewCommandBuffer(
     73       int32 surface_id,
     74       const GPUCreateCommandBufferConfig& init_params,
     75       int32 route_id) = 0;
     76   virtual void CreateImage(
     77       gfx::PluginWindowHandle window,
     78       int32 image_id,
     79       const CreateImageCallback& callback) = 0;
     80   virtual void DeleteImage(int32 image_id, int32 sync_point) = 0;
     81   virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
     82       size_t width,
     83       size_t height,
     84       unsigned internalformat,
     85       unsigned usage) = 0;
     86 };
     87 
     88 // Encapsulates an IPC channel between the client and one GPU process.
     89 // On the GPU process side there's a corresponding GpuChannel.
     90 // Every method can be called on any thread with a message loop, except for the
     91 // IO thread.
     92 class GpuChannelHost : public IPC::Sender,
     93                        public base::RefCountedThreadSafe<GpuChannelHost> {
     94  public:
     95   // Must be called on the main thread (as defined by the factory).
     96   static scoped_refptr<GpuChannelHost> Create(
     97       GpuChannelHostFactory* factory,
     98       const gpu::GPUInfo& gpu_info,
     99       const IPC::ChannelHandle& channel_handle,
    100       base::WaitableEvent* shutdown_event);
    101 
    102   // Returns true if |handle| is a valid GpuMemoryBuffer handle that
    103   // can be shared to the GPU process.
    104   static bool IsValidGpuMemoryBuffer(gfx::GpuMemoryBufferHandle handle);
    105 
    106   bool IsLost() const {
    107     DCHECK(channel_filter_.get());
    108     return channel_filter_->IsLost();
    109   }
    110 
    111   // The GPU stats reported by the GPU process.
    112   const gpu::GPUInfo& gpu_info() const { return gpu_info_; }
    113 
    114   // IPC::Sender implementation:
    115   virtual bool Send(IPC::Message* msg) OVERRIDE;
    116 
    117   // Create and connect to a command buffer in the GPU process.
    118   CommandBufferProxyImpl* CreateViewCommandBuffer(
    119       int32 surface_id,
    120       CommandBufferProxyImpl* share_group,
    121       const std::vector<int32>& attribs,
    122       const GURL& active_url,
    123       gfx::GpuPreference gpu_preference);
    124 
    125   // Create and connect to a command buffer in the GPU process.
    126   CommandBufferProxyImpl* CreateOffscreenCommandBuffer(
    127       const gfx::Size& size,
    128       CommandBufferProxyImpl* share_group,
    129       const std::vector<int32>& attribs,
    130       const GURL& active_url,
    131       gfx::GpuPreference gpu_preference);
    132 
    133   // Creates a video decoder in the GPU process.
    134   scoped_ptr<media::VideoDecodeAccelerator> CreateVideoDecoder(
    135       int command_buffer_route_id);
    136 
    137   // Creates a video encoder in the GPU process.
    138   scoped_ptr<media::VideoEncodeAccelerator> CreateVideoEncoder(
    139       int command_buffer_route_id);
    140 
    141   // Destroy a command buffer created by this channel.
    142   void DestroyCommandBuffer(CommandBufferProxyImpl* command_buffer);
    143 
    144   // Add a route for the current message loop.
    145   void AddRoute(int route_id, base::WeakPtr<IPC::Listener> listener);
    146   void RemoveRoute(int route_id);
    147 
    148   GpuChannelHostFactory* factory() const { return factory_; }
    149 
    150   // Returns a handle to the shared memory that can be sent via IPC to the
    151   // GPU process. The caller is responsible for ensuring it is closed. Returns
    152   // an invalid handle on failure.
    153   base::SharedMemoryHandle ShareToGpuProcess(
    154       base::SharedMemoryHandle source_handle);
    155 
    156   // Reserve one unused transfer buffer ID.
    157   int32 ReserveTransferBufferId();
    158 
    159   // Returns a GPU memory buffer handle to the buffer that can be sent via
    160   // IPC to the GPU process. The caller is responsible for ensuring it is
    161   // closed. Returns an invalid handle on failure.
    162   gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuProcess(
    163       gfx::GpuMemoryBufferHandle source_handle);
    164 
    165   // Reserve one unused gpu memory buffer ID.
    166   int32 ReserveGpuMemoryBufferId();
    167 
    168   // Generate a route ID guaranteed to be unique for this channel.
    169   int32 GenerateRouteID();
    170 
    171  private:
    172   friend class base::RefCountedThreadSafe<GpuChannelHost>;
    173   GpuChannelHost(GpuChannelHostFactory* factory,
    174                  const gpu::GPUInfo& gpu_info);
    175   virtual ~GpuChannelHost();
    176   void Connect(const IPC::ChannelHandle& channel_handle,
    177                base::WaitableEvent* shutdown_event);
    178 
    179   // A filter used internally to route incoming messages from the IO thread
    180   // to the correct message loop. It also maintains some shared state between
    181   // all the contexts.
    182   class MessageFilter : public IPC::MessageFilter {
    183    public:
    184     MessageFilter();
    185 
    186     // Called on the IO thread.
    187     void AddRoute(int route_id,
    188                   base::WeakPtr<IPC::Listener> listener,
    189                   scoped_refptr<base::MessageLoopProxy> loop);
    190     // Called on the IO thread.
    191     void RemoveRoute(int route_id);
    192 
    193     // IPC::MessageFilter implementation
    194     // (called on the IO thread):
    195     virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
    196     virtual void OnChannelError() OVERRIDE;
    197 
    198     // The following methods can be called on any thread.
    199 
    200     // Whether the channel is lost.
    201     bool IsLost() const;
    202 
    203    private:
    204     virtual ~MessageFilter();
    205 
    206     // Threading notes: |listeners_| is only accessed on the IO thread. Every
    207     // other field is protected by |lock_|.
    208     typedef base::hash_map<int, GpuListenerInfo> ListenerMap;
    209     ListenerMap listeners_;
    210 
    211     // Protects all fields below this one.
    212     mutable base::Lock lock_;
    213 
    214     // Whether the channel has been lost.
    215     bool lost_;
    216   };
    217 
    218   // Threading notes: all fields are constant during the lifetime of |this|
    219   // except:
    220   // - |next_transfer_buffer_id_|, atomic type
    221   // - |next_gpu_memory_buffer_id_|, atomic type
    222   // - |next_route_id_|, atomic type
    223   // - |proxies_|, protected by |context_lock_|
    224   GpuChannelHostFactory* const factory_;
    225 
    226   const gpu::GPUInfo gpu_info_;
    227 
    228   scoped_ptr<IPC::SyncChannel> channel_;
    229   scoped_refptr<MessageFilter> channel_filter_;
    230 
    231   // A filter for sending messages from thread other than the main thread.
    232   scoped_refptr<IPC::SyncMessageFilter> sync_filter_;
    233 
    234   // Transfer buffer IDs are allocated in sequence.
    235   base::AtomicSequenceNumber next_transfer_buffer_id_;
    236 
    237   // Gpu memory buffer IDs are allocated in sequence.
    238   base::AtomicSequenceNumber next_gpu_memory_buffer_id_;
    239 
    240   // Route IDs are allocated in sequence.
    241   base::AtomicSequenceNumber next_route_id_;
    242 
    243   // Protects proxies_.
    244   mutable base::Lock context_lock_;
    245   // Used to look up a proxy from its routing id.
    246   typedef base::hash_map<int, CommandBufferProxyImpl*> ProxyMap;
    247   ProxyMap proxies_;
    248 
    249   DISALLOW_COPY_AND_ASSIGN(GpuChannelHost);
    250 };
    251 
    252 }  // namespace content
    253 
    254 #endif  // CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
    255