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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/sync_point_manager.cc
diff --git a/gpu/command_buffer/service/sync_point_manager.cc b/gpu/command_buffer/service/sync_point_manager.cc
index 039e494de8b1d4bd5ea3df100c89ec10cb508690..ade353c7d260828347b7d95e18693bea924114fe 100644
--- a/gpu/command_buffer/service/sync_point_manager.cc
+++ b/gpu/command_buffer/service/sync_point_manager.cc
@@ -25,19 +25,136 @@ uint32_t SyncPointClientState::GenerateUnprocessedOrderNumber(
return order_num;
}
+void SyncPointClientState::BeginProcessingOrderNumber(uint32_t order_num) {
+ DCHECK(processing_thread_checker_.CalledOnValidThread());
+ DCHECK_GE(order_num, current_order_num_);
+ current_order_num_ = order_num;
+}
+
+void SyncPointClientState::FinishProcessingOrderNumber(uint32_t order_num) {
+ DCHECK(processing_thread_checker_.CalledOnValidThread());
+ DCHECK_EQ(current_order_num_, order_num);
+ DCHECK_GT(order_num, processed_order_num());
+
+ // Catch invalid waits which were waiting on fence syncs that do not exist.
+ uint32_t invalid_release = 0;
+ {
+ base::AutoLock auto_lock(fence_sync_lock_);
+ uint32_t highest_wait_release = 0;
+ while (!order_fence_queue_.empty() &&
+ order_fence_queue_.top().order_num <= order_num) {
+ const uint32_t fence_release = order_fence_queue_.top().fence_release;
+ highest_wait_release = std::max(highest_wait_release, fence_release);
+ order_fence_queue_.pop();
+ }
+
+ if (highest_wait_release > fence_sync_release_) {
+ invalid_release = fence_sync_release_;
+ }
+ }
+
+ if (invalid_release) {
+ // Bad wait for release that doesn't exist, release all waits up to here.
+ ReleaseFenceSync(invalid_release);
+ }
+
+ base::subtle::Release_Store(&processed_order_num_, order_num);
+}
+
SyncPointClientState::SyncPointClientState()
: processed_order_num_(0),
unprocessed_order_num_(0),
- current_order_num_(0) {
+ current_order_num_(0),
+ fence_sync_release_(0) {
}
SyncPointClientState::~SyncPointClientState() {
+ // Release all fences on destruction.
+ ReleaseFenceSync(UINT32_MAX);
+}
+
+SyncPointClientState::ReleaseCallback::ReleaseCallback(
+ uint32_t release, const base::Closure& callback)
+ : release_count(release),
+ callback_closure(callback) {
+}
+
+SyncPointClientState::ReleaseCallback::~ReleaseCallback() {
+}
+
+bool SyncPointClientState::WaitForRelease(uint32_t wait_order_num,
+ uint32_t release,
+ const base::Closure& callback) {
+ // Lock must be held the whole time while we validate otherwise it could be
+ // released while we are checking.
+ {
+ base::AutoLock auto_lock(fence_sync_lock_);
+ if (release > fence_sync_release_) {
+ const uint32_t processed_num = processed_order_num();
+ const uint32_t unprocessed_num = unprocessed_order_num();
+
+ // Release should have a lower order number than wait order number.
+ if (processed_num > wait_order_num)
+ return false;
+
+ // Release should have more unprocessed numbers if we are waiting.
+ if (unprocessed_num > processed_num)
+ return false;
+
+ // Add the callback which will be called upon release.
+ release_callback_queue_.push(ReleaseCallback(release, callback));
+
+ // Validate by ensuring fence is released by the expected order number.
+ const uint32_t expected_order_num = std::min(unprocessed_num,
+ wait_order_num);
+ order_fence_queue_.push(OrderFence(expected_order_num, release));
+
+ return true;
+ }
+ }
+
+ // Already released, run the callback now.
+ callback.Run();
+ return true;
+}
+
+void SyncPointClientState::ReleaseFenceSync(uint32_t release) {
+ // Call callbacks without the lock to avoid possible deadlocks.
+ std::vector<base::Closure> callback_list;
+ {
+ base::AutoLock auto_lock(fence_sync_lock_);
+ DCHECK_GT(release, fence_sync_release_);
+ fence_sync_release_ = release;
+
+ while (!release_callback_queue_.empty() &&
+ release_callback_queue_.top().release_count <= release) {
+ callback_list.push_back(release_callback_queue_.top().callback_closure);
+ release_callback_queue_.pop();
+ }
+ }
+
+ for (const base::Closure& closure : callback_list) {
+ closure.Run();
+ }
}
SyncPointClient::~SyncPointClient() {
sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_);
}
+bool SyncPointClient::Wait(scoped_refptr<SyncPointClientState> release_state,
+ uint32_t release_count,
+ const base::Closure& wait_complete_callback) {
+ const uint32_t wait_order_number = client_state_->current_order_num();
+ return release_state->WaitForRelease(wait_order_number,
+ release_count,
+ wait_complete_callback);
+}
+
+void SyncPointClient::ReleaseFenceSync(uint32_t release) {
+ client_state_->ReleaseFenceSync(release);
+}
+
SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager,
scoped_refptr<SyncPointClientState> state,
CommandBufferNamespace namespace_id,

Powered by Google App Engine
This is Rietveld 408576698