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
This commit is contained in:
bsalomon@google.com 2011-04-14 15:07:22 +00:00
parent f5848e49ae
commit 586f48cfa8
3 changed files with 52 additions and 24 deletions

View File

@ -334,7 +334,7 @@ public:
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 @@ private:
// 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

View File

@ -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 @@ SkBitmap& SkBitmap::operator=(const SkBitmap& src) {
// 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 @@ SkBitmap& SkBitmap::operator=(const SkBitmap& src) {
}
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 @@ void SkBitmap::freeMipMap() {
}
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
}
}

View File

@ -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 @@ void SkPixelRef::unlockPixels() {
}
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() {