SkPixelRef.cpp revision 9c49bc3e643c435677727c1c0904c4a7cb7a6907
1#include "SkPixelRef.h" 2#include "SkFlattenable.h" 3#include "SkThread.h" 4 5static SkMutex gPixelRefMutex; 6 7extern int32_t SkNextPixelRefGenerationID(); 8int32_t SkNextPixelRefGenerationID() { 9 static int32_t gPixelRefGenerationID; 10 // do a loop in case our global wraps around, as we never want to 11 // return a 0 12 int32_t genID; 13 do { 14 genID = sk_atomic_inc(&gPixelRefGenerationID) + 1; 15 } while (0 == genID); 16 return genID; 17} 18 19 20SkPixelRef::SkPixelRef(SkMutex* mutex) { 21 if (NULL == mutex) { 22 mutex = &gPixelRefMutex; 23 } 24 fMutex = mutex; 25 fPixels = NULL; 26 fColorTable = NULL; // we do not track ownership of this 27 fLockCount = 0; 28 fGenerationID = 0; // signal to rebuild 29 fIsImmutable = false; 30} 31 32SkPixelRef::SkPixelRef(SkFlattenableReadBuffer& buffer, SkMutex* mutex) { 33 if (NULL == mutex) { 34 mutex = &gPixelRefMutex; 35 } 36 fMutex = mutex; 37 fPixels = NULL; 38 fColorTable = NULL; // we do not track ownership of this 39 fLockCount = 0; 40 fGenerationID = 0; // signal to rebuild 41 fIsImmutable = buffer.readBool(); 42} 43 44void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { 45 buffer.writeBool(fIsImmutable); 46} 47 48void SkPixelRef::lockPixels() { 49 SkAutoMutexAcquire ac(*fMutex); 50 51 if (1 == ++fLockCount) { 52 fPixels = this->onLockPixels(&fColorTable); 53 } 54} 55 56void SkPixelRef::unlockPixels() { 57 SkAutoMutexAcquire ac(*fMutex); 58 59 SkASSERT(fLockCount > 0); 60 if (0 == --fLockCount) { 61 this->onUnlockPixels(); 62 fPixels = NULL; 63 fColorTable = NULL; 64 } 65} 66 67bool SkPixelRef::lockPixelsAreWritable() const { 68 return this->onLockPixelsAreWritable(); 69} 70 71bool SkPixelRef::onLockPixelsAreWritable() const { 72 return true; 73} 74 75uint32_t SkPixelRef::getGenerationID() const { 76 if (0 == fGenerationID) { 77 fGenerationID = SkNextPixelRefGenerationID(); 78 } 79 return fGenerationID; 80} 81 82void SkPixelRef::notifyPixelsChanged() { 83#ifdef SK_DEBUG 84 if (fIsImmutable) { 85 SkDebugf("========== notifyPixelsChanged called on immutable pixelref"); 86 } 87#endif 88 // this signals us to recompute this next time around 89 fGenerationID = 0; 90} 91 92void SkPixelRef::setImmutable() { 93 fIsImmutable = true; 94} 95 96bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) { 97 return this->onReadPixels(dst, subset); 98} 99 100bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { 101 return false; 102} 103 104/////////////////////////////////////////////////////////////////////////////// 105 106#define MAX_PAIR_COUNT 16 107 108struct Pair { 109 const char* fName; 110 SkPixelRef::Factory fFactory; 111}; 112 113static int gCount; 114static Pair gPairs[MAX_PAIR_COUNT]; 115 116void SkPixelRef::Register(const char name[], Factory factory) { 117 SkASSERT(name); 118 SkASSERT(factory); 119 120 static bool gOnce; 121 if (!gOnce) { 122 gCount = 0; 123 gOnce = true; 124 } 125 126 SkASSERT(gCount < MAX_PAIR_COUNT); 127 128 gPairs[gCount].fName = name; 129 gPairs[gCount].fFactory = factory; 130 gCount += 1; 131} 132 133SkPixelRef::Factory SkPixelRef::NameToFactory(const char name[]) { 134 const Pair* pairs = gPairs; 135 for (int i = gCount - 1; i >= 0; --i) { 136 if (strcmp(pairs[i].fName, name) == 0) { 137 return pairs[i].fFactory; 138 } 139 } 140 return NULL; 141} 142 143const char* SkPixelRef::FactoryToName(Factory fact) { 144 const Pair* pairs = gPairs; 145 for (int i = gCount - 1; i >= 0; --i) { 146 if (pairs[i].fFactory == fact) { 147 return pairs[i].fName; 148 } 149 } 150 return NULL; 151} 152 153/////////////////////////////////////////////////////////////////////////////// 154 155#ifdef ANDROID 156void SkPixelRef::globalRef(void* data) { 157 this->ref(); 158} 159 160void SkPixelRef::globalUnref() { 161 this->unref(); 162} 163#endif 164