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 | |
91 /** | |
92 * Returns true if the lockcount > 0 | 77 * Returns true if the lockcount > 0 |
93 */ | 78 */ |
94 bool isLocked() const { return fLockCount > 0; } | 79 bool isLocked() const { return fLockCount > 0; } |
95 | 80 |
96 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) | 81 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) |
97 | 82 |
98 /** | 83 /** Call to access the pixel memory, which is returned. Balance with a call |
99 * Call to access the pixel memory. Return true on success. Balance this | 84 to unlockPixels(). |
100 * with a call to unlockPixels(). | 85 */ |
101 */ | 86 void lockPixels(); |
102 bool lockPixels(); | |
103 | |
104 /** | |
105 * Call to access the pixel memory. On success, return true and fill out | |
106 * the specified rec. On failure, return false and ignore the rec parameter
. | |
107 * Balance this with a call to unlockPixels(). | |
108 */ | |
109 bool lockPixels(LockRec* rec); | |
110 | |
111 /** Call to balanace a previous call to lockPixels(). Returns the pixels | 87 /** Call to balanace a previous call to lockPixels(). Returns the pixels |
112 (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 |
113 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 |
114 memory (if the subclass implements caching/deferred-decoding.) | 90 memory (if the subclass implements caching/deferred-decoding.) |
115 */ | 91 */ |
116 void unlockPixels(); | 92 void unlockPixels(); |
117 | 93 |
118 /** | 94 /** |
119 * 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 |
120 * 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... |
257 // 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. |
258 struct GenIDChangeListener { | 234 struct GenIDChangeListener { |
259 virtual ~GenIDChangeListener() {} | 235 virtual ~GenIDChangeListener() {} |
260 virtual void onChange() = 0; | 236 virtual void onChange() = 0; |
261 }; | 237 }; |
262 | 238 |
263 // Takes ownership of listener. | 239 // Takes ownership of listener. |
264 void addGenIDChangeListener(GenIDChangeListener* listener); | 240 void addGenIDChangeListener(GenIDChangeListener* listener); |
265 | 241 |
266 protected: | 242 protected: |
267 #ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS | 243 /** Called when the lockCount goes from 0 to 1. The caller will have already |
268 virtual void* onLockPixels(SkColorTable**); | 244 acquire a mutex for thread safety, so this method need not do that. |
269 virtual bool onNewLockPixels(LockRec*); | 245 */ |
270 #else | 246 virtual void* onLockPixels(SkColorTable**) = 0; |
271 /** | 247 /** Called when the lock count goes from 1 to 0. The caller will have |
272 * On success, returns true and fills out the LockRec for the pixels. On | 248 already acquire a mutex for thread safety, so this method need not do |
273 * failure returns false and ignores the LockRec parameter. | 249 that. |
274 * | 250 */ |
275 * The caller will have already acquired a mutex for thread safety, so this | |
276 * method need not do that. | |
277 */ | |
278 virtual bool onNewLockPixels(LockRec*) = 0; | |
279 #endif | |
280 | |
281 /** | |
282 * Balancing the previous successful call to onNewLockPixels. The locked | |
283 * pixel address will no longer be referenced, so the subclass is free to | |
284 * move or discard that memory. | |
285 * | |
286 * The caller will have already acquired a mutex for thread safety, so this | |
287 * method need not do that. | |
288 */ | |
289 virtual void onUnlockPixels() = 0; | 251 virtual void onUnlockPixels() = 0; |
290 | 252 |
291 /** Default impl returns true */ | 253 /** Default impl returns true */ |
292 virtual bool onLockPixelsAreWritable() const; | 254 virtual bool onLockPixelsAreWritable() const; |
293 | 255 |
294 // returns false; | 256 // returns false; |
295 virtual bool onImplementsDecodeInto(); | 257 virtual bool onImplementsDecodeInto(); |
296 // returns false; | 258 // returns false; |
297 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); | 259 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); |
298 | 260 |
(...skipping 23 matching lines...) Expand all Loading... |
322 */ | 284 */ |
323 SkBaseMutex* mutex() const { return fMutex; } | 285 SkBaseMutex* mutex() const { return fMutex; } |
324 | 286 |
325 // serialization | 287 // serialization |
326 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); | 288 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); |
327 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; | 289 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; |
328 | 290 |
329 // only call from constructor. Flags this to always be locked, removing | 291 // only call from constructor. Flags this to always be locked, removing |
330 // the need to grab the mutex and call onLockPixels/onUnlockPixels. | 292 // the need to grab the mutex and call onLockPixels/onUnlockPixels. |
331 // Performance tweak to avoid those calls (esp. in multi-thread use case). | 293 // Performance tweak to avoid those calls (esp. in multi-thread use case). |
332 void setPreLocked(void*, size_t rowBytes, SkColorTable*); | 294 void setPreLocked(void* pixels, SkColorTable* ctable); |
333 | 295 |
334 private: | 296 private: |
335 SkBaseMutex* fMutex; // must remain in scope for the life of this object | 297 SkBaseMutex* fMutex; // must remain in scope for the life of this object |
336 SkImageInfo fInfo; | 298 SkImageInfo fInfo; |
337 | 299 |
338 // LockRec is only valid if we're in a locked state (isLocked()) | 300 void* fPixels; |
339 LockRec fRec; | 301 SkColorTable* fColorTable; // we do not track ownership, subclass does |
340 int fLockCount; | 302 int fLockCount; |
341 | 303 |
342 mutable uint32_t fGenerationID; | 304 mutable uint32_t fGenerationID; |
343 mutable bool fUniqueGenerationID; | 305 mutable bool fUniqueGenerationID; |
344 | 306 |
345 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d | 307 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d |
346 | 308 |
347 SkString fURI; | 309 SkString fURI; |
348 | 310 |
349 // can go from false to true, but never from true to false | 311 // can go from false to true, but never from true to false |
350 bool fIsImmutable; | 312 bool fIsImmutable; |
351 // only ever set in constructor, const after that | 313 // only ever set in constructor, const after that |
352 bool fPreLocked; | 314 bool fPreLocked; |
353 | 315 |
354 void needsNewGenID(); | 316 void needsNewGenID(); |
355 void callGenIDChangeListeners(); | 317 void callGenIDChangeListeners(); |
356 | 318 |
357 void setMutex(SkBaseMutex* mutex); | 319 void setMutex(SkBaseMutex* mutex); |
358 | 320 |
359 // When copying a bitmap to another with the same shape and config, we can s
afely | 321 // When copying a bitmap to another with the same shape and config, we can s
afely |
360 // clone the pixelref generation ID too, which makes them equivalent under c
aching. | 322 // clone the pixelref generation ID too, which makes them equivalent under c
aching. |
361 friend class SkBitmap; // only for cloneGenID | 323 friend class SkBitmap; // only for cloneGenID |
362 void cloneGenID(const SkPixelRef&); | 324 void cloneGenID(const SkPixelRef&); |
363 | 325 |
364 typedef SkFlattenable INHERITED; | 326 typedef SkFlattenable INHERITED; |
365 }; | 327 }; |
366 | 328 |
367 #endif | 329 #endif |
OLD | NEW |