• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2008 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #ifndef SkPixelRef_DEFINED
11 #define SkPixelRef_DEFINED
12 
13 #include "SkBitmap.h"
14 #include "SkRefCnt.h"
15 #include "SkString.h"
16 #include "SkFlattenable.h"
17 #include "SkTDArray.h"
18 
19 //#define SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR
20 
21 #ifdef SK_DEBUG
22     /**
23      *  Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref
24      *  subclasses to correctly handle lock/unlock pixels. For performance
25      *  reasons, simple malloc-based subclasses call setPreLocked() to skip
26      *  the overhead of implementing these calls.
27      *
28      *  This build-flag disables that optimization, to add in debugging our
29      *  call-sites, to ensure that they correctly balance their calls of
30      *  lock and unlock.
31      */
32 //    #define SK_IGNORE_PIXELREF_SETPRELOCKED
33 #endif
34 
35 class SkColorTable;
36 class SkData;
37 struct SkIRect;
38 class SkMutex;
39 
40 class GrTexture;
41 
42 /** \class SkPixelRef
43 
44     This class is the smart container for pixel memory, and is used with
45     SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
46     access the actual pixel memory by calling lockPixels/unlockPixels.
47 
48     This class can be shared/accessed between multiple threads.
49 */
50 class SK_API SkPixelRef : public SkFlattenable {
51 public:
52     SK_DECLARE_INST_COUNT(SkPixelRef)
53 
54 #ifdef SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR
55     // DEPRECATED -- use a constructor that takes SkImageInfo
56     explicit SkPixelRef(SkBaseMutex* mutex = NULL);
57 #endif
58 
59     explicit SkPixelRef(const SkImageInfo&);
60     SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex);
61     virtual ~SkPixelRef();
62 
info()63     const SkImageInfo& info() const {
64         return fInfo;
65     }
66 
67     /** Return the pixel memory returned from lockPixels, or null if the
68         lockCount is 0.
69     */
pixels()70     void* pixels() const { return fPixels; }
71 
72     /** Return the current colorTable (if any) if pixels are locked, or null.
73     */
colorTable()74     SkColorTable* colorTable() const { return fColorTable; }
75 
76     /**
77      *  Returns true if the lockcount > 0
78      */
isLocked()79     bool isLocked() const { return fLockCount > 0; }
80 
81     SkDEBUGCODE(int getLockCount() const { return fLockCount; })
82 
83     /** Call to access the pixel memory, which is returned. Balance with a call
84         to unlockPixels().
85     */
86     void lockPixels();
87     /** Call to balanace a previous call to lockPixels(). Returns the pixels
88         (or null) after the unlock. NOTE: lock calls can be nested, but the
89         matching number of unlock calls must be made in order to free the
90         memory (if the subclass implements caching/deferred-decoding.)
91     */
92     void unlockPixels();
93 
94     /**
95      *  Some bitmaps can return a copy of their pixels for lockPixels(), but
96      *  that copy, if modified, will not be pushed back. These bitmaps should
97      *  not be used as targets for a raster device/canvas (since all pixels
98      *  modifications will be lost when unlockPixels() is called.)
99      */
100     bool lockPixelsAreWritable() const;
101 
102     /** Returns a non-zero, unique value corresponding to the pixels in this
103         pixelref. Each time the pixels are changed (and notifyPixelsChanged is
104         called), a different generation ID will be returned.
105     */
106     uint32_t getGenerationID() const;
107 
108     /** Call this if you have changed the contents of the pixels. This will in-
109         turn cause a different generation ID value to be returned from
110         getGenerationID().
111     */
112     void notifyPixelsChanged();
113 
114     /** Returns true if this pixelref is marked as immutable, meaning that the
115         contents of its pixels will not change for the lifetime of the pixelref.
116     */
isImmutable()117     bool isImmutable() const { return fIsImmutable; }
118 
119     /** Marks this pixelref is immutable, meaning that the contents of its
120         pixels will not change for the lifetime of the pixelref. This state can
121         be set on a pixelref, but it cannot be cleared once it is set.
122     */
123     void setImmutable();
124 
125     /** Return the optional URI string associated with this pixelref. May be
126         null.
127     */
getURI()128     const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
129 
130     /** Copy a URI string to this pixelref, or clear the URI if the uri is null
131      */
setURI(const char uri[])132     void setURI(const char uri[]) {
133         fURI.set(uri);
134     }
135 
136     /** Copy a URI string to this pixelref
137      */
setURI(const char uri[],size_t len)138     void setURI(const char uri[], size_t len) {
139         fURI.set(uri, len);
140     }
141 
142     /** Assign a URI string to this pixelref.
143     */
setURI(const SkString & uri)144     void setURI(const SkString& uri) { fURI = uri; }
145 
146     /**
147      *  If the pixelRef has an encoded (i.e. compressed) representation,
148      *  return a ref to its data. If the pixelRef
149      *  is uncompressed or otherwise does not have this form, return NULL.
150      *
151      *  If non-null is returned, the caller is responsible for calling unref()
152      *  on the data when it is finished.
153      */
refEncodedData()154     SkData* refEncodedData() {
155         return this->onRefEncodedData();
156     }
157 
158     /**
159      *  Experimental -- tells the caller if it is worth it to call decodeInto().
160      *  Just an optimization at this point, to avoid checking the cache first.
161      *  We may remove/change this call in the future.
162      */
implementsDecodeInto()163     bool implementsDecodeInto() {
164         return this->onImplementsDecodeInto();
165     }
166 
167     /**
168      *  Return a decoded instance of this pixelRef in bitmap. If this cannot be
169      *  done, return false and the bitmap parameter is ignored/unchanged.
170      *
171      *  pow2 is the requeste power-of-two downscale that the caller needs. This
172      *  can be ignored, and the "original" size can be returned, but if the
173      *  underlying codec can efficiently return a smaller size, that should be
174      *  done. Some examples:
175      *
176      *  To request the "base" version (original scale), pass 0 for pow2
177      *  To request 1/2 scale version (1/2 width, 1/2 height), pass 1 for pow2
178      *  To request 1/4 scale version (1/4 width, 1/4 height), pass 2 for pow2
179      *  ...
180      *
181      *  If this returns true, then bitmap must be "locked" such that
182      *  bitmap->getPixels() will return the correct address.
183      */
decodeInto(int pow2,SkBitmap * bitmap)184     bool decodeInto(int pow2, SkBitmap* bitmap) {
185         SkASSERT(pow2 >= 0);
186         return this->onDecodeInto(pow2, bitmap);
187     }
188 
189     /** Are we really wrapping a texture instead of a bitmap?
190      */
getTexture()191     virtual GrTexture* getTexture() { return NULL; }
192 
193     bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
194 
195     /**
196      *  Makes a deep copy of this PixelRef, respecting the requested config.
197      *  @param config Desired config.
198      *  @param subset Subset of this PixelRef to copy. Must be fully contained within the bounds of
199      *         of this PixelRef.
200      *  @return A new SkPixelRef, or NULL if either there is an error (e.g. the destination could
201      *          not be created with the given config), or this PixelRef does not support deep
202      *          copies.
203      */
204     virtual SkPixelRef* deepCopy(SkBitmap::Config config, const SkIRect* subset = NULL) {
205         return NULL;
206     }
207 
208 #ifdef SK_BUILD_FOR_ANDROID
209     /**
210      *  Acquire a "global" ref on this object.
211      *  The default implementation just calls ref(), but subclasses can override
212      *  this method to implement additional behavior.
213      */
214     virtual void globalRef(void* data=NULL);
215 
216     /**
217      *  Release a "global" ref on this object.
218      *  The default implementation just calls unref(), but subclasses can override
219      *  this method to implement additional behavior.
220      */
221     virtual void globalUnref();
222 #endif
223 
224     SK_DEFINE_FLATTENABLE_TYPE(SkPixelRef)
225 
226     // Register a listener that may be called the next time our generation ID changes.
227     //
228     // We'll only call the listener if we're confident that we are the only SkPixelRef with this
229     // generation ID.  If our generation ID changes and we decide not to call the listener, we'll
230     // never call it: you must add a new listener for each generation ID change.  We also won't call
231     // the listener when we're certain no one knows what our generation ID is.
232     //
233     // This can be used to invalidate caches keyed by SkPixelRef generation ID.
234     struct GenIDChangeListener {
~GenIDChangeListenerGenIDChangeListener235         virtual ~GenIDChangeListener() {}
236         virtual void onChange() = 0;
237     };
238 
239     // Takes ownership of listener.
240     void addGenIDChangeListener(GenIDChangeListener* listener);
241 
242 protected:
243     /** Called when the lockCount goes from 0 to 1. The caller will have already
244         acquire a mutex for thread safety, so this method need not do that.
245     */
246     virtual void* onLockPixels(SkColorTable**) = 0;
247 
248     /**
249      *  Called when the lock count goes from 1 to 0. The caller will have
250      *  already acquire a mutex for thread safety, so this method need not do
251      *  that.
252      *
253      *  If the previous call to onLockPixels failed (i.e. returned NULL), then
254      *  the onUnlockPixels will NOT be called.
255      */
256     virtual void onUnlockPixels() = 0;
257 
258     /** Default impl returns true */
259     virtual bool onLockPixelsAreWritable() const;
260 
261     // returns false;
262     virtual bool onImplementsDecodeInto();
263     // returns false;
264     virtual bool onDecodeInto(int pow2, SkBitmap* bitmap);
265 
266     /**
267      *  For pixelrefs that don't have access to their raw pixels, they may be
268      *  able to make a copy of them (e.g. if the pixels are on the GPU).
269      *
270      *  The base class implementation returns false;
271      */
272     virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
273 
274     // default impl returns NULL.
275     virtual SkData* onRefEncodedData();
276 
277     /**
278      *  Returns the size (in bytes) of the internally allocated memory.
279      *  This should be implemented in all serializable SkPixelRef derived classes.
280      *  SkBitmap::fPixelRefOffset + SkBitmap::getSafeSize() should never overflow this value,
281      *  otherwise the rendering code may attempt to read memory out of bounds.
282      *
283      *  @return default impl returns 0.
284      */
285     virtual size_t getAllocatedSizeInBytes() const;
286 
287     /** Return the mutex associated with this pixelref. This value is assigned
288         in the constructor, and cannot change during the lifetime of the object.
289     */
mutex()290     SkBaseMutex* mutex() const { return fMutex; }
291 
292     // serialization
293     SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*);
294     virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
295 
296     // only call from constructor. Flags this to always be locked, removing
297     // the need to grab the mutex and call onLockPixels/onUnlockPixels.
298     // Performance tweak to avoid those calls (esp. in multi-thread use case).
299     void setPreLocked(void* pixels, SkColorTable* ctable);
300 
301 private:
302     SkBaseMutex*    fMutex; // must remain in scope for the life of this object
303     // FIXME: fInfo should be const once we remove old constructor that does
304     // not set it.
305     SkImageInfo     fInfo;
306 
307     void*           fPixels;
308     SkColorTable*   fColorTable;    // we do not track ownership, subclass does
309     int             fLockCount;
310 
311     mutable uint32_t fGenerationID;
312     mutable bool     fUniqueGenerationID;
313 
314     SkTDArray<GenIDChangeListener*> fGenIDChangeListeners;  // pointers are owned
315 
316     SkString    fURI;
317 
318     // can go from false to true, but never from true to false
319     bool    fIsImmutable;
320     // only ever set in constructor, const after that
321     bool    fPreLocked;
322 
323     void needsNewGenID();
324     void callGenIDChangeListeners();
325 
326     void setMutex(SkBaseMutex* mutex);
327 
328     // When copying a bitmap to another with the same shape and config, we can safely
329     // clone the pixelref generation ID too, which makes them equivalent under caching.
330     friend class SkBitmap;  // only for cloneGenID
331     void cloneGenID(const SkPixelRef&);
332 
333     typedef SkFlattenable INHERITED;
334 };
335 
336 #endif
337