OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
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 | 8 |
9 | 9 |
10 #ifndef SkPixelRef_DEFINED | 10 #ifndef SkPixelRef_DEFINED |
11 #define SkPixelRef_DEFINED | 11 #define SkPixelRef_DEFINED |
12 | 12 |
13 #include "SkBitmap.h" | 13 #include "SkBitmap.h" |
14 #include "SkRefCnt.h" | 14 #include "SkRefCnt.h" |
15 #include "SkString.h" | 15 #include "SkString.h" |
16 #include "SkFlattenable.h" | 16 #include "SkFlattenable.h" |
| 17 #include "SkImageInfo.h" |
17 #include "SkTDArray.h" | 18 #include "SkTDArray.h" |
18 | 19 |
| 20 //#define SK_SUPPORT_LEGACY_ONLOCKPIXELS |
| 21 |
19 #ifdef SK_DEBUG | 22 #ifdef SK_DEBUG |
20 /** | 23 /** |
21 * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref | 24 * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref |
22 * subclasses to correctly handle lock/unlock pixels. For performance | 25 * subclasses to correctly handle lock/unlock pixels. For performance |
23 * reasons, simple malloc-based subclasses call setPreLocked() to skip | 26 * reasons, simple malloc-based subclasses call setPreLocked() to skip |
24 * the overhead of implementing these calls. | 27 * the overhead of implementing these calls. |
25 * | 28 * |
26 * This build-flag disables that optimization, to add in debugging our | 29 * This build-flag disables that optimization, to add in debugging our |
27 * call-sites, to ensure that they correctly balance their calls of | 30 * call-sites, to ensure that they correctly balance their calls of |
28 * lock and unlock. | 31 * lock and unlock. |
(...skipping 24 matching lines...) Expand all Loading... |
53 SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex); | 56 SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex); |
54 virtual ~SkPixelRef(); | 57 virtual ~SkPixelRef(); |
55 | 58 |
56 const SkImageInfo& info() const { | 59 const SkImageInfo& info() const { |
57 return fInfo; | 60 return fInfo; |
58 } | 61 } |
59 | 62 |
60 /** Return the pixel memory returned from lockPixels, or null if the | 63 /** Return the pixel memory returned from lockPixels, or null if the |
61 lockCount is 0. | 64 lockCount is 0. |
62 */ | 65 */ |
63 void* pixels() const { return fPixels; } | 66 void* pixels() const { return fRec.fPixels; } |
64 | 67 |
65 /** Return the current colorTable (if any) if pixels are locked, or null. | 68 /** Return the current colorTable (if any) if pixels are locked, or null. |
66 */ | 69 */ |
67 SkColorTable* colorTable() const { return fColorTable; } | 70 SkColorTable* colorTable() const { return fRec.fColorTable; } |
68 | 71 |
69 /** | 72 /** |
| 73 * To access the actual pixels of a pixelref, it must be "locked". |
| 74 * Calling lockPixels returns a LockRec struct (on success). |
| 75 */ |
| 76 struct LockRec { |
| 77 void* fPixels; |
| 78 SkColorTable* fColorTable; |
| 79 size_t fRowBytes; |
| 80 |
| 81 void zero() { sk_bzero(this, sizeof(*this)); } |
| 82 |
| 83 bool isZero() const { |
| 84 return NULL == fPixels && NULL == fColorTable && 0 == fRowBytes; |
| 85 } |
| 86 }; |
| 87 |
| 88 /** |
70 * Returns true if the lockcount > 0 | 89 * Returns true if the lockcount > 0 |
71 */ | 90 */ |
72 bool isLocked() const { return fLockCount > 0; } | 91 bool isLocked() const { return fLockCount > 0; } |
73 | 92 |
74 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) | 93 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) |
75 | 94 |
76 /** Call to access the pixel memory, which is returned. Balance with a call | 95 /** |
77 to unlockPixels(). | 96 * Call to access the pixel memory. Return true on success. Balance this |
78 */ | 97 * with a call to unlockPixels(). |
79 void lockPixels(); | 98 */ |
| 99 bool lockPixels(); |
| 100 |
| 101 /** |
| 102 * Call to access the pixel memory. On success, return true and fill out |
| 103 * the specified rec. On failure, return false and ignore the rec parameter
. |
| 104 * Balance this with a call to unlockPixels(). |
| 105 */ |
| 106 bool lockPixels(LockRec* rec); |
| 107 |
80 /** Call to balanace a previous call to lockPixels(). Returns the pixels | 108 /** Call to balanace a previous call to lockPixels(). Returns the pixels |
81 (or null) after the unlock. NOTE: lock calls can be nested, but the | 109 (or null) after the unlock. NOTE: lock calls can be nested, but the |
82 matching number of unlock calls must be made in order to free the | 110 matching number of unlock calls must be made in order to free the |
83 memory (if the subclass implements caching/deferred-decoding.) | 111 memory (if the subclass implements caching/deferred-decoding.) |
84 */ | 112 */ |
85 void unlockPixels(); | 113 void unlockPixels(); |
86 | 114 |
87 /** | 115 /** |
88 * Some bitmaps can return a copy of their pixels for lockPixels(), but | 116 * Some bitmaps can return a copy of their pixels for lockPixels(), but |
89 * that copy, if modified, will not be pushed back. These bitmaps should | 117 * that copy, if modified, will not be pushed back. These bitmaps should |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 // This can be used to invalidate caches keyed by SkPixelRef generation ID. | 254 // This can be used to invalidate caches keyed by SkPixelRef generation ID. |
227 struct GenIDChangeListener { | 255 struct GenIDChangeListener { |
228 virtual ~GenIDChangeListener() {} | 256 virtual ~GenIDChangeListener() {} |
229 virtual void onChange() = 0; | 257 virtual void onChange() = 0; |
230 }; | 258 }; |
231 | 259 |
232 // Takes ownership of listener. | 260 // Takes ownership of listener. |
233 void addGenIDChangeListener(GenIDChangeListener* listener); | 261 void addGenIDChangeListener(GenIDChangeListener* listener); |
234 | 262 |
235 protected: | 263 protected: |
236 /** Called when the lockCount goes from 0 to 1. The caller will have already | 264 #ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS |
237 acquire a mutex for thread safety, so this method need not do that. | 265 virtual void* onLockPixels(SkColorTable**); |
238 */ | 266 virtual bool onNewLockPixels(LockRec*); |
239 virtual void* onLockPixels(SkColorTable**) = 0; | 267 #else |
| 268 /** |
| 269 * On success, returns true and fills out the LockRec for the pixels. On |
| 270 * failure returns false and ignores the LockRec parameter. |
| 271 * |
| 272 * The caller will have already acquired a mutex for thread safety, so this |
| 273 * method need not do that. |
| 274 */ |
| 275 virtual bool onNewLockPixels(LockRec*) = 0; |
| 276 #endif |
240 | 277 |
241 /** | 278 /** |
242 * Called when the lock count goes from 1 to 0. The caller will have | 279 * Balancing the previous successful call to onNewLockPixels. The locked |
243 * already acquire a mutex for thread safety, so this method need not do | 280 * pixel address will no longer be referenced, so the subclass is free to |
244 * that. | 281 * move or discard that memory. |
245 * | 282 * |
246 * If the previous call to onLockPixels failed (i.e. returned NULL), then | 283 * The caller will have already acquired a mutex for thread safety, so this |
247 * the onUnlockPixels will NOT be called. | 284 * method need not do that. |
248 */ | 285 */ |
249 virtual void onUnlockPixels() = 0; | 286 virtual void onUnlockPixels() = 0; |
250 | 287 |
251 /** Default impl returns true */ | 288 /** Default impl returns true */ |
252 virtual bool onLockPixelsAreWritable() const; | 289 virtual bool onLockPixelsAreWritable() const; |
253 | 290 |
254 // returns false; | 291 // returns false; |
255 virtual bool onImplementsDecodeInto(); | 292 virtual bool onImplementsDecodeInto(); |
256 // returns false; | 293 // returns false; |
257 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); | 294 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); |
(...skipping 24 matching lines...) Expand all Loading... |
282 */ | 319 */ |
283 SkBaseMutex* mutex() const { return fMutex; } | 320 SkBaseMutex* mutex() const { return fMutex; } |
284 | 321 |
285 // serialization | 322 // serialization |
286 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); | 323 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); |
287 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; | 324 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; |
288 | 325 |
289 // only call from constructor. Flags this to always be locked, removing | 326 // only call from constructor. Flags this to always be locked, removing |
290 // the need to grab the mutex and call onLockPixels/onUnlockPixels. | 327 // the need to grab the mutex and call onLockPixels/onUnlockPixels. |
291 // Performance tweak to avoid those calls (esp. in multi-thread use case). | 328 // Performance tweak to avoid those calls (esp. in multi-thread use case). |
292 void setPreLocked(void* pixels, SkColorTable* ctable); | 329 void setPreLocked(void*, size_t rowBytes, SkColorTable*); |
293 | 330 |
294 private: | 331 private: |
295 SkBaseMutex* fMutex; // must remain in scope for the life of this object | 332 SkBaseMutex* fMutex; // must remain in scope for the life of this object |
296 | 333 |
297 const SkImageInfo fInfo; | 334 const SkImageInfo fInfo; |
298 | 335 |
299 void* fPixels; | 336 // LockRec is only valid if we're in a locked state (isLocked()) |
300 SkColorTable* fColorTable; // we do not track ownership, subclass does | 337 LockRec fRec; |
301 int fLockCount; | 338 int fLockCount; |
302 | 339 |
303 mutable uint32_t fGenerationID; | 340 mutable uint32_t fGenerationID; |
304 mutable bool fUniqueGenerationID; | 341 mutable bool fUniqueGenerationID; |
305 | 342 |
306 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d | 343 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d |
307 | 344 |
308 SkString fURI; | 345 SkString fURI; |
309 | 346 |
310 // can go from false to true, but never from true to false | 347 // can go from false to true, but never from true to false |
311 bool fIsImmutable; | 348 bool fIsImmutable; |
312 // only ever set in constructor, const after that | 349 // only ever set in constructor, const after that |
313 bool fPreLocked; | 350 bool fPreLocked; |
314 | 351 |
315 void needsNewGenID(); | 352 void needsNewGenID(); |
316 void callGenIDChangeListeners(); | 353 void callGenIDChangeListeners(); |
317 | 354 |
318 void setMutex(SkBaseMutex* mutex); | 355 void setMutex(SkBaseMutex* mutex); |
319 | 356 |
320 // When copying a bitmap to another with the same shape and config, we can s
afely | 357 // When copying a bitmap to another with the same shape and config, we can s
afely |
321 // clone the pixelref generation ID too, which makes them equivalent under c
aching. | 358 // clone the pixelref generation ID too, which makes them equivalent under c
aching. |
322 friend class SkBitmap; // only for cloneGenID | 359 friend class SkBitmap; // only for cloneGenID |
323 void cloneGenID(const SkPixelRef&); | 360 void cloneGenID(const SkPixelRef&); |
324 | 361 |
325 typedef SkFlattenable INHERITED; | 362 typedef SkFlattenable INHERITED; |
326 }; | 363 }; |
327 | 364 |
328 #endif | 365 #endif |
OLD | NEW |