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 <climits> | 7 #include <climits> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
11 #include "base/sequence_checker.h" | 11 #include "base/sequence_checker.h" |
12 | 12 |
13 namespace gpu { | 13 namespace gpu { |
14 | 14 |
15 static const int kMaxSyncBase = INT_MAX; | 15 static const int kMaxSyncBase = INT_MAX; |
16 | 16 |
| 17 SyncPointClientState::SyncPointClientState() |
| 18 : processed_order_num_(0), |
| 19 unprocessed_order_num_(0) { |
| 20 } |
| 21 |
| 22 SyncPointClientState::~SyncPointClientState() { |
| 23 } |
| 24 |
| 25 SyncPointClient::~SyncPointClient() { |
| 26 sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_); |
| 27 } |
| 28 |
| 29 uint32_t SyncPointClient::GenerateUnprocessedOrderNumber() { |
| 30 DCHECK(sync_point_manager_); |
| 31 const uint32_t order_num = sync_point_manager_->GenerateOrderNumber(); |
| 32 client_state_->SetUnprocessedOrderNum(order_num); |
| 33 return order_num; |
| 34 } |
| 35 |
| 36 SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager, |
| 37 CommandBufferNamespace namespace_id, |
| 38 uint64_t client_id) |
| 39 : sync_point_manager_(sync_point_manager), |
| 40 namespace_id_(namespace_id), |
| 41 client_id_(client_id), |
| 42 current_order_num_(0) { |
| 43 } |
| 44 |
17 SyncPointManager::SyncPointManager(bool allow_threaded_wait) | 45 SyncPointManager::SyncPointManager(bool allow_threaded_wait) |
18 : allow_threaded_wait_(allow_threaded_wait), | 46 : allow_threaded_wait_(allow_threaded_wait), |
19 // To reduce the risk that a sync point created in a previous GPU process | 47 // To reduce the risk that a sync point created in a previous GPU process |
20 // will be in flight in the next GPU process, randomize the starting sync | 48 // will be in flight in the next GPU process, randomize the starting sync |
21 // point number. http://crbug.com/373452 | 49 // point number. http://crbug.com/373452 |
22 next_sync_point_(base::RandInt(1, kMaxSyncBase)), | 50 next_sync_point_(base::RandInt(1, kMaxSyncBase)), |
23 retire_cond_var_(&lock_) {} | 51 retire_cond_var_(&lock_) { |
| 52 global_order_num_.GetNext(); |
| 53 } |
24 | 54 |
25 SyncPointManager::~SyncPointManager() {} | 55 SyncPointManager::~SyncPointManager() { |
| 56 for (const ClientMap& client_map : client_maps_) { |
| 57 DCHECK(client_map.empty()); |
| 58 } |
| 59 } |
| 60 |
| 61 scoped_ptr<SyncPointClient> SyncPointManager::CreateSyncPointClient( |
| 62 CommandBufferNamespace namespace_id, uint64_t client_id) { |
| 63 DCHECK_GE(namespace_id, 0); |
| 64 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
| 65 base::AutoLock auto_lock(client_maps_lock_); |
| 66 |
| 67 ClientMap& client_map = client_maps_[namespace_id]; |
| 68 std::pair<ClientMap::iterator, bool> result = client_map.insert( |
| 69 std::make_pair(client_id, new SyncPointClient(this, |
| 70 namespace_id, |
| 71 client_id))); |
| 72 DCHECK(result.second); |
| 73 |
| 74 return make_scoped_ptr(result.first->second); |
| 75 } |
| 76 |
| 77 scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( |
| 78 CommandBufferNamespace namespace_id, uint64_t client_id) { |
| 79 DCHECK_GE(namespace_id, 0); |
| 80 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
| 81 base::AutoLock auto_lock(client_maps_lock_); |
| 82 |
| 83 ClientMap& client_map = client_maps_[namespace_id]; |
| 84 ClientMap::iterator it = client_map.find(client_id); |
| 85 if (it != client_map.end()) { |
| 86 return it->second->client_state(); |
| 87 } |
| 88 return nullptr; |
| 89 } |
26 | 90 |
27 uint32 SyncPointManager::GenerateSyncPoint() { | 91 uint32 SyncPointManager::GenerateSyncPoint() { |
28 base::AutoLock lock(lock_); | 92 base::AutoLock lock(lock_); |
29 uint32 sync_point = next_sync_point_++; | 93 uint32 sync_point = next_sync_point_++; |
30 // When an integer overflow occurs, don't return 0. | 94 // When an integer overflow occurs, don't return 0. |
31 if (!sync_point) | 95 if (!sync_point) |
32 sync_point = next_sync_point_++; | 96 sync_point = next_sync_point_++; |
33 | 97 |
34 // Note: wrapping would take days for a buggy/compromized renderer that would | 98 // Note: wrapping would take days for a buggy/compromized renderer that would |
35 // insert sync points in a loop, but if that were to happen, better explicitly | 99 // insert sync points in a loop, but if that were to happen, better explicitly |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 while (!IsSyncPointRetiredLocked(sync_point)) { | 152 while (!IsSyncPointRetiredLocked(sync_point)) { |
89 retire_cond_var_.Wait(); | 153 retire_cond_var_.Wait(); |
90 } | 154 } |
91 } | 155 } |
92 | 156 |
93 bool SyncPointManager::IsSyncPointRetiredLocked(uint32 sync_point) { | 157 bool SyncPointManager::IsSyncPointRetiredLocked(uint32 sync_point) { |
94 lock_.AssertAcquired(); | 158 lock_.AssertAcquired(); |
95 return sync_point_map_.find(sync_point) == sync_point_map_.end(); | 159 return sync_point_map_.find(sync_point) == sync_point_map_.end(); |
96 } | 160 } |
97 | 161 |
| 162 uint32_t SyncPointManager::GenerateOrderNumber() { |
| 163 return global_order_num_.GetNext(); |
| 164 } |
| 165 |
| 166 void SyncPointManager::DestroySyncPointClient( |
| 167 CommandBufferNamespace namespace_id, uint64_t client_id) { |
| 168 DCHECK_GE(namespace_id, 0); |
| 169 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
| 170 |
| 171 base::AutoLock auto_lock(client_maps_lock_); |
| 172 ClientMap& client_map = client_maps_[namespace_id]; |
| 173 ClientMap::iterator it = client_map.find(client_id); |
| 174 DCHECK(it != client_map.end()); |
| 175 client_map.erase(it); |
| 176 } |
| 177 |
98 } // namespace gpu | 178 } // namespace gpu |
OLD | NEW |