Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SkPixelRef_DEFINED
     18 #define SkPixelRef_DEFINED
     19 
     20 #include "SkRefCnt.h"
     21 #include "SkString.h"
     22 
     23 class SkColorTable;
     24 class SkMutex;
     25 class SkFlattenableReadBuffer;
     26 class SkFlattenableWriteBuffer;
     27 
     28 /** \class SkPixelRef
     29 
     30     This class is the smart container for pixel memory, and is used with
     31     SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
     32     access the actual pixel memory by calling lockPixels/unlockPixels.
     33 
     34     This class can be shared/accessed between multiple threads.
     35 */
     36 class SkPixelRef : public SkRefCnt {
     37 public:
     38     explicit SkPixelRef(SkMutex* mutex = NULL);
     39 
     40     /** Return the pixel memory returned from lockPixels, or null if the
     41         lockCount is 0.
     42     */
     43     void* pixels() const { return fPixels; }
     44 
     45     /** Return the current colorTable (if any) if pixels are locked, or null.
     46     */
     47     SkColorTable* colorTable() const { return fColorTable; }
     48 
     49     /** Return the current lockcount (defaults to 0)
     50     */
     51     int getLockCount() const { return fLockCount; }
     52 
     53     /** Call to access the pixel memory, which is returned. Balance with a call
     54         to unlockPixels().
     55     */
     56     void lockPixels();
     57     /** Call to balanace a previous call to lockPixels(). Returns the pixels
     58         (or null) after the unlock. NOTE: lock calls can be nested, but the
     59         matching number of unlock calls must be made in order to free the
     60         memory (if the subclass implements caching/deferred-decoding.)
     61     */
     62     void unlockPixels();
     63 
     64     /** Returns a non-zero, unique value corresponding to the pixels in this
     65         pixelref. Each time the pixels are changed (and notifyPixelsChanged is
     66         called), a different generation ID will be returned.
     67     */
     68     uint32_t getGenerationID() const;
     69 
     70     /** Call this if you have changed the contents of the pixels. This will in-
     71         turn cause a different generation ID value to be returned from
     72         getGenerationID().
     73     */
     74     void notifyPixelsChanged();
     75 
     76     /** Returns true if this pixelref is marked as immutable, meaning that the
     77         contents of its pixels will not change for the lifetime of the pixelref.
     78     */
     79     bool isImmutable() const { return fIsImmutable; }
     80 
     81     /** Marks this pixelref is immutable, meaning that the contents of its
     82         pixels will not change for the lifetime of the pixelref. This state can
     83         be set on a pixelref, but it cannot be cleared once it is set.
     84     */
     85     void setImmutable();
     86 
     87     /** Return the optional URI string associated with this pixelref. May be
     88         null.
     89     */
     90     const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
     91 
     92     /** Copy a URI string to this pixelref, or clear the URI if the uri is null
     93      */
     94     void setURI(const char uri[]) {
     95         fURI.set(uri);
     96     }
     97 
     98     /** Copy a URI string to this pixelref
     99      */
    100     void setURI(const char uri[], size_t len) {
    101         fURI.set(uri, len);
    102     }
    103 
    104     /** Assign a URI string to this pixelref.
    105     */
    106     void setURI(const SkString& uri) { fURI = uri; }
    107 
    108     // serialization
    109 
    110     typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
    111 
    112     virtual Factory getFactory() const { return NULL; }
    113     virtual void flatten(SkFlattenableWriteBuffer&) const;
    114 
    115     static Factory NameToFactory(const char name[]);
    116     static const char* FactoryToName(Factory);
    117     static void Register(const char name[], Factory);
    118 
    119     class Registrar {
    120     public:
    121         Registrar(const char name[], Factory factory) {
    122             SkPixelRef::Register(name, factory);
    123         }
    124     };
    125 
    126 protected:
    127     /** Called when the lockCount goes from 0 to 1. The caller will have already
    128         acquire a mutex for thread safety, so this method need not do that.
    129     */
    130     virtual void* onLockPixels(SkColorTable**) = 0;
    131     /** Called when the lock count goes from 1 to 0. The caller will have
    132         already acquire a mutex for thread safety, so this method need not do
    133         that.
    134     */
    135     virtual void onUnlockPixels() = 0;
    136 
    137     /** Return the mutex associated with this pixelref. This value is assigned
    138         in the constructor, and cannot change during the lifetime of the object.
    139     */
    140     SkMutex* mutex() const { return fMutex; }
    141 
    142     SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
    143 
    144 private:
    145     SkMutex*        fMutex; // must remain in scope for the life of this object
    146     void*           fPixels;
    147     SkColorTable*   fColorTable;    // we do not track ownership, subclass does
    148     int             fLockCount;
    149 
    150     mutable uint32_t fGenerationID;
    151 
    152     SkString    fURI;
    153 
    154     // can go from false to true, but never from true to false
    155     bool    fIsImmutable;
    156 };
    157 
    158 #endif
    159