OLD | NEW |
| (Empty) |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef SKIA_EXT_REFPTR_H_ | |
6 #define SKIA_EXT_REFPTR_H_ | |
7 | |
8 #include "third_party/skia/include/core/SkRefCnt.h" | |
9 | |
10 namespace skia { | |
11 | |
12 // When creating/receiving a ref-counted pointer from Skia, wrap that pointer in | |
13 // this class to avoid dealing with the ref-counting and prevent leaks/crashes | |
14 // due to ref-counting bugs. | |
15 // | |
16 // Example of creating a new SkShader* and setting it on a SkPaint: | |
17 // skia::RefPtr<SkShader> shader = skia::AdoptRef(SkGradientShader::Create()); | |
18 // paint.setShader(shader.get()); | |
19 // | |
20 // When passing around a ref-counted pointer to methods outside of Skia, always | |
21 // pass around the skia::RefPtr instead of the raw pointer. An example method | |
22 // that takes a SkShader* parameter and saves the SkShader* in the class. | |
23 // void AMethodThatSavesAShader(const skia::RefPtr<SkShader>& shader) { | |
24 // member_refptr_ = shader; | |
25 // } | |
26 // skia::RefPtr<SkShader> member_refptr_; | |
27 // | |
28 // When returning a ref-counted pointer, also return the skia::RefPtr instead. | |
29 // An example method that creates an SkShader* and returns it: | |
30 // skia::RefPtr<SkShader> MakeAShader() { | |
31 // return skia::AdoptRef(SkGradientShader::Create()); | |
32 // } | |
33 // | |
34 // To take a scoped reference to an object whose references are all owned | |
35 // by other objects (i.e. does not have one that needs to be adopted) use the | |
36 // skia::SharePtr helper: | |
37 // | |
38 // skia::RefPtr<SkShader> shader = skia::SharePtr(paint.getShader()); | |
39 // | |
40 // Never call ref() or unref() on the underlying ref-counted pointer. If you | |
41 // AdoptRef() the raw pointer immediately into a skia::RefPtr and always work | |
42 // with skia::RefPtr instances instead, the ref-counting will be taken care of | |
43 // for you. | |
44 template<typename T> | |
45 class RefPtr { | |
46 public: | |
47 RefPtr() : ptr_(NULL) {} | |
48 | |
49 RefPtr(const RefPtr& other) | |
50 : ptr_(other.get()) { | |
51 SkSafeRef(ptr_); | |
52 } | |
53 | |
54 template<typename U> | |
55 RefPtr(const RefPtr<U>& other) | |
56 : ptr_(other.get()) { | |
57 SkSafeRef(ptr_); | |
58 } | |
59 | |
60 ~RefPtr() { | |
61 clear(); | |
62 } | |
63 | |
64 RefPtr& operator=(const RefPtr& other) { | |
65 SkRefCnt_SafeAssign(ptr_, other.get()); | |
66 return *this; | |
67 } | |
68 | |
69 template<typename U> | |
70 RefPtr& operator=(const RefPtr<U>& other) { | |
71 SkRefCnt_SafeAssign(ptr_, other.get()); | |
72 return *this; | |
73 } | |
74 | |
75 void clear() { | |
76 T* to_unref = ptr_; | |
77 ptr_ = NULL; | |
78 SkSafeUnref(to_unref); | |
79 } | |
80 | |
81 T* get() const { return ptr_; } | |
82 T& operator*() const { return *ptr_; } | |
83 T* operator->() const { return ptr_; } | |
84 | |
85 typedef T* RefPtr::*unspecified_bool_type; | |
86 operator unspecified_bool_type() const { | |
87 return ptr_ ? &RefPtr::ptr_ : NULL; | |
88 } | |
89 | |
90 private: | |
91 T* ptr_; | |
92 | |
93 // This function cannot be public because Skia starts its ref-counted | |
94 // objects at refcnt=1. This makes it impossible to differentiate | |
95 // between a newly created object (that doesn't need to be ref'd) or an | |
96 // already existing object with one owner (that does need to be ref'd so that | |
97 // this RefPtr can also manage its lifetime). | |
98 explicit RefPtr(T* ptr) : ptr_(ptr) {} | |
99 | |
100 template<typename U> | |
101 friend RefPtr<U> AdoptRef(U* ptr); | |
102 | |
103 template<typename U> | |
104 friend RefPtr<U> SharePtr(U* ptr); | |
105 }; | |
106 | |
107 // For objects that have an unowned reference (such as newly created objects). | |
108 template<typename T> | |
109 RefPtr<T> AdoptRef(T* ptr) { return RefPtr<T>(ptr); } | |
110 | |
111 // For objects that are already owned. This doesn't take ownership of existing | |
112 // references and adds a new one. | |
113 template<typename T> | |
114 RefPtr<T> SharePtr(T* ptr) { return RefPtr<T>(SkSafeRef(ptr)); } | |
115 | |
116 } // namespace skia | |
117 | |
118 #endif // SKIA_EXT_REFPTR_H_ | |
OLD | NEW |