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 04a92e015b6e3264591115700e2819a5a6cce5c3..85210e8816122aeac76e12cb294ad3756f083d12 100644 |
--- a/gpu/command_buffer/service/sync_point_manager.cc |
+++ b/gpu/command_buffer/service/sync_point_manager.cc |
@@ -8,15 +8,10 @@ |
#include <stddef.h> |
#include <stdint.h> |
-#include <climits> |
- |
#include "base/bind.h" |
-#include "base/containers/hash_tables.h" |
#include "base/location.h" |
#include "base/logging.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/rand_util.h" |
-#include "base/sequence_checker.h" |
+#include "base/memory/ref_counted.h" |
#include "base/single_thread_task_runner.h" |
namespace gpu { |
@@ -146,12 +141,7 @@ SyncPointOrderData::OrderFence::OrderFence(const OrderFence& other) = default; |
SyncPointOrderData::OrderFence::~OrderFence() {} |
-SyncPointOrderData::SyncPointOrderData() |
- : current_order_num_(0), |
- paused_(false), |
- destroyed_(false), |
- processed_order_num_(0), |
- unprocessed_order_num_(0) {} |
+SyncPointOrderData::SyncPointOrderData() {} |
SyncPointOrderData::~SyncPointOrderData() {} |
@@ -164,8 +154,8 @@ bool SyncPointOrderData::ValidateReleaseOrderNumber( |
if (destroyed_) |
return false; |
- // Release should have a possible unprocessed order number lower |
- // than the wait order number. |
+ // Release should have a possible unprocessed order number lower than the wait |
+ // order number. |
if ((processed_order_num_ + 1) >= wait_order_num) |
return false; |
@@ -175,7 +165,7 @@ bool SyncPointOrderData::ValidateReleaseOrderNumber( |
// So far it could be valid, but add an order fence guard to be sure it |
// gets released eventually. |
- const uint32_t expected_order_num = |
+ uint32_t expected_order_num = |
std::min(unprocessed_order_num_, wait_order_num); |
order_fence_queue_.push(OrderFence(expected_order_num, fence_release, |
release_callback, client_state)); |
@@ -194,37 +184,32 @@ SyncPointClientState::ReleaseCallback::~ReleaseCallback() {} |
SyncPointClientState::SyncPointClientState( |
scoped_refptr<SyncPointOrderData> order_data) |
- : order_data_(order_data), fence_sync_release_(0) {} |
+ : order_data_(order_data) {} |
+ |
+SyncPointClientState::~SyncPointClientState() {} |
-SyncPointClientState::~SyncPointClientState() { |
+bool SyncPointClientState::IsFenceSyncReleased(uint64_t release) { |
+ base::AutoLock lock(fence_sync_lock_); |
+ return release <= fence_sync_release_; |
} |
-bool SyncPointClientState::WaitForRelease(CommandBufferNamespace namespace_id, |
- CommandBufferId client_id, |
+bool SyncPointClientState::WaitForRelease(uint64_t release, |
uint32_t wait_order_num, |
- uint64_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_) { |
- if (!order_data_->ValidateReleaseOrderNumber(this, wait_order_num, |
- release, callback)) { |
- return false; |
- } else { |
- // Add the callback which will be called upon release. |
- release_callback_queue_.push(ReleaseCallback(release, callback)); |
- if (!on_wait_callback_.is_null()) |
- on_wait_callback_.Run(namespace_id, client_id); |
- return true; |
- } |
+ if (release > fence_sync_release_ && |
+ order_data_->ValidateReleaseOrderNumber(this, wait_order_num, release, |
+ callback)) { |
+ // Add the callback which will be called upon release. |
+ release_callback_queue_.push(ReleaseCallback(release, callback)); |
+ return true; |
} |
} |
- |
- // Already released, run the callback now. |
- callback.Run(); |
- return true; |
+ // Already released, do not run the callback. |
+ return false; |
} |
void SyncPointClientState::ReleaseFenceSync(uint64_t release) { |
@@ -232,10 +217,11 @@ void SyncPointClientState::ReleaseFenceSync(uint64_t release) { |
std::vector<base::Closure> callback_list; |
{ |
base::AutoLock auto_lock(fence_sync_lock_); |
+ |
DLOG_IF(ERROR, release <= fence_sync_release_) |
<< "Client submitted fence releases out of order."; |
- |
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); |
@@ -286,166 +272,149 @@ void SyncPointClientState::EnsureWaitReleased(uint64_t release, |
} |
} |
-void SyncPointClientState::SetOnWaitCallback(const OnWaitCallback& callback) { |
- on_wait_callback_ = callback; |
+SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager, |
+ scoped_refptr<SyncPointOrderData> order_data, |
+ CommandBufferNamespace namespace_id, |
+ CommandBufferId command_buffer_id) |
+ : sync_point_manager_(sync_point_manager), |
+ order_data_(order_data), |
+ client_state_(new SyncPointClientState(order_data)), |
+ namespace_id_(namespace_id), |
+ command_buffer_id_(command_buffer_id) { |
+ sync_point_manager_->RegisterSyncPointClient(client_state_, namespace_id, |
+ command_buffer_id); |
} |
SyncPointClient::~SyncPointClient() { |
- if (namespace_id_ != gpu::CommandBufferNamespace::INVALID) { |
- // Release all fences on destruction. |
- client_state_->ReleaseFenceSync(UINT64_MAX); |
- |
- sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_); |
- } |
+ // Release all fences on destruction. |
+ client_state_->ReleaseFenceSync(UINT64_MAX); |
+ sync_point_manager_->DeregisterSyncPointClient(namespace_id_, |
+ command_buffer_id_); |
} |
-bool SyncPointClient::Wait(SyncPointClientState* release_state, |
- uint64_t release_count, |
- const base::Closure& wait_complete_callback) { |
+bool SyncPointClient::Wait(const SyncToken& sync_token, |
+ const base::Closure& callback) { |
// Validate that this Wait call is between BeginProcessingOrderNumber() and |
// FinishProcessingOrderNumber(), or else we may deadlock. |
- DCHECK(client_state_->order_data()->IsProcessingOrderNumber()); |
- |
- const uint32_t wait_order_number = |
- client_state_->order_data()->current_order_num(); |
- |
- // If waiting on self or wait was invalid, call the callback and return false. |
- if (client_state_ == release_state || |
- !release_state->WaitForRelease(namespace_id_, client_id_, |
- wait_order_number, release_count, |
- wait_complete_callback)) { |
- wait_complete_callback.Run(); |
+ DCHECK(order_data_->IsProcessingOrderNumber()); |
+ if (sync_token.namespace_id() == namespace_id_ && |
+ sync_token.command_buffer_id() == command_buffer_id_) { |
return false; |
} |
- return true; |
+ uint32_t wait_order_number = order_data_->current_order_num(); |
+ return sync_point_manager_->Wait(sync_token, wait_order_number, callback); |
} |
bool SyncPointClient::WaitNonThreadSafe( |
- SyncPointClientState* release_state, |
- uint64_t release_count, |
- scoped_refptr<base::SingleThreadTaskRunner> runner, |
- const base::Closure& wait_complete_callback) { |
- return Wait(release_state, release_count, |
- base::Bind(&RunOnThread, runner, wait_complete_callback)); |
-} |
- |
-bool SyncPointClient::WaitOutOfOrder( |
- SyncPointClientState* release_state, |
- uint64_t release_count, |
- const base::Closure& wait_complete_callback) { |
- // Validate that this Wait call is not between BeginProcessingOrderNumber() |
- // and FinishProcessingOrderNumber(), or else we may deadlock. |
- DCHECK(!client_state_ || |
- !client_state_->order_data()->IsProcessingOrderNumber()); |
- |
- // No order number associated with the current execution context, using |
- // UINT32_MAX will just assume the release is in the SyncPointClientState's |
- // order numbers to be executed. |
- if (!release_state->WaitForRelease(namespace_id_, client_id_, UINT32_MAX, |
- release_count, wait_complete_callback)) { |
- wait_complete_callback.Run(); |
- return false; |
- } |
- return true; |
-} |
- |
-bool SyncPointClient::WaitOutOfOrderNonThreadSafe( |
- SyncPointClientState* release_state, |
- uint64_t release_count, |
- scoped_refptr<base::SingleThreadTaskRunner> runner, |
- const base::Closure& wait_complete_callback) { |
- return WaitOutOfOrder( |
- release_state, release_count, |
- base::Bind(&RunOnThread, runner, wait_complete_callback)); |
+ const SyncToken& sync_token, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
+ const base::Closure& callback) { |
+ return Wait(sync_token, base::Bind(&RunOnThread, task_runner, callback)); |
} |
void SyncPointClient::ReleaseFenceSync(uint64_t release) { |
// Validate that this Release call is between BeginProcessingOrderNumber() and |
// FinishProcessingOrderNumber(), or else we may deadlock. |
- DCHECK(client_state_->order_data()->IsProcessingOrderNumber()); |
+ DCHECK(order_data_->IsProcessingOrderNumber()); |
client_state_->ReleaseFenceSync(release); |
} |
-void SyncPointClient::SetOnWaitCallback(const OnWaitCallback& callback) { |
- client_state_->SetOnWaitCallback(callback); |
+SyncPointManager::SyncPointManager() { |
+ global_order_num_.GetNext(); |
} |
-SyncPointClient::SyncPointClient() |
- : sync_point_manager_(nullptr), |
- namespace_id_(gpu::CommandBufferNamespace::INVALID), |
- client_id_() {} |
- |
-SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager, |
- scoped_refptr<SyncPointOrderData> order_data, |
- CommandBufferNamespace namespace_id, |
- CommandBufferId client_id) |
- : sync_point_manager_(sync_point_manager), |
- client_state_(new SyncPointClientState(order_data)), |
- namespace_id_(namespace_id), |
- client_id_(client_id) {} |
+SyncPointManager::~SyncPointManager() { |
+ for (const ClientStateMap& client_state_map : client_state_maps_) |
+ DCHECK(client_state_map.empty()); |
+} |
-SyncPointManager::SyncPointManager(bool allow_threaded_wait) { |
- global_order_num_.GetNext(); |
+bool SyncPointManager::IsSyncTokenReleased(const SyncToken& sync_token) { |
+ scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( |
+ sync_token.namespace_id(), sync_token.command_buffer_id()); |
+ if (release_state) |
+ return release_state->IsFenceSyncReleased(sync_token.release_count()); |
+ return true; |
} |
-SyncPointManager::~SyncPointManager() { |
- for (const ClientMap& client_map : client_maps_) { |
- DCHECK(client_map.empty()); |
+bool SyncPointManager::Wait(const SyncToken& sync_token, |
+ uint32_t wait_order_num, |
+ const base::Closure& callback) { |
+ scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( |
+ sync_token.namespace_id(), sync_token.command_buffer_id()); |
+ if (release_state && |
+ release_state->WaitForRelease(sync_token.release_count(), wait_order_num, |
+ callback)) { |
+ return true; |
} |
+ // Do not run callback if wait is invalid. |
+ return false; |
} |
-std::unique_ptr<SyncPointClient> SyncPointManager::CreateSyncPointClient( |
- scoped_refptr<SyncPointOrderData> order_data, |
- CommandBufferNamespace namespace_id, |
- CommandBufferId client_id) { |
- DCHECK_GE(namespace_id, 0); |
- DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
- base::AutoLock auto_lock(client_maps_lock_); |
+bool SyncPointManager::WaitNonThreadSafe( |
+ const SyncToken& sync_token, |
+ uint32_t wait_order_num, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
+ const base::Closure& callback) { |
+ return Wait(sync_token, wait_order_num, |
+ base::Bind(&RunOnThread, task_runner, callback)); |
+} |
- ClientMap& client_map = client_maps_[namespace_id]; |
- std::pair<ClientMap::iterator, bool> result = client_map.insert( |
- std::make_pair(client_id, new SyncPointClient(this, order_data, |
- namespace_id, client_id))); |
- DCHECK(result.second); |
+bool SyncPointManager::WaitOutOfOrder(const SyncToken& trusted_sync_token, |
+ const base::Closure& callback) { |
+ // No order number associated with the current execution context, using |
+ // UINT32_MAX will just assume the release is in the SyncPointClientState's |
+ // order numbers to be executed. |
+ return Wait(trusted_sync_token, UINT32_MAX, callback); |
+} |
- return base::WrapUnique(result.first->second); |
+bool SyncPointManager::WaitOutOfOrderNonThreadSafe( |
+ const SyncToken& trusted_sync_token, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
+ const base::Closure& callback) { |
+ return WaitOutOfOrder(trusted_sync_token, |
+ base::Bind(&RunOnThread, task_runner, callback)); |
} |
-std::unique_ptr<SyncPointClient> |
-SyncPointManager::CreateSyncPointClientWaiter() { |
- return base::WrapUnique(new SyncPointClient); |
+void SyncPointManager::RegisterSyncPointClient( |
+ scoped_refptr<SyncPointClientState> client_state, |
+ CommandBufferNamespace namespace_id, |
+ CommandBufferId command_buffer_id) { |
+ DCHECK_GE(namespace_id, 0); |
+ DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); |
+ |
+ base::AutoLock auto_lock(client_state_maps_lock_); |
+ DCHECK(!client_state_maps_[namespace_id].count(command_buffer_id)); |
+ client_state_maps_[namespace_id].insert( |
+ std::make_pair(command_buffer_id, client_state)); |
} |
-scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( |
+void SyncPointManager::DeregisterSyncPointClient( |
CommandBufferNamespace namespace_id, |
- CommandBufferId client_id) { |
- if (namespace_id >= 0) { |
- DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
- base::AutoLock auto_lock(client_maps_lock_); |
- ClientMap& client_map = client_maps_[namespace_id]; |
- ClientMap::iterator it = client_map.find(client_id); |
- if (it != client_map.end()) { |
- return it->second->client_state(); |
- } |
- } |
- return nullptr; |
+ CommandBufferId command_buffer_id) { |
+ DCHECK_GE(namespace_id, 0); |
+ DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); |
+ |
+ base::AutoLock auto_lock(client_state_maps_lock_); |
+ DCHECK(client_state_maps_[namespace_id].count(command_buffer_id)); |
+ client_state_maps_[namespace_id].erase(command_buffer_id); |
} |
uint32_t SyncPointManager::GenerateOrderNumber() { |
return global_order_num_.GetNext(); |
} |
-void SyncPointManager::DestroySyncPointClient( |
+scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( |
CommandBufferNamespace namespace_id, |
- CommandBufferId client_id) { |
- DCHECK_GE(namespace_id, 0); |
- DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); |
- |
- base::AutoLock auto_lock(client_maps_lock_); |
- ClientMap& client_map = client_maps_[namespace_id]; |
- ClientMap::iterator it = client_map.find(client_id); |
- DCHECK(it != client_map.end()); |
- client_map.erase(it); |
+ CommandBufferId command_buffer_id) { |
+ if (namespace_id >= 0) { |
+ DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); |
+ base::AutoLock auto_lock(client_state_maps_lock_); |
+ ClientStateMap& client_state_map = client_state_maps_[namespace_id]; |
+ auto it = client_state_map.find(command_buffer_id); |
+ if (it != client_state_map.end()) |
+ return it->second; |
+ } |
+ return nullptr; |
} |
} // namespace gpu |