Add genID for SkBitmaps with raw pixels
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 14 Apr 2011 15:07:22 +0000 (15:07 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 14 Apr 2011 15:07:22 +0000 (15:07 +0000)
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
src/core/SkBitmap.cpp
src/core/SkPixelRef.cpp

index 349489e..0a8b11c 100644 (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
index c19e84d..3c179fb 100644 (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
     }
 }
 
index 9b12226..967a872 100644 (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() {