xref: /aosp_15_r20/external/skia/include/private/SkIDChangeListener.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2020 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkIDChangeListener_DEFINED
9 #define SkIDChangeListener_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/private/base/SkMutex.h"
13 #include "include/private/base/SkTArray.h"
14 #include "include/private/base/SkThreadAnnotations.h"
15 
16 #include <atomic>
17 
18 /**
19  * Used to be notified when a gen/unique ID is invalidated, typically to preemptively purge
20  * associated items from a cache that are no longer reachable. The listener can
21  * be marked for deregistration if the cached item is remove before the listener is
22  * triggered. This prevents unbounded listener growth when cache items are routinely
23  * removed before the gen ID/unique ID is invalidated.
24  */
25 class SkIDChangeListener : public SkRefCnt {
26 public:
27     SkIDChangeListener();
28 
29     ~SkIDChangeListener() override;
30 
31     virtual void changed() = 0;
32 
33     /**
34      * Mark the listener is no longer needed. It should be removed and changed() should not be
35      * called.
36      */
markShouldDeregister()37     void markShouldDeregister() { fShouldDeregister.store(true, std::memory_order_relaxed); }
38 
39     /** Indicates whether markShouldDeregister was called. */
shouldDeregister()40     bool shouldDeregister() { return fShouldDeregister.load(std::memory_order_acquire); }
41 
42     /** Manages a list of SkIDChangeListeners. */
43     class List {
44     public:
45         List();
46 
47         ~List();
48 
49         /**
50          * Add a new listener to the list. It must not already be deregistered. Also clears out
51          * previously deregistered listeners.
52          */
53         void add(sk_sp<SkIDChangeListener> listener) SK_EXCLUDES(fMutex);
54 
55         /**
56          * The number of registered listeners (including deregisterd listeners that are yet-to-be
57          * removed.
58          */
59         int count() const SK_EXCLUDES(fMutex);
60 
61         /** Calls changed() on all listeners that haven't been deregistered and resets the list. */
62         void changed() SK_EXCLUDES(fMutex);
63 
64         /** Resets without calling changed() on the listeners. */
65         void reset() SK_EXCLUDES(fMutex);
66 
67     private:
68         mutable SkMutex fMutex;
69         skia_private::STArray<1, sk_sp<SkIDChangeListener>> fListeners SK_GUARDED_BY(fMutex);
70     };
71 
72 private:
73     std::atomic<bool> fShouldDeregister;
74 };
75 
76 #endif
77