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 /** |
70 * To access the actual pixels of a pixelref, it must be "locked". | 73 * To access the actual pixels of a pixelref, it must be "locked". |
71 * Calling lockPixels returns a LockRec struct (on success). | 74 * Calling lockPixels returns a LockRec struct (on success). |
72 */ | 75 */ |
73 struct LockRec { | 76 struct LockRec { |
74 void* fPixels; | 77 void* fPixels; |
75 SkColorTable* fColorTable; | 78 SkColorTable* fColorTable; |
76 size_t fRowBytes; | 79 size_t fRowBytes; |
77 | 80 |
78 void zero() { sk_bzero(this, sizeof(*this)); } | 81 void zero() { sk_bzero(this, sizeof(*this)); } |
79 | 82 |
80 bool isZero() const { | 83 bool isZero() const { |
81 return NULL == fPixels && NULL == fColorTable && 0 == fRowBytes; | 84 return NULL == fPixels && NULL == fColorTable && 0 == fRowBytes; |
82 } | 85 } |
83 }; | 86 }; |
84 | 87 |
85 /** | 88 /** |
86 * Returns true if the lockcount > 0 | 89 * Returns true if the lockcount > 0 |
87 */ | 90 */ |
88 bool isLocked() const { return fLockCount > 0; } | 91 bool isLocked() const { return fLockCount > 0; } |
89 | 92 |
90 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) | 93 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) |
91 | 94 |
92 /** Call to access the pixel memory, which is returned. Balance with a call | 95 /** |
93 to unlockPixels(). | 96 * Call to access the pixel memory. Return true on success. Balance this |
94 */ | 97 * with a call to unlockPixels(). |
95 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 |
96 /** Call to balanace a previous call to lockPixels(). Returns the pixels | 108 /** Call to balanace a previous call to lockPixels(). Returns the pixels |
97 (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 |
98 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 |
99 memory (if the subclass implements caching/deferred-decoding.) | 111 memory (if the subclass implements caching/deferred-decoding.) |
100 */ | 112 */ |
101 void unlockPixels(); | 113 void unlockPixels(); |
102 | 114 |
103 /** | 115 /** |
104 * 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 |
105 * 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... |
242 // 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. |
243 struct GenIDChangeListener { | 255 struct GenIDChangeListener { |
244 virtual ~GenIDChangeListener() {} | 256 virtual ~GenIDChangeListener() {} |
245 virtual void onChange() = 0; | 257 virtual void onChange() = 0; |
246 }; | 258 }; |
247 | 259 |
248 // Takes ownership of listener. | 260 // Takes ownership of listener. |
249 void addGenIDChangeListener(GenIDChangeListener* listener); | 261 void addGenIDChangeListener(GenIDChangeListener* listener); |
250 | 262 |
251 protected: | 263 protected: |
252 /** Called when the lockCount goes from 0 to 1. The caller will have already | 264 #ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS |
253 acquire a mutex for thread safety, so this method need not do that. | 265 virtual void* onLockPixels(SkColorTable**); |
254 */ | 266 virtual bool onNewLockPixels(LockRec*); |
255 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 |
256 | 277 |
257 /** | 278 /** |
258 * Called when the lock count goes from 1 to 0. The caller will have | 279 * Balancing the previous successful call to onNewLockPixels. The locked |
259 * 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 |
260 * that. | 281 * move or discard that memory. |
261 * | 282 * |
262 * 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 |
263 * the onUnlockPixels will NOT be called. | 284 * method need not do that. |
264 */ | 285 */ |
265 virtual void onUnlockPixels() = 0; | 286 virtual void onUnlockPixels() = 0; |
266 | 287 |
267 /** Default impl returns true */ | 288 /** Default impl returns true */ |
268 virtual bool onLockPixelsAreWritable() const; | 289 virtual bool onLockPixelsAreWritable() const; |
269 | 290 |
270 // returns false; | 291 // returns false; |
271 virtual bool onImplementsDecodeInto(); | 292 virtual bool onImplementsDecodeInto(); |
272 // returns false; | 293 // returns false; |
273 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); | 294 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); |
(...skipping 24 matching lines...) Expand all Loading... |
298 */ | 319 */ |
299 SkBaseMutex* mutex() const { return fMutex; } | 320 SkBaseMutex* mutex() const { return fMutex; } |
300 | 321 |
301 // serialization | 322 // serialization |
302 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); | 323 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); |
303 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; | 324 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; |
304 | 325 |
305 // only call from constructor. Flags this to always be locked, removing | 326 // only call from constructor. Flags this to always be locked, removing |
306 // the need to grab the mutex and call onLockPixels/onUnlockPixels. | 327 // the need to grab the mutex and call onLockPixels/onUnlockPixels. |
307 // 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). |
308 void setPreLocked(void* pixels, size_t rowBytes, SkColorTable* ctable); | 329 void setPreLocked(void*, size_t rowBytes, SkColorTable*); |
309 | 330 |
310 private: | 331 private: |
311 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 |
312 | 333 |
313 const SkImageInfo fInfo; | 334 const SkImageInfo fInfo; |
314 | 335 |
315 void* fPixels; | 336 // LockRec is only valid if we're in a locked state (isLocked()) |
316 SkColorTable* fColorTable; // we do not track ownership, subclass does | 337 LockRec fRec; |
317 int fLockCount; | 338 int fLockCount; |
318 | 339 |
319 mutable uint32_t fGenerationID; | 340 mutable uint32_t fGenerationID; |
320 mutable bool fUniqueGenerationID; | 341 mutable bool fUniqueGenerationID; |
321 | 342 |
322 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d | 343 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d |
323 | 344 |
324 SkString fURI; | 345 SkString fURI; |
325 | 346 |
326 // 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 |
327 bool fIsImmutable; | 348 bool fIsImmutable; |
328 // only ever set in constructor, const after that | 349 // only ever set in constructor, const after that |
329 bool fPreLocked; | 350 bool fPreLocked; |
330 | 351 |
331 void needsNewGenID(); | 352 void needsNewGenID(); |
332 void callGenIDChangeListeners(); | 353 void callGenIDChangeListeners(); |
333 | 354 |
334 void setMutex(SkBaseMutex* mutex); | 355 void setMutex(SkBaseMutex* mutex); |
335 | 356 |
336 // 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 |
337 // 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. |
338 friend class SkBitmap; // only for cloneGenID | 359 friend class SkBitmap; // only for cloneGenID |
339 void cloneGenID(const SkPixelRef&); | 360 void cloneGenID(const SkPixelRef&); |
340 | 361 |
341 typedef SkFlattenable INHERITED; | 362 typedef SkFlattenable INHERITED; |
342 }; | 363 }; |
343 | 364 |
344 #endif | 365 #endif |
OLD | NEW |