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

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

Issue 1975663002: Invalid sync token waits now automatically get released. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Combine the 2 while loops into 1 Created 4 years, 7 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 <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 if (order_fence_queue_.top().order_num < order_num) { 81 if (order_fence_queue_.top().order_num < order_num) {
82 ensure_releases.push_back(order_fence); 82 ensure_releases.push_back(order_fence);
83 order_fence_queue_.pop(); 83 order_fence_queue_.pop();
84 continue; 84 continue;
85 } 85 }
86 break; 86 break;
87 } 87 }
88 } 88 }
89 89
90 for (OrderFence& order_fence : ensure_releases) { 90 for (OrderFence& order_fence : ensure_releases) {
91 order_fence.client_state->EnsureReleased(order_fence.fence_release); 91 order_fence.client_state->EnsureWaitReleased(order_fence.fence_release,
92 order_fence.release_callback);
92 } 93 }
93 } 94 }
94 95
95 void SyncPointOrderData::PauseProcessingOrderNumber(uint32_t order_num) { 96 void SyncPointOrderData::PauseProcessingOrderNumber(uint32_t order_num) {
96 DCHECK(processing_thread_checker_.CalledOnValidThread()); 97 DCHECK(processing_thread_checker_.CalledOnValidThread());
97 DCHECK_EQ(current_order_num_, order_num); 98 DCHECK_EQ(current_order_num_, order_num);
98 DCHECK(!paused_); 99 DCHECK(!paused_);
99 paused_ = true; 100 paused_ = true;
100 } 101 }
101 102
(...skipping 17 matching lines...) Expand all
119 if (order_fence_queue_.top().order_num <= order_num) { 120 if (order_fence_queue_.top().order_num <= order_num) {
120 ensure_releases.push_back(order_fence); 121 ensure_releases.push_back(order_fence);
121 order_fence_queue_.pop(); 122 order_fence_queue_.pop();
122 continue; 123 continue;
123 } 124 }
124 break; 125 break;
125 } 126 }
126 } 127 }
127 128
128 for (OrderFence& order_fence : ensure_releases) { 129 for (OrderFence& order_fence : ensure_releases) {
129 order_fence.client_state->EnsureReleased(order_fence.fence_release); 130 order_fence.client_state->EnsureWaitReleased(order_fence.fence_release,
131 order_fence.release_callback);
130 } 132 }
131 } 133 }
132 134
133 SyncPointOrderData::OrderFence::OrderFence( 135 SyncPointOrderData::OrderFence::OrderFence(
134 uint32_t order, 136 uint32_t order,
135 uint64_t release, 137 uint64_t release,
138 const base::Closure& callback,
136 scoped_refptr<SyncPointClientState> state) 139 scoped_refptr<SyncPointClientState> state)
137 : order_num(order), fence_release(release), client_state(state) {} 140 : order_num(order),
141 fence_release(release),
142 release_callback(callback),
143 client_state(state) {}
138 144
139 SyncPointOrderData::OrderFence::OrderFence(const OrderFence& other) = default; 145 SyncPointOrderData::OrderFence::OrderFence(const OrderFence& other) = default;
140 146
141 SyncPointOrderData::OrderFence::~OrderFence() {} 147 SyncPointOrderData::OrderFence::~OrderFence() {}
142 148
143 SyncPointOrderData::SyncPointOrderData() 149 SyncPointOrderData::SyncPointOrderData()
144 : current_order_num_(0), 150 : current_order_num_(0),
145 paused_(false), 151 paused_(false),
146 destroyed_(false), 152 destroyed_(false),
147 processed_order_num_(0), 153 processed_order_num_(0),
148 unprocessed_order_num_(0) {} 154 unprocessed_order_num_(0) {}
149 155
150 SyncPointOrderData::~SyncPointOrderData() {} 156 SyncPointOrderData::~SyncPointOrderData() {}
151 157
152 bool SyncPointOrderData::ValidateReleaseOrderNumber( 158 bool SyncPointOrderData::ValidateReleaseOrderNumber(
153 scoped_refptr<SyncPointClientState> client_state, 159 scoped_refptr<SyncPointClientState> client_state,
154 uint32_t wait_order_num, 160 uint32_t wait_order_num,
155 uint64_t fence_release) { 161 uint64_t fence_release,
162 const base::Closure& release_callback) {
156 base::AutoLock auto_lock(lock_); 163 base::AutoLock auto_lock(lock_);
157 if (destroyed_) 164 if (destroyed_)
158 return false; 165 return false;
159 166
160 // Release should have a possible unprocessed order number lower 167 // Release should have a possible unprocessed order number lower
161 // than the wait order number. 168 // than the wait order number.
162 if ((processed_order_num_ + 1) >= wait_order_num) 169 if ((processed_order_num_ + 1) >= wait_order_num)
163 return false; 170 return false;
164 171
165 // Release should have more unprocessed numbers if we are waiting. 172 // Release should have more unprocessed numbers if we are waiting.
166 if (unprocessed_order_num_ <= processed_order_num_) 173 if (unprocessed_order_num_ <= processed_order_num_)
167 return false; 174 return false;
168 175
169 // So far it could be valid, but add an order fence guard to be sure it 176 // So far it could be valid, but add an order fence guard to be sure it
170 // gets released eventually. 177 // gets released eventually.
171 const uint32_t expected_order_num = 178 const uint32_t expected_order_num =
172 std::min(unprocessed_order_num_, wait_order_num); 179 std::min(unprocessed_order_num_, wait_order_num);
173 order_fence_queue_.push( 180 order_fence_queue_.push(OrderFence(expected_order_num, fence_release,
174 OrderFence(expected_order_num, fence_release, client_state)); 181 release_callback, client_state));
175 return true; 182 return true;
176 } 183 }
177 184
178 SyncPointClientState::ReleaseCallback::ReleaseCallback( 185 SyncPointClientState::ReleaseCallback::ReleaseCallback(
179 uint64_t release, 186 uint64_t release,
180 const base::Closure& callback) 187 const base::Closure& callback)
181 : release_count(release), callback_closure(callback) {} 188 : release_count(release), callback_closure(callback) {}
182 189
183 SyncPointClientState::ReleaseCallback::ReleaseCallback( 190 SyncPointClientState::ReleaseCallback::ReleaseCallback(
184 const ReleaseCallback& other) = default; 191 const ReleaseCallback& other) = default;
(...skipping 11 matching lines...) Expand all
196 CommandBufferId client_id, 203 CommandBufferId client_id,
197 uint32_t wait_order_num, 204 uint32_t wait_order_num,
198 uint64_t release, 205 uint64_t release,
199 const base::Closure& callback) { 206 const base::Closure& callback) {
200 // Lock must be held the whole time while we validate otherwise it could be 207 // Lock must be held the whole time while we validate otherwise it could be
201 // released while we are checking. 208 // released while we are checking.
202 { 209 {
203 base::AutoLock auto_lock(fence_sync_lock_); 210 base::AutoLock auto_lock(fence_sync_lock_);
204 if (release > fence_sync_release_) { 211 if (release > fence_sync_release_) {
205 if (!order_data_->ValidateReleaseOrderNumber(this, wait_order_num, 212 if (!order_data_->ValidateReleaseOrderNumber(this, wait_order_num,
206 release)) { 213 release, callback)) {
207 return false; 214 return false;
208 } else { 215 } else {
209 // Add the callback which will be called upon release. 216 // Add the callback which will be called upon release.
210 release_callback_queue_.push(ReleaseCallback(release, callback)); 217 release_callback_queue_.push(ReleaseCallback(release, callback));
211 if (!on_wait_callback_.is_null()) 218 if (!on_wait_callback_.is_null())
212 on_wait_callback_.Run(namespace_id, client_id); 219 on_wait_callback_.Run(namespace_id, client_id);
213 return true; 220 return true;
214 } 221 }
215 } 222 }
216 } 223 }
217 224
218 // Already released, run the callback now. 225 // Already released, run the callback now.
219 callback.Run(); 226 callback.Run();
220 return true; 227 return true;
221 } 228 }
222 229
223 void SyncPointClientState::ReleaseFenceSync(uint64_t release) { 230 void SyncPointClientState::ReleaseFenceSync(uint64_t release) {
224 // Call callbacks without the lock to avoid possible deadlocks. 231 // Call callbacks without the lock to avoid possible deadlocks.
225 std::vector<base::Closure> callback_list; 232 std::vector<base::Closure> callback_list;
226 { 233 {
227 base::AutoLock auto_lock(fence_sync_lock_); 234 base::AutoLock auto_lock(fence_sync_lock_);
228 ReleaseFenceSyncLocked(release, &callback_list); 235 DCHECK_GT(release, fence_sync_release_);
236
237 fence_sync_release_ = release;
238 while (!release_callback_queue_.empty() &&
239 release_callback_queue_.top().release_count <= release) {
240 callback_list.push_back(release_callback_queue_.top().callback_closure);
241 release_callback_queue_.pop();
242 }
229 } 243 }
230 244
231 for (const base::Closure& closure : callback_list) { 245 for (const base::Closure& closure : callback_list) {
232 closure.Run(); 246 closure.Run();
233 } 247 }
234 } 248 }
235 249
236 void SyncPointClientState::EnsureReleased(uint64_t release) { 250 void SyncPointClientState::EnsureWaitReleased(uint64_t release,
251 const base::Closure& callback) {
237 // Call callbacks without the lock to avoid possible deadlocks. 252 // Call callbacks without the lock to avoid possible deadlocks.
238 std::vector<base::Closure> callback_list; 253 bool call_callback = false;
239 { 254 {
240 base::AutoLock auto_lock(fence_sync_lock_); 255 base::AutoLock auto_lock(fence_sync_lock_);
241 if (release <= fence_sync_release_) 256 if (release <= fence_sync_release_)
242 return; 257 return;
243 258
244 ReleaseFenceSyncLocked(release, &callback_list); 259 std::vector<ReleaseCallback> popped_callbacks;
260 popped_callbacks.reserve(release_callback_queue_.size());
261
262 while (!release_callback_queue_.empty() &&
263 release_callback_queue_.top().release_count <= release) {
264 const ReleaseCallback& top_item = release_callback_queue_.top();
265 if (top_item.release_count == release &&
266 top_item.callback_closure.Equals(callback)) {
267 // Call the callback, and discard this item from the callback queue.
268 call_callback = true;
269 } else {
270 // Store the item to be placed back into the callback queue later.
271 popped_callbacks.push_back(top_item);
272 }
273 release_callback_queue_.pop();
274 }
275
276 // Add back in popped items.
277 for (const ReleaseCallback& popped_callback : popped_callbacks) {
278 release_callback_queue_.push(popped_callback);
279 }
245 } 280 }
246 281
247 for (const base::Closure& closure : callback_list) { 282 if (call_callback) {
248 closure.Run(); 283 // This effectively releases the wait without releasing the fence.
284 callback.Run();
249 } 285 }
250 } 286 }
251 287
252 void SyncPointClientState::ReleaseFenceSyncLocked(
253 uint64_t release,
254 std::vector<base::Closure>* callback_list) {
255 fence_sync_lock_.AssertAcquired();
256 DCHECK_GT(release, fence_sync_release_);
257
258 fence_sync_release_ = release;
259 while (!release_callback_queue_.empty() &&
260 release_callback_queue_.top().release_count <= release) {
261 callback_list->push_back(release_callback_queue_.top().callback_closure);
262 release_callback_queue_.pop();
263 }
264 }
265
266 void SyncPointClientState::SetOnWaitCallback(const OnWaitCallback& callback) { 288 void SyncPointClientState::SetOnWaitCallback(const OnWaitCallback& callback) {
267 on_wait_callback_ = callback; 289 on_wait_callback_ = callback;
268 } 290 }
269 291
270 SyncPointClient::~SyncPointClient() { 292 SyncPointClient::~SyncPointClient() {
271 if (namespace_id_ != gpu::CommandBufferNamespace::INVALID) { 293 if (namespace_id_ != gpu::CommandBufferNamespace::INVALID) {
272 // Release all fences on destruction. 294 // Release all fences on destruction.
273 client_state_->ReleaseFenceSync(UINT64_MAX); 295 client_state_->ReleaseFenceSync(UINT64_MAX);
274 296
275 sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_); 297 sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); 441 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_));
420 442
421 base::AutoLock auto_lock(client_maps_lock_); 443 base::AutoLock auto_lock(client_maps_lock_);
422 ClientMap& client_map = client_maps_[namespace_id]; 444 ClientMap& client_map = client_maps_[namespace_id];
423 ClientMap::iterator it = client_map.find(client_id); 445 ClientMap::iterator it = client_map.find(client_id);
424 DCHECK(it != client_map.end()); 446 DCHECK(it != client_map.end());
425 client_map.erase(it); 447 client_map.erase(it);
426 } 448 }
427 449
428 } // namespace gpu 450 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/sync_point_manager.h ('k') | gpu/command_buffer/service/sync_point_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698