blob: 17cf6b43912c9537b8e1884ad5052dc42169387f [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
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
reed@google.com50dfa012011-04-01 19:05:36 +000023class SkBitmap;
reed@android.com8a1c16f2008-12-17 15:59:43 +000024class SkColorTable;
reed@google.com50dfa012011-04-01 19:05:36 +000025struct SkIRect;
reed@android.com8a1c16f2008-12-17 15:59:43 +000026class SkMutex;
27class SkFlattenableReadBuffer;
28class SkFlattenableWriteBuffer;
29
reed@android.comce4e53a2010-09-09 16:01:26 +000030// this is an opaque class, not interpreted by skia
31class SkGpuTexture;
32
reed@android.com8a1c16f2008-12-17 15:59:43 +000033/** \class SkPixelRef
34
35 This class is the smart container for pixel memory, and is used with
36 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
37 access the actual pixel memory by calling lockPixels/unlockPixels.
38
39 This class can be shared/accessed between multiple threads.
40*/
41class SkPixelRef : public SkRefCnt {
42public:
43 explicit SkPixelRef(SkMutex* mutex = NULL);
reed@google.com93c5f9e2011-02-24 18:09:46 +000044
reed@android.com8a1c16f2008-12-17 15:59:43 +000045 /** Return the pixel memory returned from lockPixels, or null if the
46 lockCount is 0.
47 */
48 void* pixels() const { return fPixels; }
49
50 /** Return the current colorTable (if any) if pixels are locked, or null.
51 */
52 SkColorTable* colorTable() const { return fColorTable; }
53
54 /** Return the current lockcount (defaults to 0)
55 */
56 int getLockCount() const { return fLockCount; }
57
58 /** Call to access the pixel memory, which is returned. Balance with a call
59 to unlockPixels().
60 */
61 void lockPixels();
62 /** Call to balanace a previous call to lockPixels(). Returns the pixels
63 (or null) after the unlock. NOTE: lock calls can be nested, but the
64 matching number of unlock calls must be made in order to free the
65 memory (if the subclass implements caching/deferred-decoding.)
66 */
67 void unlockPixels();
reed@google.com93c5f9e2011-02-24 18:09:46 +000068
reed@google.com9c49bc32011-07-07 13:42:37 +000069 /**
70 * Some bitmaps can return a copy of their pixels for lockPixels(), but
71 * that copy, if modified, will not be pushed back. These bitmaps should
72 * not be used as targets for a raster device/canvas (since all pixels
73 * modifications will be lost when unlockPixels() is called.)
74 */
75 bool lockPixelsAreWritable() const;
76
reed@android.com8a1c16f2008-12-17 15:59:43 +000077 /** Returns a non-zero, unique value corresponding to the pixels in this
78 pixelref. Each time the pixels are changed (and notifyPixelsChanged is
79 called), a different generation ID will be returned.
80 */
81 uint32_t getGenerationID() const;
reed@google.com93c5f9e2011-02-24 18:09:46 +000082
reed@android.com8a1c16f2008-12-17 15:59:43 +000083 /** Call this if you have changed the contents of the pixels. This will in-
84 turn cause a different generation ID value to be returned from
85 getGenerationID().
86 */
87 void notifyPixelsChanged();
88
89 /** Returns true if this pixelref is marked as immutable, meaning that the
90 contents of its pixels will not change for the lifetime of the pixelref.
91 */
92 bool isImmutable() const { return fIsImmutable; }
reed@google.com93c5f9e2011-02-24 18:09:46 +000093
reed@android.com8a1c16f2008-12-17 15:59:43 +000094 /** Marks this pixelref is immutable, meaning that the contents of its
95 pixels will not change for the lifetime of the pixelref. This state can
96 be set on a pixelref, but it cannot be cleared once it is set.
97 */
98 void setImmutable();
99
100 /** Return the optional URI string associated with this pixelref. May be
101 null.
102 */
103 const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
104
105 /** Copy a URI string to this pixelref, or clear the URI if the uri is null
106 */
107 void setURI(const char uri[]) {
108 fURI.set(uri);
109 }
reed@google.com93c5f9e2011-02-24 18:09:46 +0000110
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111 /** Copy a URI string to this pixelref
112 */
113 void setURI(const char uri[], size_t len) {
114 fURI.set(uri, len);
115 }
reed@google.com93c5f9e2011-02-24 18:09:46 +0000116
reed@android.com8a1c16f2008-12-17 15:59:43 +0000117 /** Assign a URI string to this pixelref.
118 */
119 void setURI(const SkString& uri) { fURI = uri; }
120
reed@android.comce4e53a2010-09-09 16:01:26 +0000121 /** Are we really wrapping a texture instead of a bitmap?
122 */
123 virtual SkGpuTexture* getTexture() { return NULL; }
124
reed@google.com50dfa012011-04-01 19:05:36 +0000125 bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
126
reed@android.com8a1c16f2008-12-17 15:59:43 +0000127 // serialization
128
129 typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
130
131 virtual Factory getFactory() const { return NULL; }
132 virtual void flatten(SkFlattenableWriteBuffer&) const;
133
reed@google.com93c5f9e2011-02-24 18:09:46 +0000134#ifdef ANDROID
135 /**
136 * Acquire a "global" ref on this object.
137 * The default implementation just calls ref(), but subclasses can override
138 * this method to implement additional behavior.
139 */
djsollen@google.com57f49692011-02-23 20:46:31 +0000140 virtual void globalRef(void* data=NULL);
141
reed@google.com93c5f9e2011-02-24 18:09:46 +0000142 /**
143 * Release a "global" ref on this object.
144 * The default implementation just calls unref(), but subclasses can override
145 * this method to implement additional behavior.
146 */
djsollen@google.com57f49692011-02-23 20:46:31 +0000147 virtual void globalUnref();
reed@google.com93c5f9e2011-02-24 18:09:46 +0000148#endif
djsollen@google.com57f49692011-02-23 20:46:31 +0000149
reed@android.com8a1c16f2008-12-17 15:59:43 +0000150 static Factory NameToFactory(const char name[]);
151 static const char* FactoryToName(Factory);
152 static void Register(const char name[], Factory);
reed@google.com93c5f9e2011-02-24 18:09:46 +0000153
reed@android.com8a1c16f2008-12-17 15:59:43 +0000154 class Registrar {
155 public:
156 Registrar(const char name[], Factory factory) {
157 SkPixelRef::Register(name, factory);
158 }
159 };
160
161protected:
162 /** Called when the lockCount goes from 0 to 1. The caller will have already
163 acquire a mutex for thread safety, so this method need not do that.
164 */
165 virtual void* onLockPixels(SkColorTable**) = 0;
166 /** Called when the lock count goes from 1 to 0. The caller will have
167 already acquire a mutex for thread safety, so this method need not do
168 that.
169 */
170 virtual void onUnlockPixels() = 0;
171
reed@google.com9c49bc32011-07-07 13:42:37 +0000172 /** Default impl returns true */
173 virtual bool onLockPixelsAreWritable() const;
174
reed@google.com50dfa012011-04-01 19:05:36 +0000175 /**
176 * For pixelrefs that don't have access to their raw pixels, they may be
177 * able to make a copy of them (e.g. if the pixels are on the GPU).
178 *
179 * The base class implementation returns false;
180 */
181 virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
182
reed@android.com8a1c16f2008-12-17 15:59:43 +0000183 /** Return the mutex associated with this pixelref. This value is assigned
184 in the constructor, and cannot change during the lifetime of the object.
185 */
186 SkMutex* mutex() const { return fMutex; }
187
188 SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
189
190private:
191 SkMutex* fMutex; // must remain in scope for the life of this object
192 void* fPixels;
193 SkColorTable* fColorTable; // we do not track ownership, subclass does
194 int fLockCount;
reed@google.com93c5f9e2011-02-24 18:09:46 +0000195
reed@android.com8a1c16f2008-12-17 15:59:43 +0000196 mutable uint32_t fGenerationID;
reed@google.com93c5f9e2011-02-24 18:09:46 +0000197
reed@android.com8a1c16f2008-12-17 15:59:43 +0000198 SkString fURI;
199
200 // can go from false to true, but never from true to false
201 bool fIsImmutable;
202};
203
204#endif