Add genID for SkBitmaps with raw pixels
Review URL: http://codereview.appspot.com/4413047/
git-svn-id: http://skia.googlecode.com/svn/trunk@1125 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 349489e..0a8b11c 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -334,7 +334,7 @@
SkColorTable* getColorTable() const { return fColorTable; }
/** Returns a non-zero, unique value corresponding to the pixels in our
- pixelref, or 0 if we do not have a pixelref. Each time the pixels are
+ pixelref (or raw pixels set via setPixels). Each time the pixels are
changed (and notifyPixelsChanged is called), a different generation ID
will be returned.
*/
@@ -551,6 +551,10 @@
// or a cache of the returned value from fPixelRef->lockPixels()
mutable void* fPixels;
mutable SkColorTable* fColorTable; // only meaningful for kIndex8
+ // When there is no pixel ref (setPixels was called) we still need a
+ // gen id for SkDevice implementations that may cache a copy of the
+ // pixels (e.g. as a gpu texture)
+ mutable int fRawPixelGenerationID;
enum Flags {
kImageIsOpaque_Flag = 0x01
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index c19e84d..3c179fb 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -27,6 +27,8 @@
#include "SkPackBits.h"
#include <new>
+extern int32_t SkNextPixelRefGenerationID();
+
static bool isPos32Bits(const Sk64& value) {
return !value.isNeg() && value.is32();
}
@@ -122,6 +124,12 @@
// ignore the values from the memcpy
fPixels = NULL;
fColorTable = NULL;
+ // Note that what to for genID is somewhat arbitrary. We have no
+ // way to track changes to raw pixels across multiple SkBitmaps.
+ // Would benefit from an SkRawPixelRef type created by
+ // setPixels.
+ // Just leave the memcpy'ed one but they'll get out of sync
+ // as soon either is modified.
}
}
@@ -130,18 +138,19 @@
}
void SkBitmap::swap(SkBitmap& other) {
- SkTSwap<SkColorTable*>(fColorTable, other.fColorTable);
- SkTSwap<SkPixelRef*>(fPixelRef, other.fPixelRef);
- SkTSwap<size_t>(fPixelRefOffset, other.fPixelRefOffset);
- SkTSwap<int>(fPixelLockCount, other.fPixelLockCount);
- SkTSwap<MipMap*>(fMipMap, other.fMipMap);
- SkTSwap<void*>(fPixels, other.fPixels);
- SkTSwap<uint32_t>(fRowBytes, other.fRowBytes);
- SkTSwap<uint32_t>(fWidth, other.fWidth);
- SkTSwap<uint32_t>(fHeight, other.fHeight);
- SkTSwap<uint8_t>(fConfig, other.fConfig);
- SkTSwap<uint8_t>(fFlags, other.fFlags);
- SkTSwap<uint8_t>(fBytesPerPixel, other.fBytesPerPixel);
+ SkTSwap(fColorTable, other.fColorTable);
+ SkTSwap(fPixelRef, other.fPixelRef);
+ SkTSwap(fPixelRefOffset, other.fPixelRefOffset);
+ SkTSwap(fPixelLockCount, other.fPixelLockCount);
+ SkTSwap(fMipMap, other.fMipMap);
+ SkTSwap(fPixels, other.fPixels);
+ SkTSwap(fRawPixelGenerationID, other.fRawPixelGenerationID);
+ SkTSwap(fRowBytes, other.fRowBytes);
+ SkTSwap(fWidth, other.fWidth);
+ SkTSwap(fHeight, other.fHeight);
+ SkTSwap(fConfig, other.fConfig);
+ SkTSwap(fFlags, other.fFlags);
+ SkTSwap(fBytesPerPixel, other.fBytesPerPixel);
SkDEBUGCODE(this->validate();)
}
@@ -387,12 +396,22 @@
}
uint32_t SkBitmap::getGenerationID() const {
- return fPixelRef ? fPixelRef->getGenerationID() : 0;
+ if (fPixelRef) {
+ return fPixelRef->getGenerationID();
+ } else {
+ SkASSERT(fPixels || !fRawPixelGenerationID);
+ if (fPixels && !fRawPixelGenerationID) {
+ fRawPixelGenerationID = SkNextPixelRefGenerationID();
+ }
+ return fRawPixelGenerationID;
+ }
}
void SkBitmap::notifyPixelsChanged() const {
if (fPixelRef) {
fPixelRef->notifyPixelsChanged();
+ } else {
+ fRawPixelGenerationID = 0; // will grab next ID in getGenerationID
}
}
diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp
index 9b12226..967a872 100644
--- a/src/core/SkPixelRef.cpp
+++ b/src/core/SkPixelRef.cpp
@@ -3,7 +3,18 @@
#include "SkThread.h"
static SkMutex gPixelRefMutex;
-static int32_t gPixelRefGenerationID;
+
+extern int32_t SkNextPixelRefGenerationID() {
+ static int32_t gPixelRefGenerationID;
+ // do a loop in case our global wraps around, as we never want to
+ // return a 0
+ int32_t genID;
+ do {
+ genID = sk_atomic_inc(&gPixelRefGenerationID) + 1;
+ } while (0 == genID);
+ return genID;
+}
+
SkPixelRef::SkPixelRef(SkMutex* mutex) {
if (NULL == mutex) {
@@ -53,16 +64,10 @@
}
uint32_t SkPixelRef::getGenerationID() const {
- uint32_t genID = fGenerationID;
- if (0 == genID) {
- // do a loop in case our global wraps around, as we never want to
- // return a 0
- do {
- genID = sk_atomic_inc(&gPixelRefGenerationID) + 1;
- } while (0 == genID);
- fGenerationID = genID;
+ if (0 == fGenerationID) {
+ fGenerationID = SkNextPixelRefGenerationID();
}
- return genID;
+ return fGenerationID;
}
void SkPixelRef::notifyPixelsChanged() {