xref: /aosp_15_r20/external/skia/src/core/SkPtrRecorder.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2008 The Android Open Source Project
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 
9 #ifndef SkPtrSet_DEFINED
10 #define SkPtrSet_DEFINED
11 
12 #include "include/core/SkFlattenable.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/private/base/SkTDArray.h"
15 
16 #include <cstdint>
17 
18 /**
19  *  Maintains a set of ptrs, assigning each a unique ID [1...N]. Duplicate ptrs
20  *  return the same ID (since its a set). Subclasses can override inPtr()
21  *  and decPtr(). incPtr() is called each time a unique ptr is added ot the
22  *  set. decPtr() is called on each ptr when the set is destroyed or reset.
23  */
24 class SkPtrSet : public SkRefCnt {
25 public:
26 
27 
28     /**
29      *  Search for the specified ptr in the set. If it is found, return its
30      *  32bit ID [1..N], or if not found, return 0. Always returns 0 for nullptr.
31      */
32     uint32_t find(void*) const;
33 
34     /**
35      *  Add the specified ptr to the set, returning a unique 32bit ID for it
36      *  [1...N]. Duplicate ptrs will return the same ID.
37      *
38      *  If the ptr is nullptr, it is not added, and 0 is returned.
39      */
40     uint32_t add(void*);
41 
42     /**
43      *  Return the number of (non-null) ptrs in the set.
44      */
count()45     int count() const { return fList.size(); }
46 
47     /**
48      *  Copy the ptrs in the set into the specified array (allocated by the
49      *  caller). The ptrs are assgined to the array based on their corresponding
50      *  ID. e.g. array[ptr.ID - 1] = ptr.
51      *
52      *  incPtr() and decPtr() are not called during this operation.
53      */
54     void copyToArray(void* array[]) const;
55 
56     /**
57      *  Call decPtr() on each ptr in the set, and the reset the size of the set
58      *  to 0.
59      */
60     void reset();
61 
62     /**
63      * Set iterator.
64      */
65     class Iter {
66     public:
Iter(const SkPtrSet & set)67         Iter(const SkPtrSet& set)
68             : fSet(set)
69             , fIndex(0) {}
70 
71         /**
72          * Return the next ptr in the set or null if the end was reached.
73          */
next()74         void* next() {
75             return fIndex < fSet.fList.size() ? fSet.fList[fIndex++].fPtr : nullptr;
76         }
77 
78     private:
79         const SkPtrSet& fSet;
80         int             fIndex;
81     };
82 
83 protected:
incPtr(void *)84     virtual void incPtr(void*) {}
decPtr(void *)85     virtual void decPtr(void*) {}
86 
87 private:
88     struct Pair {
89         void*       fPtr;   // never nullptr
90         uint32_t    fIndex; // 1...N
91     };
92 
93     // we store the ptrs in sorted-order (using Cmp) so that we can efficiently
94     // detect duplicates when add() is called. Hence we need to store the
95     // ptr and its ID/fIndex explicitly, since the ptr's position in the array
96     // is not related to its "index".
97     SkTDArray<Pair>  fList;
98 
99     static bool Less(const Pair& a, const Pair& b);
100 
101     using INHERITED = SkRefCnt;
102 };
103 
104 /**
105  *  Templated wrapper for SkPtrSet, just meant to automate typecasting
106  *  parameters to and from void* (which the base class expects).
107  */
108 template <typename T> class SkTPtrSet : public SkPtrSet {
109 public:
find(T ptr)110     uint32_t find(T ptr) {
111         return this->INHERITED::find((void*)ptr);
112     }
add(T ptr)113     uint32_t add(T ptr) {
114         return this->INHERITED::add((void*)ptr);
115     }
116 
copyToArray(T * array)117     void copyToArray(T* array) const {
118         this->INHERITED::copyToArray((void**)array);
119     }
120 
121 private:
122     using INHERITED = SkPtrSet;
123 };
124 
125 /**
126  *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
127  *  base class's incPtr() and decPtr() are called. This makes it a valid owner
128  *  of each ptr, which is released when the set is reset or destroyed.
129  */
130 class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
131 public:
132     ~SkRefCntSet() override;
133 
134 protected:
135     // overrides
136     void incPtr(void*) override;
137     void decPtr(void*) override;
138 };
139 
140 class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
141 
142 /**
143  * Similar to SkFactorySet, but only allows Factorys that have registered names.
144  * Also has a function to return the next added Factory's name.
145  */
146 class SkNamedFactorySet : public SkRefCnt {
147 public:
148 
149 
150     SkNamedFactorySet();
151 
152     /**
153      * Find the specified Factory in the set. If it is not already in the set,
154      * and has registered its name, add it to the set, and return its index.
155      * If the Factory has no registered name, return 0.
156      */
157     uint32_t find(SkFlattenable::Factory);
158 
159     /**
160      * If new Factorys have been added to the set, return the name of the first
161      * Factory added after the Factory name returned by the last call to this
162      * function.
163      */
164     const char* getNextAddedFactoryName();
165 private:
166     int                    fNextAddedFactory;
167     SkFactorySet           fFactorySet;
168     SkTDArray<const char*> fNames;
169 
170     using INHERITED = SkRefCnt;
171 };
172 
173 #endif
174