1 :
2 : /*
3 : * Copyright 2011 Google Inc.
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 : #include "SkPixelRef.h"
9 : #include "SkFlattenable.h"
10 : #include "SkThread.h"
11 :
12 1464 : static SkMutex gPixelRefMutex;
13 :
14 : extern int32_t SkNextPixelRefGenerationID();
15 0 : int32_t SkNextPixelRefGenerationID() {
16 : static int32_t gPixelRefGenerationID;
17 : // do a loop in case our global wraps around, as we never want to
18 : // return a 0
19 : int32_t genID;
20 0 : do {
21 0 : genID = sk_atomic_inc(&gPixelRefGenerationID) + 1;
22 : } while (0 == genID);
23 0 : return genID;
24 : }
25 :
26 :
27 0 : SkPixelRef::SkPixelRef(SkMutex* mutex) {
28 0 : if (NULL == mutex) {
29 0 : mutex = &gPixelRefMutex;
30 : }
31 0 : fMutex = mutex;
32 0 : fPixels = NULL;
33 0 : fColorTable = NULL; // we do not track ownership of this
34 0 : fLockCount = 0;
35 0 : fGenerationID = 0; // signal to rebuild
36 0 : fIsImmutable = false;
37 0 : }
38 :
39 0 : SkPixelRef::SkPixelRef(SkFlattenableReadBuffer& buffer, SkMutex* mutex) {
40 0 : if (NULL == mutex) {
41 0 : mutex = &gPixelRefMutex;
42 : }
43 0 : fMutex = mutex;
44 0 : fPixels = NULL;
45 0 : fColorTable = NULL; // we do not track ownership of this
46 0 : fLockCount = 0;
47 0 : fGenerationID = 0; // signal to rebuild
48 0 : fIsImmutable = buffer.readBool();
49 0 : }
50 :
51 0 : void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
52 0 : buffer.writeBool(fIsImmutable);
53 0 : }
54 :
55 0 : void SkPixelRef::lockPixels() {
56 0 : SkAutoMutexAcquire ac(*fMutex);
57 :
58 0 : if (1 == ++fLockCount) {
59 0 : fPixels = this->onLockPixels(&fColorTable);
60 : }
61 0 : }
62 :
63 0 : void SkPixelRef::unlockPixels() {
64 0 : SkAutoMutexAcquire ac(*fMutex);
65 :
66 0 : SkASSERT(fLockCount > 0);
67 0 : if (0 == --fLockCount) {
68 0 : this->onUnlockPixels();
69 0 : fPixels = NULL;
70 0 : fColorTable = NULL;
71 : }
72 0 : }
73 :
74 0 : bool SkPixelRef::lockPixelsAreWritable() const {
75 0 : return this->onLockPixelsAreWritable();
76 : }
77 :
78 0 : bool SkPixelRef::onLockPixelsAreWritable() const {
79 0 : return true;
80 : }
81 :
82 0 : uint32_t SkPixelRef::getGenerationID() const {
83 0 : if (0 == fGenerationID) {
84 0 : fGenerationID = SkNextPixelRefGenerationID();
85 : }
86 0 : return fGenerationID;
87 : }
88 :
89 0 : void SkPixelRef::notifyPixelsChanged() {
90 : #ifdef SK_DEBUG
91 0 : if (fIsImmutable) {
92 0 : SkDebugf("========== notifyPixelsChanged called on immutable pixelref");
93 : }
94 : #endif
95 : // this signals us to recompute this next time around
96 0 : fGenerationID = 0;
97 0 : }
98 :
99 0 : void SkPixelRef::setImmutable() {
100 0 : fIsImmutable = true;
101 0 : }
102 :
103 0 : bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) {
104 0 : return this->onReadPixels(dst, subset);
105 : }
106 :
107 0 : bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
108 0 : return false;
109 : }
110 :
111 : ///////////////////////////////////////////////////////////////////////////////
112 :
113 : #define MAX_PAIR_COUNT 16
114 :
115 : struct Pair {
116 : const char* fName;
117 : SkPixelRef::Factory fFactory;
118 : };
119 :
120 : static int gCount;
121 : static Pair gPairs[MAX_PAIR_COUNT];
122 :
123 1464 : void SkPixelRef::Register(const char name[], Factory factory) {
124 1464 : SkASSERT(name);
125 1464 : SkASSERT(factory);
126 :
127 : static bool gOnce;
128 1464 : if (!gOnce) {
129 1464 : gCount = 0;
130 1464 : gOnce = true;
131 : }
132 :
133 1464 : SkASSERT(gCount < MAX_PAIR_COUNT);
134 :
135 1464 : gPairs[gCount].fName = name;
136 1464 : gPairs[gCount].fFactory = factory;
137 1464 : gCount += 1;
138 1464 : }
139 :
140 : #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
141 : static void report_no_entries(const char* functionName) {
142 : if (!gCount) {
143 : SkDebugf("%s has no registered name/factory pairs."
144 : " Call SkGraphics::Init() at process initialization time.",
145 : functionName);
146 : }
147 : }
148 : #endif
149 :
150 0 : SkPixelRef::Factory SkPixelRef::NameToFactory(const char name[]) {
151 : #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
152 : report_no_entries(__FUNCTION__);
153 : #endif
154 0 : const Pair* pairs = gPairs;
155 0 : for (int i = gCount - 1; i >= 0; --i) {
156 0 : if (strcmp(pairs[i].fName, name) == 0) {
157 0 : return pairs[i].fFactory;
158 : }
159 : }
160 0 : return NULL;
161 : }
162 :
163 0 : const char* SkPixelRef::FactoryToName(Factory fact) {
164 : #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
165 : report_no_entries(__FUNCTION__);
166 : #endif
167 0 : const Pair* pairs = gPairs;
168 0 : for (int i = gCount - 1; i >= 0; --i) {
169 0 : if (pairs[i].fFactory == fact) {
170 0 : return pairs[i].fName;
171 : }
172 : }
173 0 : return NULL;
174 4392 : }
175 :
176 : ///////////////////////////////////////////////////////////////////////////////
177 :
178 : #ifdef SK_BUILD_FOR_ANDROID
179 : void SkPixelRef::globalRef(void* data) {
180 : this->ref();
181 : }
182 :
183 : void SkPixelRef::globalUnref() {
184 : this->unref();
185 : }
186 : #endif
|