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 #include "gpu/command_buffer/service/sync_point_manager.h" | 5 #include "gpu/command_buffer/service/sync_point_manager.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/memory/ptr_util.h" | |
14 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
15 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
16 | 17 |
17 namespace gpu { | 18 namespace gpu { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 void RunOnThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 22 void RunOnThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
22 const base::Closure& callback) { | 23 const base::Closure& callback) { |
23 if (task_runner->BelongsToCurrentThread()) { | 24 if (task_runner->BelongsToCurrentThread()) { |
24 callback.Run(); | 25 callback.Run(); |
25 } else { | 26 } else { |
26 task_runner->PostTask(FROM_HERE, callback); | 27 task_runner->PostTask(FROM_HERE, callback); |
27 } | 28 } |
28 } | 29 } |
29 | 30 |
30 } // namespace | 31 } // namespace |
31 | 32 |
32 scoped_refptr<SyncPointOrderData> SyncPointOrderData::Create() { | 33 SyncPointOrderData::OrderFence::OrderFence( |
33 return new SyncPointOrderData; | 34 uint32_t order, |
35 uint64_t release, | |
36 const base::Closure& callback, | |
37 scoped_refptr<SyncPointClientState> state) | |
38 : order_num(order), | |
39 fence_release(release), | |
40 release_callback(callback), | |
41 client_state(std::move(state)) {} | |
42 | |
43 SyncPointOrderData::OrderFence::OrderFence(const OrderFence& other) = default; | |
44 | |
45 SyncPointOrderData::OrderFence::~OrderFence() {} | |
46 | |
47 SyncPointOrderData::SyncPointOrderData(SyncPointManager* sync_point_manager, | |
48 SequenceId sequence_id) | |
49 : sync_point_manager_(sync_point_manager), sequence_id_(sequence_id) {} | |
50 | |
51 SyncPointOrderData::~SyncPointOrderData() { | |
52 DCHECK(destroyed_); | |
34 } | 53 } |
35 | 54 |
36 void SyncPointOrderData::Destroy() { | 55 void SyncPointOrderData::Destroy() { |
37 // Because of circular references between the SyncPointOrderData and | 56 // Because of circular references between the SyncPointOrderData and |
38 // SyncPointClientState, we must remove the references on destroy. Releasing | 57 // SyncPointClientState, we must remove the references on destroy. Releasing |
39 // the fence syncs in the order fence queue would be redundant at this point | 58 // the fence syncs in the order fence queue would be redundant at this point |
40 // because they are assumed to be released on the destruction of the | 59 // because they are assumed to be released on the destruction of the |
41 // SyncPointClient. | 60 // SyncPointClientState. |
42 base::AutoLock auto_lock(lock_); | 61 base::AutoLock auto_lock(lock_); |
62 DCHECK(!destroyed_); | |
43 destroyed_ = true; | 63 destroyed_ = true; |
44 while (!order_fence_queue_.empty()) { | 64 while (!order_fence_queue_.empty()) { |
45 order_fence_queue_.pop(); | 65 order_fence_queue_.pop(); |
46 } | 66 } |
67 sync_point_manager_->DestroyedSyncPointOrderData(sequence_id_); | |
47 } | 68 } |
48 | 69 |
49 uint32_t SyncPointOrderData::GenerateUnprocessedOrderNumber( | 70 uint32_t SyncPointOrderData::GenerateUnprocessedOrderNumber() { |
50 SyncPointManager* sync_point_manager) { | |
51 const uint32_t order_num = sync_point_manager->GenerateOrderNumber(); | |
52 base::AutoLock auto_lock(lock_); | 71 base::AutoLock auto_lock(lock_); |
53 unprocessed_order_num_ = order_num; | 72 DCHECK(!destroyed_); |
54 return order_num; | 73 unprocessed_order_num_ = sync_point_manager_->GenerateOrderNumber(); |
74 return unprocessed_order_num_; | |
55 } | 75 } |
56 | 76 |
57 void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) { | 77 void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) { |
58 DCHECK(processing_thread_checker_.CalledOnValidThread()); | 78 DCHECK(processing_thread_checker_.CalledOnValidThread()); |
59 DCHECK_GE(order_num, current_order_num_); | 79 DCHECK_GE(order_num, current_order_num_); |
60 // Use thread-safe accessors here because |processed_order_num_| and | 80 // Use thread-safe accessors here because |processed_order_num_| and |
61 // |unprocessed_order_num_| are protected by a lock. | 81 // |unprocessed_order_num_| are protected by a lock. |
62 DCHECK_GT(order_num, processed_order_num()); | 82 DCHECK_GT(order_num, processed_order_num()); |
63 DCHECK_LE(order_num, unprocessed_order_num()); | 83 DCHECK_LE(order_num, unprocessed_order_num()); |
64 current_order_num_ = order_num; | 84 current_order_num_ = order_num; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 break; | 140 break; |
121 } | 141 } |
122 } | 142 } |
123 | 143 |
124 for (OrderFence& order_fence : ensure_releases) { | 144 for (OrderFence& order_fence : ensure_releases) { |
125 order_fence.client_state->EnsureWaitReleased(order_fence.fence_release, | 145 order_fence.client_state->EnsureWaitReleased(order_fence.fence_release, |
126 order_fence.release_callback); | 146 order_fence.release_callback); |
127 } | 147 } |
128 } | 148 } |
129 | 149 |
130 SyncPointOrderData::OrderFence::OrderFence( | |
131 uint32_t order, | |
132 uint64_t release, | |
133 const base::Closure& callback, | |
134 scoped_refptr<SyncPointClientState> state) | |
135 : order_num(order), | |
136 fence_release(release), | |
137 release_callback(callback), | |
138 client_state(std::move(state)) {} | |
139 | |
140 SyncPointOrderData::OrderFence::OrderFence(const OrderFence& other) = default; | |
141 | |
142 SyncPointOrderData::OrderFence::~OrderFence() {} | |
143 | |
144 SyncPointOrderData::SyncPointOrderData() {} | |
145 | |
146 SyncPointOrderData::~SyncPointOrderData() {} | |
147 | |
148 bool SyncPointOrderData::ValidateReleaseOrderNumber( | 150 bool SyncPointOrderData::ValidateReleaseOrderNumber( |
149 scoped_refptr<SyncPointClientState> client_state, | 151 scoped_refptr<SyncPointClientState> client_state, |
150 uint32_t wait_order_num, | 152 uint32_t wait_order_num, |
151 uint64_t fence_release, | 153 uint64_t fence_release, |
152 const base::Closure& release_callback) { | 154 const base::Closure& release_callback) { |
153 base::AutoLock auto_lock(lock_); | 155 base::AutoLock auto_lock(lock_); |
154 if (destroyed_) | 156 if (destroyed_) |
155 return false; | 157 return false; |
156 | 158 |
157 // Release should have a possible unprocessed order number lower than the wait | 159 // Release should have a possible unprocessed order number lower than the wait |
(...skipping 19 matching lines...) Expand all Loading... | |
177 uint64_t release, | 179 uint64_t release, |
178 const base::Closure& callback) | 180 const base::Closure& callback) |
179 : release_count(release), callback_closure(callback) {} | 181 : release_count(release), callback_closure(callback) {} |
180 | 182 |
181 SyncPointClientState::ReleaseCallback::ReleaseCallback( | 183 SyncPointClientState::ReleaseCallback::ReleaseCallback( |
182 const ReleaseCallback& other) = default; | 184 const ReleaseCallback& other) = default; |
183 | 185 |
184 SyncPointClientState::ReleaseCallback::~ReleaseCallback() {} | 186 SyncPointClientState::ReleaseCallback::~ReleaseCallback() {} |
185 | 187 |
186 SyncPointClientState::SyncPointClientState( | 188 SyncPointClientState::SyncPointClientState( |
187 scoped_refptr<SyncPointOrderData> order_data) | 189 SyncPointManager* sync_point_manager, |
188 : order_data_(std::move(order_data)) {} | 190 scoped_refptr<SyncPointOrderData> order_data, |
191 CommandBufferNamespace namespace_id, | |
192 CommandBufferId command_buffer_id) | |
193 : sync_point_manager_(sync_point_manager), | |
194 order_data_(std::move(order_data)), | |
195 namespace_id_(namespace_id), | |
196 command_buffer_id_(command_buffer_id) {} | |
189 | 197 |
190 SyncPointClientState::~SyncPointClientState() {} | 198 SyncPointClientState::~SyncPointClientState() { |
199 DCHECK_EQ(UINT64_MAX, fence_sync_release_); | |
200 } | |
201 | |
202 void SyncPointClientState::Destroy() { | |
203 // Release all fences on destruction. | |
204 ReleaseFenceSyncHelper(UINT64_MAX); | |
205 DCHECK(sync_point_manager_); // not destroyed | |
206 sync_point_manager_->DestroyedSyncPointClientState(namespace_id_, | |
207 command_buffer_id_); | |
208 sync_point_manager_ = nullptr; | |
209 } | |
210 | |
211 bool SyncPointClientState::Wait(const SyncToken& sync_token, | |
212 const base::Closure& callback) { | |
213 DCHECK(sync_point_manager_); // not destroyed | |
214 // Validate that this Wait call is between BeginProcessingOrderNumber() and | |
215 // FinishProcessingOrderNumber(), or else we may deadlock. | |
216 DCHECK(order_data_->IsProcessingOrderNumber()); | |
217 if (sync_token.namespace_id() == namespace_id_ && | |
218 sync_token.command_buffer_id() == command_buffer_id_) { | |
219 return false; | |
220 } | |
221 uint32_t wait_order_number = order_data_->current_order_num(); | |
222 return sync_point_manager_->Wait(sync_token, wait_order_number, callback); | |
223 } | |
224 | |
225 bool SyncPointClientState::WaitNonThreadSafe( | |
226 const SyncToken& sync_token, | |
227 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
228 const base::Closure& callback) { | |
229 return Wait(sync_token, base::Bind(&RunOnThread, task_runner, callback)); | |
230 } | |
191 | 231 |
192 bool SyncPointClientState::IsFenceSyncReleased(uint64_t release) { | 232 bool SyncPointClientState::IsFenceSyncReleased(uint64_t release) { |
193 base::AutoLock lock(fence_sync_lock_); | 233 base::AutoLock lock(fence_sync_lock_); |
194 return release <= fence_sync_release_; | 234 return release <= fence_sync_release_; |
195 } | 235 } |
196 | 236 |
197 bool SyncPointClientState::WaitForRelease(uint64_t release, | 237 bool SyncPointClientState::WaitForRelease(uint64_t release, |
198 uint32_t wait_order_num, | 238 uint32_t wait_order_num, |
199 const base::Closure& callback) { | 239 const base::Closure& callback) { |
200 // Lock must be held the whole time while we validate otherwise it could be | 240 // Lock must be held the whole time while we validate otherwise it could be |
201 // released while we are checking. | 241 // released while we are checking. |
202 { | 242 { |
203 base::AutoLock auto_lock(fence_sync_lock_); | 243 base::AutoLock auto_lock(fence_sync_lock_); |
204 if (release > fence_sync_release_ && | 244 if (release > fence_sync_release_ && |
205 order_data_->ValidateReleaseOrderNumber(this, wait_order_num, release, | 245 order_data_->ValidateReleaseOrderNumber(this, wait_order_num, release, |
206 callback)) { | 246 callback)) { |
207 // Add the callback which will be called upon release. | 247 // Add the callback which will be called upon release. |
208 release_callback_queue_.push(ReleaseCallback(release, callback)); | 248 release_callback_queue_.push(ReleaseCallback(release, callback)); |
209 return true; | 249 return true; |
210 } | 250 } |
211 } | 251 } |
212 // Already released, do not run the callback. | 252 // Already released, do not run the callback. |
213 return false; | 253 return false; |
214 } | 254 } |
215 | 255 |
216 void SyncPointClientState::ReleaseFenceSync(uint64_t release) { | 256 void SyncPointClientState::ReleaseFenceSync(uint64_t release) { |
257 // Validate that this Release call is between BeginProcessingOrderNumber() and | |
258 // FinishProcessingOrderNumber(), or else we may deadlock. | |
259 DCHECK(order_data_->IsProcessingOrderNumber()); | |
260 ReleaseFenceSyncHelper(release); | |
261 } | |
262 | |
263 void SyncPointClientState::ReleaseFenceSyncHelper(uint64_t release) { | |
217 // Call callbacks without the lock to avoid possible deadlocks. | 264 // Call callbacks without the lock to avoid possible deadlocks. |
218 std::vector<base::Closure> callback_list; | 265 std::vector<base::Closure> callback_list; |
219 { | 266 { |
220 base::AutoLock auto_lock(fence_sync_lock_); | 267 base::AutoLock auto_lock(fence_sync_lock_); |
221 | 268 |
222 DLOG_IF(ERROR, release <= fence_sync_release_) | 269 DLOG_IF(ERROR, release <= fence_sync_release_) |
223 << "Client submitted fence releases out of order."; | 270 << "Client submitted fence releases out of order."; |
224 fence_sync_release_ = release; | 271 fence_sync_release_ = release; |
225 | 272 |
226 while (!release_callback_queue_.empty() && | 273 while (!release_callback_queue_.empty() && |
227 release_callback_queue_.top().release_count <= release) { | 274 release_callback_queue_.top().release_count <= release) { |
228 callback_list.push_back(release_callback_queue_.top().callback_closure); | 275 callback_list.push_back(release_callback_queue_.top().callback_closure); |
229 release_callback_queue_.pop(); | 276 release_callback_queue_.pop(); |
230 } | 277 } |
231 } | 278 } |
232 | 279 |
233 for (const base::Closure& closure : callback_list) { | 280 for (const base::Closure& closure : callback_list) |
234 closure.Run(); | 281 closure.Run(); |
235 } | |
236 } | 282 } |
237 | 283 |
238 void SyncPointClientState::EnsureWaitReleased(uint64_t release, | 284 void SyncPointClientState::EnsureWaitReleased(uint64_t release, |
239 const base::Closure& callback) { | 285 const base::Closure& callback) { |
240 // Call callbacks without the lock to avoid possible deadlocks. | 286 // Call callbacks without the lock to avoid possible deadlocks. |
241 bool call_callback = false; | 287 bool call_callback = false; |
242 { | 288 { |
243 base::AutoLock auto_lock(fence_sync_lock_); | 289 base::AutoLock auto_lock(fence_sync_lock_); |
244 if (release <= fence_sync_release_) | 290 if (release <= fence_sync_release_) |
245 return; | 291 return; |
(...skipping 20 matching lines...) Expand all Loading... | |
266 release_callback_queue_.push(popped_callback); | 312 release_callback_queue_.push(popped_callback); |
267 } | 313 } |
268 } | 314 } |
269 | 315 |
270 if (call_callback) { | 316 if (call_callback) { |
271 // This effectively releases the wait without releasing the fence. | 317 // This effectively releases the wait without releasing the fence. |
272 callback.Run(); | 318 callback.Run(); |
273 } | 319 } |
274 } | 320 } |
275 | 321 |
276 SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager, | |
277 scoped_refptr<SyncPointOrderData> order_data, | |
278 CommandBufferNamespace namespace_id, | |
279 CommandBufferId command_buffer_id) | |
280 : sync_point_manager_(sync_point_manager), | |
281 order_data_(std::move(order_data)), | |
282 client_state_(new SyncPointClientState(order_data_)), | |
283 namespace_id_(namespace_id), | |
284 command_buffer_id_(command_buffer_id) { | |
285 sync_point_manager_->RegisterSyncPointClient(client_state_, namespace_id, | |
286 command_buffer_id); | |
287 } | |
288 | |
289 SyncPointClient::~SyncPointClient() { | |
290 // Release all fences on destruction. | |
291 client_state_->ReleaseFenceSync(UINT64_MAX); | |
292 sync_point_manager_->DeregisterSyncPointClient(namespace_id_, | |
293 command_buffer_id_); | |
294 } | |
295 | |
296 bool SyncPointClient::Wait(const SyncToken& sync_token, | |
297 const base::Closure& callback) { | |
298 // Validate that this Wait call is between BeginProcessingOrderNumber() and | |
299 // FinishProcessingOrderNumber(), or else we may deadlock. | |
300 DCHECK(order_data_->IsProcessingOrderNumber()); | |
301 if (sync_token.namespace_id() == namespace_id_ && | |
302 sync_token.command_buffer_id() == command_buffer_id_) { | |
303 return false; | |
304 } | |
305 uint32_t wait_order_number = order_data_->current_order_num(); | |
306 return sync_point_manager_->Wait(sync_token, wait_order_number, callback); | |
307 } | |
308 | |
309 bool SyncPointClient::WaitNonThreadSafe( | |
310 const SyncToken& sync_token, | |
311 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
312 const base::Closure& callback) { | |
313 return Wait(sync_token, base::Bind(&RunOnThread, task_runner, callback)); | |
314 } | |
315 | |
316 void SyncPointClient::ReleaseFenceSync(uint64_t release) { | |
317 // Validate that this Release call is between BeginProcessingOrderNumber() and | |
318 // FinishProcessingOrderNumber(), or else we may deadlock. | |
319 DCHECK(order_data_->IsProcessingOrderNumber()); | |
320 client_state_->ReleaseFenceSync(release); | |
321 } | |
322 | |
323 SyncPointManager::SyncPointManager() { | 322 SyncPointManager::SyncPointManager() { |
324 global_order_num_.GetNext(); | 323 order_num_generator_.GetNext(); |
325 } | 324 } |
326 | 325 |
327 SyncPointManager::~SyncPointManager() { | 326 SyncPointManager::~SyncPointManager() { |
327 DCHECK(order_data_map_.empty()); | |
328 for (const ClientStateMap& client_state_map : client_state_maps_) | 328 for (const ClientStateMap& client_state_map : client_state_maps_) |
329 DCHECK(client_state_map.empty()); | 329 DCHECK(client_state_map.empty()); |
330 } | 330 } |
331 | 331 |
332 scoped_refptr<SyncPointOrderData> SyncPointManager::CreateSyncPointOrderData() { | |
333 base::AutoLock auto_lock(lock_); | |
334 SequenceId sequence_id = SequenceId::FromUnsafeValue(next_sequence_id_++); | |
335 scoped_refptr<SyncPointOrderData> order_data = | |
336 new SyncPointOrderData(this, sequence_id); | |
337 DCHECK(!order_data_map_.count(sequence_id)); | |
338 order_data_map_.insert(std::make_pair(sequence_id, order_data)); | |
339 return order_data; | |
340 } | |
341 | |
342 void SyncPointManager::DestroyedSyncPointOrderData(SequenceId sequence_id) { | |
343 base::AutoLock auto_lock(lock_); | |
344 DCHECK(order_data_map_.count(sequence_id)); | |
345 order_data_map_.erase(sequence_id); | |
346 } | |
347 | |
348 scoped_refptr<SyncPointClientState> | |
349 SyncPointManager::CreateSyncPointClientState( | |
350 CommandBufferNamespace namespace_id, | |
351 CommandBufferId command_buffer_id, | |
352 SequenceId sequence_id) { | |
353 scoped_refptr<SyncPointOrderData> order_data = | |
354 GetSyncPointOrderData(sequence_id); | |
355 | |
356 scoped_refptr<SyncPointClientState> client_state = new SyncPointClientState( | |
357 this, order_data, namespace_id, command_buffer_id); | |
358 | |
359 { | |
360 base::AutoLock auto_lock(lock_); | |
361 DCHECK_GE(namespace_id, 0); | |
362 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | |
363 DCHECK(!client_state_maps_[namespace_id].count(command_buffer_id)); | |
364 client_state_maps_[namespace_id].insert( | |
365 std::make_pair(command_buffer_id, client_state)); | |
366 } | |
367 | |
368 return client_state; | |
369 } | |
370 | |
371 void SyncPointManager::DestroyedSyncPointClientState( | |
372 CommandBufferNamespace namespace_id, | |
373 CommandBufferId command_buffer_id) { | |
374 base::AutoLock auto_lock(lock_); | |
375 DCHECK_GE(namespace_id, 0); | |
376 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | |
377 DCHECK(client_state_maps_[namespace_id].count(command_buffer_id)); | |
378 client_state_maps_[namespace_id].erase(command_buffer_id); | |
379 } | |
380 | |
332 bool SyncPointManager::IsSyncTokenReleased(const SyncToken& sync_token) { | 381 bool SyncPointManager::IsSyncTokenReleased(const SyncToken& sync_token) { |
333 scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( | 382 scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( |
334 sync_token.namespace_id(), sync_token.command_buffer_id()); | 383 sync_token.namespace_id(), sync_token.command_buffer_id()); |
335 if (release_state) | 384 if (release_state) |
336 return release_state->IsFenceSyncReleased(sync_token.release_count()); | 385 return release_state->IsFenceSyncReleased(sync_token.release_count()); |
337 return true; | 386 return true; |
338 } | 387 } |
339 | 388 |
389 SequenceId SyncPointManager::GetSyncTokenReleaseSequenceId( | |
390 const SyncToken& sync_token) { | |
391 scoped_refptr<SyncPointClientState> client_state = GetSyncPointClientState( | |
392 sync_token.namespace_id(), sync_token.command_buffer_id()); | |
393 if (client_state) | |
394 return client_state->sequence_id(); | |
395 return SequenceId(); | |
396 } | |
397 | |
398 uint32_t SyncPointManager::GetProcessedOrderNum() const { | |
399 // Copy order data map to prevent deadlock. | |
piman
2017/03/20 21:30:23
That seems expensive... Which lock order inversion
sunnyps
2017/03/20 21:40:34
Yes, it's the inversion in Destroy. I've changed D
| |
400 OrderDataMap order_data_map; | |
401 { | |
402 base::AutoLock auto_lock(lock_); | |
403 order_data_map = order_data_map_; | |
404 } | |
405 uint32_t processed_order_num = 0; | |
406 for (const auto& kv : order_data_map) { | |
407 processed_order_num = | |
408 std::max(processed_order_num, kv.second->processed_order_num()); | |
409 } | |
410 return processed_order_num; | |
411 } | |
412 | |
413 uint32_t SyncPointManager::GetUnprocessedOrderNum() const { | |
414 // Copy order data map to prevent deadlock. | |
415 OrderDataMap order_data_map; | |
416 { | |
417 base::AutoLock auto_lock(lock_); | |
418 order_data_map = order_data_map_; | |
419 } | |
420 uint32_t unprocessed_order_num = 0; | |
421 for (const auto& kv : order_data_map) { | |
422 unprocessed_order_num = | |
423 std::max(unprocessed_order_num, kv.second->unprocessed_order_num()); | |
424 } | |
425 return unprocessed_order_num; | |
426 } | |
427 | |
340 bool SyncPointManager::Wait(const SyncToken& sync_token, | 428 bool SyncPointManager::Wait(const SyncToken& sync_token, |
341 uint32_t wait_order_num, | 429 uint32_t wait_order_num, |
342 const base::Closure& callback) { | 430 const base::Closure& callback) { |
343 scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( | 431 scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( |
344 sync_token.namespace_id(), sync_token.command_buffer_id()); | 432 sync_token.namespace_id(), sync_token.command_buffer_id()); |
345 if (release_state && | 433 if (release_state && |
346 release_state->WaitForRelease(sync_token.release_count(), wait_order_num, | 434 release_state->WaitForRelease(sync_token.release_count(), wait_order_num, |
347 callback)) { | 435 callback)) { |
348 return true; | 436 return true; |
349 } | 437 } |
(...skipping 19 matching lines...) Expand all Loading... | |
369 } | 457 } |
370 | 458 |
371 bool SyncPointManager::WaitOutOfOrderNonThreadSafe( | 459 bool SyncPointManager::WaitOutOfOrderNonThreadSafe( |
372 const SyncToken& trusted_sync_token, | 460 const SyncToken& trusted_sync_token, |
373 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 461 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
374 const base::Closure& callback) { | 462 const base::Closure& callback) { |
375 return WaitOutOfOrder(trusted_sync_token, | 463 return WaitOutOfOrder(trusted_sync_token, |
376 base::Bind(&RunOnThread, task_runner, callback)); | 464 base::Bind(&RunOnThread, task_runner, callback)); |
377 } | 465 } |
378 | 466 |
379 void SyncPointManager::RegisterSyncPointClient( | |
380 scoped_refptr<SyncPointClientState> client_state, | |
381 CommandBufferNamespace namespace_id, | |
382 CommandBufferId command_buffer_id) { | |
383 DCHECK_GE(namespace_id, 0); | |
384 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | |
385 | |
386 base::AutoLock auto_lock(client_state_maps_lock_); | |
387 DCHECK(!client_state_maps_[namespace_id].count(command_buffer_id)); | |
388 client_state_maps_[namespace_id].insert( | |
389 std::make_pair(command_buffer_id, std::move(client_state))); | |
390 } | |
391 | |
392 void SyncPointManager::DeregisterSyncPointClient( | |
393 CommandBufferNamespace namespace_id, | |
394 CommandBufferId command_buffer_id) { | |
395 DCHECK_GE(namespace_id, 0); | |
396 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | |
397 | |
398 base::AutoLock auto_lock(client_state_maps_lock_); | |
399 DCHECK(client_state_maps_[namespace_id].count(command_buffer_id)); | |
400 client_state_maps_[namespace_id].erase(command_buffer_id); | |
401 } | |
402 | |
403 uint32_t SyncPointManager::GenerateOrderNumber() { | 467 uint32_t SyncPointManager::GenerateOrderNumber() { |
404 return global_order_num_.GetNext(); | 468 return order_num_generator_.GetNext(); |
405 } | 469 } |
406 | 470 |
407 scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( | 471 scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( |
408 CommandBufferNamespace namespace_id, | 472 CommandBufferNamespace namespace_id, |
409 CommandBufferId command_buffer_id) { | 473 CommandBufferId command_buffer_id) { |
410 if (namespace_id >= 0) { | 474 if (namespace_id >= 0) { |
411 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | 475 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); |
412 base::AutoLock auto_lock(client_state_maps_lock_); | 476 base::AutoLock auto_lock(lock_); |
413 ClientStateMap& client_state_map = client_state_maps_[namespace_id]; | 477 ClientStateMap& client_state_map = client_state_maps_[namespace_id]; |
414 auto it = client_state_map.find(command_buffer_id); | 478 auto it = client_state_map.find(command_buffer_id); |
415 if (it != client_state_map.end()) | 479 if (it != client_state_map.end()) |
416 return it->second; | 480 return it->second; |
417 } | 481 } |
418 return nullptr; | 482 return nullptr; |
419 } | 483 } |
420 | 484 |
485 scoped_refptr<SyncPointOrderData> SyncPointManager::GetSyncPointOrderData( | |
486 SequenceId sequence_id) { | |
487 base::AutoLock auto_lock(lock_); | |
488 auto it = order_data_map_.find(sequence_id); | |
489 if (it != order_data_map_.end()) | |
490 return it->second; | |
491 return nullptr; | |
492 } | |
493 | |
421 } // namespace gpu | 494 } // namespace gpu |
OLD | NEW |