OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2014 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 #include "SkCachedData_priv.h" | |
9 #include "SkRefCnt.h" | |
10 #include "SkDiscardableMemory.h" | |
11 | |
12 SkCachedData::SkCachedData(void* data, size_t size) | |
13 : fData(data) | |
14 , fSize(size) | |
15 , fRefCnt(2) // 1 owner, not in cache | |
16 {} | |
17 | |
18 void SkCachedData::ref() { | |
19 const int32_t count = sk_atomic_add(&fRefCnt, 2) + 2; | |
20 const int owners = count >> 1; | |
21 const int in_cache = count & 1; | |
22 | |
23 SkASSERT(owners >= 2); | |
24 | |
25 if (2 == owners) { | |
26 sk_membar_acquire__after_atomic_dec(); | |
27 if (in_cache) { | |
mtklein
2014/09/23 22:16:55
So, if I add SkASSERT(in_cache) just before each i
reed2
2014/09/24 01:23:57
Sounds like I need to expand my tests to (try to)
| |
28 this->lock(); | |
29 } | |
30 } | |
31 } | |
32 | |
33 void SkCachedData::unref() { | |
34 const int32_t count = sk_atomic_add(&fRefCnt, -2) - 2; | |
35 const int owners = count >> 1; | |
36 const int in_cache = count & 1; | |
37 | |
38 switch (owners) { | |
39 case 0: | |
40 sk_membar_acquire__after_atomic_dec(); | |
41 SkDELETE(this); | |
42 break; | |
43 case 1: | |
44 sk_membar_acquire__after_atomic_dec(); | |
45 if (in_cache) { | |
46 this->unlock(); | |
47 } | |
48 break; | |
49 default: | |
50 break; | |
51 } | |
52 } | |
53 | |
54 void SkCachedData::ref_from_cache() { | |
55 SkASSERT(0 == (fRefCnt & 1)); | |
56 sk_atomic_add(&fRefCnt, 3); | |
57 } | |
58 | |
59 void SkCachedData::unref_from_cache() { | |
60 SkASSERT(1 == (fRefCnt & 1)); | |
61 sk_atomic_add(&fRefCnt, -3); | |
62 } | |
63 | |
64 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
65 | |
66 class SkCachedData_Discardable : public SkCachedData { | |
67 public: | |
68 // we take ownership of dm | |
69 SkCachedData_Discardable(SkDiscardableMemory* dm, size_t size) | |
70 : INHERITED(dm->data(), size) | |
71 , fDM(dm) | |
72 , fSuccessfulLock(false) | |
73 {} | |
74 | |
75 virtual ~SkCachedData_Discardable() { | |
76 SkDELETE(fDM); | |
77 } | |
78 | |
79 protected: | |
80 virtual void onLock() SK_OVERRIDE { | |
81 fSuccessfulLock = fDM->lock(); | |
82 this->setData(fSuccessfulLock ? fDM->data() : NULL); | |
83 } | |
84 | |
85 virtual void onUnlock() SK_OVERRIDE { | |
86 if (fSuccessfulLock) { | |
87 fDM->unlock(); | |
88 } | |
89 } | |
90 | |
91 private: | |
92 SkDiscardableMemory* fDM; | |
93 bool fSuccessfulLock; | |
94 | |
95 typedef SkCachedData INHERITED; | |
96 }; | |
97 | |
98 class SkCachedData_Malloc : public SkCachedData { | |
99 public: | |
100 // data was allocated via sk_malloc | |
101 SkCachedData_Malloc(void* data, size_t size) : INHERITED(data, size), fMallo cData(data) {} | |
102 | |
103 virtual ~SkCachedData_Malloc() { | |
104 sk_free(fMallocData); | |
105 } | |
106 | |
107 virtual void onLock() SK_OVERRIDE { | |
108 this->setData(fMallocData); | |
109 } | |
110 | |
111 virtual void onUnlock() SK_OVERRIDE {} | |
112 | |
113 private: | |
114 void* fMallocData; | |
115 | |
116 typedef SkCachedData INHERITED; | |
117 }; | |
118 | |
119 SkCachedData* SkCachedData::Create(size_t size, SkDiscardableMemory* dm) { | |
120 if (dm) { | |
121 return SkNEW_ARGS(SkCachedData_Discardable, (dm, size)); | |
122 } else { | |
123 return SkNEW_ARGS(SkCachedData_Malloc, (sk_malloc_throw(size), size)); | |
124 } | |
125 } | |
126 | |
OLD | NEW |