SkPixelRef.cpp revision 50dfa0130b0705414df7ba7da9915139f6320b09
1#include "SkPixelRef.h" 2#include "SkFlattenable.h" 3#include "SkThread.h" 4 5static SkMutex gPixelRefMutex; 6static int32_t gPixelRefGenerationID; 7 8SkPixelRef::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 20SkPixelRef::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 32void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { 33 buffer.writeBool(fIsImmutable); 34} 35 36void SkPixelRef::lockPixels() { 37 SkAutoMutexAcquire ac(*fMutex); 38 39 if (1 == ++fLockCount) { 40 fPixels = this->onLockPixels(&fColorTable); 41 } 42} 43 44void 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 55uint32_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 68void 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 78void SkPixelRef::setImmutable() { 79 fIsImmutable = true; 80} 81 82bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) { 83 return this->onReadPixels(dst, subset); 84} 85 86bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { 87 return false; 88} 89 90/////////////////////////////////////////////////////////////////////////////// 91 92#define MAX_PAIR_COUNT 16 93 94struct Pair { 95 const char* fName; 96 SkPixelRef::Factory fFactory; 97}; 98 99static int gCount; 100static Pair gPairs[MAX_PAIR_COUNT]; 101 102void SkPixelRef::Register(const char name[], Factory factory) { 103 SkASSERT(name); 104 SkASSERT(factory); 105 106 static bool gOnce; 107 if (!gOnce) { 108 gCount = 0; 109 gOnce = true; 110 } 111 112 SkASSERT(gCount < MAX_PAIR_COUNT); 113 114 gPairs[gCount].fName = name; 115 gPairs[gCount].fFactory = factory; 116 gCount += 1; 117} 118 119SkPixelRef::Factory SkPixelRef::NameToFactory(const char name[]) { 120 const Pair* pairs = gPairs; 121 for (int i = gCount - 1; i >= 0; --i) { 122 if (strcmp(pairs[i].fName, name) == 0) { 123 return pairs[i].fFactory; 124 } 125 } 126 return NULL; 127} 128 129const char* SkPixelRef::FactoryToName(Factory fact) { 130 const Pair* pairs = gPairs; 131 for (int i = gCount - 1; i >= 0; --i) { 132 if (pairs[i].fFactory == fact) { 133 return pairs[i].fName; 134 } 135 } 136 return NULL; 137} 138 139/////////////////////////////////////////////////////////////////////////////// 140 141#ifdef ANDROID 142void SkPixelRef::globalRef(void* data) { 143 this->ref(); 144} 145 146void SkPixelRef::globalUnref() { 147 this->unref(); 148} 149#endif 150