OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ | 5 #ifndef GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ |
6 #define GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ | 6 #define GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <functional> | 10 #include <functional> |
(...skipping 24 matching lines...) Expand all Loading... |
35 class SyncPointManager; | 35 class SyncPointManager; |
36 | 36 |
37 class GPU_EXPORT SyncPointOrderData | 37 class GPU_EXPORT SyncPointOrderData |
38 : public base::RefCountedThreadSafe<SyncPointOrderData> { | 38 : public base::RefCountedThreadSafe<SyncPointOrderData> { |
39 public: | 39 public: |
40 static scoped_refptr<SyncPointOrderData> Create(); | 40 static scoped_refptr<SyncPointOrderData> Create(); |
41 void Destroy(); | 41 void Destroy(); |
42 | 42 |
43 uint32_t GenerateUnprocessedOrderNumber(SyncPointManager* sync_point_manager); | 43 uint32_t GenerateUnprocessedOrderNumber(SyncPointManager* sync_point_manager); |
44 void BeginProcessingOrderNumber(uint32_t order_num); | 44 void BeginProcessingOrderNumber(uint32_t order_num); |
| 45 void PauseProcessingOrderNumber(uint32_t order_num); |
45 void FinishProcessingOrderNumber(uint32_t order_num); | 46 void FinishProcessingOrderNumber(uint32_t order_num); |
46 | 47 |
47 uint32_t processed_order_num() const { | 48 uint32_t processed_order_num() const { |
48 base::AutoLock auto_lock(lock_); | 49 base::AutoLock auto_lock(lock_); |
49 return processed_order_num_; | 50 return processed_order_num_; |
50 } | 51 } |
51 | 52 |
52 uint32_t unprocessed_order_num() const { | 53 uint32_t unprocessed_order_num() const { |
53 base::AutoLock auto_lock(lock_); | 54 base::AutoLock auto_lock(lock_); |
54 return unprocessed_order_num_; | 55 return unprocessed_order_num_; |
55 } | 56 } |
56 | 57 |
57 uint32_t current_order_num() const { | 58 uint32_t current_order_num() const { |
58 DCHECK(processing_thread_checker_.CalledOnValidThread()); | 59 DCHECK(processing_thread_checker_.CalledOnValidThread()); |
59 return current_order_num_; | 60 return current_order_num_; |
60 } | 61 } |
61 | 62 |
| 63 bool IsProcessingOrderNumber() { |
| 64 DCHECK(processing_thread_checker_.CalledOnValidThread()); |
| 65 return !paused_ && current_order_num_ > processed_order_num(); |
| 66 } |
| 67 |
62 private: | 68 private: |
63 friend class base::RefCountedThreadSafe<SyncPointOrderData>; | 69 friend class base::RefCountedThreadSafe<SyncPointOrderData>; |
64 friend class SyncPointClientState; | 70 friend class SyncPointClientState; |
65 | 71 |
66 struct OrderFence { | 72 struct OrderFence { |
67 uint32_t order_num; | 73 uint32_t order_num; |
68 uint64_t fence_release; | 74 uint64_t fence_release; |
69 scoped_refptr<SyncPointClientState> client_state; | 75 scoped_refptr<SyncPointClientState> client_state; |
70 | 76 |
71 OrderFence(uint32_t order, | 77 OrderFence(uint32_t order, |
(...skipping 18 matching lines...) Expand all Loading... |
90 scoped_refptr<SyncPointClientState> client_state, | 96 scoped_refptr<SyncPointClientState> client_state, |
91 uint32_t wait_order_num, | 97 uint32_t wait_order_num, |
92 uint64_t fence_release); | 98 uint64_t fence_release); |
93 | 99 |
94 // Non thread-safe functions need to be called from a single thread. | 100 // Non thread-safe functions need to be called from a single thread. |
95 base::ThreadChecker processing_thread_checker_; | 101 base::ThreadChecker processing_thread_checker_; |
96 | 102 |
97 // Current IPC order number being processed (only used on processing thread). | 103 // Current IPC order number being processed (only used on processing thread). |
98 uint32_t current_order_num_; | 104 uint32_t current_order_num_; |
99 | 105 |
| 106 // Whether or not the current order number is being processed or paused. |
| 107 bool paused_; |
| 108 |
100 // This lock protects destroyed_, processed_order_num_, | 109 // This lock protects destroyed_, processed_order_num_, |
101 // unprocessed_order_num_, and order_fence_queue_. All order numbers (n) in | 110 // unprocessed_order_num_, and order_fence_queue_. All order numbers (n) in |
102 // order_fence_queue_ must follow the invariant: | 111 // order_fence_queue_ must follow the invariant: |
103 // processed_order_num_ < n <= unprocessed_order_num_. | 112 // processed_order_num_ < n <= unprocessed_order_num_. |
104 mutable base::Lock lock_; | 113 mutable base::Lock lock_; |
105 | 114 |
106 bool destroyed_; | 115 bool destroyed_; |
107 | 116 |
108 // Last finished IPC order number. | 117 // Last finished IPC order number. |
109 uint32_t processed_order_num_; | 118 uint32_t processed_order_num_; |
(...skipping 23 matching lines...) Expand all Loading... |
133 } | 142 } |
134 | 143 |
135 uint64_t fence_sync_release() { | 144 uint64_t fence_sync_release() { |
136 base::AutoLock auto_lock(fence_sync_lock_); | 145 base::AutoLock auto_lock(fence_sync_lock_); |
137 return fence_sync_release_; | 146 return fence_sync_release_; |
138 } | 147 } |
139 | 148 |
140 private: | 149 private: |
141 friend class base::RefCountedThreadSafe<SyncPointClientState>; | 150 friend class base::RefCountedThreadSafe<SyncPointClientState>; |
142 friend class SyncPointClient; | 151 friend class SyncPointClient; |
143 friend class SyncPointClientWaiter; | |
144 friend class SyncPointOrderData; | 152 friend class SyncPointOrderData; |
145 | 153 |
146 struct ReleaseCallback { | 154 struct ReleaseCallback { |
147 uint64_t release_count; | 155 uint64_t release_count; |
148 base::Closure callback_closure; | 156 base::Closure callback_closure; |
149 | 157 |
150 ReleaseCallback(uint64_t release, const base::Closure& callback); | 158 ReleaseCallback(uint64_t release, const base::Closure& callback); |
151 ~ReleaseCallback(); | 159 ~ReleaseCallback(); |
152 | 160 |
153 bool operator>(const ReleaseCallback& rhs) const { | 161 bool operator>(const ReleaseCallback& rhs) const { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 // can supply a task runner. | 214 // can supply a task runner. |
207 bool Wait(SyncPointClientState* release_state, | 215 bool Wait(SyncPointClientState* release_state, |
208 uint64_t release_count, | 216 uint64_t release_count, |
209 const base::Closure& wait_complete_callback); | 217 const base::Closure& wait_complete_callback); |
210 | 218 |
211 bool WaitNonThreadSafe(SyncPointClientState* release_state, | 219 bool WaitNonThreadSafe(SyncPointClientState* release_state, |
212 uint64_t release_count, | 220 uint64_t release_count, |
213 scoped_refptr<base::SingleThreadTaskRunner> runner, | 221 scoped_refptr<base::SingleThreadTaskRunner> runner, |
214 const base::Closure& wait_complete_callback); | 222 const base::Closure& wait_complete_callback); |
215 | 223 |
| 224 // Unordered waits are waits which do not occur within the global order number |
| 225 // processing order (IE. Not between the corresponding |
| 226 // SyncPointOrderData::BeginProcessingOrderNumber() and |
| 227 // SyncPointOrderData::FinishProcessingOrderNumber() calls). Because fence |
| 228 // sync releases must occur within a corresponding order number, these waits |
| 229 // cannot deadlock because they can never depend on any fence sync releases. |
| 230 // This is useful for IPC messages that may be processed out of order with |
| 231 // respect to regular command buffer processing. |
| 232 bool WaitOutOfOrder(SyncPointClientState* release_state, |
| 233 uint64_t release_count, |
| 234 const base::Closure& wait_complete_callback); |
| 235 |
| 236 bool WaitOutOfOrderNonThreadSafe( |
| 237 SyncPointClientState* release_state, |
| 238 uint64_t release_count, |
| 239 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 240 const base::Closure& wait_complete_callback); |
| 241 |
216 void ReleaseFenceSync(uint64_t release); | 242 void ReleaseFenceSync(uint64_t release); |
217 | 243 |
218 private: | 244 private: |
219 friend class SyncPointManager; | 245 friend class SyncPointManager; |
220 | 246 |
| 247 SyncPointClient(); |
221 SyncPointClient(SyncPointManager* sync_point_manager, | 248 SyncPointClient(SyncPointManager* sync_point_manager, |
222 scoped_refptr<SyncPointOrderData> order_data, | 249 scoped_refptr<SyncPointOrderData> order_data, |
223 CommandBufferNamespace namespace_id, | 250 CommandBufferNamespace namespace_id, |
224 uint64_t client_id); | 251 uint64_t client_id); |
225 | 252 |
226 // Sync point manager is guaranteed to exist in the lifetime of the client. | 253 // Sync point manager is guaranteed to exist in the lifetime of the client. |
227 SyncPointManager* sync_point_manager_; | 254 SyncPointManager* sync_point_manager_; |
228 | 255 |
229 // Keep the state that is sharable across multiple threads. | 256 // Keep the state that is sharable across multiple threads. |
230 scoped_refptr<SyncPointClientState> client_state_; | 257 scoped_refptr<SyncPointClientState> client_state_; |
231 | 258 |
232 // Unique namespace/client id pair for this sync point client. | 259 // Unique namespace/client id pair for this sync point client. |
233 const CommandBufferNamespace namespace_id_; | 260 const CommandBufferNamespace namespace_id_; |
234 const uint64_t client_id_; | 261 const uint64_t client_id_; |
235 | 262 |
236 DISALLOW_COPY_AND_ASSIGN(SyncPointClient); | 263 DISALLOW_COPY_AND_ASSIGN(SyncPointClient); |
237 }; | 264 }; |
238 | 265 |
239 // A SyncPointClientWaiter is a Sync Point Client which can only wait and on | |
240 // fence syncs and not release any fence syncs itself. Because they cannot | |
241 // release any fence syncs they do not need an associated order number since | |
242 // deadlocks cannot happen. Note that it is important that this class does | |
243 // not exist in the same execution context as a SyncPointClient, or else a | |
244 // deadlock could occur. Basically, SyncPointClientWaiter::Wait() should never | |
245 // be called between SyncPointOrderData::BeginProcessingOrderNumber() and | |
246 // SyncPointOrderData::FinishProcessingOrderNumber() on the same thread. | |
247 class GPU_EXPORT SyncPointClientWaiter { | |
248 public: | |
249 SyncPointClientWaiter() {} | |
250 ~SyncPointClientWaiter() {} | |
251 | |
252 bool Wait(SyncPointClientState* release_state, | |
253 uint64_t release_count, | |
254 const base::Closure& wait_complete_callback); | |
255 | |
256 bool WaitNonThreadSafe(SyncPointClientState* release_state, | |
257 uint64_t release_count, | |
258 scoped_refptr<base::SingleThreadTaskRunner> runner, | |
259 const base::Closure& wait_complete_callback); | |
260 | |
261 private: | |
262 DISALLOW_COPY_AND_ASSIGN(SyncPointClientWaiter); | |
263 }; | |
264 | |
265 // This class manages the sync points, which allow cross-channel | 266 // This class manages the sync points, which allow cross-channel |
266 // synchronization. | 267 // synchronization. |
267 class GPU_EXPORT SyncPointManager { | 268 class GPU_EXPORT SyncPointManager { |
268 public: | 269 public: |
269 explicit SyncPointManager(bool allow_threaded_wait); | 270 explicit SyncPointManager(bool allow_threaded_wait); |
270 ~SyncPointManager(); | 271 ~SyncPointManager(); |
271 | 272 |
272 // Creates/Destroy a sync point client which message processors should hold. | 273 // Creates/Destroy a sync point client which message processors should hold. |
273 scoped_ptr<SyncPointClient> CreateSyncPointClient( | 274 scoped_ptr<SyncPointClient> CreateSyncPointClient( |
274 scoped_refptr<SyncPointOrderData> order_data, | 275 scoped_refptr<SyncPointOrderData> order_data, |
275 CommandBufferNamespace namespace_id, | 276 CommandBufferNamespace namespace_id, |
276 uint64_t client_id); | 277 uint64_t client_id); |
277 | 278 |
| 279 // Creates a sync point client which cannot process order numbers but can only |
| 280 // Wait out of order. |
| 281 scoped_ptr<SyncPointClient> CreateSyncPointClientWaiter(); |
| 282 |
278 // Finds the state of an already created sync point client. | 283 // Finds the state of an already created sync point client. |
279 scoped_refptr<SyncPointClientState> GetSyncPointClientState( | 284 scoped_refptr<SyncPointClientState> GetSyncPointClientState( |
280 CommandBufferNamespace namespace_id, uint64_t client_id); | 285 CommandBufferNamespace namespace_id, uint64_t client_id); |
281 | 286 |
282 // Generates a sync point, returning its ID. This can me called on any thread. | 287 // Generates a sync point, returning its ID. This can me called on any thread. |
283 // IDs start at a random number. Never return 0. | 288 // IDs start at a random number. Never return 0. |
284 uint32_t GenerateSyncPoint(); | 289 uint32_t GenerateSyncPoint(); |
285 | 290 |
286 // Retires a sync point. This will call all the registered callbacks for this | 291 // Retires a sync point. This will call all the registered callbacks for this |
287 // sync point. This can only be called on the main thread. | 292 // sync point. This can only be called on the main thread. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 SyncPointMap sync_point_map_; | 332 SyncPointMap sync_point_map_; |
328 uint32_t next_sync_point_; | 333 uint32_t next_sync_point_; |
329 base::ConditionVariable retire_cond_var_; | 334 base::ConditionVariable retire_cond_var_; |
330 | 335 |
331 DISALLOW_COPY_AND_ASSIGN(SyncPointManager); | 336 DISALLOW_COPY_AND_ASSIGN(SyncPointManager); |
332 }; | 337 }; |
333 | 338 |
334 } // namespace gpu | 339 } // namespace gpu |
335 | 340 |
336 #endif // GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ | 341 #endif // GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ |
OLD | NEW |