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_ONLOCKPIXELS | |
21 | |
22 #ifdef SK_DEBUG | 19 #ifdef SK_DEBUG |
23 /** | 20 /** |
24 * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref | 21 * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref |
25 * subclasses to correctly handle lock/unlock pixels. For performance | 22 * subclasses to correctly handle lock/unlock pixels. For performance |
26 * reasons, simple malloc-based subclasses call setPreLocked() to skip | 23 * reasons, simple malloc-based subclasses call setPreLocked() to skip |
27 * the overhead of implementing these calls. | 24 * the overhead of implementing these calls. |
28 * | 25 * |
29 * This build-flag disables that optimization, to add in debugging our | 26 * This build-flag disables that optimization, to add in debugging our |
30 * call-sites, to ensure that they correctly balance their calls of | 27 * call-sites, to ensure that they correctly balance their calls of |
31 * lock and unlock. | 28 * lock and unlock. |
(...skipping 13 matching lines...) Expand all Loading... |
45 This class is the smart container for pixel memory, and is used with | 42 This class is the smart container for pixel memory, and is used with |
46 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can | 43 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can |
47 access the actual pixel memory by calling lockPixels/unlockPixels. | 44 access the actual pixel memory by calling lockPixels/unlockPixels. |
48 | 45 |
49 This class can be shared/accessed between multiple threads. | 46 This class can be shared/accessed between multiple threads. |
50 */ | 47 */ |
51 class SK_API SkPixelRef : public SkFlattenable { | 48 class SK_API SkPixelRef : public SkFlattenable { |
52 public: | 49 public: |
53 SK_DECLARE_INST_COUNT(SkPixelRef) | 50 SK_DECLARE_INST_COUNT(SkPixelRef) |
54 | 51 |
55 explicit SkPixelRef(const SkImageInfo&); | 52 explicit SkPixelRef(SkBaseMutex* mutex = NULL); |
56 SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex); | |
57 virtual ~SkPixelRef(); | 53 virtual ~SkPixelRef(); |
58 | 54 |
59 const SkImageInfo& info() const { | |
60 return fInfo; | |
61 } | |
62 | |
63 /** Return the pixel memory returned from lockPixels, or null if the | 55 /** Return the pixel memory returned from lockPixels, or null if the |
64 lockCount is 0. | 56 lockCount is 0. |
65 */ | 57 */ |
66 void* pixels() const { return fRec.fPixels; } | 58 void* pixels() const { return fPixels; } |
67 | 59 |
68 /** Return the current colorTable (if any) if pixels are locked, or null. | 60 /** Return the current colorTable (if any) if pixels are locked, or null. |
69 */ | 61 */ |
70 SkColorTable* colorTable() const { return fRec.fColorTable; } | 62 SkColorTable* colorTable() const { return fColorTable; } |
71 | 63 |
72 /** | 64 /** |
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 /** | |
85 * Returns true if the lockcount > 0 | 65 * Returns true if the lockcount > 0 |
86 */ | 66 */ |
87 bool isLocked() const { return fLockCount > 0; } | 67 bool isLocked() const { return fLockCount > 0; } |
88 | 68 |
89 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) | 69 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) |
90 | 70 |
91 /** | 71 /** Call to access the pixel memory, which is returned. Balance with a call |
92 * Call to access the pixel memory. Return true on success. Balance this | 72 to unlockPixels(). |
93 * with a call to unlockPixels(). | 73 */ |
94 */ | 74 void lockPixels(); |
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 | |
104 /** Call to balanace a previous call to lockPixels(). Returns the pixels | 75 /** Call to balanace a previous call to lockPixels(). Returns the pixels |
105 (or null) after the unlock. NOTE: lock calls can be nested, but the | 76 (or null) after the unlock. NOTE: lock calls can be nested, but the |
106 matching number of unlock calls must be made in order to free the | 77 matching number of unlock calls must be made in order to free the |
107 memory (if the subclass implements caching/deferred-decoding.) | 78 memory (if the subclass implements caching/deferred-decoding.) |
108 */ | 79 */ |
109 void unlockPixels(); | 80 void unlockPixels(); |
110 | 81 |
111 /** | 82 /** |
112 * Some bitmaps can return a copy of their pixels for lockPixels(), but | 83 * Some bitmaps can return a copy of their pixels for lockPixels(), but |
113 * that copy, if modified, will not be pushed back. These bitmaps should | 84 * 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... |
250 // This can be used to invalidate caches keyed by SkPixelRef generation ID. | 221 // This can be used to invalidate caches keyed by SkPixelRef generation ID. |
251 struct GenIDChangeListener { | 222 struct GenIDChangeListener { |
252 virtual ~GenIDChangeListener() {} | 223 virtual ~GenIDChangeListener() {} |
253 virtual void onChange() = 0; | 224 virtual void onChange() = 0; |
254 }; | 225 }; |
255 | 226 |
256 // Takes ownership of listener. | 227 // Takes ownership of listener. |
257 void addGenIDChangeListener(GenIDChangeListener* listener); | 228 void addGenIDChangeListener(GenIDChangeListener* listener); |
258 | 229 |
259 protected: | 230 protected: |
260 #ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS | 231 /** Called when the lockCount goes from 0 to 1. The caller will have already |
261 virtual void* onLockPixels(SkColorTable**); | 232 acquire a mutex for thread safety, so this method need not do that. |
262 virtual bool onNewLockPixels(LockRec*); | 233 */ |
263 #else | 234 virtual void* onLockPixels(SkColorTable**) = 0; |
264 /** | 235 /** Called when the lock count goes from 1 to 0. The caller will have |
265 * On success, returns true and fills out the LockRec for the pixels. On | 236 already acquire a mutex for thread safety, so this method need not do |
266 * failure returns false and ignores the LockRec parameter. | 237 that. |
267 * | 238 */ |
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 */ | |
282 virtual void onUnlockPixels() = 0; | 239 virtual void onUnlockPixels() = 0; |
283 | 240 |
284 /** Default impl returns true */ | 241 /** Default impl returns true */ |
285 virtual bool onLockPixelsAreWritable() const; | 242 virtual bool onLockPixelsAreWritable() const; |
286 | 243 |
287 // returns false; | 244 // returns false; |
288 virtual bool onImplementsDecodeInto(); | 245 virtual bool onImplementsDecodeInto(); |
289 // returns false; | 246 // returns false; |
290 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); | 247 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); |
291 | 248 |
(...skipping 23 matching lines...) Expand all Loading... |
315 */ | 272 */ |
316 SkBaseMutex* mutex() const { return fMutex; } | 273 SkBaseMutex* mutex() const { return fMutex; } |
317 | 274 |
318 // serialization | 275 // serialization |
319 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); | 276 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); |
320 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; | 277 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; |
321 | 278 |
322 // only call from constructor. Flags this to always be locked, removing | 279 // only call from constructor. Flags this to always be locked, removing |
323 // the need to grab the mutex and call onLockPixels/onUnlockPixels. | 280 // the need to grab the mutex and call onLockPixels/onUnlockPixels. |
324 // Performance tweak to avoid those calls (esp. in multi-thread use case). | 281 // Performance tweak to avoid those calls (esp. in multi-thread use case). |
325 void setPreLocked(void*, size_t rowBytes, SkColorTable*); | 282 void setPreLocked(void* pixels, SkColorTable* ctable); |
326 | 283 |
327 private: | 284 private: |
328 SkBaseMutex* fMutex; // must remain in scope for the life of this object | 285 SkBaseMutex* fMutex; // must remain in scope for the life of this object |
329 SkImageInfo fInfo; | 286 void* fPixels; |
330 | 287 SkColorTable* fColorTable; // we do not track ownership, subclass does |
331 // LockRec is only valid if we're in a locked state (isLocked()) | |
332 LockRec fRec; | |
333 int fLockCount; | 288 int fLockCount; |
334 | 289 |
335 mutable uint32_t fGenerationID; | 290 mutable uint32_t fGenerationID; |
336 mutable bool fUniqueGenerationID; | 291 mutable bool fUniqueGenerationID; |
337 | 292 |
338 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d | 293 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d |
339 | 294 |
340 SkString fURI; | 295 SkString fURI; |
341 | 296 |
342 // can go from false to true, but never from true to false | 297 // can go from false to true, but never from true to false |
343 bool fIsImmutable; | 298 bool fIsImmutable; |
344 // only ever set in constructor, const after that | 299 // only ever set in constructor, const after that |
345 bool fPreLocked; | 300 bool fPreLocked; |
346 | 301 |
347 void needsNewGenID(); | 302 void needsNewGenID(); |
348 void callGenIDChangeListeners(); | 303 void callGenIDChangeListeners(); |
349 | 304 |
350 void setMutex(SkBaseMutex* mutex); | 305 void setMutex(SkBaseMutex* mutex); |
351 | 306 |
352 // When copying a bitmap to another with the same shape and config, we can s
afely | 307 // When copying a bitmap to another with the same shape and config, we can s
afely |
353 // clone the pixelref generation ID too, which makes them equivalent under c
aching. | 308 // clone the pixelref generation ID too, which makes them equivalent under c
aching. |
354 friend class SkBitmap; // only for cloneGenID | 309 friend class SkBitmap; // only for cloneGenID |
355 void cloneGenID(const SkPixelRef&); | 310 void cloneGenID(const SkPixelRef&); |
356 | 311 |
357 typedef SkFlattenable INHERITED; | 312 typedef SkFlattenable INHERITED; |
358 }; | 313 }; |
359 | 314 |
360 #endif | 315 #endif |
OLD | NEW |