Home | History | Annotate | Download | only in core
      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 
     34 class SkColorTable;
     35 class SkData;
     36 struct SkIRect;
     37 class SkMutex;
     38 
     39 class 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 */
     49 class SK_API SkPixelRef : public SkFlattenable {
     50 public:
     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 
    282 protected:
    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 
    345 private:
    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 
    383 class SkPixelRefFactory : public SkRefCnt {
    384 public:
    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