xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrNonAtomicRef.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2015 Google Inc.
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 GrNonAtomicRef_DEFINED
9 #define GrNonAtomicRef_DEFINED
10 
11 #include "include/core/SkTypes.h"
12 #include "include/private/base/SkNoncopyable.h"
13 
14 #include <cstdint>
15 
16 /**
17  * A simple non-atomic ref used in the GrBackendApi when we don't want to pay for the overhead of a
18  * threadsafe ref counted object
19  */
20 template<typename TSubclass> class GrNonAtomicRef : public SkNoncopyable {
21 public:
GrNonAtomicRef()22     GrNonAtomicRef() : fRefCnt(1) {}
23 
24 #ifdef SK_DEBUG
~GrNonAtomicRef()25     ~GrNonAtomicRef() {
26         // fRefCnt can be one when a subclass is created statically
27         SkASSERT((0 == fRefCnt || 1 == fRefCnt));
28         // Set to invalid values.
29         fRefCnt = -10;
30     }
31 #endif
32 
unique()33     bool unique() const { return 1 == fRefCnt; }
34 
35     // We allow this getter because this type is not thread-safe, meaning only one thread should
36     // have ownership and be manipulating the ref count or querying this.
refCnt()37     int refCnt() const { return fRefCnt; }
38 
ref()39     void ref() const {
40         // Once the ref cnt reaches zero it should never be ref'ed again.
41         SkASSERT(fRefCnt > 0);
42         ++fRefCnt;
43     }
44 
unref()45     void unref() const {
46         SkASSERT(fRefCnt > 0);
47         --fRefCnt;
48         if (0 == fRefCnt) {
49             GrTDeleteNonAtomicRef(static_cast<const TSubclass*>(this));
50             return;
51         }
52     }
53 
54 private:
55     mutable int32_t fRefCnt;
56 
57     using INHERITED = SkNoncopyable;
58 };
59 
GrTDeleteNonAtomicRef(const T * ref)60 template<typename T> inline void GrTDeleteNonAtomicRef(const T* ref) {
61     delete ref;
62 }
63 
64 #endif
65