Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/core/SkPixelRef.cpp

Issue 26734003: Proactive SkPixelRef invalidation (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: tweaks Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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->invalidate();
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 it's ge nID isn't 0.
scroggo 2013/10/22 21:04:02 its*
mtklein 2013/10/23 15:28:10 Done.
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
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::invalidate() {
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.
scroggo 2013/10/22 21:04:02 Should these comments go in the header file so a f
mtklein 2013/10/23 15:28:10 See if the header makes more sense now? Leaving t
scroggo 2013/10/23 15:39:19 Yes, the header makes more sense now.
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->invalidate();
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698