Home | History | Annotate | Download | only in core
      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 
     17 class SkColorTable;
     18 struct SkIRect;
     19 class SkMutex;
     20 class SkFlattenableReadBuffer;
     21 class SkFlattenableWriteBuffer;
     22 
     23 // this is an opaque class, not interpreted by skia
     24 class SkGpuTexture;
     25 
     26 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
     27 
     28 #define SK_DECLARE_PIXEL_REF_REGISTRAR()
     29 
     30 #define SK_DEFINE_PIXEL_REF_REGISTRAR(pixelRef) \
     31     static SkPixelRef::Registrar g##pixelRef##Reg(#pixelRef, \
     32                                                   pixelRef::Create);
     33 
     34 #else
     35 
     36 #define SK_DECLARE_PIXEL_REF_REGISTRAR() static void Init();
     37 
     38 #define SK_DEFINE_PIXEL_REF_REGISTRAR(pixelRef) \
     39     void pixelRef::Init() { \
     40         SkPixelRef::Registrar(#pixelRef, Create); \
     41     }
     42 
     43 #endif
     44 
     45 /** \class SkPixelRef
     46 
     47     This class is the smart container for pixel memory, and is used with
     48     SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
     49     access the actual pixel memory by calling lockPixels/unlockPixels.
     50 
     51     This class can be shared/accessed between multiple threads.
     52 */
     53 class SK_API SkPixelRef : public SkRefCnt {
     54 public:
     55     explicit SkPixelRef(SkBaseMutex* mutex = NULL);
     56 
     57     /** Return the pixel memory returned from lockPixels, or null if the
     58         lockCount is 0.
     59     */
     60     void* pixels() const { return fPixels; }
     61 
     62     /** Return the current colorTable (if any) if pixels are locked, or null.
     63     */
     64     SkColorTable* colorTable() const { return fColorTable; }
     65 
     66     /**
     67      *  Returns true if the lockcount > 0
     68      */
     69     bool isLocked() const { return fLockCount > 0; }
     70 
     71     /** Call to access the pixel memory, which is returned. Balance with a call
     72         to unlockPixels().
     73     */
     74     void lockPixels();
     75     /** Call to balanace a previous call to lockPixels(). Returns the pixels
     76         (or null) after the unlock. NOTE: lock calls can be nested, but the
     77         matching number of unlock calls must be made in order to free the
     78         memory (if the subclass implements caching/deferred-decoding.)
     79     */
     80     void unlockPixels();
     81 
     82     /**
     83      *  Some bitmaps can return a copy of their pixels for lockPixels(), but
     84      *  that copy, if modified, will not be pushed back. These bitmaps should
     85      *  not be used as targets for a raster device/canvas (since all pixels
     86      *  modifications will be lost when unlockPixels() is called.)
     87      */
     88     bool lockPixelsAreWritable() const;
     89 
     90     /** Returns a non-zero, unique value corresponding to the pixels in this
     91         pixelref. Each time the pixels are changed (and notifyPixelsChanged is
     92         called), a different generation ID will be returned.
     93     */
     94     uint32_t getGenerationID() const;
     95 
     96     /** Call this if you have changed the contents of the pixels. This will in-
     97         turn cause a different generation ID value to be returned from
     98         getGenerationID().
     99     */
    100     void notifyPixelsChanged();
    101 
    102     /** Returns true if this pixelref is marked as immutable, meaning that the
    103         contents of its pixels will not change for the lifetime of the pixelref.
    104     */
    105     bool isImmutable() const { return fIsImmutable; }
    106 
    107     /** Marks this pixelref is immutable, meaning that the contents of its
    108         pixels will not change for the lifetime of the pixelref. This state can
    109         be set on a pixelref, but it cannot be cleared once it is set.
    110     */
    111     void setImmutable();
    112 
    113     /** Return the optional URI string associated with this pixelref. May be
    114         null.
    115     */
    116     const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
    117 
    118     /** Copy a URI string to this pixelref, or clear the URI if the uri is null
    119      */
    120     void setURI(const char uri[]) {
    121         fURI.set(uri);
    122     }
    123 
    124     /** Copy a URI string to this pixelref
    125      */
    126     void setURI(const char uri[], size_t len) {
    127         fURI.set(uri, len);
    128     }
    129 
    130     /** Assign a URI string to this pixelref.
    131     */
    132     void setURI(const SkString& uri) { fURI = uri; }
    133 
    134     /** Are we really wrapping a texture instead of a bitmap?
    135      */
    136     virtual SkGpuTexture* getTexture() { return NULL; }
    137 
    138     bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
    139 
    140     /** Makes a deep copy of this PixelRef, respecting the requested config.
    141         Returns NULL if either there is an error (e.g. the destination could
    142         not be created with the given config), or this PixelRef does not
    143         support deep copies.  */
    144     virtual SkPixelRef* deepCopy(SkBitmap::Config config) { return NULL; }
    145 
    146     // serialization
    147 
    148     typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
    149 
    150     virtual Factory getFactory() const { return NULL; }
    151     virtual void flatten(SkFlattenableWriteBuffer&) const;
    152 
    153 #ifdef SK_BUILD_FOR_ANDROID
    154     /**
    155      *  Acquire a "global" ref on this object.
    156      *  The default implementation just calls ref(), but subclasses can override
    157      *  this method to implement additional behavior.
    158      */
    159     virtual void globalRef(void* data=NULL);
    160 
    161     /**
    162      *  Release a "global" ref on this object.
    163      *  The default implementation just calls unref(), but subclasses can override
    164      *  this method to implement additional behavior.
    165      */
    166     virtual void globalUnref();
    167 #endif
    168 
    169     static Factory NameToFactory(const char name[]);
    170     static const char* FactoryToName(Factory);
    171     static void Register(const char name[], Factory);
    172 
    173     class Registrar {
    174     public:
    175         Registrar(const char name[], Factory factory) {
    176             SkPixelRef::Register(name, factory);
    177         }
    178     };
    179 
    180 protected:
    181     /** Called when the lockCount goes from 0 to 1. The caller will have already
    182         acquire a mutex for thread safety, so this method need not do that.
    183     */
    184     virtual void* onLockPixels(SkColorTable**) = 0;
    185     /** Called when the lock count goes from 1 to 0. The caller will have
    186         already acquire a mutex for thread safety, so this method need not do
    187         that.
    188     */
    189     virtual void onUnlockPixels() = 0;
    190 
    191     /** Default impl returns true */
    192     virtual bool onLockPixelsAreWritable() const;
    193 
    194     /**
    195      *  For pixelrefs that don't have access to their raw pixels, they may be
    196      *  able to make a copy of them (e.g. if the pixels are on the GPU).
    197      *
    198      *  The base class implementation returns false;
    199      */
    200     virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
    201 
    202     /** Return the mutex associated with this pixelref. This value is assigned
    203         in the constructor, and cannot change during the lifetime of the object.
    204     */
    205     SkBaseMutex* mutex() const { return fMutex; }
    206 
    207     SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*);
    208 
    209     // only call from constructor. Flags this to always be locked, removing
    210     // the need to grab the mutex and call onLockPixels/onUnlockPixels.
    211     // Performance tweak to avoid those calls (esp. in multi-thread use case).
    212     void setPreLocked(void* pixels, SkColorTable* ctable);
    213 
    214     // only call from constructor. Specify a (possibly) different mutex, or
    215     // null to use the default. Use with caution.
    216     // The default logic is to provide a mutex, but possibly one that is
    217     // shared with other instances, though this sharing is implementation
    218     // specific, and it is legal for each instance to have its own mutex.
    219     void useDefaultMutex() { this->setMutex(NULL); }
    220 
    221 private:
    222 #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
    223     static void InitializeFlattenables();
    224 #endif
    225 
    226     SkBaseMutex*    fMutex; // must remain in scope for the life of this object
    227     void*           fPixels;
    228     SkColorTable*   fColorTable;    // we do not track ownership, subclass does
    229     int             fLockCount;
    230 
    231     mutable uint32_t fGenerationID;
    232 
    233     SkString    fURI;
    234 
    235     // can go from false to true, but never from true to false
    236     bool    fIsImmutable;
    237     // only ever set in constructor, const after that
    238     bool    fPreLocked;
    239 
    240     void setMutex(SkBaseMutex* mutex);
    241 
    242     friend class SkGraphics;
    243 };
    244 
    245 #endif
    246