OLD | NEW |
| (Empty) |
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 GPU_IPC_SERVICE_GPU_CHANNEL_H_ | |
6 #define GPU_IPC_SERVICE_GPU_CHANNEL_H_ | |
7 | |
8 #include <stddef.h> | |
9 #include <stdint.h> | |
10 | |
11 #include <string> | |
12 | |
13 #include "base/containers/hash_tables.h" | |
14 #include "base/containers/scoped_ptr_hash_map.h" | |
15 #include "base/macros.h" | |
16 #include "base/memory/ref_counted.h" | |
17 #include "base/memory/scoped_ptr.h" | |
18 #include "base/memory/weak_ptr.h" | |
19 #include "base/process/process.h" | |
20 #include "base/threading/thread_checker.h" | |
21 #include "base/trace_event/memory_dump_provider.h" | |
22 #include "build/build_config.h" | |
23 #include "gpu/command_buffer/service/valuebuffer_manager.h" | |
24 #include "gpu/gpu_export.h" | |
25 #include "gpu/ipc/common/gpu_stream_constants.h" | |
26 #include "gpu/ipc/service/gpu_command_buffer_stub.h" | |
27 #include "gpu/ipc/service/gpu_memory_manager.h" | |
28 #include "ipc/ipc_sync_channel.h" | |
29 #include "ipc/message_router.h" | |
30 #include "ui/gfx/geometry/size.h" | |
31 #include "ui/gfx/native_widget_types.h" | |
32 #include "ui/gl/gl_share_group.h" | |
33 #include "ui/gl/gpu_preference.h" | |
34 | |
35 struct GPUCreateCommandBufferConfig; | |
36 | |
37 namespace base { | |
38 class WaitableEvent; | |
39 } | |
40 | |
41 namespace IPC { | |
42 class MessageFilter; | |
43 } | |
44 | |
45 namespace gpu { | |
46 | |
47 class PreemptionFlag; | |
48 class SyncPointOrderData; | |
49 class SyncPointManager; | |
50 union ValueState; | |
51 class ValueStateMap; | |
52 class GpuChannelManager; | |
53 class GpuChannelMessageFilter; | |
54 class GpuChannelMessageQueue; | |
55 class GpuWatchdog; | |
56 | |
57 namespace gles2 { | |
58 class SubscriptionRefSet; | |
59 } | |
60 | |
61 // Encapsulates an IPC channel between the GPU process and one renderer | |
62 // process. On the renderer side there's a corresponding GpuChannelHost. | |
63 class GPU_EXPORT GpuChannel | |
64 : public IPC::Listener, | |
65 public IPC::Sender, | |
66 public gles2::SubscriptionRefSet::Observer { | |
67 public: | |
68 // Takes ownership of the renderer process handle. | |
69 GpuChannel(GpuChannelManager* gpu_channel_manager, | |
70 SyncPointManager* sync_point_manager, | |
71 GpuWatchdog* watchdog, | |
72 gfx::GLShareGroup* share_group, | |
73 gles2::MailboxManager* mailbox_manager, | |
74 PreemptionFlag* preempting_flag, | |
75 PreemptionFlag* preempted_flag, | |
76 base::SingleThreadTaskRunner* task_runner, | |
77 base::SingleThreadTaskRunner* io_task_runner, | |
78 int32_t client_id, | |
79 uint64_t client_tracing_id, | |
80 bool allow_view_command_buffers, | |
81 bool allow_real_time_streams); | |
82 ~GpuChannel() override; | |
83 | |
84 // Initializes the IPC channel. Caller takes ownership of the client FD in | |
85 // the returned handle and is responsible for closing it. | |
86 virtual IPC::ChannelHandle Init(base::WaitableEvent* shutdown_event); | |
87 | |
88 void SetUnhandledMessageListener(IPC::Listener* listener); | |
89 | |
90 // Get the GpuChannelManager that owns this channel. | |
91 GpuChannelManager* gpu_channel_manager() const { | |
92 return gpu_channel_manager_; | |
93 } | |
94 | |
95 const std::string& channel_id() const { return channel_id_; } | |
96 | |
97 virtual base::ProcessId GetClientPID() const; | |
98 | |
99 int client_id() const { return client_id_; } | |
100 | |
101 uint64_t client_tracing_id() const { return client_tracing_id_; } | |
102 | |
103 base::WeakPtr<GpuChannel> AsWeakPtr(); | |
104 | |
105 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner() const { | |
106 return io_task_runner_; | |
107 } | |
108 | |
109 // IPC::Listener implementation: | |
110 bool OnMessageReceived(const IPC::Message& msg) override; | |
111 void OnChannelError() override; | |
112 | |
113 // IPC::Sender implementation: | |
114 bool Send(IPC::Message* msg) override; | |
115 | |
116 // SubscriptionRefSet::Observer implementation | |
117 void OnAddSubscription(unsigned int target) override; | |
118 void OnRemoveSubscription(unsigned int target) override; | |
119 | |
120 void OnStreamRescheduled(int32_t stream_id, bool scheduled); | |
121 | |
122 gfx::GLShareGroup* share_group() const { return share_group_.get(); } | |
123 | |
124 GpuCommandBufferStub* LookupCommandBuffer(int32_t route_id); | |
125 | |
126 void LoseAllContexts(); | |
127 void MarkAllContextsLost(); | |
128 | |
129 // Called to add a listener for a particular message routing ID. | |
130 // Returns true if succeeded. | |
131 bool AddRoute(int32_t route_id, int32_t stream_id, IPC::Listener* listener); | |
132 | |
133 // Called to remove a listener for a particular message routing ID. | |
134 void RemoveRoute(int32_t route_id); | |
135 | |
136 void CacheShader(const std::string& key, const std::string& shader); | |
137 | |
138 void AddFilter(IPC::MessageFilter* filter); | |
139 void RemoveFilter(IPC::MessageFilter* filter); | |
140 | |
141 uint64_t GetMemoryUsage(); | |
142 | |
143 scoped_refptr<gl::GLImage> CreateImageForGpuMemoryBuffer( | |
144 const gfx::GpuMemoryBufferHandle& handle, | |
145 const gfx::Size& size, | |
146 gfx::BufferFormat format, | |
147 uint32_t internalformat); | |
148 | |
149 void HandleUpdateValueState(unsigned int target, | |
150 const ValueState& state); | |
151 | |
152 GpuChannelMessageFilter* filter() const { return filter_.get(); } | |
153 | |
154 // Visible for testing. | |
155 const ValueStateMap* pending_valuebuffer_state() const { | |
156 return pending_valuebuffer_state_.get(); | |
157 } | |
158 | |
159 // Returns the global order number for the last processed IPC message. | |
160 uint32_t GetProcessedOrderNum() const; | |
161 | |
162 // Returns the global order number for the last unprocessed IPC message. | |
163 uint32_t GetUnprocessedOrderNum() const; | |
164 | |
165 // Returns the shared sync point global order data for the stream. | |
166 scoped_refptr<SyncPointOrderData> GetSyncPointOrderData( | |
167 int32_t stream_id); | |
168 | |
169 void PostHandleOutOfOrderMessage(const IPC::Message& message); | |
170 void PostHandleMessage(const scoped_refptr<GpuChannelMessageQueue>& queue); | |
171 | |
172 // Synchronously handle the message to make testing convenient. | |
173 void HandleMessageForTesting(const IPC::Message& msg); | |
174 | |
175 #if defined(OS_ANDROID) | |
176 const GpuCommandBufferStub* GetOneStub() const; | |
177 #endif | |
178 | |
179 protected: | |
180 // The message filter on the io thread. | |
181 scoped_refptr<GpuChannelMessageFilter> filter_; | |
182 | |
183 // Map of routing id to command buffer stub. | |
184 base::ScopedPtrHashMap<int32_t, scoped_ptr<GpuCommandBufferStub>> stubs_; | |
185 | |
186 private: | |
187 bool OnControlMessageReceived(const IPC::Message& msg); | |
188 | |
189 void HandleMessage(const scoped_refptr<GpuChannelMessageQueue>& queue); | |
190 | |
191 // Some messages such as WaitForGetOffsetInRange and WaitForTokenInRange are | |
192 // processed as soon as possible because the client is blocked until they | |
193 // are completed. | |
194 void HandleOutOfOrderMessage(const IPC::Message& msg); | |
195 | |
196 void HandleMessageHelper(const IPC::Message& msg); | |
197 | |
198 scoped_refptr<GpuChannelMessageQueue> CreateStream( | |
199 int32_t stream_id, | |
200 GpuStreamPriority stream_priority); | |
201 | |
202 scoped_refptr<GpuChannelMessageQueue> LookupStream(int32_t stream_id); | |
203 | |
204 void DestroyStreamIfNecessary( | |
205 const scoped_refptr<GpuChannelMessageQueue>& queue); | |
206 | |
207 void AddRouteToStream(int32_t route_id, int32_t stream_id); | |
208 void RemoveRouteFromStream(int32_t route_id); | |
209 | |
210 // Message handlers for control messages. | |
211 void OnCreateCommandBuffer(SurfaceHandle surface_handle, | |
212 const gfx::Size& size, | |
213 const GPUCreateCommandBufferConfig& init_params, | |
214 int32_t route_id, | |
215 bool* succeeded); | |
216 void OnDestroyCommandBuffer(int32_t route_id); | |
217 | |
218 | |
219 // The lifetime of objects of this class is managed by a GpuChannelManager. | |
220 // The GpuChannelManager destroy all the GpuChannels that they own when they | |
221 // are destroyed. So a raw pointer is safe. | |
222 GpuChannelManager* const gpu_channel_manager_; | |
223 | |
224 // Sync point manager. Outlives the channel and is guaranteed to outlive the | |
225 // message loop. | |
226 SyncPointManager* const sync_point_manager_; | |
227 | |
228 scoped_ptr<IPC::SyncChannel> channel_; | |
229 | |
230 IPC::Listener* unhandled_message_listener_; | |
231 | |
232 // Uniquely identifies the channel within this GPU process. | |
233 std::string channel_id_; | |
234 | |
235 // Used to implement message routing functionality to CommandBuffer objects | |
236 IPC::MessageRouter router_; | |
237 | |
238 // Whether the processing of IPCs on this channel is stalled and we should | |
239 // preempt other GpuChannels. | |
240 scoped_refptr<PreemptionFlag> preempting_flag_; | |
241 | |
242 // If non-NULL, all stubs on this channel should stop processing GL | |
243 // commands (via their CommandExecutor) when preempted_flag_->IsSet() | |
244 scoped_refptr<PreemptionFlag> preempted_flag_; | |
245 | |
246 // The id of the client who is on the other side of the channel. | |
247 const int32_t client_id_; | |
248 | |
249 // The tracing ID used for memory allocations associated with this client. | |
250 const uint64_t client_tracing_id_; | |
251 | |
252 // The task runners for the main thread and the io thread. | |
253 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
254 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; | |
255 | |
256 // The share group that all contexts associated with a particular renderer | |
257 // process use. | |
258 scoped_refptr<gfx::GLShareGroup> share_group_; | |
259 | |
260 scoped_refptr<gles2::MailboxManager> mailbox_manager_; | |
261 | |
262 scoped_refptr<gles2::SubscriptionRefSet> subscription_ref_set_; | |
263 | |
264 scoped_refptr<ValueStateMap> pending_valuebuffer_state_; | |
265 | |
266 gles2::DisallowedFeatures disallowed_features_; | |
267 GpuWatchdog* const watchdog_; | |
268 | |
269 // Map of stream id to appropriate message queue. | |
270 base::hash_map<int32_t, scoped_refptr<GpuChannelMessageQueue>> streams_; | |
271 | |
272 // Multimap of stream id to route ids. | |
273 base::hash_map<int32_t, int> streams_to_num_routes_; | |
274 | |
275 // Map of route id to stream id; | |
276 base::hash_map<int32_t, int32_t> routes_to_streams_; | |
277 | |
278 // Can view command buffers be created on this channel. | |
279 const bool allow_view_command_buffers_; | |
280 | |
281 // Can real time streams be created on this channel. | |
282 const bool allow_real_time_streams_; | |
283 | |
284 // Member variables should appear before the WeakPtrFactory, to ensure | |
285 // that any WeakPtrs to Controller are invalidated before its members | |
286 // variable's destructors are executed, rendering them invalid. | |
287 base::WeakPtrFactory<GpuChannel> weak_factory_; | |
288 | |
289 DISALLOW_COPY_AND_ASSIGN(GpuChannel); | |
290 }; | |
291 | |
292 // This filter does three things: | |
293 // - it counts and timestamps each message forwarded to the channel | |
294 // so that we can preempt other channels if a message takes too long to | |
295 // process. To guarantee fairness, we must wait a minimum amount of time | |
296 // before preempting and we limit the amount of time that we can preempt in | |
297 // one shot (see constants above). | |
298 // - it handles the GpuCommandBufferMsg_InsertSyncPoint message on the IO | |
299 // thread, generating the sync point ID and responding immediately, and then | |
300 // posting a task to insert the GpuCommandBufferMsg_RetireSyncPoint message | |
301 // into the channel's queue. | |
302 // - it generates mailbox names for clients of the GPU process on the IO thread. | |
303 class GPU_EXPORT GpuChannelMessageFilter : public IPC::MessageFilter { | |
304 public: | |
305 GpuChannelMessageFilter(); | |
306 | |
307 // IPC::MessageFilter implementation. | |
308 void OnFilterAdded(IPC::Sender* sender) override; | |
309 void OnFilterRemoved() override; | |
310 void OnChannelConnected(int32_t peer_pid) override; | |
311 void OnChannelError() override; | |
312 void OnChannelClosing() override; | |
313 bool OnMessageReceived(const IPC::Message& message) override; | |
314 | |
315 void AddChannelFilter(scoped_refptr<IPC::MessageFilter> filter); | |
316 void RemoveChannelFilter(scoped_refptr<IPC::MessageFilter> filter); | |
317 | |
318 void AddRoute(int32_t route_id, | |
319 const scoped_refptr<GpuChannelMessageQueue>& queue); | |
320 void RemoveRoute(int32_t route_id); | |
321 | |
322 bool Send(IPC::Message* message); | |
323 | |
324 protected: | |
325 ~GpuChannelMessageFilter() override; | |
326 | |
327 private: | |
328 scoped_refptr<GpuChannelMessageQueue> LookupStreamByRoute(int32_t route_id); | |
329 | |
330 bool MessageErrorHandler(const IPC::Message& message, const char* error_msg); | |
331 | |
332 // Map of route id to message queue. | |
333 base::hash_map<int32_t, scoped_refptr<GpuChannelMessageQueue>> routes_; | |
334 base::Lock routes_lock_; // Protects |routes_|. | |
335 | |
336 IPC::Sender* sender_; | |
337 base::ProcessId peer_pid_; | |
338 std::vector<scoped_refptr<IPC::MessageFilter>> channel_filters_; | |
339 | |
340 DISALLOW_COPY_AND_ASSIGN(GpuChannelMessageFilter); | |
341 }; | |
342 | |
343 struct GpuChannelMessage { | |
344 IPC::Message message; | |
345 uint32_t order_number; | |
346 base::TimeTicks time_received; | |
347 | |
348 GpuChannelMessage(const IPC::Message& msg, | |
349 uint32_t order_num, | |
350 base::TimeTicks ts) | |
351 : message(msg), order_number(order_num), time_received(ts) {} | |
352 | |
353 private: | |
354 DISALLOW_COPY_AND_ASSIGN(GpuChannelMessage); | |
355 }; | |
356 | |
357 class GpuChannelMessageQueue | |
358 : public base::RefCountedThreadSafe<GpuChannelMessageQueue> { | |
359 public: | |
360 static scoped_refptr<GpuChannelMessageQueue> Create( | |
361 int32_t stream_id, | |
362 GpuStreamPriority stream_priority, | |
363 GpuChannel* channel, | |
364 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | |
365 const scoped_refptr<PreemptionFlag>& preempting_flag, | |
366 const scoped_refptr<PreemptionFlag>& preempted_flag, | |
367 SyncPointManager* sync_point_manager); | |
368 | |
369 void Disable(); | |
370 void DisableIO(); | |
371 | |
372 int32_t stream_id() const { return stream_id_; } | |
373 GpuStreamPriority stream_priority() const { return stream_priority_; } | |
374 | |
375 bool IsScheduled() const; | |
376 void OnRescheduled(bool scheduled); | |
377 | |
378 bool HasQueuedMessages() const; | |
379 | |
380 base::TimeTicks GetNextMessageTimeTick() const; | |
381 | |
382 scoped_refptr<SyncPointOrderData> GetSyncPointOrderData(); | |
383 | |
384 // Returns the global order number for the last unprocessed IPC message. | |
385 uint32_t GetUnprocessedOrderNum() const; | |
386 | |
387 // Returns the global order number for the last unprocessed IPC message. | |
388 uint32_t GetProcessedOrderNum() const; | |
389 | |
390 // Should be called before a message begins to be processed. Returns false if | |
391 // there are no messages to process. | |
392 const GpuChannelMessage* BeginMessageProcessing(); | |
393 // Should be called if a message began processing but did not finish. | |
394 void PauseMessageProcessing(); | |
395 // Should be called if a message is completely processed. Returns true if | |
396 // there are more messages to process. | |
397 void FinishMessageProcessing(); | |
398 | |
399 bool PushBackMessage(const IPC::Message& message); | |
400 | |
401 private: | |
402 enum PreemptionState { | |
403 // Either there's no other channel to preempt, there are no messages | |
404 // pending processing, or we just finished preempting and have to wait | |
405 // before preempting again. | |
406 IDLE, | |
407 // We are waiting kPreemptWaitTimeMs before checking if we should preempt. | |
408 WAITING, | |
409 // We can preempt whenever any IPC processing takes more than | |
410 // kPreemptWaitTimeMs. | |
411 CHECKING, | |
412 // We are currently preempting (i.e. no stub is descheduled). | |
413 PREEMPTING, | |
414 // We would like to preempt, but some stub is descheduled. | |
415 WOULD_PREEMPT_DESCHEDULED, | |
416 }; | |
417 | |
418 friend class base::RefCountedThreadSafe<GpuChannelMessageQueue>; | |
419 | |
420 GpuChannelMessageQueue( | |
421 int32_t stream_id, | |
422 GpuStreamPriority stream_priority, | |
423 GpuChannel* channel, | |
424 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | |
425 const scoped_refptr<PreemptionFlag>& preempting_flag, | |
426 const scoped_refptr<PreemptionFlag>& preempted_flag, | |
427 SyncPointManager* sync_point_manager); | |
428 ~GpuChannelMessageQueue(); | |
429 | |
430 void UpdatePreemptionState(); | |
431 void UpdatePreemptionStateHelper(); | |
432 | |
433 void UpdateStateIdle(); | |
434 void UpdateStateWaiting(); | |
435 void UpdateStateChecking(); | |
436 void UpdateStatePreempting(); | |
437 void UpdateStateWouldPreemptDescheduled(); | |
438 | |
439 void TransitionToIdle(); | |
440 void TransitionToWaiting(); | |
441 void TransitionToChecking(); | |
442 void TransitionToPreempting(); | |
443 void TransitionToWouldPreemptDescheduled(); | |
444 | |
445 bool ShouldTransitionToIdle() const; | |
446 | |
447 const int32_t stream_id_; | |
448 const GpuStreamPriority stream_priority_; | |
449 | |
450 // These can be accessed from both IO and main threads and are protected by | |
451 // |channel_lock_|. | |
452 bool enabled_; | |
453 bool scheduled_; | |
454 GpuChannel* const channel_; | |
455 std::deque<scoped_ptr<GpuChannelMessage>> channel_messages_; | |
456 mutable base::Lock channel_lock_; | |
457 | |
458 // The following are accessed on the IO thread only. | |
459 // No lock is necessary for preemption state because it's only accessed on the | |
460 // IO thread. | |
461 PreemptionState preemption_state_; | |
462 // Maximum amount of time that we can spend in PREEMPTING. | |
463 // It is reset when we transition to IDLE. | |
464 base::TimeDelta max_preemption_time_; | |
465 // This timer is used and runs tasks on the IO thread. | |
466 scoped_ptr<base::OneShotTimer> timer_; | |
467 base::ThreadChecker io_thread_checker_; | |
468 | |
469 // Keeps track of sync point related state such as message order numbers. | |
470 scoped_refptr<SyncPointOrderData> sync_point_order_data_; | |
471 | |
472 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; | |
473 scoped_refptr<PreemptionFlag> preempting_flag_; | |
474 scoped_refptr<PreemptionFlag> preempted_flag_; | |
475 SyncPointManager* const sync_point_manager_; | |
476 | |
477 DISALLOW_COPY_AND_ASSIGN(GpuChannelMessageQueue); | |
478 }; | |
479 | |
480 } // namespace gpu | |
481 | |
482 #endif // GPU_IPC_SERVICE_GPU_CHANNEL_H_ | |
OLD | NEW |