Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 "SkReadBuffer.h"
10 #include "SkWriteBuffer.h"
11 #include "SkThread.h"
13 #ifdef SK_USE_POSIX_THREADS
15 static SkBaseMutex gPixelRefMutexRing[] = {
16 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
17 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
18 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
19 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
21 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
22 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
23 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
24 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
26 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
27 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
28 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
29 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
31 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
32 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
33 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
34 { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
35 };
37 // must be a power-of-2. undef to just use 1 mutex
38 #define PIXELREF_MUTEX_RING_COUNT SK_ARRAY_COUNT(gPixelRefMutexRing)
40 #else // not pthreads
42 // must be a power-of-2. undef to just use 1 mutex
43 #define PIXELREF_MUTEX_RING_COUNT 32
44 static SkBaseMutex gPixelRefMutexRing[PIXELREF_MUTEX_RING_COUNT];
46 #endif
48 static SkBaseMutex* get_default_mutex() {
49 static int32_t gPixelRefMutexRingIndex;
51 SkASSERT(SkIsPow2(PIXELREF_MUTEX_RING_COUNT));
53 // atomic_inc might be overkill here. It may be fine if once in a while
54 // we hit a race-condition and two subsequent calls get the same index...
55 int index = sk_atomic_inc(&gPixelRefMutexRingIndex);
56 return &gPixelRefMutexRing[index & (PIXELREF_MUTEX_RING_COUNT - 1)];
57 }
59 ///////////////////////////////////////////////////////////////////////////////
61 int32_t SkNextPixelRefGenerationID();
63 int32_t SkNextPixelRefGenerationID() {
64 static int32_t gPixelRefGenerationID;
65 // do a loop in case our global wraps around, as we never want to
66 // return a 0
67 int32_t genID;
68 do {
69 genID = sk_atomic_inc(&gPixelRefGenerationID) + 1;
70 } while (0 == genID);
71 return genID;
72 }
74 ///////////////////////////////////////////////////////////////////////////////
76 void SkPixelRef::setMutex(SkBaseMutex* mutex) {
77 if (NULL == mutex) {
78 mutex = get_default_mutex();
79 }
80 fMutex = mutex;
81 }
83 // just need a > 0 value, so pick a funny one to aid in debugging
84 #define SKPIXELREF_PRELOCKED_LOCKCOUNT 123456789
86 SkPixelRef::SkPixelRef(const SkImageInfo& info) : fInfo(info) {
87 this->setMutex(NULL);
88 fRec.zero();
89 fLockCount = 0;
90 this->needsNewGenID();
91 fIsImmutable = false;
92 fPreLocked = false;
93 }
96 SkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex) : fInfo(info) {
97 this->setMutex(mutex);
98 fRec.zero();
99 fLockCount = 0;
100 this->needsNewGenID();
101 fIsImmutable = false;
102 fPreLocked = false;
103 }
105 static SkImageInfo read_info(SkReadBuffer& buffer) {
106 SkImageInfo info;
107 info.unflatten(buffer);
108 return info;
109 }
111 SkPixelRef::SkPixelRef(SkReadBuffer& buffer, SkBaseMutex* mutex)
112 : INHERITED(buffer)
113 , fInfo(read_info(buffer))
114 {
115 this->setMutex(mutex);
116 fRec.zero();
117 fLockCount = 0;
118 fIsImmutable = buffer.readBool();
119 fGenerationID = buffer.readUInt();
120 fUniqueGenerationID = false; // Conservatively assuming the original still exists.
121 fPreLocked = false;
122 }
124 SkPixelRef::~SkPixelRef() {
125 this->callGenIDChangeListeners();
126 }
128 void SkPixelRef::needsNewGenID() {
129 fGenerationID = 0;
130 fUniqueGenerationID = false;
131 }
133 void SkPixelRef::cloneGenID(const SkPixelRef& that) {
134 // This is subtle. We must call that.getGenerationID() to make sure its genID isn't 0.
135 this->fGenerationID = that.getGenerationID();
136 this->fUniqueGenerationID = false;
137 that.fUniqueGenerationID = false;
138 }
140 void SkPixelRef::setPreLocked(void* pixels, size_t rowBytes, SkColorTable* ctable) {
141 #ifndef SK_IGNORE_PIXELREF_SETPRELOCKED
142 // only call me in your constructor, otherwise fLockCount tracking can get
143 // out of sync.
144 fRec.fPixels = pixels;
145 fRec.fColorTable = ctable;
146 fRec.fRowBytes = rowBytes;
147 fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT;
148 fPreLocked = true;
149 #endif
150 }
152 void SkPixelRef::flatten(SkWriteBuffer& buffer) const {
153 this->INHERITED::flatten(buffer);
154 fInfo.flatten(buffer);
155 buffer.writeBool(fIsImmutable);
156 // We write the gen ID into the picture for within-process recording. This
157 // is safe since the same genID will never refer to two different sets of
158 // pixels (barring overflow). However, each process has its own "namespace"
159 // of genIDs. So for cross-process recording we write a zero which will
160 // trigger assignment of a new genID in playback.
161 if (buffer.isCrossProcess()) {
162 buffer.writeUInt(0);
163 } else {
164 buffer.writeUInt(fGenerationID);
165 fUniqueGenerationID = false; // Conservative, a copy is probably about to exist.
166 }
167 }
169 bool SkPixelRef::lockPixels(LockRec* rec) {
170 SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
172 if (!fPreLocked) {
173 SkAutoMutexAcquire ac(*fMutex);
175 if (1 == ++fLockCount) {
176 SkASSERT(fRec.isZero());
178 LockRec rec;
179 if (!this->onNewLockPixels(&rec)) {
180 return false;
181 }
182 SkASSERT(!rec.isZero()); // else why did onNewLock return true?
183 fRec = rec;
184 }
185 }
186 *rec = fRec;
187 return true;
188 }
190 bool SkPixelRef::lockPixels() {
191 LockRec rec;
192 return this->lockPixels(&rec);
193 }
195 void SkPixelRef::unlockPixels() {
196 SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
198 if (!fPreLocked) {
199 SkAutoMutexAcquire ac(*fMutex);
201 SkASSERT(fLockCount > 0);
202 if (0 == --fLockCount) {
203 // don't call onUnlockPixels unless onLockPixels succeeded
204 if (fRec.fPixels) {
205 this->onUnlockPixels();
206 fRec.zero();
207 } else {
208 SkASSERT(fRec.isZero());
209 }
210 }
211 }
212 }
214 bool SkPixelRef::lockPixelsAreWritable() const {
215 return this->onLockPixelsAreWritable();
216 }
218 bool SkPixelRef::onLockPixelsAreWritable() const {
219 return true;
220 }
222 bool SkPixelRef::onImplementsDecodeInto() {
223 return false;
224 }
226 bool SkPixelRef::onDecodeInto(int pow2, SkBitmap* bitmap) {
227 return false;
228 }
230 uint32_t SkPixelRef::getGenerationID() const {
231 if (0 == fGenerationID) {
232 fGenerationID = SkNextPixelRefGenerationID();
233 fUniqueGenerationID = true; // The only time we can be sure of this!
234 }
235 return fGenerationID;
236 }
238 void SkPixelRef::addGenIDChangeListener(GenIDChangeListener* listener) {
239 if (NULL == listener || !fUniqueGenerationID) {
240 // No point in tracking this if we're not going to call it.
241 SkDELETE(listener);
242 return;
243 }
244 *fGenIDChangeListeners.append() = listener;
245 }
247 void SkPixelRef::callGenIDChangeListeners() {
248 // We don't invalidate ourselves if we think another SkPixelRef is sharing our genID.
249 if (fUniqueGenerationID) {
250 for (int i = 0; i < fGenIDChangeListeners.count(); i++) {
251 fGenIDChangeListeners[i]->onChange();
252 }
253 }
254 // Listeners get at most one shot, so whether these triggered or not, blow them away.
255 fGenIDChangeListeners.deleteAll();
256 }
258 void SkPixelRef::notifyPixelsChanged() {
259 #ifdef SK_DEBUG
260 if (fIsImmutable) {
261 SkDebugf("========== notifyPixelsChanged called on immutable pixelref");
262 }
263 #endif
264 this->callGenIDChangeListeners();
265 this->needsNewGenID();
266 }
268 void SkPixelRef::changeAlphaType(SkAlphaType at) {
269 *const_cast<SkAlphaType*>(&fInfo.fAlphaType) = at;
270 }
272 void SkPixelRef::setImmutable() {
273 fIsImmutable = true;
274 }
276 bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) {
277 return this->onReadPixels(dst, subset);
278 }
280 bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
281 return false;
282 }
284 SkData* SkPixelRef::onRefEncodedData() {
285 return NULL;
286 }
288 size_t SkPixelRef::getAllocatedSizeInBytes() const {
289 return 0;
290 }
292 ///////////////////////////////////////////////////////////////////////////////
294 #ifdef SK_BUILD_FOR_ANDROID
295 void SkPixelRef::globalRef(void* data) {
296 this->ref();
297 }
299 void SkPixelRef::globalUnref() {
300 this->unref();
301 }
302 #endif