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