blob: adfc3c02e97bb394b8a5f6d48ff4555ea5fb1996 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#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 if (fIsImmutable) {
70 SkDebugf("========== notifyPixelsChanged called on immutable pixelref");
71 sk_throw();
72 }
73 // this signals us to recompute this next time around
74 fGenerationID = 0;
75}
76
77void SkPixelRef::setImmutable() {
78 fIsImmutable = true;
79}
80
81///////////////////////////////////////////////////////////////////////////////
82
83#define MAX_PAIR_COUNT 16
84
85struct Pair {
86 const char* fName;
87 SkPixelRef::Factory fFactory;
88};
89
90static int gCount;
91static Pair gPairs[MAX_PAIR_COUNT];
92
93void SkPixelRef::Register(const char name[], Factory factory) {
94 SkASSERT(name);
95 SkASSERT(factory);
96
97 static bool gOnce;
98 if (!gOnce) {
99 gCount = 0;
100 gOnce = true;
101 }
102
103 SkASSERT(gCount < MAX_PAIR_COUNT);
104
105 gPairs[gCount].fName = name;
106 gPairs[gCount].fFactory = factory;
107 gCount += 1;
108}
109
110SkPixelRef::Factory SkPixelRef::NameToFactory(const char name[]) {
111 const Pair* pairs = gPairs;
112 for (int i = gCount - 1; i >= 0; --i) {
113 if (strcmp(pairs[i].fName, name) == 0) {
114 return pairs[i].fFactory;
115 }
116 }
117 return NULL;
118}
119
120const char* SkPixelRef::FactoryToName(Factory fact) {
121 const Pair* pairs = gPairs;
122 for (int i = gCount - 1; i >= 0; --i) {
123 if (pairs[i].fFactory == fact) {
124 return pairs[i].fName;
125 }
126 }
127 return NULL;
128}
129