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   virtual ~GpuChannelHostFactory() {}
     65 
     66   virtual bool IsMainThread() = 0;
     67   virtual base::MessageLoop* GetMainLoop() = 0;
     68   virtual scoped_refptr<base::MessageLoopProxy> GetIOLoopProxy() = 0;
     69   virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(size_t size) = 0;
     70   virtual CreateCommandBufferResult CreateViewCommandBuffer(
     71       int32 surface_id,
     72       const GPUCreateCommandBufferConfig& init_params,
     73       int32 route_id) = 0;
     74   virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
     75       size_t width,
     76       size_t height,
     77       unsigned internalformat,
     78       unsigned usage) = 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       const gpu::GPUInfo& gpu_info,
     92       const IPC::ChannelHandle& channel_handle,
     93       base::WaitableEvent* shutdown_event);
     94 
     95   // Returns true if |handle| is a valid GpuMemoryBuffer handle that
     96   // can be shared to the GPU process.
     97   static bool IsValidGpuMemoryBuffer(gfx::GpuMemoryBufferHandle handle);
     98 
     99   bool IsLost() const {
    100     DCHECK(channel_filter_.get());
    101     return channel_filter_->IsLost();
    102   }
    103 
    104   // The GPU stats reported by the GPU process.
    105   const gpu::GPUInfo& gpu_info() const { return gpu_info_; }
    106 
    107   // IPC::Sender implementation:
    108   virtual bool Send(IPC::Message* msg) OVERRIDE;
    109 
    110   // Create and connect to a command buffer in the GPU process.
    111   CommandBufferProxyImpl* CreateViewCommandBuffer(
    112       int32 surface_id,
    113       CommandBufferProxyImpl* share_group,
    114       const std::vector<int32>& attribs,
    115       const GURL& active_url,
    116       gfx::GpuPreference gpu_preference);
    117 
    118   // Create and connect to a command buffer in the GPU process.
    119   CommandBufferProxyImpl* CreateOffscreenCommandBuffer(
    120       const gfx::Size& size,
    121       CommandBufferProxyImpl* share_group,
    122       const std::vector<int32>& attribs,
    123       const GURL& active_url,
    124       gfx::GpuPreference gpu_preference);
    125 
    126   // Creates a video decoder in the GPU process.
    127   scoped_ptr<media::VideoDecodeAccelerator> CreateVideoDecoder(
    128       int command_buffer_route_id);
    129 
    130   // Creates a video encoder in the GPU process.
    131   scoped_ptr<media::VideoEncodeAccelerator> CreateVideoEncoder(
    132       int command_buffer_route_id);
    133 
    134   // Destroy a command buffer created by this channel.
    135   void DestroyCommandBuffer(CommandBufferProxyImpl* command_buffer);
    136 
    137   // Add a route for the current message loop.
    138   void AddRoute(int route_id, base::WeakPtr<IPC::Listener> listener);
    139   void RemoveRoute(int route_id);
    140 
    141   GpuChannelHostFactory* factory() const { return factory_; }
    142 
    143   // Returns a handle to the shared memory that can be sent via IPC to the
    144   // GPU process. The caller is responsible for ensuring it is closed. Returns
    145   // an invalid handle on failure.
    146   base::SharedMemoryHandle ShareToGpuProcess(
    147       base::SharedMemoryHandle source_handle);
    148 
    149   // Reserve one unused transfer buffer ID.
    150   int32 ReserveTransferBufferId();
    151 
    152   // Returns a GPU memory buffer handle to the buffer that can be sent via
    153   // IPC to the GPU process. The caller is responsible for ensuring it is
    154   // closed. Returns an invalid handle on failure.
    155   gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuProcess(
    156       gfx::GpuMemoryBufferHandle source_handle);
    157 
    158   // Reserve one unused gpu memory buffer ID.
    159   int32 ReserveGpuMemoryBufferId();
    160 
    161   // Generate a route ID guaranteed to be unique for this channel.
    162   int32 GenerateRouteID();
    163 
    164  private:
    165   friend class base::RefCountedThreadSafe<GpuChannelHost>;
    166   GpuChannelHost(GpuChannelHostFactory* factory,
    167                  const gpu::GPUInfo& gpu_info);
    168   virtual ~GpuChannelHost();
    169   void Connect(const IPC::ChannelHandle& channel_handle,
    170                base::WaitableEvent* shutdown_event);
    171 
    172   // A filter used internally to route incoming messages from the IO thread
    173   // to the correct message loop. It also maintains some shared state between
    174   // all the contexts.
    175   class MessageFilter : public IPC::MessageFilter {
    176    public:
    177     MessageFilter();
    178 
    179     // Called on the IO thread.
    180     void AddRoute(int route_id,
    181                   base::WeakPtr<IPC::Listener> listener,
    182                   scoped_refptr<base::MessageLoopProxy> loop);
    183     // Called on the IO thread.
    184     void RemoveRoute(int route_id);
    185 
    186     // IPC::MessageFilter implementation
    187     // (called on the IO thread):
    188     virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
    189     virtual void OnChannelError() OVERRIDE;
    190 
    191     // The following methods can be called on any thread.
    192 
    193     // Whether the channel is lost.
    194     bool IsLost() const;
    195 
    196    private:
    197     virtual ~MessageFilter();
    198 
    199     // Threading notes: |listeners_| is only accessed on the IO thread. Every
    200     // other field is protected by |lock_|.
    201     typedef base::hash_map<int, GpuListenerInfo> ListenerMap;
    202     ListenerMap listeners_;
    203 
    204     // Protects all fields below this one.
    205     mutable base::Lock lock_;
    206 
    207     // Whether the channel has been lost.
    208     bool lost_;
    209   };
    210 
    211   // Threading notes: all fields are constant during the lifetime of |this|
    212   // except:
    213   // - |next_transfer_buffer_id_|, atomic type
    214   // - |next_gpu_memory_buffer_id_|, atomic type
    215   // - |next_route_id_|, atomic type
    216   // - |proxies_|, protected by |context_lock_|
    217   GpuChannelHostFactory* const factory_;
    218 
    219   const gpu::GPUInfo gpu_info_;
    220 
    221   scoped_ptr<IPC::SyncChannel> channel_;
    222   scoped_refptr<MessageFilter> channel_filter_;
    223 
    224   // A filter for sending messages from thread other than the main thread.
    225   scoped_refptr<IPC::SyncMessageFilter> sync_filter_;
    226 
    227   // Transfer buffer IDs are allocated in sequence.
    228   base::AtomicSequenceNumber next_transfer_buffer_id_;
    229 
    230   // Gpu memory buffer IDs are allocated in sequence.
    231   base::AtomicSequenceNumber next_gpu_memory_buffer_id_;
    232 
    233   // Route IDs are allocated in sequence.
    234   base::AtomicSequenceNumber next_route_id_;
    235 
    236   // Protects proxies_.
    237   mutable base::Lock context_lock_;
    238   // Used to look up a proxy from its routing id.
    239   typedef base::hash_map<int, CommandBufferProxyImpl*> ProxyMap;
    240   ProxyMap proxies_;
    241 
    242   DISALLOW_COPY_AND_ASSIGN(GpuChannelHost);
    243 };
    244 
    245 }  // namespace content
    246 
    247 #endif  // CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
    248