Index: cc/output/context_cache_controller.h |
diff --git a/cc/output/context_cache_controller.h b/cc/output/context_cache_controller.h |
index 03f7e2cd74f9117e11cb95ac6db4a747199301f7..357e5daacb5862f0863492625804ec1e8c7353bc 100644 |
--- a/cc/output/context_cache_controller.h |
+++ b/cc/output/context_cache_controller.h |
@@ -10,11 +10,13 @@ |
#include "base/macros.h" |
#include "base/memory/ref_counted.h" |
+#include "base/memory/weak_ptr.h" |
#include "cc/base/cc_export.h" |
class GrContext; |
namespace base { |
+class Lock; |
class SingleThreadTaskRunner; |
} |
@@ -25,26 +27,26 @@ class ContextSupport; |
namespace cc { |
// ContextCacheController manages clearing cached data on ContextProvider when |
-// appropriate. Currently, cache clearing happens when the ContextProvider |
-// transitions from visible to not visible. As a ContextProvider may have |
-// multiple clients, ContextCacheController tracks visibility across all |
-// clients and only cleans up when appropriate. |
-// |
-// Note: Virtuals on this function are for testing only. This function is not |
-// designed to have multiple implementations. |
+// appropriate. Currently, cache clearing is triggered when the Context |
+// provider transitions from Visible to Not Visible, or from Busy to Idle. As a |
+// ContextProvider may have multiple clients, ContextCacheController tracks |
+// visibility and idle status across all clients and only cleans up when |
+// appropriate. |
class CC_EXPORT ContextCacheController { |
public: |
- class CC_EXPORT ScopedVisibility { |
+ class CC_EXPORT ScopedToken { |
public: |
- ~ScopedVisibility(); |
+ ~ScopedToken(); |
private: |
friend class ContextCacheController; |
- ScopedVisibility(); |
+ ScopedToken(); |
void Release(); |
bool released_ = false; |
}; |
+ using ScopedVisibility = ScopedToken; |
+ using ScopedBusy = ScopedToken; |
ContextCacheController( |
gpu::ContextSupport* context_support, |
@@ -52,6 +54,7 @@ class CC_EXPORT ContextCacheController { |
virtual ~ContextCacheController(); |
void SetGrContext(GrContext* gr_context); |
+ void SetLock(base::Lock* lock); |
// Clients of the owning ContextProvider should call this function when they |
// become visible. The returned ScopedVisibility pointer must be passed back |
@@ -64,17 +67,42 @@ class CC_EXPORT ContextCacheController { |
virtual void ClientBecameNotVisible( |
std::unique_ptr<ScopedVisibility> scoped_visibility); |
- protected: |
- std::unique_ptr<ScopedVisibility> CreateScopedVisibilityForTesting() const; |
- void ReleaseScopedVisibilityForTesting( |
- std::unique_ptr<ScopedVisibility> scoped_visibility) const; |
+ // Clients of the owning ContextProvider may call this function when they |
+ // become busy. The returned ScopedBusy pointer must be passed back |
+ // to ClientBecameNotBusy or it will DCHECK in its destructor. |
+ std::unique_ptr<ScopedBusy> ClientBecameBusy(); |
+ |
+ // When a client becomes not busy, it must pass back any ScopedBusy |
+ // pointers it owns via this function. |
+ void ClientBecameNotBusy(std::unique_ptr<ScopedBusy> scoped_busy); |
private: |
+ void OnIdle(uint32_t idle_generation); |
+ void PostIdleCallback(uint32_t current_idle_generation) const; |
+ void InvalidatePendingIdleCallbacks(); |
+ |
gpu::ContextSupport* context_support_; |
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
GrContext* gr_context_ = nullptr; |
+ // If set, |context_lock_| must be held before accessing any member within |
+ // the idle callback. Exceptions to this are |current_idle_generation_|, |
+ // which has its own lock, and weak_ptr_ and task_runner_, which may be |
+ // accessed from multiple threads without locking. |
+ base::Lock* context_lock_ = nullptr; |
+ |
uint32_t num_clients_visible_ = 0; |
+ uint32_t num_clients_busy_ = 0; |
+ bool callback_pending_ = false; |
+ |
+ // |current_idle_generation_lock_| must be held when accessing |
+ // |current_idle_generation_|. |current_idle_generation_lock_| must never be |
+ // held while acquiring |context_lock_|. |
+ base::Lock current_idle_generation_lock_; |
+ uint32_t current_idle_generation_ = 0; |
+ |
+ base::WeakPtr<ContextCacheController> weak_ptr_; |
+ base::WeakPtrFactory<ContextCacheController> weak_factory_; |
}; |
} // namespace cc |