• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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