Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(983)

Side by Side Diff: gpu/command_buffer/service/sync_point_manager.h

Issue 1568563002: Added a way for sync point clients to issue out of order waits. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Allow WaitOutOfOrder if no client order data Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/in_process_command_buffer.cc ('k') | gpu/command_buffer/service/sync_point_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698