1 #include "SkPixelRef.h"
2 #include "SkFlattenable.h"
3 #include "SkThread.h"
4
5 static SkMutex gPixelRefMutex;
6
SkNextPixelRefGenerationID()7 extern 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
SkPixelRef(SkMutex * mutex)19 SkPixelRef::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
SkPixelRef(SkFlattenableReadBuffer & buffer,SkMutex * mutex)31 SkPixelRef::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
flatten(SkFlattenableWriteBuffer & buffer) const43 void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
44 buffer.writeBool(fIsImmutable);
45 }
46
lockPixels()47 void SkPixelRef::lockPixels() {
48 SkAutoMutexAcquire ac(*fMutex);
49
50 if (1 == ++fLockCount) {
51 fPixels = this->onLockPixels(&fColorTable);
52 }
53 }
54
unlockPixels()55 void 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
getGenerationID() const66 uint32_t SkPixelRef::getGenerationID() const {
67 if (0 == fGenerationID) {
68 fGenerationID = SkNextPixelRefGenerationID();
69 }
70 return fGenerationID;
71 }
72
notifyPixelsChanged()73 void 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
setImmutable()83 void SkPixelRef::setImmutable() {
84 fIsImmutable = true;
85 }
86
readPixels(SkBitmap * dst,const SkIRect * subset)87 bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) {
88 return this->onReadPixels(dst, subset);
89 }
90
onReadPixels(SkBitmap * dst,const SkIRect * subset)91 bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
92 return false;
93 }
94
95 ///////////////////////////////////////////////////////////////////////////////
96
97 #define MAX_PAIR_COUNT 16
98
99 struct Pair {
100 const char* fName;
101 SkPixelRef::Factory fFactory;
102 };
103
104 static int gCount;
105 static Pair gPairs[MAX_PAIR_COUNT];
106
Register(const char name[],Factory factory)107 void 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
NameToFactory(const char name[])124 SkPixelRef::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
FactoryToName(Factory fact)134 const 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
globalRef(void * data)147 void SkPixelRef::globalRef(void* data) {
148 this->ref();
149 }
150
globalUnref()151 void SkPixelRef::globalUnref() {
152 this->unref();
153 }
154 #endif
155