• 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 
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     */
pixels()60     void* pixels() const { return fPixels; }
61 
62     /** Return the current colorTable (if any) if pixels are locked, or null.
63     */
colorTable()64     SkColorTable* colorTable() const { return fColorTable; }
65 
66     /**
67      *  Returns true if the lockcount > 0
68      */
isLocked()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     */
isImmutable()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     */
getURI()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      */
setURI(const char uri[])120     void setURI(const char uri[]) {
121         fURI.set(uri);
122     }
123 
124     /** Copy a URI string to this pixelref
125      */
setURI(const char uri[],size_t len)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     */
setURI(const SkString & uri)132     void setURI(const SkString& uri) { fURI = uri; }
133 
134     /** Are we really wrapping a texture instead of a bitmap?
135      */
getTexture()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.  */
deepCopy(SkBitmap::Config config)144     virtual SkPixelRef* deepCopy(SkBitmap::Config config) { return NULL; }
145 
146     // serialization
147 
148     typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
149 
getFactory()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:
Registrar(const char name[],Factory factory)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     */
mutex()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.
useDefaultMutex()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