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_GPU_CHANNEL_H_ 6 #define CONTENT_COMMON_GPU_GPU_CHANNEL_H_ 7 8 #include <deque> 9 #include <string> 10 11 #include "base/id_map.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_vector.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/process/process.h" 17 #include "build/build_config.h" 18 #include "content/common/gpu/gpu_command_buffer_stub.h" 19 #include "content/common/gpu/gpu_memory_manager.h" 20 #include "content/common/gpu/gpu_result_codes.h" 21 #include "content/common/message_router.h" 22 #include "ipc/ipc_sync_channel.h" 23 #include "ui/gfx/native_widget_types.h" 24 #include "ui/gfx/size.h" 25 #include "ui/gl/gl_share_group.h" 26 #include "ui/gl/gpu_preference.h" 27 28 struct GPUCreateCommandBufferConfig; 29 30 namespace base { 31 class MessageLoopProxy; 32 class WaitableEvent; 33 } 34 35 namespace gpu { 36 class PreemptionFlag; 37 namespace gles2 { 38 class ImageManager; 39 } 40 } 41 42 namespace IPC { 43 class MessageFilter; 44 } 45 46 namespace content { 47 class DevToolsGpuAgent; 48 class GpuChannelManager; 49 class GpuChannelMessageFilter; 50 class GpuWatchdog; 51 52 // Encapsulates an IPC channel between the GPU process and one renderer 53 // process. On the renderer side there's a corresponding GpuChannelHost. 54 class GpuChannel : public IPC::Listener, public IPC::Sender { 55 public: 56 // Takes ownership of the renderer process handle. 57 GpuChannel(GpuChannelManager* gpu_channel_manager, 58 GpuWatchdog* watchdog, 59 gfx::GLShareGroup* share_group, 60 gpu::gles2::MailboxManager* mailbox_manager, 61 int client_id, 62 bool software); 63 virtual ~GpuChannel(); 64 65 void Init(base::MessageLoopProxy* io_message_loop, 66 base::WaitableEvent* shutdown_event); 67 68 // Get the GpuChannelManager that owns this channel. 69 GpuChannelManager* gpu_channel_manager() const { 70 return gpu_channel_manager_; 71 } 72 73 // Returns the name of the associated IPC channel. 74 std::string GetChannelName(); 75 76 #if defined(OS_POSIX) 77 int TakeRendererFileDescriptor(); 78 #endif // defined(OS_POSIX) 79 80 base::ProcessId renderer_pid() const { return channel_->GetPeerPID(); } 81 82 int client_id() const { return client_id_; } 83 84 scoped_refptr<base::MessageLoopProxy> io_message_loop() const { 85 return io_message_loop_; 86 } 87 88 // IPC::Listener implementation: 89 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; 90 virtual void OnChannelError() OVERRIDE; 91 92 // IPC::Sender implementation: 93 virtual bool Send(IPC::Message* msg) OVERRIDE; 94 95 // Requeue the message that is currently being processed to the beginning of 96 // the queue. Used when the processing of a message gets aborted because of 97 // unscheduling conditions. 98 void RequeueMessage(); 99 100 // This is called when a command buffer transitions from the unscheduled 101 // state to the scheduled state, which potentially means the channel 102 // transitions from the unscheduled to the scheduled state. When this occurs 103 // deferred IPC messaged are handled. 104 void OnScheduled(); 105 106 // This is called when a command buffer transitions between scheduled and 107 // descheduled states. When any stub is descheduled, we stop preempting 108 // other channels. 109 void StubSchedulingChanged(bool scheduled); 110 111 CreateCommandBufferResult CreateViewCommandBuffer( 112 const gfx::GLSurfaceHandle& window, 113 int32 surface_id, 114 const GPUCreateCommandBufferConfig& init_params, 115 int32 route_id); 116 117 void CreateImage( 118 gfx::PluginWindowHandle window, 119 int32 image_id, 120 gfx::Size* size); 121 void DeleteImage(int32 image_id); 122 123 gfx::GLShareGroup* share_group() const { return share_group_.get(); } 124 125 GpuCommandBufferStub* LookupCommandBuffer(int32 route_id); 126 127 void LoseAllContexts(); 128 void MarkAllContextsLost(); 129 130 // Called to add a listener for a particular message routing ID. 131 // Returns true if succeeded. 132 bool AddRoute(int32 route_id, IPC::Listener* listener); 133 134 // Called to remove a listener for a particular message routing ID. 135 void RemoveRoute(int32 route_id); 136 137 gpu::PreemptionFlag* GetPreemptionFlag(); 138 139 bool handle_messages_scheduled() const { return handle_messages_scheduled_; } 140 uint64 messages_processed() const { return messages_processed_; } 141 142 // If |preemption_flag->IsSet()|, any stub on this channel 143 // should stop issuing GL commands. Setting this to NULL stops deferral. 144 void SetPreemptByFlag( 145 scoped_refptr<gpu::PreemptionFlag> preemption_flag); 146 147 void CacheShader(const std::string& key, const std::string& shader); 148 149 void AddFilter(IPC::MessageFilter* filter); 150 void RemoveFilter(IPC::MessageFilter* filter); 151 152 uint64 GetMemoryUsage(); 153 154 private: 155 friend class GpuChannelMessageFilter; 156 157 void OnDestroy(); 158 159 bool OnControlMessageReceived(const IPC::Message& msg); 160 161 void HandleMessage(); 162 163 // Message handlers. 164 void OnCreateOffscreenCommandBuffer( 165 const gfx::Size& size, 166 const GPUCreateCommandBufferConfig& init_params, 167 int32 route_id, 168 bool* succeeded); 169 void OnDestroyCommandBuffer(int32 route_id); 170 void OnDevToolsStartEventsRecording(int32 route_id, bool* succeeded); 171 void OnDevToolsStopEventsRecording(); 172 173 // Decrement the count of unhandled IPC messages and defer preemption. 174 void MessageProcessed(); 175 176 // The lifetime of objects of this class is managed by a GpuChannelManager. 177 // The GpuChannelManager destroy all the GpuChannels that they own when they 178 // are destroyed. So a raw pointer is safe. 179 GpuChannelManager* gpu_channel_manager_; 180 181 scoped_ptr<IPC::SyncChannel> channel_; 182 183 uint64 messages_processed_; 184 185 // Whether the processing of IPCs on this channel is stalled and we should 186 // preempt other GpuChannels. 187 scoped_refptr<gpu::PreemptionFlag> preempting_flag_; 188 189 // If non-NULL, all stubs on this channel should stop processing GL 190 // commands (via their GpuScheduler) when preempted_flag_->IsSet() 191 scoped_refptr<gpu::PreemptionFlag> preempted_flag_; 192 193 std::deque<IPC::Message*> deferred_messages_; 194 195 // The id of the client who is on the other side of the channel. 196 int client_id_; 197 198 // Uniquely identifies the channel within this GPU process. 199 std::string channel_id_; 200 201 // Used to implement message routing functionality to CommandBuffer objects 202 MessageRouter router_; 203 204 // The share group that all contexts associated with a particular renderer 205 // process use. 206 scoped_refptr<gfx::GLShareGroup> share_group_; 207 208 scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_; 209 scoped_refptr<gpu::gles2::ImageManager> image_manager_; 210 211 typedef IDMap<GpuCommandBufferStub, IDMapOwnPointer> StubMap; 212 StubMap stubs_; 213 214 bool log_messages_; // True if we should log sent and received messages. 215 gpu::gles2::DisallowedFeatures disallowed_features_; 216 GpuWatchdog* watchdog_; 217 bool software_; 218 bool handle_messages_scheduled_; 219 IPC::Message* currently_processing_message_; 220 221 base::WeakPtrFactory<GpuChannel> weak_factory_; 222 223 scoped_refptr<GpuChannelMessageFilter> filter_; 224 scoped_refptr<base::MessageLoopProxy> io_message_loop_; 225 scoped_ptr<DevToolsGpuAgent> devtools_gpu_agent_; 226 227 size_t num_stubs_descheduled_; 228 229 DISALLOW_COPY_AND_ASSIGN(GpuChannel); 230 }; 231 232 } // namespace content 233 234 #endif // CONTENT_COMMON_GPU_GPU_CHANNEL_H_ 235