1 #include "SkPixelRef.h" 2 #include "SkFlattenable.h" 3 #include "SkThread.h" 4 5 static SkMutex gPixelRefMutex; 6 static int32_t gPixelRefGenerationID; 7 8 SkPixelRef::SkPixelRef(SkMutex* mutex) { 9 if (NULL == mutex) { 10 mutex = &gPixelRefMutex; 11 } 12 fMutex = mutex; 13 fPixels = NULL; 14 fColorTable = NULL; // we do not track ownership of this 15 fLockCount = 0; 16 fGenerationID = 0; // signal to rebuild 17 fIsImmutable = false; 18 } 19 20 SkPixelRef::SkPixelRef(SkFlattenableReadBuffer& buffer, 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 = buffer.readBool(); 30 } 31 32 void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { 33 buffer.writeBool(fIsImmutable); 34 } 35 36 void SkPixelRef::lockPixels() { 37 SkAutoMutexAcquire ac(*fMutex); 38 39 if (1 == ++fLockCount) { 40 fPixels = this->onLockPixels(&fColorTable); 41 } 42 } 43 44 void SkPixelRef::unlockPixels() { 45 SkAutoMutexAcquire ac(*fMutex); 46 47 SkASSERT(fLockCount > 0); 48 if (0 == --fLockCount) { 49 this->onUnlockPixels(); 50 fPixels = NULL; 51 fColorTable = NULL; 52 } 53 } 54 55 uint32_t SkPixelRef::getGenerationID() const { 56 uint32_t genID = fGenerationID; 57 if (0 == genID) { 58 // do a loop in case our global wraps around, as we never want to 59 // return a 0 60 do { 61 genID = sk_atomic_inc(&gPixelRefGenerationID) + 1; 62 } while (0 == genID); 63 fGenerationID = genID; 64 } 65 return genID; 66 } 67 68 void SkPixelRef::notifyPixelsChanged() { 69 #ifdef SK_DEBUG 70 if (fIsImmutable) { 71 SkDebugf("========== notifyPixelsChanged called on immutable pixelref"); 72 } 73 #endif 74 // this signals us to recompute this next time around 75 fGenerationID = 0; 76 } 77 78 void SkPixelRef::setImmutable() { 79 fIsImmutable = true; 80 } 81 82 /////////////////////////////////////////////////////////////////////////////// 83 84 #define MAX_PAIR_COUNT 16 85 86 struct Pair { 87 const char* fName; 88 SkPixelRef::Factory fFactory; 89 }; 90 91 static int gCount; 92 static Pair gPairs[MAX_PAIR_COUNT]; 93 94 void SkPixelRef::Register(const char name[], Factory factory) { 95 SkASSERT(name); 96 SkASSERT(factory); 97 98 static bool gOnce; 99 if (!gOnce) { 100 gCount = 0; 101 gOnce = true; 102 } 103 104 SkASSERT(gCount < MAX_PAIR_COUNT); 105 106 gPairs[gCount].fName = name; 107 gPairs[gCount].fFactory = factory; 108 gCount += 1; 109 } 110 111 SkPixelRef::Factory SkPixelRef::NameToFactory(const char name[]) { 112 const Pair* pairs = gPairs; 113 for (int i = gCount - 1; i >= 0; --i) { 114 if (strcmp(pairs[i].fName, name) == 0) { 115 return pairs[i].fFactory; 116 } 117 } 118 return NULL; 119 } 120 121 const char* SkPixelRef::FactoryToName(Factory fact) { 122 const Pair* pairs = gPairs; 123 for (int i = gCount - 1; i >= 0; --i) { 124 if (pairs[i].fFactory == fact) { 125 return pairs[i].fName; 126 } 127 } 128 return NULL; 129 } 130 131