OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkPixelRef.h" | 8 #include "SkPixelRef.h" |
9 #include "SkFlattenableBuffers.h" | 9 #include "SkFlattenableBuffers.h" |
10 #include "SkThread.h" | 10 #include "SkThread.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 void SkPixelRef::setMutex(SkBaseMutex* mutex) { | 78 void SkPixelRef::setMutex(SkBaseMutex* mutex) { |
79 if (NULL == mutex) { | 79 if (NULL == mutex) { |
80 mutex = get_default_mutex(); | 80 mutex = get_default_mutex(); |
81 } | 81 } |
82 fMutex = mutex; | 82 fMutex = mutex; |
83 } | 83 } |
84 | 84 |
85 // just need a > 0 value, so pick a funny one to aid in debugging | 85 // just need a > 0 value, so pick a funny one to aid in debugging |
86 #define SKPIXELREF_PRELOCKED_LOCKCOUNT 123456789 | 86 #define SKPIXELREF_PRELOCKED_LOCKCOUNT 123456789 |
87 | 87 |
88 SkPixelRef::SkPixelRef(SkBaseMutex* mutex) : fPreLocked(false) { | 88 SkPixelRef::SkPixelRef(SkBaseMutex* mutex) { |
89 this->setMutex(mutex); | 89 this->setMutex(mutex); |
90 fPixels = NULL; | 90 fPixels = NULL; |
91 fColorTable = NULL; // we do not track ownership of this | 91 fColorTable = NULL; // we do not track ownership of this |
92 fLockCount = 0; | 92 fLockCount = 0; |
93 fGenerationID = 0; // signal to rebuild | 93 this->needsNewGenID(); |
94 fIsImmutable = false; | 94 fIsImmutable = false; |
95 fPreLocked = false; | 95 fPreLocked = false; |
96 } | 96 } |
97 | 97 |
98 SkPixelRef::SkPixelRef(SkFlattenableReadBuffer& buffer, SkBaseMutex* mutex) | 98 SkPixelRef::SkPixelRef(SkFlattenableReadBuffer& buffer, SkBaseMutex* mutex) |
99 : INHERITED(buffer) { | 99 : INHERITED(buffer) { |
100 this->setMutex(mutex); | 100 this->setMutex(mutex); |
101 fPixels = NULL; | 101 fPixels = NULL; |
102 fColorTable = NULL; // we do not track ownership of this | 102 fColorTable = NULL; // we do not track ownership of this |
103 fLockCount = 0; | 103 fLockCount = 0; |
104 fIsImmutable = buffer.readBool(); | 104 fIsImmutable = buffer.readBool(); |
105 fGenerationID = buffer.readUInt(); | 105 fGenerationID = buffer.readUInt(); |
| 106 fUniqueGenerationID = false; // Conservatively assuming the original still
exists. |
106 fPreLocked = false; | 107 fPreLocked = false; |
107 } | 108 } |
108 | 109 |
| 110 SkPixelRef::~SkPixelRef() { |
| 111 this->callInvalidationListeners(); |
| 112 } |
| 113 |
| 114 void SkPixelRef::needsNewGenID() { |
| 115 fGenerationID = 0; |
| 116 fUniqueGenerationID = false; |
| 117 } |
| 118 |
| 119 void SkPixelRef::cloneGenID(const SkPixelRef& that) { |
| 120 // This is subtle. We must call that.getGenerationID() to make sure its gen
ID isn't 0. |
| 121 this->fGenerationID = that.getGenerationID(); |
| 122 this->fUniqueGenerationID = false; |
| 123 that.fUniqueGenerationID = false; |
| 124 } |
| 125 |
109 void SkPixelRef::setPreLocked(void* pixels, SkColorTable* ctable) { | 126 void SkPixelRef::setPreLocked(void* pixels, SkColorTable* ctable) { |
110 #ifndef SK_IGNORE_PIXELREF_SETPRELOCKED | 127 #ifndef SK_IGNORE_PIXELREF_SETPRELOCKED |
111 // only call me in your constructor, otherwise fLockCount tracking can get | 128 // only call me in your constructor, otherwise fLockCount tracking can get |
112 // out of sync. | 129 // out of sync. |
113 fPixels = pixels; | 130 fPixels = pixels; |
114 fColorTable = ctable; | 131 fColorTable = ctable; |
115 fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT; | 132 fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT; |
116 fPreLocked = true; | 133 fPreLocked = true; |
117 #endif | 134 #endif |
118 } | 135 } |
119 | 136 |
120 void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { | 137 void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { |
121 this->INHERITED::flatten(buffer); | 138 this->INHERITED::flatten(buffer); |
122 buffer.writeBool(fIsImmutable); | 139 buffer.writeBool(fIsImmutable); |
123 // We write the gen ID into the picture for within-process recording. This | 140 // We write the gen ID into the picture for within-process recording. This |
124 // is safe since the same genID will never refer to two different sets of | 141 // is safe since the same genID will never refer to two different sets of |
125 // pixels (barring overflow). However, each process has its own "namespace" | 142 // pixels (barring overflow). However, each process has its own "namespace" |
126 // of genIDs. So for cross-process recording we write a zero which will | 143 // of genIDs. So for cross-process recording we write a zero which will |
127 // trigger assignment of a new genID in playback. | 144 // trigger assignment of a new genID in playback. |
128 if (buffer.isCrossProcess()) { | 145 if (buffer.isCrossProcess()) { |
129 buffer.writeUInt(0); | 146 buffer.writeUInt(0); |
130 } else { | 147 } else { |
131 buffer.writeUInt(fGenerationID); | 148 buffer.writeUInt(fGenerationID); |
| 149 fUniqueGenerationID = false; // Conservative, a copy is probably about
to exist. |
132 } | 150 } |
133 } | 151 } |
134 | 152 |
135 void SkPixelRef::lockPixels() { | 153 void SkPixelRef::lockPixels() { |
136 SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); | 154 SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); |
137 | 155 |
138 if (!fPreLocked) { | 156 if (!fPreLocked) { |
139 SkAutoMutexAcquire ac(*fMutex); | 157 SkAutoMutexAcquire ac(*fMutex); |
140 | 158 |
141 if (1 == ++fLockCount) { | 159 if (1 == ++fLockCount) { |
(...skipping 29 matching lines...) Expand all Loading... |
171 return false; | 189 return false; |
172 } | 190 } |
173 | 191 |
174 bool SkPixelRef::onDecodeInto(int pow2, SkBitmap* bitmap) { | 192 bool SkPixelRef::onDecodeInto(int pow2, SkBitmap* bitmap) { |
175 return false; | 193 return false; |
176 } | 194 } |
177 | 195 |
178 uint32_t SkPixelRef::getGenerationID() const { | 196 uint32_t SkPixelRef::getGenerationID() const { |
179 if (0 == fGenerationID) { | 197 if (0 == fGenerationID) { |
180 fGenerationID = SkNextPixelRefGenerationID(); | 198 fGenerationID = SkNextPixelRefGenerationID(); |
| 199 fUniqueGenerationID = true; // The only time we can be sure of this! |
181 } | 200 } |
182 return fGenerationID; | 201 return fGenerationID; |
183 } | 202 } |
184 | 203 |
| 204 void SkPixelRef::addInvalidationListener(InvalidationListener* listener) { |
| 205 if (NULL == listener || !fUniqueGenerationID) { |
| 206 // No point in tracking this if we're not going to call it. |
| 207 SkDELETE(listener); |
| 208 return; |
| 209 } |
| 210 *fInvalidationListeners.append() = listener; |
| 211 } |
| 212 |
| 213 void SkPixelRef::callInvalidationListeners() { |
| 214 // We don't invalidate ourselves if we think another SkPixelRef is sharing o
ur genID. |
| 215 if (fUniqueGenerationID) { |
| 216 for (int i = 0; i < fInvalidationListeners.count(); i++) { |
| 217 fInvalidationListeners[i]->onInvalidate(); |
| 218 } |
| 219 } |
| 220 // Listeners get at most one shot, so whether these triggered or not, blow t
hem away. |
| 221 fInvalidationListeners.deleteAll(); |
| 222 } |
| 223 |
185 void SkPixelRef::notifyPixelsChanged() { | 224 void SkPixelRef::notifyPixelsChanged() { |
186 #ifdef SK_DEBUG | 225 #ifdef SK_DEBUG |
187 if (fIsImmutable) { | 226 if (fIsImmutable) { |
188 SkDebugf("========== notifyPixelsChanged called on immutable pixelref"); | 227 SkDebugf("========== notifyPixelsChanged called on immutable pixelref"); |
189 } | 228 } |
190 #endif | 229 #endif |
191 // this signals us to recompute this next time around | 230 this->callInvalidationListeners(); |
192 fGenerationID = 0; | 231 this->needsNewGenID(); |
193 } | 232 } |
194 | 233 |
195 void SkPixelRef::setImmutable() { | 234 void SkPixelRef::setImmutable() { |
196 fIsImmutable = true; | 235 fIsImmutable = true; |
197 } | 236 } |
198 | 237 |
199 bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) { | 238 bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) { |
200 return this->onReadPixels(dst, subset); | 239 return this->onReadPixels(dst, subset); |
201 } | 240 } |
202 | 241 |
203 bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { | 242 bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { |
204 return false; | 243 return false; |
205 } | 244 } |
206 | 245 |
207 SkData* SkPixelRef::onRefEncodedData() { | 246 SkData* SkPixelRef::onRefEncodedData() { |
208 return NULL; | 247 return NULL; |
209 } | 248 } |
210 | 249 |
211 /////////////////////////////////////////////////////////////////////////////// | 250 /////////////////////////////////////////////////////////////////////////////// |
212 | 251 |
213 #ifdef SK_BUILD_FOR_ANDROID | 252 #ifdef SK_BUILD_FOR_ANDROID |
214 void SkPixelRef::globalRef(void* data) { | 253 void SkPixelRef::globalRef(void* data) { |
215 this->ref(); | 254 this->ref(); |
216 } | 255 } |
217 | 256 |
218 void SkPixelRef::globalUnref() { | 257 void SkPixelRef::globalUnref() { |
219 this->unref(); | 258 this->unref(); |
220 } | 259 } |
221 #endif | 260 #endif |
OLD | NEW |