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