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 #include "SkFlattenable.h" 17 #include "SkTDArray.h" 18 19 //#define SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR 20 21 #ifdef SK_DEBUG 22 /** 23 * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref 24 * subclasses to correctly handle lock/unlock pixels. For performance 25 * reasons, simple malloc-based subclasses call setPreLocked() to skip 26 * the overhead of implementing these calls. 27 * 28 * This build-flag disables that optimization, to add in debugging our 29 * call-sites, to ensure that they correctly balance their calls of 30 * lock and unlock. 31 */ 32 // #define SK_IGNORE_PIXELREF_SETPRELOCKED 33 #endif 34 35 class SkColorTable; 36 class SkData; 37 struct SkIRect; 38 class SkMutex; 39 40 class GrTexture; 41 42 /** \class SkPixelRef 43 44 This class is the smart container for pixel memory, and is used with 45 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can 46 access the actual pixel memory by calling lockPixels/unlockPixels. 47 48 This class can be shared/accessed between multiple threads. 49 */ 50 class SK_API SkPixelRef : public SkFlattenable { 51 public: 52 SK_DECLARE_INST_COUNT(SkPixelRef) 53 54 #ifdef SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR 55 // DEPRECATED -- use a constructor that takes SkImageInfo 56 explicit SkPixelRef(SkBaseMutex* mutex = NULL); 57 #endif 58 59 explicit SkPixelRef(const SkImageInfo&); 60 SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex); 61 virtual ~SkPixelRef(); 62 63 const SkImageInfo& info() const { 64 return fInfo; 65 } 66 67 /** Return the pixel memory returned from lockPixels, or null if the 68 lockCount is 0. 69 */ 70 void* pixels() const { return fPixels; } 71 72 /** Return the current colorTable (if any) if pixels are locked, or null. 73 */ 74 SkColorTable* colorTable() const { return fColorTable; } 75 76 /** 77 * Returns true if the lockcount > 0 78 */ 79 bool isLocked() const { return fLockCount > 0; } 80 81 SkDEBUGCODE(int getLockCount() const { return fLockCount; }) 82 83 /** Call to access the pixel memory, which is returned. Balance with a call 84 to unlockPixels(). 85 */ 86 void lockPixels(); 87 /** Call to balanace a previous call to lockPixels(). Returns the pixels 88 (or null) after the unlock. NOTE: lock calls can be nested, but the 89 matching number of unlock calls must be made in order to free the 90 memory (if the subclass implements caching/deferred-decoding.) 91 */ 92 void unlockPixels(); 93 94 /** 95 * Some bitmaps can return a copy of their pixels for lockPixels(), but 96 * that copy, if modified, will not be pushed back. These bitmaps should 97 * not be used as targets for a raster device/canvas (since all pixels 98 * modifications will be lost when unlockPixels() is called.) 99 */ 100 bool lockPixelsAreWritable() const; 101 102 /** Returns a non-zero, unique value corresponding to the pixels in this 103 pixelref. Each time the pixels are changed (and notifyPixelsChanged is 104 called), a different generation ID will be returned. 105 */ 106 uint32_t getGenerationID() const; 107 108 /** Call this if you have changed the contents of the pixels. This will in- 109 turn cause a different generation ID value to be returned from 110 getGenerationID(). 111 */ 112 void notifyPixelsChanged(); 113 114 /** Returns true if this pixelref is marked as immutable, meaning that the 115 contents of its pixels will not change for the lifetime of the pixelref. 116 */ 117 bool isImmutable() const { return fIsImmutable; } 118 119 /** Marks this pixelref is immutable, meaning that the contents of its 120 pixels will not change for the lifetime of the pixelref. This state can 121 be set on a pixelref, but it cannot be cleared once it is set. 122 */ 123 void setImmutable(); 124 125 /** Return the optional URI string associated with this pixelref. May be 126 null. 127 */ 128 const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; } 129 130 /** Copy a URI string to this pixelref, or clear the URI if the uri is null 131 */ 132 void setURI(const char uri[]) { 133 fURI.set(uri); 134 } 135 136 /** Copy a URI string to this pixelref 137 */ 138 void setURI(const char uri[], size_t len) { 139 fURI.set(uri, len); 140 } 141 142 /** Assign a URI string to this pixelref. 143 */ 144 void setURI(const SkString& uri) { fURI = uri; } 145 146 /** 147 * If the pixelRef has an encoded (i.e. compressed) representation, 148 * return a ref to its data. If the pixelRef 149 * is uncompressed or otherwise does not have this form, return NULL. 150 * 151 * If non-null is returned, the caller is responsible for calling unref() 152 * on the data when it is finished. 153 */ 154 SkData* refEncodedData() { 155 return this->onRefEncodedData(); 156 } 157 158 /** 159 * Experimental -- tells the caller if it is worth it to call decodeInto(). 160 * Just an optimization at this point, to avoid checking the cache first. 161 * We may remove/change this call in the future. 162 */ 163 bool implementsDecodeInto() { 164 return this->onImplementsDecodeInto(); 165 } 166 167 /** 168 * Return a decoded instance of this pixelRef in bitmap. If this cannot be 169 * done, return false and the bitmap parameter is ignored/unchanged. 170 * 171 * pow2 is the requeste power-of-two downscale that the caller needs. This 172 * can be ignored, and the "original" size can be returned, but if the 173 * underlying codec can efficiently return a smaller size, that should be 174 * done. Some examples: 175 * 176 * To request the "base" version (original scale), pass 0 for pow2 177 * To request 1/2 scale version (1/2 width, 1/2 height), pass 1 for pow2 178 * To request 1/4 scale version (1/4 width, 1/4 height), pass 2 for pow2 179 * ... 180 * 181 * If this returns true, then bitmap must be "locked" such that 182 * bitmap->getPixels() will return the correct address. 183 */ 184 bool decodeInto(int pow2, SkBitmap* bitmap) { 185 SkASSERT(pow2 >= 0); 186 return this->onDecodeInto(pow2, bitmap); 187 } 188 189 /** Are we really wrapping a texture instead of a bitmap? 190 */ 191 virtual GrTexture* getTexture() { return NULL; } 192 193 bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL); 194 195 /** 196 * Makes a deep copy of this PixelRef, respecting the requested config. 197 * @param config Desired config. 198 * @param subset Subset of this PixelRef to copy. Must be fully contained within the bounds of 199 * of this PixelRef. 200 * @return A new SkPixelRef, or NULL if either there is an error (e.g. the destination could 201 * not be created with the given config), or this PixelRef does not support deep 202 * copies. 203 */ 204 virtual SkPixelRef* deepCopy(SkBitmap::Config config, const SkIRect* subset = NULL) { 205 return NULL; 206 } 207 208 #ifdef SK_BUILD_FOR_ANDROID 209 /** 210 * Acquire a "global" ref on this object. 211 * The default implementation just calls ref(), but subclasses can override 212 * this method to implement additional behavior. 213 */ 214 virtual void globalRef(void* data=NULL); 215 216 /** 217 * Release a "global" ref on this object. 218 * The default implementation just calls unref(), but subclasses can override 219 * this method to implement additional behavior. 220 */ 221 virtual void globalUnref(); 222 #endif 223 224 SK_DEFINE_FLATTENABLE_TYPE(SkPixelRef) 225 226 // Register a listener that may be called the next time our generation ID changes. 227 // 228 // We'll only call the listener if we're confident that we are the only SkPixelRef with this 229 // generation ID. If our generation ID changes and we decide not to call the listener, we'll 230 // never call it: you must add a new listener for each generation ID change. We also won't call 231 // the listener when we're certain no one knows what our generation ID is. 232 // 233 // This can be used to invalidate caches keyed by SkPixelRef generation ID. 234 struct GenIDChangeListener { 235 virtual ~GenIDChangeListener() {} 236 virtual void onChange() = 0; 237 }; 238 239 // Takes ownership of listener. 240 void addGenIDChangeListener(GenIDChangeListener* listener); 241 242 protected: 243 /** Called when the lockCount goes from 0 to 1. The caller will have already 244 acquire a mutex for thread safety, so this method need not do that. 245 */ 246 virtual void* onLockPixels(SkColorTable**) = 0; 247 248 /** 249 * Called when the lock count goes from 1 to 0. The caller will have 250 * already acquire a mutex for thread safety, so this method need not do 251 * that. 252 * 253 * If the previous call to onLockPixels failed (i.e. returned NULL), then 254 * the onUnlockPixels will NOT be called. 255 */ 256 virtual void onUnlockPixels() = 0; 257 258 /** Default impl returns true */ 259 virtual bool onLockPixelsAreWritable() const; 260 261 // returns false; 262 virtual bool onImplementsDecodeInto(); 263 // returns false; 264 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); 265 266 /** 267 * For pixelrefs that don't have access to their raw pixels, they may be 268 * able to make a copy of them (e.g. if the pixels are on the GPU). 269 * 270 * The base class implementation returns false; 271 */ 272 virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull); 273 274 // default impl returns NULL. 275 virtual SkData* onRefEncodedData(); 276 277 /** 278 * Returns the size (in bytes) of the internally allocated memory. 279 * This should be implemented in all serializable SkPixelRef derived classes. 280 * SkBitmap::fPixelRefOffset + SkBitmap::getSafeSize() should never overflow this value, 281 * otherwise the rendering code may attempt to read memory out of bounds. 282 * 283 * @return default impl returns 0. 284 */ 285 virtual size_t getAllocatedSizeInBytes() const; 286 287 /** Return the mutex associated with this pixelref. This value is assigned 288 in the constructor, and cannot change during the lifetime of the object. 289 */ 290 SkBaseMutex* mutex() const { return fMutex; } 291 292 // serialization 293 SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); 294 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; 295 296 // only call from constructor. Flags this to always be locked, removing 297 // the need to grab the mutex and call onLockPixels/onUnlockPixels. 298 // Performance tweak to avoid those calls (esp. in multi-thread use case). 299 void setPreLocked(void* pixels, SkColorTable* ctable); 300 301 private: 302 SkBaseMutex* fMutex; // must remain in scope for the life of this object 303 // FIXME: fInfo should be const once we remove old constructor that does 304 // not set it. 305 SkImageInfo fInfo; 306 307 void* fPixels; 308 SkColorTable* fColorTable; // we do not track ownership, subclass does 309 int fLockCount; 310 311 mutable uint32_t fGenerationID; 312 mutable bool fUniqueGenerationID; 313 314 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owned 315 316 SkString fURI; 317 318 // can go from false to true, but never from true to false 319 bool fIsImmutable; 320 // only ever set in constructor, const after that 321 bool fPreLocked; 322 323 void needsNewGenID(); 324 void callGenIDChangeListeners(); 325 326 void setMutex(SkBaseMutex* mutex); 327 328 // When copying a bitmap to another with the same shape and config, we can safely 329 // clone the pixelref generation ID too, which makes them equivalent under caching. 330 friend class SkBitmap; // only for cloneGenID 331 void cloneGenID(const SkPixelRef&); 332 333 typedef SkFlattenable INHERITED; 334 }; 335 336 #endif 337