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 scoped_refptr<SyncPointClientState> SyncPointClientState::Create() { |
| 18 return new SyncPointClientState; |
| 19 } |
| 20 |
| 21 uint32_t SyncPointClientState::GenerateUnprocessedOrderNumber( |
| 22 SyncPointManager* sync_point_manager) { |
| 23 const uint32_t order_num = sync_point_manager->GenerateOrderNumber(); |
| 24 base::subtle::Release_Store(&unprocessed_order_num_, order_num); |
| 25 return order_num; |
| 26 } |
| 27 |
| 28 SyncPointClientState::SyncPointClientState() |
| 29 : processed_order_num_(0), |
| 30 unprocessed_order_num_(0), |
| 31 current_order_num_(0) { |
| 32 } |
| 33 |
| 34 SyncPointClientState::~SyncPointClientState() { |
| 35 } |
| 36 |
| 37 SyncPointClient::~SyncPointClient() { |
| 38 sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_); |
| 39 } |
| 40 |
| 41 SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager, |
| 42 scoped_refptr<SyncPointClientState> state, |
| 43 CommandBufferNamespace namespace_id, |
| 44 uint64_t client_id) |
| 45 : sync_point_manager_(sync_point_manager), |
| 46 client_state_(state), |
| 47 namespace_id_(namespace_id), |
| 48 client_id_(client_id) { |
| 49 } |
| 50 |
17 SyncPointManager::SyncPointManager(bool allow_threaded_wait) | 51 SyncPointManager::SyncPointManager(bool allow_threaded_wait) |
18 : allow_threaded_wait_(allow_threaded_wait), | 52 : allow_threaded_wait_(allow_threaded_wait), |
19 // To reduce the risk that a sync point created in a previous GPU process | 53 // 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 | 54 // will be in flight in the next GPU process, randomize the starting sync |
21 // point number. http://crbug.com/373452 | 55 // point number. http://crbug.com/373452 |
22 next_sync_point_(base::RandInt(1, kMaxSyncBase)), | 56 next_sync_point_(base::RandInt(1, kMaxSyncBase)), |
23 retire_cond_var_(&lock_) {} | 57 retire_cond_var_(&lock_) { |
| 58 global_order_num_.GetNext(); |
| 59 } |
24 | 60 |
25 SyncPointManager::~SyncPointManager() {} | 61 SyncPointManager::~SyncPointManager() { |
| 62 for (const ClientMap& client_map : client_maps_) { |
| 63 DCHECK(client_map.empty()); |
| 64 } |
| 65 } |
| 66 |
| 67 scoped_ptr<SyncPointClient> SyncPointManager::CreateSyncPointClient( |
| 68 scoped_refptr<SyncPointClientState> client_state, |
| 69 CommandBufferNamespace namespace_id, uint64_t client_id) { |
| 70 DCHECK_GE(namespace_id, 0); |
| 71 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
| 72 base::AutoLock auto_lock(client_maps_lock_); |
| 73 |
| 74 ClientMap& client_map = client_maps_[namespace_id]; |
| 75 std::pair<ClientMap::iterator, bool> result = client_map.insert( |
| 76 std::make_pair(client_id, new SyncPointClient(this, |
| 77 client_state, |
| 78 namespace_id, |
| 79 client_id))); |
| 80 DCHECK(result.second); |
| 81 |
| 82 return make_scoped_ptr(result.first->second); |
| 83 } |
| 84 |
| 85 scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( |
| 86 CommandBufferNamespace namespace_id, uint64_t client_id) { |
| 87 DCHECK_GE(namespace_id, 0); |
| 88 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
| 89 base::AutoLock auto_lock(client_maps_lock_); |
| 90 |
| 91 ClientMap& client_map = client_maps_[namespace_id]; |
| 92 ClientMap::iterator it = client_map.find(client_id); |
| 93 if (it != client_map.end()) { |
| 94 return it->second->client_state(); |
| 95 } |
| 96 return nullptr; |
| 97 } |
26 | 98 |
27 uint32 SyncPointManager::GenerateSyncPoint() { | 99 uint32 SyncPointManager::GenerateSyncPoint() { |
28 base::AutoLock lock(lock_); | 100 base::AutoLock lock(lock_); |
29 uint32 sync_point = next_sync_point_++; | 101 uint32 sync_point = next_sync_point_++; |
30 // When an integer overflow occurs, don't return 0. | 102 // When an integer overflow occurs, don't return 0. |
31 if (!sync_point) | 103 if (!sync_point) |
32 sync_point = next_sync_point_++; | 104 sync_point = next_sync_point_++; |
33 | 105 |
34 // Note: wrapping would take days for a buggy/compromized renderer that would | 106 // 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 | 107 // 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)) { | 160 while (!IsSyncPointRetiredLocked(sync_point)) { |
89 retire_cond_var_.Wait(); | 161 retire_cond_var_.Wait(); |
90 } | 162 } |
91 } | 163 } |
92 | 164 |
93 bool SyncPointManager::IsSyncPointRetiredLocked(uint32 sync_point) { | 165 bool SyncPointManager::IsSyncPointRetiredLocked(uint32 sync_point) { |
94 lock_.AssertAcquired(); | 166 lock_.AssertAcquired(); |
95 return sync_point_map_.find(sync_point) == sync_point_map_.end(); | 167 return sync_point_map_.find(sync_point) == sync_point_map_.end(); |
96 } | 168 } |
97 | 169 |
| 170 uint32_t SyncPointManager::GenerateOrderNumber() { |
| 171 return global_order_num_.GetNext(); |
| 172 } |
| 173 |
| 174 void SyncPointManager::DestroySyncPointClient( |
| 175 CommandBufferNamespace namespace_id, uint64_t client_id) { |
| 176 DCHECK_GE(namespace_id, 0); |
| 177 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
| 178 |
| 179 base::AutoLock auto_lock(client_maps_lock_); |
| 180 ClientMap& client_map = client_maps_[namespace_id]; |
| 181 ClientMap::iterator it = client_map.find(client_id); |
| 182 DCHECK(it != client_map.end()); |
| 183 client_map.erase(it); |
| 184 } |
| 185 |
98 } // namespace gpu | 186 } // namespace gpu |
OLD | NEW |