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 98e849b76ced244c3400b171d12cf513c4f4f739..b136d4b5fe9738fbe4d279834dd5ccf80dd98b84 100644 |
--- a/gpu/command_buffer/service/sync_point_manager.h |
+++ b/gpu/command_buffer/service/sync_point_manager.h |
@@ -7,15 +7,96 @@ |
#include <vector> |
+#include "base/atomic_sequence_num.h" |
#include "base/callback.h" |
#include "base/containers/hash_tables.h" |
+#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/synchronization/condition_variable.h" |
#include "base/synchronization/lock.h" |
+#include "base/threading/thread_checker.h" |
#include "gpu/gpu_export.h" |
namespace gpu { |
+class SyncPointManager; |
+ |
+enum SyncPointNamespace { |
+ kSyncPointNamespace_GpuIO, |
+ kSyncPointNamespace_InProcess, |
+ |
+ NUM_SYNC_POINT_NAMESPACES |
+}; |
+ |
+class GPU_EXPORT SyncPointClient |
+ : public base::RefCountedThreadSafe<SyncPointClient> { |
+ public: |
+ uint32_t GenerateUnprocessedOrderNumber(); |
+ |
+ void BeginProcessingOrderNumber(uint32_t order_num) { |
+ DCHECK(processing_thread_checker_.CalledOnValidThread()); |
+ |
+ DCHECK_GE(order_num, current_order_num_); |
+ current_order_num_ = order_num; |
+ } |
+ |
+ void FinishProcessingOrderNumber(uint32_t order_num) { |
+ DCHECK(processing_thread_checker_.CalledOnValidThread()); |
+ |
+ DCHECK_EQ(current_order_num_, order_num); |
+ DCHECK_GT(order_num, processed_order_num()); |
+ base::subtle::Release_Store(&processed_order_num_, order_num); |
+ } |
+ |
+ bool IsValid() const { return sync_point_manager_ != nullptr; } |
+ |
+ uint32_t current_order_num() const { |
+ DCHECK(processing_thread_checker_.CalledOnValidThread()); |
+ return current_order_num_; |
+ } |
+ |
+ uint32_t processed_order_num() const { |
+ return base::subtle::Acquire_Load(&processed_order_num_); |
+ } |
+ |
+ uint32_t unprocessed_order_num() const { |
+ return base::subtle::Acquire_Load(&unprocessed_order_num_); |
+ } |
+ |
+ private: |
+ friend class base::RefCountedThreadSafe<SyncPointClient>; |
+ friend class SyncPointManager; |
+ |
+ SyncPointClient(SyncPointManager* sync_point_manager, |
+ SyncPointNamespace namespace_id, uint64_t client_id); |
+ void Destroy(); |
+ |
+ protected: |
+ virtual ~SyncPointClient(); |
+ |
+ // This point is cleared upon destroy which invalidates this object. |
+ SyncPointManager* sync_point_manager_; |
+ |
+ // Unique namespace/client id pair for this sync point client. |
+ SyncPointNamespace namespace_id_; |
+ uint64_t client_id_; |
+ |
+ // 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_; |
+ |
+ // Last finished IPC order number. |
+ base::subtle::Atomic32 processed_order_num_; |
+ |
+ // Unprocessed order number expected to be processed under normal execution. |
+ base::subtle::Atomic32 unprocessed_order_num_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SyncPointClient); |
+}; |
+ |
// This class manages the sync points, which allow cross-channel |
// synchronization. |
class GPU_EXPORT SyncPointManager { |
@@ -23,6 +104,15 @@ class GPU_EXPORT SyncPointManager { |
explicit SyncPointManager(bool allow_threaded_wait); |
~SyncPointManager(); |
+ // Creates/Destroy a sync point client which message processors should hold. |
+ scoped_refptr<SyncPointClient> CreateSyncPointClient( |
+ SyncPointNamespace namespace_id, uint64_t client_id); |
+ void DestroySyncPointClient(scoped_refptr<SyncPointClient> client); |
+ |
+ // Finds an already created sync point client. |
+ scoped_refptr<SyncPointClient> GetSyncPointClient( |
+ SyncPointNamespace namespace_id, uint64_t client_id); |
+ |
// Generates a sync point, returning its ID. This can me called on any thread. |
// IDs start at a random number. Never return 0. |
uint32 GenerateSyncPoint(); |
@@ -44,14 +134,24 @@ class GPU_EXPORT SyncPointManager { |
void WaitSyncPoint(uint32 sync_point); |
private: |
+ friend class SyncPointClient; |
+ |
typedef std::vector<base::Closure> ClosureList; |
typedef base::hash_map<uint32, ClosureList> SyncPointMap; |
- |
+ typedef base::hash_map<uint64_t, SyncPointClient*> ClientMap; |
bool IsSyncPointRetiredLocked(uint32 sync_point); |
+ uint32_t GenerateOrderNumber(); |
const bool allow_threaded_wait_; |
+ // 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_SYNC_POINT_NAMESPACES]; |
+ |
// Protects the 2 fields below. Note: callbacks shouldn't be called with this |
// held. |
base::Lock lock_; |