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