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