gpu_channel_host.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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/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.h" 17#include "base/process_util.h" 18#include "base/synchronization/lock.h" 19#include "content/common/content_export.h" 20#include "content/common/gpu/gpu_process_launch_causes.h" 21#include "content/common/message_router.h" 22#include "content/public/common/gpu_info.h" 23#include "ipc/ipc_channel_handle.h" 24#include "ipc/ipc_channel_proxy.h" 25#include "ipc/ipc_sync_channel.h" 26#include "media/video/video_decode_accelerator.h" 27#include "ui/gfx/native_widget_types.h" 28#include "ui/gfx/size.h" 29#include "ui/gl/gpu_preference.h" 30 31class GURL; 32class TransportTextureService; 33struct GPUCreateCommandBufferConfig; 34 35namespace base { 36class MessageLoop; 37class MessageLoopProxy; 38} 39 40namespace gpu { 41struct Mailbox; 42} 43 44namespace IPC { 45class SyncMessageFilter; 46} 47 48namespace content { 49class CommandBufferProxyImpl; 50class GpuChannelHost; 51struct GpuRenderingStats; 52 53struct GpuListenerInfo { 54 GpuListenerInfo(); 55 ~GpuListenerInfo(); 56 57 base::WeakPtr<IPC::Listener> listener; 58 scoped_refptr<base::MessageLoopProxy> loop; 59}; 60 61class CONTENT_EXPORT GpuChannelHostFactory { 62 public: 63 typedef base::Callback<void(const gfx::Size)> CreateImageCallback; 64 65 virtual ~GpuChannelHostFactory() {} 66 67 virtual bool IsMainThread() = 0; 68 virtual bool IsIOThread() = 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 GpuChannelHost* EstablishGpuChannelSync(CauseForGpuLaunch) = 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}; 82 83// Encapsulates an IPC channel between the client and one GPU process. 84// On the GPU process side there's a corresponding GpuChannel. 85class GpuChannelHost : public IPC::Sender, 86 public base::RefCountedThreadSafe<GpuChannelHost>, 87 public base::SupportsWeakPtr<GpuChannelHost> { 88 public: 89 enum State { 90 // Not yet connected. 91 kUnconnected, 92 // Ready to use. 93 kConnected, 94 // An error caused the host to become disconnected. Recreate channel to 95 // reestablish connection. 96 kLost 97 }; 98 99 // Called on the render thread 100 GpuChannelHost(GpuChannelHostFactory* factory, 101 int gpu_host_id, 102 int client_id); 103 104 // Connect to GPU process channel. 105 void Connect(const IPC::ChannelHandle& channel_handle); 106 107 State state() const { return state_; } 108 109 // Change state to kLost. 110 void SetStateLost(); 111 112 // The GPU stats reported by the GPU process. 113 void set_gpu_info(const GPUInfo& gpu_info); 114 const GPUInfo& gpu_info() const; 115 116 void OnMessageReceived(const IPC::Message& message); 117 void OnChannelError(); 118 119 // IPC::Sender implementation: 120 virtual bool Send(IPC::Message* msg) OVERRIDE; 121 122 // Create and connect to a command buffer in the GPU process. 123 CommandBufferProxyImpl* CreateViewCommandBuffer( 124 int32 surface_id, 125 CommandBufferProxyImpl* share_group, 126 const std::string& allowed_extensions, 127 const std::vector<int32>& attribs, 128 const GURL& active_url, 129 gfx::GpuPreference gpu_preference); 130 131 // Create and connect to a command buffer in the GPU process. 132 CommandBufferProxyImpl* CreateOffscreenCommandBuffer( 133 const gfx::Size& size, 134 CommandBufferProxyImpl* share_group, 135 const std::string& allowed_extensions, 136 const std::vector<int32>& attribs, 137 const GURL& active_url, 138 gfx::GpuPreference gpu_preference); 139 140 // Creates a video decoder in the GPU process. 141 scoped_ptr<media::VideoDecodeAccelerator> CreateVideoDecoder( 142 int command_buffer_route_id, 143 media::VideoCodecProfile profile, 144 media::VideoDecodeAccelerator::Client* client); 145 146 // Destroy a command buffer created by this channel. 147 void DestroyCommandBuffer(CommandBufferProxyImpl* command_buffer); 148 149 // Collect rendering stats from GPU process. 150 bool CollectRenderingStatsForSurface( 151 int surface_id, GpuRenderingStats* stats); 152 153 // Add a route for the current message loop. 154 void AddRoute(int route_id, base::WeakPtr<IPC::Listener> listener); 155 void RemoveRoute(int route_id); 156 157 GpuChannelHostFactory* factory() const { return factory_; } 158 int gpu_host_id() const { return gpu_host_id_; } 159 160 int client_id() const { return client_id_; } 161 162 // Returns a handle to the shared memory that can be sent via IPC to the 163 // GPU process. The caller is responsible for ensuring it is closed. Returns 164 // an invalid handle on failure. 165 base::SharedMemoryHandle ShareToGpuProcess( 166 base::SharedMemoryHandle source_handle); 167 168 // Generates n unique mailbox names that can be used with 169 // GL_texture_mailbox_CHROMIUM. Unlike genMailboxCHROMIUM, this IPC is 170 // handled only on the GPU process' IO thread, and so is not effectively 171 // a finish. 172 bool GenerateMailboxNames(unsigned num, std::vector<gpu::Mailbox>* names); 173 174 // Reserve one unused transfer buffer ID. 175 int32 ReserveTransferBufferId(); 176 177 private: 178 friend class base::RefCountedThreadSafe<GpuChannelHost>; 179 virtual ~GpuChannelHost(); 180 181 // Message handlers. 182 void OnGenerateMailboxNamesReply(const std::vector<gpu::Mailbox>& names); 183 184 // A filter used internally to route incoming messages from the IO thread 185 // to the correct message loop. 186 class MessageFilter : public IPC::ChannelProxy::MessageFilter { 187 public: 188 MessageFilter(base::WeakPtr<GpuChannelHost> parent, 189 GpuChannelHostFactory* factory); 190 191 void AddRoute(int route_id, 192 base::WeakPtr<IPC::Listener> listener, 193 scoped_refptr<base::MessageLoopProxy> loop); 194 void RemoveRoute(int route_id); 195 196 // IPC::ChannelProxy::MessageFilter implementation: 197 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; 198 virtual void OnChannelError() OVERRIDE; 199 200 private: 201 virtual ~MessageFilter(); 202 203 // Note: this reference can only be used to post tasks back to the 204 // GpuChannelHost, it is illegal to dereference on the IO thread where the 205 // MessageFilter lives. 206 base::WeakPtr<GpuChannelHost> parent_; 207 208 scoped_refptr<base::MessageLoopProxy> main_thread_loop_; 209 210 typedef base::hash_map<int, GpuListenerInfo> ListenerMap; 211 ListenerMap listeners_; 212 }; 213 214 GpuChannelHostFactory* factory_; 215 int client_id_; 216 int gpu_host_id_; 217 218 State state_; 219 220 GPUInfo gpu_info_; 221 222 scoped_ptr<IPC::SyncChannel> channel_; 223 scoped_refptr<MessageFilter> channel_filter_; 224 225 // Used to look up a proxy from its routing id. 226 typedef base::hash_map<int, CommandBufferProxyImpl*> ProxyMap; 227 ProxyMap proxies_; 228 229 // A lock to guard against concurrent access to members like the proxies map 230 // for calls from contexts that may live on the compositor or main thread. 231 mutable base::Lock context_lock_; 232 233 // A filter for sending messages from thread other than the main thread. 234 scoped_refptr<IPC::SyncMessageFilter> sync_filter_; 235 236 // A pool of valid mailbox names. 237 std::vector<gpu::Mailbox> mailbox_name_pool_; 238 239 // Transfer buffer IDs are allocated in sequence. 240 base::AtomicSequenceNumber next_transfer_buffer_id_; 241 242 DISALLOW_COPY_AND_ASSIGN(GpuChannelHost); 243}; 244 245} // namespace content 246 247#endif // CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_ 248