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