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/message_router.h"
     21 #include "gpu/config/gpu_info.h"
     22 #include "ipc/ipc_channel_handle.h"
     23 #include "ipc/ipc_channel_proxy.h"
     24 #include "ipc/ipc_sync_channel.h"
     25 #include "media/video/video_decode_accelerator.h"
     26 #include "media/video/video_encode_accelerator.h"
     27 #include "ui/gfx/gpu_memory_buffer.h"
     28 #include "ui/gfx/native_widget_types.h"
     29 #include "ui/gfx/size.h"
     30 #include "ui/gl/gpu_preference.h"
     31 
     32 class GURL;
     33 class TransportTextureService;
     34 struct GPUCreateCommandBufferConfig;
     35 
     36 namespace base {
     37 class MessageLoop;
     38 class MessageLoopProxy;
     39 }
     40 
     41 namespace gpu {
     42 struct Mailbox;
     43 }
     44 
     45 namespace IPC {
     46 class SyncMessageFilter;
     47 }
     48 
     49 namespace content {
     50 class CommandBufferProxyImpl;
     51 class GpuChannelHost;
     52 struct GpuRenderingStats;
     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 base::WaitableEvent* GetShutDownEvent() = 0;
     72   virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(size_t size) = 0;
     73   virtual int32 CreateViewCommandBuffer(
     74       int32 surface_id, const GPUCreateCommandBufferConfig& init_params) = 0;
     75   virtual void CreateImage(
     76       gfx::PluginWindowHandle window,
     77       int32 image_id,
     78       const CreateImageCallback& callback) = 0;
     79   virtual void DeleteImage(int32 image_id, int32 sync_point) = 0;
     80   virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
     81       size_t width,
     82       size_t height,
     83       unsigned internalformat) = 0;
     84 };
     85 
     86 // Encapsulates an IPC channel between the client and one GPU process.
     87 // On the GPU process side there's a corresponding GpuChannel.
     88 // Every method can be called on any thread with a message loop, except for the
     89 // IO thread.
     90 class GpuChannelHost : public IPC::Sender,
     91                        public base::RefCountedThreadSafe<GpuChannelHost> {
     92  public:
     93   // Must be called on the main thread (as defined by the factory).
     94   static scoped_refptr<GpuChannelHost> Create(
     95       GpuChannelHostFactory* factory,
     96       int gpu_host_id,
     97       const gpu::GPUInfo& gpu_info,
     98       const IPC::ChannelHandle& channel_handle);
     99 
    100   // Returns true if |handle| is a valid GpuMemoryBuffer handle that
    101   // can be shared to the GPU process.
    102   static bool IsValidGpuMemoryBuffer(gfx::GpuMemoryBufferHandle handle);
    103 
    104   bool IsLost() const {
    105     DCHECK(channel_filter_.get());
    106     return channel_filter_->IsLost();
    107   }
    108 
    109   // The GPU stats reported by the GPU process.
    110   const gpu::GPUInfo& gpu_info() const { return gpu_info_; }
    111 
    112   // IPC::Sender implementation:
    113   virtual bool Send(IPC::Message* msg) OVERRIDE;
    114 
    115   // Create and connect to a command buffer in the GPU process.
    116   CommandBufferProxyImpl* CreateViewCommandBuffer(
    117       int32 surface_id,
    118       CommandBufferProxyImpl* share_group,
    119       const std::vector<int32>& attribs,
    120       const GURL& active_url,
    121       gfx::GpuPreference gpu_preference);
    122 
    123   // Create and connect to a command buffer in the GPU process.
    124   CommandBufferProxyImpl* CreateOffscreenCommandBuffer(
    125       const gfx::Size& size,
    126       CommandBufferProxyImpl* share_group,
    127       const std::vector<int32>& attribs,
    128       const GURL& active_url,
    129       gfx::GpuPreference gpu_preference);
    130 
    131   // Creates a video decoder in the GPU process.
    132   scoped_ptr<media::VideoDecodeAccelerator> CreateVideoDecoder(
    133       int command_buffer_route_id,
    134       media::VideoCodecProfile profile,
    135       media::VideoDecodeAccelerator::Client* client);
    136 
    137   // Creates a video encoder in the GPU process.
    138   scoped_ptr<media::VideoEncodeAccelerator> CreateVideoEncoder(
    139       media::VideoEncodeAccelerator::Client* client);
    140 
    141   // Destroy a command buffer created by this channel.
    142   void DestroyCommandBuffer(CommandBufferProxyImpl* command_buffer);
    143 
    144   // Collect rendering stats from GPU process.
    145   bool CollectRenderingStatsForSurface(
    146       int surface_id, GpuRenderingStats* stats);
    147 
    148   // Add a route for the current message loop.
    149   void AddRoute(int route_id, base::WeakPtr<IPC::Listener> listener);
    150   void RemoveRoute(int route_id);
    151 
    152   GpuChannelHostFactory* factory() const { return factory_; }
    153   int gpu_host_id() const { return gpu_host_id_; }
    154 
    155   // Returns a handle to the shared memory that can be sent via IPC to the
    156   // GPU process. The caller is responsible for ensuring it is closed. Returns
    157   // an invalid handle on failure.
    158   base::SharedMemoryHandle ShareToGpuProcess(
    159       base::SharedMemoryHandle source_handle);
    160 
    161   // Generates |num| unique mailbox names that can be used with
    162   // GL_texture_mailbox_CHROMIUM. Unlike genMailboxCHROMIUM, this IPC is
    163   // handled only on the GPU process' IO thread, and so is not effectively
    164   // a finish.
    165   bool GenerateMailboxNames(unsigned num, std::vector<gpu::Mailbox>* names);
    166 
    167   // Reserve one unused transfer buffer ID.
    168   int32 ReserveTransferBufferId();
    169 
    170   // Returns a GPU memory buffer handle to the buffer that can be sent via
    171   // IPC to the GPU process. The caller is responsible for ensuring it is
    172   // closed. Returns an invalid handle on failure.
    173   gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuProcess(
    174       gfx::GpuMemoryBufferHandle source_handle);
    175 
    176   // Reserve one unused gpu memory buffer ID.
    177   int32 ReserveGpuMemoryBufferId();
    178 
    179  private:
    180   friend class base::RefCountedThreadSafe<GpuChannelHost>;
    181   GpuChannelHost(GpuChannelHostFactory* factory,
    182                  int gpu_host_id,
    183                  const gpu::GPUInfo& gpu_info);
    184   virtual ~GpuChannelHost();
    185   void Connect(const IPC::ChannelHandle& channel_handle);
    186 
    187   // A filter used internally to route incoming messages from the IO thread
    188   // to the correct message loop. It also maintains some shared state between
    189   // all the contexts.
    190   class MessageFilter : public IPC::ChannelProxy::MessageFilter {
    191    public:
    192     MessageFilter();
    193 
    194     // Called on the IO thread.
    195     void AddRoute(int route_id,
    196                   base::WeakPtr<IPC::Listener> listener,
    197                   scoped_refptr<base::MessageLoopProxy> loop);
    198     // Called on the IO thread.
    199     void RemoveRoute(int route_id);
    200 
    201     // IPC::ChannelProxy::MessageFilter implementation
    202     // (called on the IO thread):
    203     virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
    204     virtual void OnChannelError() OVERRIDE;
    205 
    206     // The following methods can be called on any thread.
    207 
    208     // Whether the channel is lost.
    209     bool IsLost() const;
    210 
    211     // Gets mailboxes from the pool, and return the number of mailboxes to ask
    212     // the GPU process to maintain a good pool size. The caller is responsible
    213     // for sending the GpuChannelMsg_GenerateMailboxNamesAsync message.
    214     size_t GetMailboxNames(size_t num, std::vector<gpu::Mailbox>* names);
    215 
    216    private:
    217     virtual ~MessageFilter();
    218     bool OnControlMessageReceived(const IPC::Message& msg);
    219 
    220     // Message handlers.
    221     void OnGenerateMailboxNamesReply(const std::vector<gpu::Mailbox>& names);
    222 
    223     // Threading notes: |listeners_| is only accessed on the IO thread. Every
    224     // other field is protected by |lock_|.
    225     typedef base::hash_map<int, GpuListenerInfo> ListenerMap;
    226     ListenerMap listeners_;
    227 
    228     // Protects all fields below this one.
    229     mutable base::Lock lock_;
    230 
    231     // Whether the channel has been lost.
    232     bool lost_;
    233 
    234     // A pool of valid mailbox names.
    235     std::vector<gpu::Mailbox> mailbox_name_pool_;
    236 
    237     // Number of pending mailbox requested from the GPU process.
    238     size_t requested_mailboxes_;
    239   };
    240 
    241   // Threading notes: all fields are constant during the lifetime of |this|
    242   // except:
    243   // - |next_transfer_buffer_id_|, atomic type
    244   // - |next_gpu_memory_buffer_id_|, atomic type
    245   // - |proxies_|, protected by |context_lock_|
    246   GpuChannelHostFactory* const factory_;
    247   const int gpu_host_id_;
    248 
    249   const gpu::GPUInfo gpu_info_;
    250 
    251   scoped_ptr<IPC::SyncChannel> channel_;
    252   scoped_refptr<MessageFilter> channel_filter_;
    253 
    254   // A filter for sending messages from thread other than the main thread.
    255   scoped_refptr<IPC::SyncMessageFilter> sync_filter_;
    256 
    257   // Transfer buffer IDs are allocated in sequence.
    258   base::AtomicSequenceNumber next_transfer_buffer_id_;
    259 
    260   // Gpu memory buffer IDs are allocated in sequence.
    261   base::AtomicSequenceNumber next_gpu_memory_buffer_id_;
    262 
    263   // Protects proxies_.
    264   mutable base::Lock context_lock_;
    265   // Used to look up a proxy from its routing id.
    266   typedef base::hash_map<int, CommandBufferProxyImpl*> ProxyMap;
    267   ProxyMap proxies_;
    268 
    269   DISALLOW_COPY_AND_ASSIGN(GpuChannelHost);
    270 };
    271 
    272 }  // namespace content
    273 
    274 #endif  // CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
    275