| 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 |