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

Unified Diff: gpu/command_buffer/service/sync_point_manager.cc

Issue 2722883002: gpu: Allow waiting on sync tokens without sync token client. (Closed)
Patch Set: review Created 3 years, 10 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 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
« 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