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 <functional> | |
9 #include <queue> | |
8 #include <vector> | 10 #include <vector> |
9 | 11 |
10 #include "base/atomic_sequence_num.h" | 12 #include "base/atomic_sequence_num.h" |
11 #include "base/callback.h" | 13 #include "base/callback.h" |
12 #include "base/containers/hash_tables.h" | 14 #include "base/containers/hash_tables.h" |
13 #include "base/logging.h" | 15 #include "base/logging.h" |
14 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
15 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
16 #include "base/synchronization/condition_variable.h" | 18 #include "base/synchronization/condition_variable.h" |
17 #include "base/synchronization/lock.h" | 19 #include "base/synchronization/lock.h" |
18 #include "base/threading/thread_checker.h" | 20 #include "base/threading/thread_checker.h" |
19 #include "gpu/command_buffer/common/constants.h" | 21 #include "gpu/command_buffer/common/constants.h" |
20 #include "gpu/gpu_export.h" | 22 #include "gpu/gpu_export.h" |
21 | 23 |
24 namespace base { | |
25 class SingleThreadTaskRunner; | |
26 } // namespace base | |
27 | |
22 namespace gpu { | 28 namespace gpu { |
23 | 29 |
24 class SyncPointClient; | 30 class SyncPointClient; |
31 class SyncPointClientState; | |
25 class SyncPointManager; | 32 class SyncPointManager; |
26 | 33 |
27 class GPU_EXPORT SyncPointClientState | 34 class GPU_EXPORT SyncPointOrderData |
28 : public base::RefCountedThreadSafe<SyncPointClientState> { | 35 : public base::RefCountedThreadSafe<SyncPointOrderData> { |
29 public: | 36 public: |
30 static scoped_refptr<SyncPointClientState> Create(); | 37 static scoped_refptr<SyncPointOrderData> Create(); |
38 void Destroy(); | |
39 | |
31 uint32_t GenerateUnprocessedOrderNumber(SyncPointManager* sync_point_manager); | 40 uint32_t GenerateUnprocessedOrderNumber(SyncPointManager* sync_point_manager); |
32 | 41 void BeginProcessingOrderNumber(uint32_t order_num); |
33 void BeginProcessingOrderNumber(uint32_t order_num) { | 42 void FinishProcessingOrderNumber(uint32_t order_num); |
34 DCHECK(processing_thread_checker_.CalledOnValidThread()); | |
35 DCHECK_GE(order_num, current_order_num_); | |
36 current_order_num_ = order_num; | |
37 } | |
38 | |
39 void FinishProcessingOrderNumber(uint32_t order_num) { | |
40 DCHECK(processing_thread_checker_.CalledOnValidThread()); | |
41 DCHECK_EQ(current_order_num_, order_num); | |
42 DCHECK_GT(order_num, processed_order_num()); | |
43 base::subtle::Release_Store(&processed_order_num_, order_num); | |
44 } | |
45 | 43 |
46 uint32_t processed_order_num() const { | 44 uint32_t processed_order_num() const { |
47 return base::subtle::Acquire_Load(&processed_order_num_); | 45 return base::subtle::Acquire_Load(&processed_order_num_); |
48 } | 46 } |
49 | 47 |
50 uint32_t unprocessed_order_num() const { | 48 uint32_t unprocessed_order_num() const { |
51 return base::subtle::Acquire_Load(&unprocessed_order_num_); | 49 return base::subtle::Acquire_Load(&unprocessed_order_num_); |
52 } | 50 } |
53 | 51 |
54 uint32_t current_order_num() const { | 52 uint32_t current_order_num() const { |
55 DCHECK(processing_thread_checker_.CalledOnValidThread()); | 53 DCHECK(processing_thread_checker_.CalledOnValidThread()); |
56 return current_order_num_; | 54 return current_order_num_; |
57 } | 55 } |
58 | 56 |
59 protected: | 57 protected: |
60 friend class base::RefCountedThreadSafe<SyncPointClientState>; | 58 friend class base::RefCountedThreadSafe<SyncPointOrderData>; |
61 friend class SyncPointClient; | 59 friend class SyncPointClientState; |
62 | 60 |
63 SyncPointClientState(); | 61 struct OrderFence { |
64 virtual ~SyncPointClientState(); | 62 uint32_t order_num; |
63 uint64_t fence_release; | |
64 scoped_refptr<SyncPointClientState> client_state; | |
65 | |
66 OrderFence(uint32_t order, uint64_t release, | |
67 scoped_refptr<SyncPointClientState> state); | |
68 ~OrderFence(); | |
69 | |
70 bool operator>(const OrderFence& rhs) const { | |
71 return (order_num > rhs.order_num) || | |
72 ((order_num == rhs.order_num) && | |
73 (fence_release > rhs.fence_release)); | |
74 } | |
75 }; | |
76 typedef std::priority_queue<OrderFence, | |
77 std::vector<OrderFence>, | |
78 std::greater<OrderFence>> OrderFenceQueue; | |
79 | |
80 SyncPointOrderData(); | |
81 virtual ~SyncPointOrderData(); | |
piman
2015/09/30 22:50:23
This doesn't need to be virtual, because nothing d
David Yen
2015/09/30 23:55:18
Done.
| |
82 | |
83 void AddOrderFenceGuard(uint32_t order_num, uint64_t fence_release, | |
84 scoped_refptr<SyncPointClientState> client_state); | |
65 | 85 |
66 // Last finished IPC order number. | 86 // Last finished IPC order number. |
67 base::subtle::Atomic32 processed_order_num_; | 87 base::subtle::Atomic32 processed_order_num_; |
68 | 88 |
69 // Unprocessed order number expected to be processed under normal execution. | 89 // Unprocessed order number expected to be processed under normal execution. |
70 base::subtle::Atomic32 unprocessed_order_num_; | 90 base::subtle::Atomic32 unprocessed_order_num_; |
71 | 91 |
72 // Non thread-safe functions need to be called from a single thread. | 92 // Non thread-safe functions need to be called from a single thread. |
73 base::ThreadChecker processing_thread_checker_; | 93 base::ThreadChecker processing_thread_checker_; |
74 | 94 |
75 // Current IPC order number being processed (only used on processing thread). | 95 // Current IPC order number being processed (only used on processing thread). |
76 uint32_t current_order_num_; | 96 uint32_t current_order_num_; |
77 | 97 |
98 // In situations where we are waiting on fence syncs that do not exist, we | |
99 // validate by making sure the order number does not pass the order number | |
100 // which the wait command was issued. If the order number reaches the | |
101 // wait command's, we should automatically release up to the expected | |
102 // release count. Note that this also releases other lower release counts, | |
103 // so a single misbehaved fence sync is enough to invalidate/signal all | |
104 // previous fence syncs. | |
105 base::Lock order_fence_queue_lock_; | |
106 OrderFenceQueue order_fence_queue_; | |
107 | |
108 DISALLOW_COPY_AND_ASSIGN(SyncPointOrderData); | |
109 }; | |
110 | |
111 class GPU_EXPORT SyncPointClientState | |
112 : public base::RefCountedThreadSafe<SyncPointClientState> { | |
113 public: | |
114 scoped_refptr<SyncPointOrderData> order_data() { return order_data_; } | |
115 | |
116 bool IsFenceSyncReleased(uint64_t release) { | |
117 return release <= fence_sync_release(); | |
118 } | |
119 | |
120 uint64_t fence_sync_release() { | |
121 base::AutoLock auto_lock(fence_sync_lock_); | |
122 return fence_sync_release_; | |
123 } | |
124 | |
125 protected: | |
126 friend class base::RefCountedThreadSafe<SyncPointClientState>; | |
127 friend class SyncPointClient; | |
128 friend class SyncPointOrderData; | |
129 | |
130 struct ReleaseCallback { | |
131 uint64_t release_count; | |
132 base::Closure callback_closure; | |
133 | |
134 ReleaseCallback(uint64_t release, const base::Closure& callback); | |
135 ~ReleaseCallback(); | |
136 | |
137 bool operator>(const ReleaseCallback& rhs) const { | |
138 return release_count > rhs.release_count; | |
139 } | |
140 }; | |
141 typedef std::priority_queue< | |
142 ReleaseCallback, | |
143 std::vector<ReleaseCallback>, | |
144 std::greater<ReleaseCallback>> ReleaseCallbackQueue; | |
145 | |
146 SyncPointClientState(scoped_refptr<SyncPointOrderData> order_data); | |
147 virtual ~SyncPointClientState(); | |
piman
2015/09/30 22:50:23
same here, no need to be virtual.
David Yen
2015/09/30 23:55:18
Done.
| |
148 | |
149 bool WaitForRelease(uint32_t wait_order_num, | |
150 uint64_t release, | |
151 const base::Closure& callback); | |
152 | |
153 void ReleaseFenceSync(uint64_t release); | |
154 void EnsureReleased(uint64_t release); | |
155 void ReleaseFenceSyncLocked(uint64_t release, | |
156 std::vector<base::Closure>* callback_list); | |
157 | |
158 // Global order data where releases will originate from. | |
159 scoped_refptr<SyncPointOrderData> order_data_; | |
160 | |
161 // Protects fence_sync_release_, fence_callback_queue_. | |
162 base::Lock fence_sync_lock_; | |
163 | |
164 // Current fence sync release that has been signaled. | |
165 uint64_t fence_sync_release_; | |
166 | |
167 // In well defined fence sync operations, fence syncs are released in order | |
168 // so simply having a priority queue for callbacks is enough. | |
169 ReleaseCallbackQueue release_callback_queue_; | |
170 | |
78 DISALLOW_COPY_AND_ASSIGN(SyncPointClientState); | 171 DISALLOW_COPY_AND_ASSIGN(SyncPointClientState); |
79 }; | 172 }; |
80 | 173 |
81 class GPU_EXPORT SyncPointClient { | 174 class GPU_EXPORT SyncPointClient { |
82 public: | 175 public: |
83 ~SyncPointClient(); | 176 ~SyncPointClient(); |
84 | 177 |
85 scoped_refptr<SyncPointClientState> client_state() { return client_state_; } | 178 scoped_refptr<SyncPointClientState> client_state() { return client_state_; } |
86 | 179 |
180 // Wait for a release count to be reached on a SyncPointClientState. If this | |
181 // function returns false, that means the wait was invalid. Otherwise if it | |
182 // returns True it means wait_complete_callback will be called eventually. | |
183 // In the case where the release happened already, it will call the callback | |
184 // immediately before returning. The callback function may be called on | |
185 // on another thread so it should be thread-safe. For convenience, another | |
186 // non-threadsafe version is defined below where you can supply a task runner. | |
187 bool Wait(scoped_refptr<SyncPointClientState> release_state, | |
188 uint64_t release_count, | |
189 const base::Closure& wait_complete_callback); | |
190 | |
191 bool WaitNonThreadSafe(scoped_refptr<SyncPointClientState> release_state, | |
192 uint64_t release_count, | |
193 scoped_refptr<base::SingleThreadTaskRunner> runner, | |
194 const base::Closure& wait_complete_callback); | |
195 | |
196 void ReleaseFenceSync(uint64_t release); | |
197 | |
87 private: | 198 private: |
88 friend class SyncPointManager; | 199 friend class SyncPointManager; |
89 | 200 |
90 SyncPointClient(SyncPointManager* sync_point_manager, | 201 SyncPointClient(SyncPointManager* sync_point_manager, |
91 scoped_refptr<SyncPointClientState> state, | 202 scoped_refptr<SyncPointOrderData> order_data, |
92 CommandBufferNamespace namespace_id, uint64_t client_id); | 203 CommandBufferNamespace namespace_id, uint64_t client_id); |
93 | 204 |
94 // Sync point manager is guaranteed to exist in the lifetime of the client. | 205 // Sync point manager is guaranteed to exist in the lifetime of the client. |
95 SyncPointManager* sync_point_manager_; | 206 SyncPointManager* sync_point_manager_; |
96 | 207 |
97 // Keep the state that is sharable across multiple threads. | 208 // Keep the state that is sharable across multiple threads. |
98 scoped_refptr<SyncPointClientState> client_state_; | 209 scoped_refptr<SyncPointClientState> client_state_; |
99 | 210 |
100 // Unique namespace/client id pair for this sync point client. | 211 // Unique namespace/client id pair for this sync point client. |
101 CommandBufferNamespace namespace_id_; | 212 const CommandBufferNamespace namespace_id_; |
102 uint64_t client_id_; | 213 const uint64_t client_id_; |
103 | 214 |
104 DISALLOW_COPY_AND_ASSIGN(SyncPointClient); | 215 DISALLOW_COPY_AND_ASSIGN(SyncPointClient); |
105 }; | 216 }; |
106 | 217 |
107 // This class manages the sync points, which allow cross-channel | 218 // This class manages the sync points, which allow cross-channel |
108 // synchronization. | 219 // synchronization. |
109 class GPU_EXPORT SyncPointManager { | 220 class GPU_EXPORT SyncPointManager { |
110 public: | 221 public: |
111 explicit SyncPointManager(bool allow_threaded_wait); | 222 explicit SyncPointManager(bool allow_threaded_wait); |
112 ~SyncPointManager(); | 223 ~SyncPointManager(); |
113 | 224 |
114 // Creates/Destroy a sync point client which message processors should hold. | 225 // Creates/Destroy a sync point client which message processors should hold. |
115 scoped_ptr<SyncPointClient> CreateSyncPointClient( | 226 scoped_ptr<SyncPointClient> CreateSyncPointClient( |
116 scoped_refptr<SyncPointClientState> client_state, | 227 scoped_refptr<SyncPointOrderData> order_data, |
117 CommandBufferNamespace namespace_id, uint64_t client_id); | 228 CommandBufferNamespace namespace_id, uint64_t client_id); |
118 | 229 |
119 // Finds the state of an already created sync point client. | 230 // Finds the state of an already created sync point client. |
120 scoped_refptr<SyncPointClientState> GetSyncPointClientState( | 231 scoped_refptr<SyncPointClientState> GetSyncPointClientState( |
121 CommandBufferNamespace namespace_id, uint64_t client_id); | 232 CommandBufferNamespace namespace_id, uint64_t client_id); |
122 | 233 |
123 // Generates a sync point, returning its ID. This can me called on any thread. | 234 // Generates a sync point, returning its ID. This can me called on any thread. |
124 // IDs start at a random number. Never return 0. | 235 // IDs start at a random number. Never return 0. |
125 uint32 GenerateSyncPoint(); | 236 uint32 GenerateSyncPoint(); |
126 | 237 |
127 // Retires a sync point. This will call all the registered callbacks for this | 238 // Retires a sync point. This will call all the registered callbacks for this |
128 // sync point. This can only be called on the main thread. | 239 // sync point. This can only be called on the main thread. |
129 void RetireSyncPoint(uint32 sync_point); | 240 void RetireSyncPoint(uint32 sync_point); |
130 | 241 |
131 // Adds a callback to the sync point. The callback will be called when the | 242 // Adds a callback to the sync point. The callback will be called when the |
132 // sync point is retired, or immediately (from within that function) if the | 243 // sync point is retired, or immediately (from within that function) if the |
133 // sync point was already retired (or not created yet). This can only be | 244 // sync point was already retired (or not created yet). This can only be |
134 // called on the main thread. | 245 // called on the main thread. |
135 void AddSyncPointCallback(uint32 sync_point, const base::Closure& callback); | 246 void AddSyncPointCallback(uint32 sync_point, const base::Closure& callback); |
136 | 247 |
137 bool IsSyncPointRetired(uint32 sync_point); | 248 bool IsSyncPointRetired(uint32 sync_point); |
138 | 249 |
139 // Block and wait until a sync point is signaled. This is only useful when | 250 // Block and wait until a sync point is signaled. This is only useful when |
140 // the sync point is signaled on another thread. | 251 // the sync point is signaled on another thread. |
141 void WaitSyncPoint(uint32 sync_point); | 252 void WaitSyncPoint(uint32 sync_point); |
142 | 253 |
143 private: | 254 private: |
144 friend class SyncPointClient; | 255 friend class SyncPointClient; |
145 friend class SyncPointClientState; | 256 friend class SyncPointOrderData; |
146 | 257 |
147 typedef std::vector<base::Closure> ClosureList; | 258 typedef std::vector<base::Closure> ClosureList; |
148 typedef base::hash_map<uint32, ClosureList> SyncPointMap; | 259 typedef base::hash_map<uint32, ClosureList> SyncPointMap; |
149 typedef base::hash_map<uint64_t, SyncPointClient*> ClientMap; | 260 typedef base::hash_map<uint64_t, SyncPointClient*> ClientMap; |
150 | 261 |
151 bool IsSyncPointRetiredLocked(uint32 sync_point); | 262 bool IsSyncPointRetiredLocked(uint32 sync_point); |
152 uint32_t GenerateOrderNumber(); | 263 uint32_t GenerateOrderNumber(); |
153 void DestroySyncPointClient(CommandBufferNamespace namespace_id, | 264 void DestroySyncPointClient(CommandBufferNamespace namespace_id, |
154 uint64_t client_id); | 265 uint64_t client_id); |
155 | 266 |
(...skipping 12 matching lines...) Expand all Loading... | |
168 SyncPointMap sync_point_map_; | 279 SyncPointMap sync_point_map_; |
169 uint32 next_sync_point_; | 280 uint32 next_sync_point_; |
170 base::ConditionVariable retire_cond_var_; | 281 base::ConditionVariable retire_cond_var_; |
171 | 282 |
172 DISALLOW_COPY_AND_ASSIGN(SyncPointManager); | 283 DISALLOW_COPY_AND_ASSIGN(SyncPointManager); |
173 }; | 284 }; |
174 | 285 |
175 } // namespace gpu | 286 } // namespace gpu |
176 | 287 |
177 #endif // GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ | 288 #endif // GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ |
OLD | NEW |