From 586f48cfa8b1fa7b29d8ee8d0a028489a33866de Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Thu, 14 Apr 2011 15:07:22 +0000 Subject: [PATCH] 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 --- include/core/SkBitmap.h | 6 +++++- src/core/SkBitmap.cpp | 45 ++++++++++++++++++++++++++++++++------------- src/core/SkPixelRef.cpp | 25 +++++++++++++++---------- 3 files changed, 52 insertions(+), 24 deletions(-) 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 @@ 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 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 +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(fColorTable, other.fColorTable); - SkTSwap(fPixelRef, other.fPixelRef); - SkTSwap(fPixelRefOffset, other.fPixelRefOffset); - SkTSwap(fPixelLockCount, other.fPixelLockCount); - SkTSwap(fMipMap, other.fMipMap); - SkTSwap(fPixels, other.fPixels); - SkTSwap(fRowBytes, other.fRowBytes); - SkTSwap(fWidth, other.fWidth); - SkTSwap(fHeight, other.fHeight); - SkTSwap(fConfig, other.fConfig); - SkTSwap(fFlags, other.fFlags); - SkTSwap(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 } } 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 @@ 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() { -- 2.7.4