Skia
2DGraphicsLibrary
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkPixelRef.h
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 "../private/SkAtomics.h"
12 #include "../private/SkMutex.h"
13 #include "../private/SkTDArray.h"
14 #include "SkBitmap.h"
15 #include "SkFilterQuality.h"
16 #include "SkImageInfo.h"
17 #include "SkPixmap.h"
18 #include "SkRefCnt.h"
19 #include "SkSize.h"
20 #include "SkString.h"
21 #include "SkYUVSizeInfo.h"
22 
23 class SkColorTable;
24 class SkData;
25 struct SkIRect;
26 
27 class GrTexture;
28 class SkDiscardableMemory;
29 
38 class SK_API SkPixelRef : public SkRefCnt {
39 public:
40  explicit SkPixelRef(const SkImageInfo&);
41  virtual ~SkPixelRef();
42 
43  const SkImageInfo& info() const {
44  return fInfo;
45  }
46 
50  void* pixels() const { return fRec.fPixels; }
51 
54  SkColorTable* colorTable() const { return fRec.fColorTable; }
55 
56  size_t rowBytes() const { return fRec.fRowBytes; }
57 
62  struct LockRec {
63  LockRec() : fPixels(NULL), fColorTable(NULL) {}
64 
65  void* fPixels;
66  SkColorTable* fColorTable;
67  size_t fRowBytes;
68 
69  void zero() { sk_bzero(this, sizeof(*this)); }
70 
71  bool isZero() const {
72  return NULL == fPixels && NULL == fColorTable && 0 == fRowBytes;
73  }
74  };
75 
76  SkDEBUGCODE(bool isLocked() const { return fLockCount > 0; })
77  SkDEBUGCODE(int getLockCount() const { return fLockCount; })
78 
83  bool lockPixels();
84 
90  bool lockPixels(LockRec* rec);
91 
97  void unlockPixels();
98 
105  bool lockPixelsAreWritable() const;
106 
111  uint32_t getGenerationID() const;
112 
113 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
114 
122  uint32_t getStableID() const { return fStableID; }
123 #endif
124 
130  void notifyPixelsChanged();
131 
137  void changeAlphaType(SkAlphaType at);
138 
142  bool isImmutable() const { return fMutability != kMutable; }
143 
148  void setImmutable();
149 
153  const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
154 
157  void setURI(const char uri[]) {
158  fURI.set(uri);
159  }
160 
163  void setURI(const char uri[], size_t len) {
164  fURI.set(uri, len);
165  }
166 
169  void setURI(const SkString& uri) { fURI = uri; }
170 
180  return this->onRefEncodedData();
181  }
182 
183  struct LockRequest {
184  SkISize fSize;
185  SkFilterQuality fQuality;
186  };
187 
188  struct LockResult {
189  LockResult() : fPixels(NULL), fCTable(NULL) {}
190 
191  void (*fUnlockProc)(void* ctx);
192  void* fUnlockContext;
193 
194  const void* fPixels;
195  SkColorTable* fCTable; // should be NULL unless colortype is kIndex8
196  size_t fRowBytes;
197  SkISize fSize;
198 
199  void unlock() {
200  if (fUnlockProc) {
201  fUnlockProc(fUnlockContext);
202  fUnlockProc = NULL; // can't unlock twice!
203  }
204  }
205  };
206 
207  bool requestLock(const LockRequest&, LockResult*);
208 
217  bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const {
218  return this->onQueryYUV8(sizeInfo, colorSpace);
219  }
220 
230  bool getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) {
231  return this->onGetYUV8Planes(sizeInfo, planes);
232  }
233 
235  bool readPixels(SkBitmap* dst, SkColorType colorType, const SkIRect* subset = NULL);
236 
237  // Register a listener that may be called the next time our generation ID changes.
238  //
239  // We'll only call the listener if we're confident that we are the only SkPixelRef with this
240  // generation ID. If our generation ID changes and we decide not to call the listener, we'll
241  // never call it: you must add a new listener for each generation ID change. We also won't call
242  // the listener when we're certain no one knows what our generation ID is.
243  //
244  // This can be used to invalidate caches keyed by SkPixelRef generation ID.
246  virtual ~GenIDChangeListener() {}
247  virtual void onChange() = 0;
248  };
249 
250  // Takes ownership of listener.
251  void addGenIDChangeListener(GenIDChangeListener* listener);
252 
253  // Call when this pixelref is part of the key to a resourcecache entry. This allows the cache
254  // to know automatically those entries can be purged when this pixelref is changed or deleted.
255  void notifyAddedToCache() {
256  fAddedToCache.store(true);
257  }
258 
259  virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return NULL; }
260 
264  bool isLazyGenerated() const { return this->onIsLazyGenerated(); }
265 
266 protected:
274  virtual bool onNewLockPixels(LockRec*) = 0;
275 
284  virtual void onUnlockPixels() = 0;
285 
287  virtual bool onLockPixelsAreWritable() const;
288 
295  virtual bool onReadPixels(SkBitmap* dst, SkColorType colorType, const SkIRect* subsetOrNull);
296 
297  // default impl returns NULL.
298  virtual SkData* onRefEncodedData();
299 
300  // default impl does nothing.
301  virtual void onNotifyPixelsChanged();
302 
303  virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const {
304  return false;
305  }
306  virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) {
307  return false;
308  }
309 
318  virtual size_t getAllocatedSizeInBytes() const;
319 
320  virtual bool onRequestLock(const LockRequest&, LockResult*);
321 
322  virtual bool onIsLazyGenerated() const { return false; }
323 
327  SkBaseMutex* mutex() const { return &fMutex; }
328 
329  // only call from constructor. Flags this to always be locked, removing
330  // the need to grab the mutex and call onLockPixels/onUnlockPixels.
331  // Performance tweak to avoid those calls (esp. in multi-thread use case).
332  void setPreLocked(void*, size_t rowBytes, SkColorTable*);
333 
334 private:
335  mutable SkMutex fMutex;
336 
337  // mostly const. fInfo.fAlpahType can be changed at runtime.
338  const SkImageInfo fInfo;
339 
340  // LockRec is only valid if we're in a locked state (isLocked())
341  LockRec fRec;
342  int fLockCount;
343 
344  bool lockPixelsInsideMutex();
345 
346  // Bottom bit indicates the Gen ID is unique.
347  bool genIDIsUnique() const { return SkToBool(fTaggedGenID.load() & 1); }
348  mutable SkAtomic<uint32_t> fTaggedGenID;
349 
350 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
351  const uint32_t fStableID;
352 #endif
353 
354  SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owned
355 
356  SkString fURI;
357 
358  // Set true by caches when they cache content that's derived from the current pixels.
359  SkAtomic<bool> fAddedToCache;
360 
361  enum {
362  kMutable, // PixelRefs begin mutable.
363  kTemporarilyImmutable, // Considered immutable, but can revert to mutable.
364  kImmutable, // Once set to this state, it never leaves.
365  } fMutability : 8; // easily fits inside a byte
366 
367  // only ever set in constructor, const after that
368  bool fPreLocked;
369 
370  void needsNewGenID();
371  void callGenIDChangeListeners();
372 
373  void setTemporarilyImmutable();
374  void restoreMutability();
375  friend class SkSurface_Raster; // For the two methods above.
376 
377  bool isPreLocked() const { return fPreLocked; }
378  friend class SkImage_Raster;
379  friend class SkSpecialImage_Raster;
380 
381  // When copying a bitmap to another with the same shape and config, we can safely
382  // clone the pixelref generation ID too, which makes them equivalent under caching.
383  friend class SkBitmap; // only for cloneGenID
384  void cloneGenID(const SkPixelRef&);
385 
386  void setImmutableWithID(uint32_t genID);
387  friend class SkImage_Gpu;
388  friend class SkImageCacherator;
389  friend class SkSpecialImage_Gpu;
390 
391  typedef SkRefCnt INHERITED;
392 };
393 
394 class SkPixelRefFactory : public SkRefCnt {
395 public:
402  virtual SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) = 0;
403 };
404 
405 #endif
Definition: SkPixelRef.h:183
void setURI(const char uri[], size_t len)
Copy a URI string to this pixelref.
Definition: SkPixelRef.h:163
Describe an image's dimensions and pixel type.
Definition: SkImageInfo.h:181
virtual SkPixelRef * create(const SkImageInfo &, size_t rowBytes, SkColorTable *)=0
Allocate a new pixelref matching the specified ImageInfo, allocating the memory for the pixels...
SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by 8-bit bitmaps...
Definition: SkColorTable.h:25
SkColorTable * colorTable() const
Return the current colorTable (if any) if pixels are locked, or null.
Definition: SkPixelRef.h:54
bool isLazyGenerated() const
Returns true if the pixels are generated on-the-fly (when required).
Definition: SkPixelRef.h:264
Definition: SkRefCnt.h:135
void setURI(const char uri[])
Copy a URI string to this pixelref, or clear the URI if the uri is null.
Definition: SkPixelRef.h:157
SkBaseMutex * mutex() const
Return the mutex associated with this pixelref.
Definition: SkPixelRef.h:327
SkData holds an immutable data buffer.
Definition: SkData.h:22
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:287
bool queryYUV8(SkYUVSizeInfo *sizeInfo, SkYUVColorSpace *colorSpace) const
If this can efficiently return YUV data, this should return true.
Definition: SkPixelRef.h:217
void * pixels() const
Return the pixel memory returned from lockPixels, or null if the lockCount is 0.
Definition: SkPixelRef.h:50
The SkBitmap class specifies a raster bitmap.
Definition: SkBitmap.h:41
Definition: SkYUVSizeInfo.h:11
This class is the smart container for pixel memory, and is used with SkBitmap.
Definition: SkPixelRef.h:38
Definition: SkPixelRef.h:245
To access the actual pixels of a pixelref, it must be "locked".
Definition: SkPixelRef.h:62
bool isImmutable() const
Returns true if this pixelref is marked as immutable, meaning that the contents of its pixels will no...
Definition: SkPixelRef.h:142
void setURI(const SkString &uri)
Assign a URI string to this pixelref.
Definition: SkPixelRef.h:169
const char * getURI() const
Return the optional URI string associated with this pixelref.
Definition: SkPixelRef.h:153
Definition: SkPixelRef.h:394
SkIRect holds four 32 bit integer coordinates for a rectangle.
Definition: SkRect.h:20
Definition: SkPixelRef.h:188
Definition: GrTexture.h:19
SkData * refEncodedData()
If the pixelRef has an encoded (i.e.
Definition: SkPixelRef.h:179
Light weight class for managing strings.
Definition: SkString.h:121
bool getYUV8Planes(const SkYUVSizeInfo &sizeInfo, void *planes[3])
Returns true on success and false on failure.
Definition: SkPixelRef.h:230