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

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

Issue 1331843005: Implemented new fence syncs which replaces the old sync points. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Improved commented out sample mojo code Created 5 years, 2 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 #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() { 17 scoped_refptr<SyncPointClientState> SyncPointClientState::Create() {
18 return new SyncPointClientState; 18 return new SyncPointClientState;
19 } 19 }
20 20
21 uint32_t SyncPointClientState::GenerateUnprocessedOrderNumber( 21 uint32_t SyncPointClientState::GenerateUnprocessedOrderNumber(
22 SyncPointManager* sync_point_manager) { 22 SyncPointManager* sync_point_manager) {
23 const uint32_t order_num = sync_point_manager->GenerateOrderNumber(); 23 const uint32_t order_num = sync_point_manager->GenerateOrderNumber();
24 base::subtle::Release_Store(&unprocessed_order_num_, order_num); 24 base::subtle::Release_Store(&unprocessed_order_num_, order_num);
25 return order_num; 25 return order_num;
26 } 26 }
27 27
28 void SyncPointClientState::BeginProcessingOrderNumber(uint32_t order_num) {
29 DCHECK(processing_thread_checker_.CalledOnValidThread());
30 DCHECK_GE(order_num, current_order_num_);
31 current_order_num_ = order_num;
32 }
33
34 void SyncPointClientState::FinishProcessingOrderNumber(uint32_t order_num) {
35 DCHECK(processing_thread_checker_.CalledOnValidThread());
36 DCHECK_EQ(current_order_num_, order_num);
37 DCHECK_GT(order_num, processed_order_num());
38
39 // Catch invalid waits which were waiting on fence syncs that do not exist.
40 uint32_t invalid_release = 0;
41 {
42 base::AutoLock auto_lock(fence_sync_lock_);
43 uint32_t highest_wait_release = 0;
44 while (!order_fence_queue_.empty() &&
45 order_fence_queue_.top().order_num <= order_num) {
46 const uint32_t fence_release = order_fence_queue_.top().fence_release;
47 highest_wait_release = std::max(highest_wait_release, fence_release);
48 order_fence_queue_.pop();
49 }
50
51 if (highest_wait_release > fence_sync_release_) {
52 invalid_release = fence_sync_release_;
53 }
54 }
55
56 if (invalid_release) {
57 // Bad wait for release that doesn't exist, release all waits up to here.
58 ReleaseFenceSync(invalid_release);
59 }
60
61 base::subtle::Release_Store(&processed_order_num_, order_num);
62 }
63
28 SyncPointClientState::SyncPointClientState() 64 SyncPointClientState::SyncPointClientState()
29 : processed_order_num_(0), 65 : processed_order_num_(0),
30 unprocessed_order_num_(0), 66 unprocessed_order_num_(0),
31 current_order_num_(0) { 67 current_order_num_(0),
68 fence_sync_release_(0) {
32 } 69 }
33 70
34 SyncPointClientState::~SyncPointClientState() { 71 SyncPointClientState::~SyncPointClientState() {
72 // Release all fences on destruction.
73 ReleaseFenceSync(UINT32_MAX);
74 }
75
76 SyncPointClientState::ReleaseCallback::ReleaseCallback(
77 uint32_t release, const base::Closure& callback)
78 : release_count(release),
79 callback_closure(callback) {
80 }
81
82 SyncPointClientState::ReleaseCallback::~ReleaseCallback() {
83 }
84
85 bool SyncPointClientState::WaitForRelease(uint32_t wait_order_num,
86 uint32_t release,
87 const base::Closure& callback) {
88 // Lock must be held the whole time while we validate otherwise it could be
89 // released while we are checking.
90 {
91 base::AutoLock auto_lock(fence_sync_lock_);
92 if (release > fence_sync_release_) {
93 const uint32_t processed_num = processed_order_num();
94 const uint32_t unprocessed_num = unprocessed_order_num();
95
96 // Release should have a lower order number than wait order number.
97 if (processed_num > wait_order_num)
98 return false;
99
100 // Release should have more unprocessed numbers if we are waiting.
101 if (unprocessed_num > processed_num)
102 return false;
103
104 // Add the callback which will be called upon release.
105 release_callback_queue_.push(ReleaseCallback(release, callback));
106
107 // Validate by ensuring fence is released by the expected order number.
108 const uint32_t expected_order_num = std::min(unprocessed_num,
109 wait_order_num);
110 order_fence_queue_.push(OrderFence(expected_order_num, release));
111
112 return true;
113 }
114 }
115
116 // Already released, run the callback now.
117 callback.Run();
118 return true;
119 }
120
121 void SyncPointClientState::ReleaseFenceSync(uint32_t release) {
122 // Call callbacks without the lock to avoid possible deadlocks.
123 std::vector<base::Closure> callback_list;
124 {
125 base::AutoLock auto_lock(fence_sync_lock_);
126 DCHECK_GT(release, fence_sync_release_);
127 fence_sync_release_ = release;
128
129 while (!release_callback_queue_.empty() &&
130 release_callback_queue_.top().release_count <= release) {
131 callback_list.push_back(release_callback_queue_.top().callback_closure);
132 release_callback_queue_.pop();
133 }
134 }
135
136 for (const base::Closure& closure : callback_list) {
137 closure.Run();
138 }
35 } 139 }
36 140
37 SyncPointClient::~SyncPointClient() { 141 SyncPointClient::~SyncPointClient() {
38 sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_); 142 sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_);
39 } 143 }
40 144
145 bool SyncPointClient::Wait(scoped_refptr<SyncPointClientState> release_state,
146 uint32_t release_count,
147 const base::Closure& wait_complete_callback) {
148 const uint32_t wait_order_number = client_state_->current_order_num();
149 return release_state->WaitForRelease(wait_order_number,
150 release_count,
151 wait_complete_callback);
152 }
153
154 void SyncPointClient::ReleaseFenceSync(uint32_t release) {
155 client_state_->ReleaseFenceSync(release);
156 }
157
41 SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager, 158 SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager,
42 scoped_refptr<SyncPointClientState> state, 159 scoped_refptr<SyncPointClientState> state,
43 CommandBufferNamespace namespace_id, 160 CommandBufferNamespace namespace_id,
44 uint64_t client_id) 161 uint64_t client_id)
45 : sync_point_manager_(sync_point_manager), 162 : sync_point_manager_(sync_point_manager),
46 client_state_(state), 163 client_state_(state),
47 namespace_id_(namespace_id), 164 namespace_id_(namespace_id),
48 client_id_(client_id) { 165 client_id_(client_id) {
49 } 166 }
50 167
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); 294 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_));
178 295
179 base::AutoLock auto_lock(client_maps_lock_); 296 base::AutoLock auto_lock(client_maps_lock_);
180 ClientMap& client_map = client_maps_[namespace_id]; 297 ClientMap& client_map = client_maps_[namespace_id];
181 ClientMap::iterator it = client_map.find(client_id); 298 ClientMap::iterator it = client_map.find(client_id);
182 DCHECK(it != client_map.end()); 299 DCHECK(it != client_map.end());
183 client_map.erase(it); 300 client_map.erase(it);
184 } 301 }
185 302
186 } // namespace gpu 303 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698