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