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