Flutter Engine
The Flutter Engine
SkCachedData.cpp
Go to the documentation of this file.
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 */
8
11
13 : fData(data)
14 , fSize(size)
15 , fRefCnt(1)
16 , fStorageType(kMalloc_StorageType)
17 , fInCache(false)
18 , fIsLocked(true)
19{
20 fStorage.fMalloc = data;
21}
22
24 : fData(dm->data())
25 , fSize(size)
26 , fRefCnt(1)
27 , fStorageType(kDiscardableMemory_StorageType)
28 , fInCache(false)
29 , fIsLocked(true)
30{
31 fStorage.fDM = dm;
32}
33
35 switch (fStorageType) {
36 case kMalloc_StorageType:
37 sk_free(fStorage.fMalloc);
38 break;
39 case kDiscardableMemory_StorageType:
40 delete fStorage.fDM;
41 break;
42 }
43}
44
46public:
47 AutoMutexWritable(const SkCachedData* cd) : fCD(const_cast<SkCachedData*>(cd)) {
48 fCD->fMutex.acquire();
49 fCD->validate();
50 }
52 fCD->validate();
53 fCD->fMutex.release();
54 }
55
56 SkCachedData* get() { return fCD; }
57 SkCachedData* operator->() { return fCD; }
58
59private:
60 SkCachedData* fCD;
61};
62
63void SkCachedData::internalRef(bool fromCache) const {
64 AutoMutexWritable(this)->inMutexRef(fromCache);
65}
66
67void SkCachedData::internalUnref(bool fromCache) const {
68 if (AutoMutexWritable(this)->inMutexUnref(fromCache)) {
69 // can't delete inside doInternalUnref, since it is locking a mutex (which we own)
70 delete this;
71 }
72}
73
74///////////////////////////////////////////////////////////////////////////////////////////////////
75
76void SkCachedData::inMutexRef(bool fromCache) {
77 if ((1 == fRefCnt) && fInCache) {
78 this->inMutexLock();
79 }
80
81 fRefCnt += 1;
82 if (fromCache) {
83 SkASSERT(!fInCache);
84 fInCache = true;
85 }
86}
87
88bool SkCachedData::inMutexUnref(bool fromCache) {
89 switch (--fRefCnt) {
90 case 0:
91 // we're going to be deleted, so we need to be unlocked (for DiscardableMemory)
92 if (fIsLocked) {
93 this->inMutexUnlock();
94 }
95 break;
96 case 1:
97 if (fInCache && !fromCache) {
98 // If we're down to 1 owner, and that owner is the cache, this it is safe
99 // to unlock (and mutate fData) even if the cache is in a different thread,
100 // as the cache is NOT allowed to inspect or use fData.
101 this->inMutexUnlock();
102 }
103 break;
104 default:
105 break;
106 }
107
108 if (fromCache) {
109 SkASSERT(fInCache);
110 fInCache = false;
111 }
112
113 // return true when we need to be deleted
114 return 0 == fRefCnt;
115}
116
117void SkCachedData::inMutexLock() {
118 fMutex.assertHeld();
119
120 SkASSERT(!fIsLocked);
121 fIsLocked = true;
122
123 switch (fStorageType) {
124 case kMalloc_StorageType:
125 this->setData(fStorage.fMalloc);
126 break;
127 case kDiscardableMemory_StorageType:
128 if (fStorage.fDM->lock()) {
129 void* ptr = fStorage.fDM->data();
130 SkASSERT(ptr);
131 this->setData(ptr);
132 } else {
133 this->setData(nullptr); // signal failure to lock, contents are gone
134 }
135 break;
136 }
137}
138
139void SkCachedData::inMutexUnlock() {
140 fMutex.assertHeld();
141
142 SkASSERT(fIsLocked);
143 fIsLocked = false;
144
145 switch (fStorageType) {
146 case kMalloc_StorageType:
147 // nothing to do/check
148 break;
149 case kDiscardableMemory_StorageType:
150 if (fData) { // did the previous lock succeed?
151 fStorage.fDM->unlock();
152 }
153 break;
154 }
155 this->setData(nullptr); // signal that we're in an unlocked state
156}
157
158///////////////////////////////////////////////////////////////////////////////////////////////////
159
160#ifdef SK_DEBUG
161void SkCachedData::validate() const {
162 if (fIsLocked) {
163 SkASSERT((fInCache && fRefCnt > 1) || !fInCache);
164 switch (fStorageType) {
165 case kMalloc_StorageType:
166 SkASSERT(fData == fStorage.fMalloc);
167 break;
168 case kDiscardableMemory_StorageType:
169 // fData can be null or the actual value, depending if DM's lock succeeded
170 break;
171 }
172 } else {
173 SkASSERT((fInCache && 1 == fRefCnt) || (0 == fRefCnt));
174 SkASSERT(nullptr == fData);
175 }
176}
177#endif
#define SkASSERT(cond)
Definition: SkAssert.h:116
SK_API void sk_free(void *)
AutoMutexWritable(const SkCachedData *cd)
virtual ~SkCachedData()
void validate() const
Definition: SkCachedData.h:87
SkCachedData(void *mallocData, size_t size)
const void * data() const
Definition: SkCachedData.h:26
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63