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

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

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.h
diff --git a/gpu/command_buffer/service/sync_point_manager.h b/gpu/command_buffer/service/sync_point_manager.h
index 7a3695c9886207853dff2f86dffdc98b2bcd1689..a34a17cede443e758d5f453b91f012c4147c11b9 100644
--- a/gpu/command_buffer/service/sync_point_manager.h
+++ b/gpu/command_buffer/service/sync_point_manager.h
@@ -23,6 +23,7 @@
#include "base/threading/thread_checker.h"
#include "gpu/command_buffer/common/command_buffer_id.h"
#include "gpu/command_buffer/common/constants.h"
+#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/gpu_export.h"
namespace base {
@@ -66,9 +67,14 @@ class GPU_EXPORT SyncPointOrderData
return !paused_ && current_order_num_ > processed_order_num();
}
+ bool ValidateReleaseOrderNumber(
+ scoped_refptr<SyncPointClientState> client_state,
+ uint32_t wait_order_num,
+ uint64_t fence_release,
+ const base::Closure& release_callback);
+
private:
friend class base::RefCountedThreadSafe<SyncPointOrderData>;
- friend class SyncPointClientState;
struct OrderFence {
uint32_t order_num;
@@ -84,32 +90,26 @@ class GPU_EXPORT SyncPointOrderData
~OrderFence();
bool operator>(const OrderFence& rhs) const {
- return (order_num > rhs.order_num) ||
- ((order_num == rhs.order_num) &&
- (fence_release > rhs.fence_release));
+ return std::tie(order_num, fence_release) >
+ std::tie(rhs.order_num, rhs.fence_release);
}
};
typedef std::priority_queue<OrderFence,
std::vector<OrderFence>,
- std::greater<OrderFence>> OrderFenceQueue;
+ std::greater<OrderFence>>
+ OrderFenceQueue;
SyncPointOrderData();
~SyncPointOrderData();
- bool ValidateReleaseOrderNumber(
- scoped_refptr<SyncPointClientState> client_state,
- uint32_t wait_order_num,
- uint64_t fence_release,
- const base::Closure& release_callback);
-
// Non thread-safe functions need to be called from a single thread.
base::ThreadChecker processing_thread_checker_;
// Current IPC order number being processed (only used on processing thread).
- uint32_t current_order_num_;
+ uint32_t current_order_num_ = 0;
// Whether or not the current order number is being processed or paused.
- bool paused_;
+ bool paused_ = false;
// This lock protects destroyed_, processed_order_num_,
// unprocessed_order_num_, and order_fence_queue_. All order numbers (n) in
@@ -117,13 +117,13 @@ class GPU_EXPORT SyncPointOrderData
// processed_order_num_ < n <= unprocessed_order_num_.
mutable base::Lock lock_;
- bool destroyed_;
+ bool destroyed_ = false;
// Last finished IPC order number.
- uint32_t processed_order_num_;
+ uint32_t processed_order_num_ = 0;
// Unprocessed order number expected to be processed under normal execution.
- uint32_t unprocessed_order_num_;
+ uint32_t unprocessed_order_num_ = 0;
// In situations where we are waiting on fence syncs that do not exist, we
// validate by making sure the order number does not pass the order number
@@ -137,24 +137,30 @@ class GPU_EXPORT SyncPointOrderData
DISALLOW_COPY_AND_ASSIGN(SyncPointOrderData);
};
+// Internal state for sync point clients.
class GPU_EXPORT SyncPointClientState
: public base::RefCountedThreadSafe<SyncPointClientState> {
public:
- scoped_refptr<SyncPointOrderData> order_data() { return order_data_; }
+ explicit SyncPointClientState(scoped_refptr<SyncPointOrderData> order_data);
- bool IsFenceSyncReleased(uint64_t release) {
- return release <= fence_sync_release();
- }
+ bool IsFenceSyncReleased(uint64_t release);
- uint64_t fence_sync_release() {
- base::AutoLock auto_lock(fence_sync_lock_);
- return fence_sync_release_;
- }
+ // Queues the callback to be called if the release is valid. If the release
+ // is invalid this function will return False and the callback will never
+ // be called.
+ bool WaitForRelease(uint64_t release,
+ uint32_t wait_order_num,
+ const base::Closure& callback);
+
+ // Releases a fence sync and all fence syncs below.
+ void ReleaseFenceSync(uint64_t release);
+
+ // Does not release the fence sync, but releases callbacks waiting on that
+ // fence sync.
+ void EnsureWaitReleased(uint64_t release, const base::Closure& callback);
private:
friend class base::RefCountedThreadSafe<SyncPointClientState>;
- friend class SyncPointClient;
- friend class SyncPointOrderData;
struct ReleaseCallback {
uint64_t release_count;
@@ -173,29 +179,8 @@ class GPU_EXPORT SyncPointClientState
std::greater<ReleaseCallback>>
ReleaseCallbackQueue;
- SyncPointClientState(scoped_refptr<SyncPointOrderData> order_data);
~SyncPointClientState();
- // Queues the callback to be called if the release is valid. If the release
- // is invalid this function will return False and the callback will never
- // be called.
- bool WaitForRelease(CommandBufferNamespace namespace_id,
- CommandBufferId client_id,
- uint32_t wait_order_num,
- uint64_t release,
- const base::Closure& callback);
-
- // Releases a fence sync and all fence syncs below.
- void ReleaseFenceSync(uint64_t release);
-
- // Does not release the fence sync, but releases callbacks waiting on that
- // fence sync.
- void EnsureWaitReleased(uint64_t release, const base::Closure& callback);
-
- typedef base::Callback<void(CommandBufferNamespace, CommandBufferId)>
- OnWaitCallback;
- void SetOnWaitCallback(const OnWaitCallback& callback);
-
// Global order data where releases will originate from.
scoped_refptr<SyncPointOrderData> order_data_;
@@ -203,87 +188,47 @@ class GPU_EXPORT SyncPointClientState
base::Lock fence_sync_lock_;
// Current fence sync release that has been signaled.
- uint64_t fence_sync_release_;
+ uint64_t fence_sync_release_ = 0;
// In well defined fence sync operations, fence syncs are released in order
// so simply having a priority queue for callbacks is enough.
ReleaseCallbackQueue release_callback_queue_;
- // Called when a release callback is queued.
- OnWaitCallback on_wait_callback_;
-
DISALLOW_COPY_AND_ASSIGN(SyncPointClientState);
};
class GPU_EXPORT SyncPointClient {
public:
+ SyncPointClient(SyncPointManager* sync_point_manager,
+ scoped_refptr<SyncPointOrderData> order_data,
+ CommandBufferNamespace namespace_id,
+ CommandBufferId command_buffer_id);
~SyncPointClient();
- scoped_refptr<SyncPointClientState> client_state() { return client_state_; }
-
- // Wait for a release count to be reached on a SyncPointClientState. If this
- // function returns false, that means the wait was invalid. Otherwise if it
- // returns True it means the release was valid. In the case where the release
- // is valid but has happened already, it will still return true. In all cases
- // wait_complete_callback will be called eventually. The callback function
- // may be called on another thread so it should be thread-safe. For
- // convenience, another non-threadsafe version is defined below where you
- // can supply a task runner.
- bool Wait(SyncPointClientState* release_state,
- uint64_t release_count,
- const base::Closure& wait_complete_callback);
-
- bool WaitNonThreadSafe(SyncPointClientState* release_state,
- uint64_t release_count,
- scoped_refptr<base::SingleThreadTaskRunner> runner,
- const base::Closure& wait_complete_callback);
-
- // Unordered waits are waits which do not occur within the global order number
- // processing order (IE. Not between the corresponding
- // SyncPointOrderData::BeginProcessingOrderNumber() and
- // SyncPointOrderData::FinishProcessingOrderNumber() calls). Because fence
- // sync releases must occur within a corresponding order number, these waits
- // cannot deadlock because they can never depend on any fence sync releases.
- // This is useful for IPC messages that may be processed out of order with
- // respect to regular command buffer processing.
- bool WaitOutOfOrder(SyncPointClientState* release_state,
- uint64_t release_count,
- const base::Closure& wait_complete_callback);
+ // This behaves similarly to SyncPointManager::Wait but uses the order data
+ // to guarantee no deadlocks with other clients.
+ bool Wait(const SyncToken& sync_token, const base::Closure& callback);
- bool WaitOutOfOrderNonThreadSafe(
- SyncPointClientState* release_state,
- uint64_t release_count,
- scoped_refptr<base::SingleThreadTaskRunner> runner,
- const base::Closure& wait_complete_callback);
+ // Like Wait but runs the callback on the given task runner's thread.
+ bool WaitNonThreadSafe(
+ const SyncToken& sync_token,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ const base::Closure& callback);
+ // Release fence sync and run queued callbacks.
void ReleaseFenceSync(uint64_t release);
- // This callback is called with the namespace and id of the waiting client
- // when a release callback is queued. The callback is called on the thread
- // where the Wait... happens and synchronization is the responsibility of the
- // caller.
- typedef base::Callback<void(CommandBufferNamespace, CommandBufferId)>
- OnWaitCallback;
- void SetOnWaitCallback(const OnWaitCallback& callback);
-
private:
- friend class SyncPointManager;
-
- SyncPointClient();
- SyncPointClient(SyncPointManager* sync_point_manager,
- scoped_refptr<SyncPointOrderData> order_data,
- CommandBufferNamespace namespace_id,
- CommandBufferId client_id);
-
// Sync point manager is guaranteed to exist in the lifetime of the client.
- SyncPointManager* sync_point_manager_;
+ SyncPointManager* const sync_point_manager_;
+
+ scoped_refptr<SyncPointOrderData> order_data_;
- // Keep the state that is sharable across multiple threads.
scoped_refptr<SyncPointClientState> client_state_;
// Unique namespace/client id pair for this sync point client.
const CommandBufferNamespace namespace_id_;
- const CommandBufferId client_id_;
+ const CommandBufferId command_buffer_id_;
DISALLOW_COPY_AND_ASSIGN(SyncPointClient);
};
@@ -292,42 +237,67 @@ class GPU_EXPORT SyncPointClient {
// synchronization.
class GPU_EXPORT SyncPointManager {
public:
- explicit SyncPointManager(bool allow_threaded_wait);
+ SyncPointManager();
~SyncPointManager();
- // Creates/Destroy a sync point client which message processors should hold.
- std::unique_ptr<SyncPointClient> CreateSyncPointClient(
- scoped_refptr<SyncPointOrderData> order_data,
- CommandBufferNamespace namespace_id,
- CommandBufferId client_id);
+ // Returns true if the sync token has been released or if the command buffer
+ // does not exist.
+ bool IsSyncTokenReleased(const SyncToken& sync_token);
+
+ // If the wait is valid (sync token hasn't been processed or command buffer
+ // does not exist), the callback is queued to run when the sync point is
+ // released. If the wait is invalid, the callback is NOT run. The callback
+ // runs on the thread the sync point is released. Clients should use
+ // SyncPointClient::Wait because that uses order data to prevent deadlocks.
+ bool Wait(const SyncToken& sync_token,
+ uint32_t wait_order_num,
+ const base::Closure& callback);
+
+ // Like Wait but runs the callback on the given task runner's thread.
+ bool WaitNonThreadSafe(
+ const SyncToken& sync_token,
+ uint32_t wait_order_num,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ const base::Closure& callback);
- // Creates a sync point client which cannot process order numbers but can only
- // Wait out of order.
- std::unique_ptr<SyncPointClient> CreateSyncPointClientWaiter();
+ // WaitOutOfOrder allows waiting for a sync token indefinitely, so it
+ // should be used with trusted sync tokens only.
+ bool WaitOutOfOrder(const SyncToken& trusted_sync_token,
+ const base::Closure& callback);
- // Finds the state of an already created sync point client.
- scoped_refptr<SyncPointClientState> GetSyncPointClientState(
- CommandBufferNamespace namespace_id,
- CommandBufferId client_id);
+ // Like WaitOutOfOrder but runs the callback on the given task runner's
+ // thread.
+ bool WaitOutOfOrderNonThreadSafe(
+ const SyncToken& trusted_sync_token,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ const base::Closure& callback);
- private:
- friend class SyncPointClient;
- friend class SyncPointOrderData;
+ // Used by SyncPointClient.
+ void RegisterSyncPointClient(scoped_refptr<SyncPointClientState> client_state,
+ CommandBufferNamespace namespace_id,
+ CommandBufferId command_buffer_id);
- using ClientMap = std::unordered_map<CommandBufferId,
- SyncPointClient*,
- CommandBufferId::Hasher>;
+ void DeregisterSyncPointClient(CommandBufferNamespace namespace_id,
+ CommandBufferId command_buffer_id);
+ // Used by SyncPointOrderData.
uint32_t GenerateOrderNumber();
- void DestroySyncPointClient(CommandBufferNamespace namespace_id,
- CommandBufferId client_id);
+
+ private:
+ using ClientStateMap = std::unordered_map<CommandBufferId,
+ scoped_refptr<SyncPointClientState>,
+ CommandBufferId::Hasher>;
+
+ scoped_refptr<SyncPointClientState> GetSyncPointClientState(
+ CommandBufferNamespace namespace_id,
+ CommandBufferId command_buffer_id);
// Order number is global for all clients.
base::AtomicSequenceNumber global_order_num_;
// Client map holds a map of clients id to client for each namespace.
- base::Lock client_maps_lock_;
- ClientMap client_maps_[NUM_COMMAND_BUFFER_NAMESPACES];
+ base::Lock client_state_maps_lock_;
+ ClientStateMap client_state_maps_[NUM_COMMAND_BUFFER_NAMESPACES];
DISALLOW_COPY_AND_ASSIGN(SyncPointManager);
};
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc ('k') | gpu/command_buffer/service/sync_point_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698