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

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

Issue 1289623004: Every pixel ref gets its own mutex. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: mutable Created 5 years, 4 months 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
« no previous file with comments | « include/core/SkPixelRef.h ('k') | src/gpu/SkGrPixelRef.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapCache.h" 8 #include "SkBitmapCache.h"
9 #include "SkMutex.h" 9 #include "SkMutex.h"
10 #include "SkPixelRef.h" 10 #include "SkPixelRef.h"
11 #include "SkTraceEvent.h" 11 #include "SkTraceEvent.h"
12 12
13 //#define SK_SUPPORT_LEGACY_UNBALANCED_PIXELREF_LOCKCOUNT 13 //#define SK_SUPPORT_LEGACY_UNBALANCED_PIXELREF_LOCKCOUNT
14 //#define SK_TRACE_PIXELREF_LIFETIME 14 //#define SK_TRACE_PIXELREF_LIFETIME
15 15
16 #ifdef SK_BUILD_FOR_WIN32
17 // We don't have SK_BASE_MUTEX_INIT on Windows.
18
19 // must be a power-of-2. undef to just use 1 mutex
20 #define PIXELREF_MUTEX_RING_COUNT 32
21 static SkBaseMutex gPixelRefMutexRing[PIXELREF_MUTEX_RING_COUNT];
22
23 #else
24 static SkBaseMutex gPixelRefMutexRing[] = {
25 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
26 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
27 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
28 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
29
30 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
31 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
32 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
33 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
34
35 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
36 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
37 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
38 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
39
40 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
41 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
42 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
43 SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
44 };
45 // must be a power-of-2. undef to just use 1 mutex
46 #define PIXELREF_MUTEX_RING_COUNT SK_ARRAY_COUNT(gPixelRefMutexRing)
47
48 #endif
49
50 static SkBaseMutex* get_default_mutex() {
51 static int32_t gPixelRefMutexRingIndex;
52
53 SkASSERT(SkIsPow2(PIXELREF_MUTEX_RING_COUNT));
54
55 // atomic_inc might be overkill here. It may be fine if once in a while
56 // we hit a race-condition and two subsequent calls get the same index...
57 int index = sk_atomic_inc(&gPixelRefMutexRingIndex);
58 return &gPixelRefMutexRing[index & (PIXELREF_MUTEX_RING_COUNT - 1)];
59 }
60
61 ///////////////////////////////////////////////////////////////////////////////
62 #include "SkNextID.h" 16 #include "SkNextID.h"
63 17
64 uint32_t SkNextID::ImageID() { 18 uint32_t SkNextID::ImageID() {
65 static uint32_t gID = 0; 19 static uint32_t gID = 0;
66 uint32_t id; 20 uint32_t id;
67 // Loop in case our global wraps around, as we never want to return a 0. 21 // Loop in case our global wraps around, as we never want to return a 0.
68 do { 22 do {
69 id = sk_atomic_fetch_add(&gID, 2u) + 2; // Never set the low bit. 23 id = sk_atomic_fetch_add(&gID, 2u) + 2; // Never set the low bit.
70 } while (0 == id); 24 } while (0 == id);
71 return id; 25 return id;
72 } 26 }
73 27
74 /////////////////////////////////////////////////////////////////////////////// 28 ///////////////////////////////////////////////////////////////////////////////
75 29
76 void SkPixelRef::setMutex(SkBaseMutex* mutex) {
77 if (NULL == mutex) {
78 mutex = get_default_mutex();
79 }
80 fMutex = mutex;
81 }
82
83 // just need a > 0 value, so pick a funny one to aid in debugging 30 // just need a > 0 value, so pick a funny one to aid in debugging
84 #define SKPIXELREF_PRELOCKED_LOCKCOUNT 123456789 31 #define SKPIXELREF_PRELOCKED_LOCKCOUNT 123456789
85 32
86 static SkImageInfo validate_info(const SkImageInfo& info) { 33 static SkImageInfo validate_info(const SkImageInfo& info) {
87 SkAlphaType newAlphaType = info.alphaType(); 34 SkAlphaType newAlphaType = info.alphaType();
88 SkAssertResult(SkColorTypeValidateAlphaType(info.colorType(), info.alphaType (), &newAlphaType)); 35 SkAssertResult(SkColorTypeValidateAlphaType(info.colorType(), info.alphaType (), &newAlphaType));
89 return info.makeAlphaType(newAlphaType); 36 return info.makeAlphaType(newAlphaType);
90 } 37 }
91 38
92 #ifdef SK_TRACE_PIXELREF_LIFETIME 39 #ifdef SK_TRACE_PIXELREF_LIFETIME
93 static int32_t gInstCounter; 40 static int32_t gInstCounter;
94 #endif 41 #endif
95 42
96 SkPixelRef::SkPixelRef(const SkImageInfo& info) 43 SkPixelRef::SkPixelRef(const SkImageInfo& info)
97 : fInfo(validate_info(info)) 44 : fInfo(validate_info(info))
98 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 45 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
99 , fStableID(SkNextID::ImageID()) 46 , fStableID(SkNextID::ImageID())
100 #endif 47 #endif
101 48
102 { 49 {
103 #ifdef SK_TRACE_PIXELREF_LIFETIME 50 #ifdef SK_TRACE_PIXELREF_LIFETIME
104 SkDebugf(" pixelref %d\n", sk_atomic_inc(&gInstCounter)); 51 SkDebugf(" pixelref %d\n", sk_atomic_inc(&gInstCounter));
105 #endif 52 #endif
106 this->setMutex(NULL);
107 fRec.zero(); 53 fRec.zero();
108 fLockCount = 0; 54 fLockCount = 0;
109 this->needsNewGenID(); 55 this->needsNewGenID();
110 fMutability = kMutable;
111 fPreLocked = false;
112 fAddedToCache.store(false);
113 }
114
115
116 SkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex)
117 : fInfo(validate_info(info))
118 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
119 , fStableID(SkNextID::ImageID())
120 #endif
121 {
122 #ifdef SK_TRACE_PIXELREF_LIFETIME
123 SkDebugf(" pixelref %d\n", sk_atomic_inc(&gInstCounter));
124 #endif
125 this->setMutex(mutex);
126 fRec.zero();
127 fLockCount = 0;
128 this->needsNewGenID();
129 fMutability = kMutable; 56 fMutability = kMutable;
130 fPreLocked = false; 57 fPreLocked = false;
131 fAddedToCache.store(false); 58 fAddedToCache.store(false);
132 } 59 }
133 60
134 SkPixelRef::~SkPixelRef() { 61 SkPixelRef::~SkPixelRef() {
135 #ifndef SK_SUPPORT_LEGACY_UNBALANCED_PIXELREF_LOCKCOUNT 62 #ifndef SK_SUPPORT_LEGACY_UNBALANCED_PIXELREF_LOCKCOUNT
136 SkASSERT(SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount || 0 == fLockCount); 63 SkASSERT(SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount || 0 == fLockCount);
137 #endif 64 #endif
138 65
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 // out of sync. 106 // out of sync.
180 fRec.fPixels = pixels; 107 fRec.fPixels = pixels;
181 fRec.fColorTable = ctable; 108 fRec.fColorTable = ctable;
182 fRec.fRowBytes = rowBytes; 109 fRec.fRowBytes = rowBytes;
183 fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT; 110 fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT;
184 fPreLocked = true; 111 fPreLocked = true;
185 } 112 }
186 113
187 // Increments fLockCount only on success 114 // Increments fLockCount only on success
188 bool SkPixelRef::lockPixelsInsideMutex() { 115 bool SkPixelRef::lockPixelsInsideMutex() {
189 fMutex->assertHeld(); 116 fMutex.assertHeld();
190 117
191 if (1 == ++fLockCount) { 118 if (1 == ++fLockCount) {
192 SkASSERT(fRec.isZero()); 119 SkASSERT(fRec.isZero());
193 if (!this->onNewLockPixels(&fRec)) { 120 if (!this->onNewLockPixels(&fRec)) {
194 fRec.zero(); 121 fRec.zero();
195 fLockCount -= 1; // we return fLockCount unchanged if we fail. 122 fLockCount -= 1; // we return fLockCount unchanged if we fail.
196 return false; 123 return false;
197 } 124 }
198 } 125 }
199 if (fRec.fPixels) { 126 if (fRec.fPixels) {
200 validate_pixels_ctable(fInfo, fRec.fColorTable); 127 validate_pixels_ctable(fInfo, fRec.fColorTable);
201 return true; 128 return true;
202 } 129 }
203 // no pixels, so we failed (somehow) 130 // no pixels, so we failed (somehow)
204 --fLockCount; 131 --fLockCount;
205 return false; 132 return false;
206 } 133 }
207 134
208 // For historical reasons, we always inc fLockCount, even if we return false. 135 // For historical reasons, we always inc fLockCount, even if we return false.
209 // It would be nice to change this (it seems), and only inc if we actually succe ed... 136 // It would be nice to change this (it seems), and only inc if we actually succe ed...
210 bool SkPixelRef::lockPixels() { 137 bool SkPixelRef::lockPixels() {
211 SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); 138 SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
212 139
213 if (!fPreLocked) { 140 if (!fPreLocked) {
214 TRACE_EVENT_BEGIN0("skia", "SkPixelRef::lockPixelsMutex"); 141 TRACE_EVENT_BEGIN0("skia", "SkPixelRef::lockPixelsMutex");
215 SkAutoMutexAcquire ac(*fMutex); 142 SkAutoMutexAcquire ac(fMutex);
216 TRACE_EVENT_END0("skia", "SkPixelRef::lockPixelsMutex"); 143 TRACE_EVENT_END0("skia", "SkPixelRef::lockPixelsMutex");
217 SkDEBUGCODE(int oldCount = fLockCount;) 144 SkDEBUGCODE(int oldCount = fLockCount;)
218 bool success = this->lockPixelsInsideMutex(); 145 bool success = this->lockPixelsInsideMutex();
219 // lockPixelsInsideMutex only increments the count if it succeeds. 146 // lockPixelsInsideMutex only increments the count if it succeeds.
220 SkASSERT(oldCount + (int)success == fLockCount); 147 SkASSERT(oldCount + (int)success == fLockCount);
221 148
222 if (!success) { 149 if (!success) {
223 // For compatibility with SkBitmap calling lockPixels, we still want to increment 150 // For compatibility with SkBitmap calling lockPixels, we still want to increment
224 // fLockCount even if we failed. If we updated SkBitmap we could rem ove this oddity. 151 // fLockCount even if we failed. If we updated SkBitmap we could rem ove this oddity.
225 fLockCount += 1; 152 fLockCount += 1;
(...skipping 12 matching lines...) Expand all
238 *rec = fRec; 165 *rec = fRec;
239 return true; 166 return true;
240 } 167 }
241 return false; 168 return false;
242 } 169 }
243 170
244 void SkPixelRef::unlockPixels() { 171 void SkPixelRef::unlockPixels() {
245 SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); 172 SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
246 173
247 if (!fPreLocked) { 174 if (!fPreLocked) {
248 SkAutoMutexAcquire ac(*fMutex); 175 SkAutoMutexAcquire ac(fMutex);
249 176
250 SkASSERT(fLockCount > 0); 177 SkASSERT(fLockCount > 0);
251 if (0 == --fLockCount) { 178 if (0 == --fLockCount) {
252 // don't call onUnlockPixels unless onLockPixels succeeded 179 // don't call onUnlockPixels unless onLockPixels succeeded
253 if (fRec.fPixels) { 180 if (fRec.fPixels) {
254 this->onUnlockPixels(); 181 this->onUnlockPixels();
255 fRec.zero(); 182 fRec.zero();
256 } else { 183 } else {
257 SkASSERT(fRec.isZero()); 184 SkASSERT(fRec.isZero());
258 } 185 }
(...skipping 12 matching lines...) Expand all
271 } 198 }
272 199
273 if (fPreLocked) { 200 if (fPreLocked) {
274 result->fUnlockProc = NULL; 201 result->fUnlockProc = NULL;
275 result->fUnlockContext = NULL; 202 result->fUnlockContext = NULL;
276 result->fCTable = fRec.fColorTable; 203 result->fCTable = fRec.fColorTable;
277 result->fPixels = fRec.fPixels; 204 result->fPixels = fRec.fPixels;
278 result->fRowBytes = fRec.fRowBytes; 205 result->fRowBytes = fRec.fRowBytes;
279 result->fSize.set(fInfo.width(), fInfo.height()); 206 result->fSize.set(fInfo.width(), fInfo.height());
280 } else { 207 } else {
281 SkAutoMutexAcquire ac(*fMutex); 208 SkAutoMutexAcquire ac(fMutex);
282 if (!this->onRequestLock(request, result)) { 209 if (!this->onRequestLock(request, result)) {
283 return false; 210 return false;
284 } 211 }
285 } 212 }
286 if (result->fPixels) { 213 if (result->fPixels) {
287 validate_pixels_ctable(fInfo, result->fCTable); 214 validate_pixels_ctable(fInfo, result->fCTable);
288 return true; 215 return true;
289 } 216 }
290 return false; 217 return false;
291 } 218 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 } 344 }
418 345
419 result->fUnlockProc = unlock_legacy_result; 346 result->fUnlockProc = unlock_legacy_result;
420 result->fUnlockContext = SkRef(this); // this is balanced in our fUnlockPr oc 347 result->fUnlockContext = SkRef(this); // this is balanced in our fUnlockPr oc
421 result->fCTable = fRec.fColorTable; 348 result->fCTable = fRec.fColorTable;
422 result->fPixels = fRec.fPixels; 349 result->fPixels = fRec.fPixels;
423 result->fRowBytes = fRec.fRowBytes; 350 result->fRowBytes = fRec.fRowBytes;
424 result->fSize.set(fInfo.width(), fInfo.height()); 351 result->fSize.set(fInfo.width(), fInfo.height());
425 return true; 352 return true;
426 } 353 }
OLDNEW
« no previous file with comments | « include/core/SkPixelRef.h ('k') | src/gpu/SkGrPixelRef.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698