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 0 : class SkPixelRef : public SkRefCnt {
54 : public:
55 : explicit SkPixelRef(SkMutex* mutex = NULL);
56 :
57 : /** Return the pixel memory returned from lockPixels, or null if the
58 : lockCount is 0.
59 : */
60 0 : void* pixels() const { return fPixels; }
61 :
62 : /** Return the current colorTable (if any) if pixels are locked, or null.
63 : */
64 0 : SkColorTable* colorTable() const { return fColorTable; }
65 :
66 : /** Return the current lockcount (defaults to 0)
67 : */
68 0 : int getLockCount() const { return fLockCount; }
69 :
70 : /** Call to access the pixel memory, which is returned. Balance with a call
71 : to unlockPixels().
72 : */
73 : void lockPixels();
74 : /** Call to balanace a previous call to lockPixels(). Returns the pixels
75 : (or null) after the unlock. NOTE: lock calls can be nested, but the
76 : matching number of unlock calls must be made in order to free the
77 : memory (if the subclass implements caching/deferred-decoding.)
78 : */
79 : void unlockPixels();
80 :
81 : /**
82 : * Some bitmaps can return a copy of their pixels for lockPixels(), but
83 : * that copy, if modified, will not be pushed back. These bitmaps should
84 : * not be used as targets for a raster device/canvas (since all pixels
85 : * modifications will be lost when unlockPixels() is called.)
86 : */
87 : bool lockPixelsAreWritable() const;
88 :
89 : /** Returns a non-zero, unique value corresponding to the pixels in this
90 : pixelref. Each time the pixels are changed (and notifyPixelsChanged is
91 : called), a different generation ID will be returned.
92 : */
93 : uint32_t getGenerationID() const;
94 :
95 : /** Call this if you have changed the contents of the pixels. This will in-
96 : turn cause a different generation ID value to be returned from
97 : getGenerationID().
98 : */
99 : void notifyPixelsChanged();
100 :
101 : /** Returns true if this pixelref is marked as immutable, meaning that the
102 : contents of its pixels will not change for the lifetime of the pixelref.
103 : */
104 0 : bool isImmutable() const { return fIsImmutable; }
105 :
106 : /** Marks this pixelref is immutable, meaning that the contents of its
107 : pixels will not change for the lifetime of the pixelref. This state can
108 : be set on a pixelref, but it cannot be cleared once it is set.
109 : */
110 : void setImmutable();
111 :
112 : /** Return the optional URI string associated with this pixelref. May be
113 : null.
114 : */
115 0 : const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
116 :
117 : /** Copy a URI string to this pixelref, or clear the URI if the uri is null
118 : */
119 : void setURI(const char uri[]) {
120 : fURI.set(uri);
121 : }
122 :
123 : /** Copy a URI string to this pixelref
124 : */
125 : void setURI(const char uri[], size_t len) {
126 : fURI.set(uri, len);
127 : }
128 :
129 : /** Assign a URI string to this pixelref.
130 : */
131 : void setURI(const SkString& uri) { fURI = uri; }
132 :
133 : /** Are we really wrapping a texture instead of a bitmap?
134 : */
135 0 : virtual SkGpuTexture* getTexture() { return NULL; }
136 :
137 : bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
138 :
139 : /** Makes a deep copy of this PixelRef, respecting the requested config.
140 : Returns NULL if either there is an error (e.g. the destination could
141 : not be created with the given config), or this PixelRef does not
142 : support deep copies. */
143 0 : virtual SkPixelRef* deepCopy(SkBitmap::Config config) { return NULL; }
144 :
145 : // serialization
146 :
147 : typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
148 :
149 0 : virtual Factory getFactory() const { return NULL; }
150 : virtual void flatten(SkFlattenableWriteBuffer&) const;
151 :
152 : #ifdef SK_BUILD_FOR_ANDROID
153 : /**
154 : * Acquire a "global" ref on this object.
155 : * The default implementation just calls ref(), but subclasses can override
156 : * this method to implement additional behavior.
157 : */
158 : virtual void globalRef(void* data=NULL);
159 :
160 : /**
161 : * Release a "global" ref on this object.
162 : * The default implementation just calls unref(), but subclasses can override
163 : * this method to implement additional behavior.
164 : */
165 : virtual void globalUnref();
166 : #endif
167 :
168 : static Factory NameToFactory(const char name[]);
169 : static const char* FactoryToName(Factory);
170 : static void Register(const char name[], Factory);
171 :
172 : class Registrar {
173 : public:
174 1464 : Registrar(const char name[], Factory factory) {
175 1464 : SkPixelRef::Register(name, factory);
176 1464 : }
177 : };
178 :
179 : protected:
180 : /** Called when the lockCount goes from 0 to 1. The caller will have already
181 : acquire a mutex for thread safety, so this method need not do that.
182 : */
183 : virtual void* onLockPixels(SkColorTable**) = 0;
184 : /** Called when the lock count goes from 1 to 0. The caller will have
185 : already acquire a mutex for thread safety, so this method need not do
186 : that.
187 : */
188 : virtual void onUnlockPixels() = 0;
189 :
190 : /** Default impl returns true */
191 : virtual bool onLockPixelsAreWritable() const;
192 :
193 : /**
194 : * For pixelrefs that don't have access to their raw pixels, they may be
195 : * able to make a copy of them (e.g. if the pixels are on the GPU).
196 : *
197 : * The base class implementation returns false;
198 : */
199 : virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
200 :
201 : /** Return the mutex associated with this pixelref. This value is assigned
202 : in the constructor, and cannot change during the lifetime of the object.
203 : */
204 : SkMutex* mutex() const { return fMutex; }
205 :
206 : SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
207 :
208 : private:
209 : #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
210 : static void InitializeFlattenables();
211 : #endif
212 :
213 : SkMutex* fMutex; // must remain in scope for the life of this object
214 : void* fPixels;
215 : SkColorTable* fColorTable; // we do not track ownership, subclass does
216 : int fLockCount;
217 :
218 : mutable uint32_t fGenerationID;
219 :
220 : SkString fURI;
221 :
222 : // can go from false to true, but never from true to false
223 : bool fIsImmutable;
224 :
225 : friend class SkGraphics;
226 : };
227 :
228 : #endif
|