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 16 matching lines...) Expand all Loading... | |
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(SkBaseMutex* mutex = NULL); |
53 virtual ~SkPixelRef(); | 56 virtual ~SkPixelRef(); |
54 | 57 |
58 struct LockRec { | |
scroggo
2013/12/04 22:47:38
Maybe add a comment that these are unowned pointer
| |
59 void* fPixels; | |
60 SkColorTable* fColorTable; | |
61 size_t fRowBytes; | |
62 | |
63 void zero() { sk_bzero(this, sizeof(*this)); } | |
64 }; | |
65 | |
55 /** Return the pixel memory returned from lockPixels, or null if the | 66 /** Return the pixel memory returned from lockPixels, or null if the |
56 lockCount is 0. | 67 lockCount is 0. |
57 */ | 68 */ |
58 void* pixels() const { return fPixels; } | 69 void* pixels() const { return fRec.fPixels; } |
59 | 70 |
60 /** Return the current colorTable (if any) if pixels are locked, or null. | 71 /** Return the current colorTable (if any) if pixels are locked, or null. |
61 */ | 72 */ |
62 SkColorTable* colorTable() const { return fColorTable; } | 73 SkColorTable* colorTable() const { return fRec.fColorTable; } |
63 | 74 |
64 /** | 75 /** |
65 * Returns true if the lockcount > 0 | 76 * Returns true if the lockcount > 0 |
66 */ | 77 */ |
67 bool isLocked() const { return fLockCount > 0; } | 78 bool isLocked() const { return fLockCount > 0; } |
68 | 79 |
69 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) | 80 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) |
70 | 81 |
71 /** Call to access the pixel memory, which is returned. Balance with a call | 82 /** Call to access the pixel memory, which is returned. Balance with a call |
mtklein
2013/12/04 22:46:00
Just happened to notice that this comment is _some
reed1
2013/12/05 13:32:39
Done.
| |
72 to unlockPixels(). | 83 to unlockPixels(). |
73 */ | 84 */ |
74 void lockPixels(); | 85 void lockPixels(); |
86 | |
87 /** | |
88 * Call to access the pixel memory. On success, return true and fill out | |
89 * the specified rec. On failure, return false and ignore the rec parameter . | |
90 */ | |
91 bool lockPixels(LockRec* rec); | |
92 | |
75 /** Call to balanace a previous call to lockPixels(). Returns the pixels | 93 /** 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 | 94 (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 | 95 matching number of unlock calls must be made in order to free the |
78 memory (if the subclass implements caching/deferred-decoding.) | 96 memory (if the subclass implements caching/deferred-decoding.) |
79 */ | 97 */ |
80 void unlockPixels(); | 98 void unlockPixels(); |
81 | 99 |
82 /** | 100 /** |
83 * Some bitmaps can return a copy of their pixels for lockPixels(), but | 101 * 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 | 102 * that copy, if modified, will not be pushed back. These bitmaps should |
85 * not be used as targets for a raster device/canvas (since all pixels | 103 * not be used as targets for a raster device/canvas (since all pixels |
86 * modifications will be lost when unlockPixels() is called.) | 104 * modifications will be lost when unlockPixels() is called.) |
87 */ | 105 */ |
88 bool lockPixelsAreWritable() const; | 106 bool lockPixelsAreWritable() const; |
89 | 107 |
108 /** | |
109 * On success, return true and return the ImageInfo. On failure, return | |
110 * false and ignore the ImageInfo parameter. | |
111 */ | |
112 bool getInfo(SkImageInfo*); | |
mtklein
2013/12/04 22:46:00
Don't forget how you, Hal, and I decided we should
reed1
2013/12/05 13:32:39
Working on it
| |
113 | |
90 /** Returns a non-zero, unique value corresponding to the pixels in this | 114 /** Returns a non-zero, unique value corresponding to the pixels in this |
91 pixelref. Each time the pixels are changed (and notifyPixelsChanged is | 115 pixelref. Each time the pixels are changed (and notifyPixelsChanged is |
92 called), a different generation ID will be returned. | 116 called), a different generation ID will be returned. |
93 */ | 117 */ |
94 uint32_t getGenerationID() const; | 118 uint32_t getGenerationID() const; |
95 | 119 |
96 /** Call this if you have changed the contents of the pixels. This will in- | 120 /** Call this if you have changed the contents of the pixels. This will in- |
97 turn cause a different generation ID value to be returned from | 121 turn cause a different generation ID value to be returned from |
98 getGenerationID(). | 122 getGenerationID(). |
99 */ | 123 */ |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 // This can be used to invalidate caches keyed by SkPixelRef generation ID. | 245 // This can be used to invalidate caches keyed by SkPixelRef generation ID. |
222 struct GenIDChangeListener { | 246 struct GenIDChangeListener { |
223 virtual ~GenIDChangeListener() {} | 247 virtual ~GenIDChangeListener() {} |
224 virtual void onChange() = 0; | 248 virtual void onChange() = 0; |
225 }; | 249 }; |
226 | 250 |
227 // Takes ownership of listener. | 251 // Takes ownership of listener. |
228 void addGenIDChangeListener(GenIDChangeListener* listener); | 252 void addGenIDChangeListener(GenIDChangeListener* listener); |
229 | 253 |
230 protected: | 254 protected: |
231 /** Called when the lockCount goes from 0 to 1. The caller will have already | 255 #ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS |
232 acquire a mutex for thread safety, so this method need not do that. | 256 virtual void* onLockPixels(SkColorTable**); |
233 */ | 257 virtual bool onGetInfo(SkImageInfo*); |
234 virtual void* onLockPixels(SkColorTable**) = 0; | 258 virtual bool onNewLockPixels(LockRec*); |
235 /** Called when the lock count goes from 1 to 0. The caller will have | 259 #else |
236 already acquire a mutex for thread safety, so this method need not do | 260 /** |
237 that. | 261 * Return the ImageInfo, returning true on success. On failure, return |
238 */ | 262 * false and ignore the info parameter. |
263 * | |
264 * The caller will have already acquired a mutex for thread safety, so this | |
265 * method need not do that. | |
266 */ | |
267 virtual bool onGetInfo(SkImageInfo*) = 0; | |
268 | |
269 /** | |
270 * On success, returns true and fills out the LockRec for the pixels. On | |
271 * failure returns false and ignores the LockRec parameter. | |
272 * | |
273 * The caller will have already acquired a mutex for thread safety, so this | |
274 * method need not do that. | |
275 */ | |
276 virtual bool onNewLockPixels(LockRec*) = 0; | |
277 #endif | |
278 | |
279 /** | |
280 * Balancing the previous successful call to onNewLockPixels. The locked | |
281 * pixel address will no longer be referenced, so the subclass is free to | |
282 * move or discard that memory. | |
283 * | |
284 * The caller will have already acquired a mutex for thread safety, so this | |
285 * method need not do that. | |
286 */ | |
239 virtual void onUnlockPixels() = 0; | 287 virtual void onUnlockPixels() = 0; |
240 | 288 |
241 /** Default impl returns true */ | 289 /** Default impl returns true */ |
242 virtual bool onLockPixelsAreWritable() const; | 290 virtual bool onLockPixelsAreWritable() const; |
243 | 291 |
244 // returns false; | 292 // returns false; |
245 virtual bool onImplementsDecodeInto(); | 293 virtual bool onImplementsDecodeInto(); |
246 // returns false; | 294 // returns false; |
247 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); | 295 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); |
248 | 296 |
(...skipping 13 matching lines...) Expand all Loading... | |
262 */ | 310 */ |
263 SkBaseMutex* mutex() const { return fMutex; } | 311 SkBaseMutex* mutex() const { return fMutex; } |
264 | 312 |
265 // serialization | 313 // serialization |
266 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); | 314 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); |
267 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; | 315 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; |
268 | 316 |
269 // only call from constructor. Flags this to always be locked, removing | 317 // only call from constructor. Flags this to always be locked, removing |
270 // the need to grab the mutex and call onLockPixels/onUnlockPixels. | 318 // the need to grab the mutex and call onLockPixels/onUnlockPixels. |
271 // Performance tweak to avoid those calls (esp. in multi-thread use case). | 319 // Performance tweak to avoid those calls (esp. in multi-thread use case). |
272 void setPreLocked(void* pixels, SkColorTable* ctable); | 320 void setPreLocked(const SkImageInfo&, void*, size_t rowBytes, SkColorTable*) ; |
273 | 321 |
274 private: | 322 private: |
275 SkBaseMutex* fMutex; // must remain in scope for the life of this object | 323 SkBaseMutex* fMutex; // must remain in scope for the life of this object |
276 void* fPixels; | 324 SkImageInfo fInfo; |
277 SkColorTable* fColorTable; // we do not track ownership, subclass does | 325 LockRec fRec; |
278 int fLockCount; | 326 int fLockCount; |
279 | 327 |
280 mutable uint32_t fGenerationID; | 328 mutable uint32_t fGenerationID; |
281 mutable bool fUniqueGenerationID; | 329 mutable bool fUniqueGenerationID; |
282 | 330 |
283 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne d | 331 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne d |
284 | 332 |
285 SkString fURI; | 333 SkString fURI; |
286 | 334 |
287 // can go from false to true, but never from true to false | 335 // can go from false to true, but never from true to false |
288 bool fIsImmutable; | 336 bool fIsImmutable; |
289 // only ever set in constructor, const after that | 337 // only ever set in constructor, const after that |
290 bool fPreLocked; | 338 bool fPreLocked; |
291 | 339 |
292 void needsNewGenID(); | 340 void needsNewGenID(); |
293 void callGenIDChangeListeners(); | 341 void callGenIDChangeListeners(); |
294 | 342 |
295 void setMutex(SkBaseMutex* mutex); | 343 void setMutex(SkBaseMutex* mutex); |
296 | 344 |
297 // When copying a bitmap to another with the same shape and config, we can s afely | 345 // When copying a bitmap to another with the same shape and config, we can s afely |
298 // clone the pixelref generation ID too, which makes them equivalent under c aching. | 346 // clone the pixelref generation ID too, which makes them equivalent under c aching. |
299 friend class SkBitmap; // only for cloneGenID | 347 friend class SkBitmap; // only for cloneGenID |
300 void cloneGenID(const SkPixelRef&); | 348 void cloneGenID(const SkPixelRef&); |
301 | 349 |
302 typedef SkFlattenable INHERITED; | 350 typedef SkFlattenable INHERITED; |
303 }; | 351 }; |
304 | 352 |
305 #endif | 353 #endif |
OLD | NEW |