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 13 matching lines...) Expand all Loading... | |
42 This class is the smart container for pixel memory, and is used with | 45 This class is the smart container for pixel memory, and is used with |
43 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can | 46 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can |
44 access the actual pixel memory by calling lockPixels/unlockPixels. | 47 access the actual pixel memory by calling lockPixels/unlockPixels. |
45 | 48 |
46 This class can be shared/accessed between multiple threads. | 49 This class can be shared/accessed between multiple threads. |
47 */ | 50 */ |
48 class SK_API SkPixelRef : public SkFlattenable { | 51 class SK_API SkPixelRef : public SkFlattenable { |
49 public: | 52 public: |
50 SK_DECLARE_INST_COUNT(SkPixelRef) | 53 SK_DECLARE_INST_COUNT(SkPixelRef) |
51 | 54 |
52 explicit SkPixelRef(SkBaseMutex* mutex = NULL); | 55 explicit SkPixelRef(const SkImageInfo&); |
56 SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex); | |
53 virtual ~SkPixelRef(); | 57 virtual ~SkPixelRef(); |
54 | 58 |
59 const SkImageInfo& info() const { | |
60 return fInfo; | |
61 } | |
62 | |
55 /** Return the pixel memory returned from lockPixels, or null if the | 63 /** Return the pixel memory returned from lockPixels, or null if the |
56 lockCount is 0. | 64 lockCount is 0. |
57 */ | 65 */ |
58 void* pixels() const { return fPixels; } | 66 void* pixels() const { return fRec.fPixels; } |
59 | 67 |
60 /** 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. |
61 */ | 69 */ |
62 SkColorTable* colorTable() const { return fColorTable; } | 70 SkColorTable* colorTable() const { return fRec.fColorTable; } |
63 | 71 |
64 /** | 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 | |
84 /** | |
65 * Returns true if the lockcount > 0 | 85 * Returns true if the lockcount > 0 |
66 */ | 86 */ |
67 bool isLocked() const { return fLockCount > 0; } | 87 bool isLocked() const { return fLockCount > 0; } |
68 | 88 |
69 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) | 89 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) |
70 | 90 |
71 /** Call to access the pixel memory, which is returned. Balance with a call | 91 /** |
72 to unlockPixels(). | 92 * Call to access the pixel memory. Return true on success. Balance this |
73 */ | 93 * with a call to unlockPixels(). |
74 void lockPixels(); | 94 */ |
95 bool lockPixels(); | |
96 | |
97 /** | |
98 * Call to access the pixel memory. On success, return true and fill out | |
99 * the specified rec. On failure, return false and ignore the rec parameter . | |
100 * Balance this with a call to unlockPixels(). | |
101 */ | |
102 bool lockPixels(LockRec* rec); | |
103 | |
75 /** Call to balanace a previous call to lockPixels(). Returns the pixels | 104 /** Call to balanace a previous call to lockPixels(). Returns the pixels |
76 (or null) after the unlock. NOTE: lock calls can be nested, but the | 105 (or null) after the unlock. NOTE: lock calls can be nested, but the |
77 matching number of unlock calls must be made in order to free the | 106 matching number of unlock calls must be made in order to free the |
78 memory (if the subclass implements caching/deferred-decoding.) | 107 memory (if the subclass implements caching/deferred-decoding.) |
79 */ | 108 */ |
80 void unlockPixels(); | 109 void unlockPixels(); |
81 | 110 |
82 /** | 111 /** |
83 * Some bitmaps can return a copy of their pixels for lockPixels(), but | 112 * Some bitmaps can return a copy of their pixels for lockPixels(), but |
84 * that copy, if modified, will not be pushed back. These bitmaps should | 113 * 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... | |
221 // This can be used to invalidate caches keyed by SkPixelRef generation ID. | 250 // This can be used to invalidate caches keyed by SkPixelRef generation ID. |
222 struct GenIDChangeListener { | 251 struct GenIDChangeListener { |
223 virtual ~GenIDChangeListener() {} | 252 virtual ~GenIDChangeListener() {} |
224 virtual void onChange() = 0; | 253 virtual void onChange() = 0; |
225 }; | 254 }; |
226 | 255 |
227 // Takes ownership of listener. | 256 // Takes ownership of listener. |
228 void addGenIDChangeListener(GenIDChangeListener* listener); | 257 void addGenIDChangeListener(GenIDChangeListener* listener); |
229 | 258 |
230 protected: | 259 protected: |
231 /** Called when the lockCount goes from 0 to 1. The caller will have already | 260 #ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS |
232 acquire a mutex for thread safety, so this method need not do that. | 261 virtual void* onLockPixels(SkColorTable**); |
233 */ | 262 virtual bool onNewLockPixels(LockRec*); |
234 virtual void* onLockPixels(SkColorTable**) = 0; | 263 #else |
235 /** Called when the lock count goes from 1 to 0. The caller will have | 264 /** |
236 already acquire a mutex for thread safety, so this method need not do | 265 * On success, returns true and fills out the LockRec for the pixels. On |
237 that. | 266 * failure returns false and ignores the LockRec parameter. |
238 */ | 267 * |
268 * The caller will have already acquired a mutex for thread safety, so this | |
269 * method need not do that. | |
270 */ | |
271 virtual bool onNewLockPixels(LockRec*) = 0; | |
272 #endif | |
273 | |
274 /** | |
275 * Balancing the previous successful call to onNewLockPixels. The locked | |
276 * pixel address will no longer be referenced, so the subclass is free to | |
277 * move or discard that memory. | |
278 * | |
279 * The caller will have already acquired a mutex for thread safety, so this | |
280 * method need not do that. | |
281 */ | |
239 virtual void onUnlockPixels() = 0; | 282 virtual void onUnlockPixels() = 0; |
240 | 283 |
241 /** Default impl returns true */ | 284 /** Default impl returns true */ |
242 virtual bool onLockPixelsAreWritable() const; | 285 virtual bool onLockPixelsAreWritable() const; |
243 | 286 |
244 // returns false; | 287 // returns false; |
245 virtual bool onImplementsDecodeInto(); | 288 virtual bool onImplementsDecodeInto(); |
246 // returns false; | 289 // returns false; |
247 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); | 290 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); |
248 | 291 |
249 /** | 292 /** |
250 * For pixelrefs that don't have access to their raw pixels, they may be | 293 * For pixelrefs that don't have access to their raw pixels, they may be |
251 * able to make a copy of them (e.g. if the pixels are on the GPU). | 294 * able to make a copy of them (e.g. if the pixels are on the GPU). |
252 * | 295 * |
253 * The base class implementation returns false; | 296 * The base class implementation returns false; |
254 */ | 297 */ |
255 virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull); | 298 virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull); |
256 | 299 |
257 // default impl returns NULL. | 300 // default impl returns NULL. |
258 virtual SkData* onRefEncodedData(); | 301 virtual SkData* onRefEncodedData(); |
259 | 302 |
260 /** | 303 /** |
261 * Returns the size (in bytes) of the internally allocated memory. | 304 * Returns the size (in bytes) of the internally allocated memory. |
262 * This should be implemented in all serializable SkPixelRef derived classe s. | 305 * This should be implemented in all serializable SkPixelRef derived classe s. |
263 * SkBitmap::fPixelRefOffset + SkBitmap::getSafeSize() should never overflo w this value, | 306 * SkBitmap::fPixelRefOffset + SkBitmap::getSafeSize() should never overflo w this value, |
scroggo
2013/12/06 14:50:33
Would it make sense to enforce this? Instead of ma
reed1
2013/12/06 15:48:46
Good idea. Next CL.
| |
264 * otherwise the rendering code may attempt to read memory out of bounds. | 307 * otherwise the rendering code may attempt to read memory out of bounds. |
265 * | 308 * |
266 * @return default impl returns 0. | 309 * @return default impl returns 0. |
267 */ | 310 */ |
268 virtual size_t getAllocatedSizeInBytes() const; | 311 virtual size_t getAllocatedSizeInBytes() const; |
269 | 312 |
270 /** Return the mutex associated with this pixelref. This value is assigned | 313 /** Return the mutex associated with this pixelref. This value is assigned |
271 in the constructor, and cannot change during the lifetime of the object. | 314 in the constructor, and cannot change during the lifetime of the object. |
272 */ | 315 */ |
273 SkBaseMutex* mutex() const { return fMutex; } | 316 SkBaseMutex* mutex() const { return fMutex; } |
274 | 317 |
275 // serialization | 318 // serialization |
276 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); | 319 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); |
277 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; | 320 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; |
278 | 321 |
279 // only call from constructor. Flags this to always be locked, removing | 322 // only call from constructor. Flags this to always be locked, removing |
280 // the need to grab the mutex and call onLockPixels/onUnlockPixels. | 323 // the need to grab the mutex and call onLockPixels/onUnlockPixels. |
281 // Performance tweak to avoid those calls (esp. in multi-thread use case). | 324 // Performance tweak to avoid those calls (esp. in multi-thread use case). |
282 void setPreLocked(void* pixels, SkColorTable* ctable); | 325 void setPreLocked(void*, size_t rowBytes, SkColorTable*); |
283 | 326 |
284 private: | 327 private: |
285 SkBaseMutex* fMutex; // must remain in scope for the life of this object | 328 SkBaseMutex* fMutex; // must remain in scope for the life of this object |
286 void* fPixels; | 329 SkImageInfo fInfo; |
287 SkColorTable* fColorTable; // we do not track ownership, subclass does | 330 |
331 // LockRec is only valid if we're in a locked state (isLocked()) | |
332 LockRec fRec; | |
288 int fLockCount; | 333 int fLockCount; |
289 | 334 |
290 mutable uint32_t fGenerationID; | 335 mutable uint32_t fGenerationID; |
291 mutable bool fUniqueGenerationID; | 336 mutable bool fUniqueGenerationID; |
292 | 337 |
293 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne d | 338 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne d |
294 | 339 |
295 SkString fURI; | 340 SkString fURI; |
296 | 341 |
297 // can go from false to true, but never from true to false | 342 // can go from false to true, but never from true to false |
298 bool fIsImmutable; | 343 bool fIsImmutable; |
299 // only ever set in constructor, const after that | 344 // only ever set in constructor, const after that |
300 bool fPreLocked; | 345 bool fPreLocked; |
301 | 346 |
302 void needsNewGenID(); | 347 void needsNewGenID(); |
303 void callGenIDChangeListeners(); | 348 void callGenIDChangeListeners(); |
304 | 349 |
305 void setMutex(SkBaseMutex* mutex); | 350 void setMutex(SkBaseMutex* mutex); |
306 | 351 |
307 // When copying a bitmap to another with the same shape and config, we can s afely | 352 // When copying a bitmap to another with the same shape and config, we can s afely |
308 // clone the pixelref generation ID too, which makes them equivalent under c aching. | 353 // clone the pixelref generation ID too, which makes them equivalent under c aching. |
309 friend class SkBitmap; // only for cloneGenID | 354 friend class SkBitmap; // only for cloneGenID |
310 void cloneGenID(const SkPixelRef&); | 355 void cloneGenID(const SkPixelRef&); |
311 | 356 |
312 typedef SkFlattenable INHERITED; | 357 typedef SkFlattenable INHERITED; |
313 }; | 358 }; |
314 | 359 |
315 #endif | 360 #endif |
OLD | NEW |