1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkPixelRef.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,302 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2011 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 +#include "SkPixelRef.h" 1.12 +#include "SkReadBuffer.h" 1.13 +#include "SkWriteBuffer.h" 1.14 +#include "SkThread.h" 1.15 + 1.16 +#ifdef SK_USE_POSIX_THREADS 1.17 + 1.18 + static SkBaseMutex gPixelRefMutexRing[] = { 1.19 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.20 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.21 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.22 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.23 + 1.24 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.25 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.26 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.27 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.28 + 1.29 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.30 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.31 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.32 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.33 + 1.34 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.35 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.36 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.37 + { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER }, 1.38 + }; 1.39 + 1.40 + // must be a power-of-2. undef to just use 1 mutex 1.41 + #define PIXELREF_MUTEX_RING_COUNT SK_ARRAY_COUNT(gPixelRefMutexRing) 1.42 + 1.43 +#else // not pthreads 1.44 + 1.45 + // must be a power-of-2. undef to just use 1 mutex 1.46 + #define PIXELREF_MUTEX_RING_COUNT 32 1.47 + static SkBaseMutex gPixelRefMutexRing[PIXELREF_MUTEX_RING_COUNT]; 1.48 + 1.49 +#endif 1.50 + 1.51 +static SkBaseMutex* get_default_mutex() { 1.52 + static int32_t gPixelRefMutexRingIndex; 1.53 + 1.54 + SkASSERT(SkIsPow2(PIXELREF_MUTEX_RING_COUNT)); 1.55 + 1.56 + // atomic_inc might be overkill here. It may be fine if once in a while 1.57 + // we hit a race-condition and two subsequent calls get the same index... 1.58 + int index = sk_atomic_inc(&gPixelRefMutexRingIndex); 1.59 + return &gPixelRefMutexRing[index & (PIXELREF_MUTEX_RING_COUNT - 1)]; 1.60 +} 1.61 + 1.62 +/////////////////////////////////////////////////////////////////////////////// 1.63 + 1.64 +int32_t SkNextPixelRefGenerationID(); 1.65 + 1.66 +int32_t SkNextPixelRefGenerationID() { 1.67 + static int32_t gPixelRefGenerationID; 1.68 + // do a loop in case our global wraps around, as we never want to 1.69 + // return a 0 1.70 + int32_t genID; 1.71 + do { 1.72 + genID = sk_atomic_inc(&gPixelRefGenerationID) + 1; 1.73 + } while (0 == genID); 1.74 + return genID; 1.75 +} 1.76 + 1.77 +/////////////////////////////////////////////////////////////////////////////// 1.78 + 1.79 +void SkPixelRef::setMutex(SkBaseMutex* mutex) { 1.80 + if (NULL == mutex) { 1.81 + mutex = get_default_mutex(); 1.82 + } 1.83 + fMutex = mutex; 1.84 +} 1.85 + 1.86 +// just need a > 0 value, so pick a funny one to aid in debugging 1.87 +#define SKPIXELREF_PRELOCKED_LOCKCOUNT 123456789 1.88 + 1.89 +SkPixelRef::SkPixelRef(const SkImageInfo& info) : fInfo(info) { 1.90 + this->setMutex(NULL); 1.91 + fRec.zero(); 1.92 + fLockCount = 0; 1.93 + this->needsNewGenID(); 1.94 + fIsImmutable = false; 1.95 + fPreLocked = false; 1.96 +} 1.97 + 1.98 + 1.99 +SkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex) : fInfo(info) { 1.100 + this->setMutex(mutex); 1.101 + fRec.zero(); 1.102 + fLockCount = 0; 1.103 + this->needsNewGenID(); 1.104 + fIsImmutable = false; 1.105 + fPreLocked = false; 1.106 +} 1.107 + 1.108 +static SkImageInfo read_info(SkReadBuffer& buffer) { 1.109 + SkImageInfo info; 1.110 + info.unflatten(buffer); 1.111 + return info; 1.112 +} 1.113 + 1.114 +SkPixelRef::SkPixelRef(SkReadBuffer& buffer, SkBaseMutex* mutex) 1.115 + : INHERITED(buffer) 1.116 + , fInfo(read_info(buffer)) 1.117 +{ 1.118 + this->setMutex(mutex); 1.119 + fRec.zero(); 1.120 + fLockCount = 0; 1.121 + fIsImmutable = buffer.readBool(); 1.122 + fGenerationID = buffer.readUInt(); 1.123 + fUniqueGenerationID = false; // Conservatively assuming the original still exists. 1.124 + fPreLocked = false; 1.125 +} 1.126 + 1.127 +SkPixelRef::~SkPixelRef() { 1.128 + this->callGenIDChangeListeners(); 1.129 +} 1.130 + 1.131 +void SkPixelRef::needsNewGenID() { 1.132 + fGenerationID = 0; 1.133 + fUniqueGenerationID = false; 1.134 +} 1.135 + 1.136 +void SkPixelRef::cloneGenID(const SkPixelRef& that) { 1.137 + // This is subtle. We must call that.getGenerationID() to make sure its genID isn't 0. 1.138 + this->fGenerationID = that.getGenerationID(); 1.139 + this->fUniqueGenerationID = false; 1.140 + that.fUniqueGenerationID = false; 1.141 +} 1.142 + 1.143 +void SkPixelRef::setPreLocked(void* pixels, size_t rowBytes, SkColorTable* ctable) { 1.144 +#ifndef SK_IGNORE_PIXELREF_SETPRELOCKED 1.145 + // only call me in your constructor, otherwise fLockCount tracking can get 1.146 + // out of sync. 1.147 + fRec.fPixels = pixels; 1.148 + fRec.fColorTable = ctable; 1.149 + fRec.fRowBytes = rowBytes; 1.150 + fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT; 1.151 + fPreLocked = true; 1.152 +#endif 1.153 +} 1.154 + 1.155 +void SkPixelRef::flatten(SkWriteBuffer& buffer) const { 1.156 + this->INHERITED::flatten(buffer); 1.157 + fInfo.flatten(buffer); 1.158 + buffer.writeBool(fIsImmutable); 1.159 + // We write the gen ID into the picture for within-process recording. This 1.160 + // is safe since the same genID will never refer to two different sets of 1.161 + // pixels (barring overflow). However, each process has its own "namespace" 1.162 + // of genIDs. So for cross-process recording we write a zero which will 1.163 + // trigger assignment of a new genID in playback. 1.164 + if (buffer.isCrossProcess()) { 1.165 + buffer.writeUInt(0); 1.166 + } else { 1.167 + buffer.writeUInt(fGenerationID); 1.168 + fUniqueGenerationID = false; // Conservative, a copy is probably about to exist. 1.169 + } 1.170 +} 1.171 + 1.172 +bool SkPixelRef::lockPixels(LockRec* rec) { 1.173 + SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); 1.174 + 1.175 + if (!fPreLocked) { 1.176 + SkAutoMutexAcquire ac(*fMutex); 1.177 + 1.178 + if (1 == ++fLockCount) { 1.179 + SkASSERT(fRec.isZero()); 1.180 + 1.181 + LockRec rec; 1.182 + if (!this->onNewLockPixels(&rec)) { 1.183 + return false; 1.184 + } 1.185 + SkASSERT(!rec.isZero()); // else why did onNewLock return true? 1.186 + fRec = rec; 1.187 + } 1.188 + } 1.189 + *rec = fRec; 1.190 + return true; 1.191 +} 1.192 + 1.193 +bool SkPixelRef::lockPixels() { 1.194 + LockRec rec; 1.195 + return this->lockPixels(&rec); 1.196 +} 1.197 + 1.198 +void SkPixelRef::unlockPixels() { 1.199 + SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); 1.200 + 1.201 + if (!fPreLocked) { 1.202 + SkAutoMutexAcquire ac(*fMutex); 1.203 + 1.204 + SkASSERT(fLockCount > 0); 1.205 + if (0 == --fLockCount) { 1.206 + // don't call onUnlockPixels unless onLockPixels succeeded 1.207 + if (fRec.fPixels) { 1.208 + this->onUnlockPixels(); 1.209 + fRec.zero(); 1.210 + } else { 1.211 + SkASSERT(fRec.isZero()); 1.212 + } 1.213 + } 1.214 + } 1.215 +} 1.216 + 1.217 +bool SkPixelRef::lockPixelsAreWritable() const { 1.218 + return this->onLockPixelsAreWritable(); 1.219 +} 1.220 + 1.221 +bool SkPixelRef::onLockPixelsAreWritable() const { 1.222 + return true; 1.223 +} 1.224 + 1.225 +bool SkPixelRef::onImplementsDecodeInto() { 1.226 + return false; 1.227 +} 1.228 + 1.229 +bool SkPixelRef::onDecodeInto(int pow2, SkBitmap* bitmap) { 1.230 + return false; 1.231 +} 1.232 + 1.233 +uint32_t SkPixelRef::getGenerationID() const { 1.234 + if (0 == fGenerationID) { 1.235 + fGenerationID = SkNextPixelRefGenerationID(); 1.236 + fUniqueGenerationID = true; // The only time we can be sure of this! 1.237 + } 1.238 + return fGenerationID; 1.239 +} 1.240 + 1.241 +void SkPixelRef::addGenIDChangeListener(GenIDChangeListener* listener) { 1.242 + if (NULL == listener || !fUniqueGenerationID) { 1.243 + // No point in tracking this if we're not going to call it. 1.244 + SkDELETE(listener); 1.245 + return; 1.246 + } 1.247 + *fGenIDChangeListeners.append() = listener; 1.248 +} 1.249 + 1.250 +void SkPixelRef::callGenIDChangeListeners() { 1.251 + // We don't invalidate ourselves if we think another SkPixelRef is sharing our genID. 1.252 + if (fUniqueGenerationID) { 1.253 + for (int i = 0; i < fGenIDChangeListeners.count(); i++) { 1.254 + fGenIDChangeListeners[i]->onChange(); 1.255 + } 1.256 + } 1.257 + // Listeners get at most one shot, so whether these triggered or not, blow them away. 1.258 + fGenIDChangeListeners.deleteAll(); 1.259 +} 1.260 + 1.261 +void SkPixelRef::notifyPixelsChanged() { 1.262 +#ifdef SK_DEBUG 1.263 + if (fIsImmutable) { 1.264 + SkDebugf("========== notifyPixelsChanged called on immutable pixelref"); 1.265 + } 1.266 +#endif 1.267 + this->callGenIDChangeListeners(); 1.268 + this->needsNewGenID(); 1.269 +} 1.270 + 1.271 +void SkPixelRef::changeAlphaType(SkAlphaType at) { 1.272 + *const_cast<SkAlphaType*>(&fInfo.fAlphaType) = at; 1.273 +} 1.274 + 1.275 +void SkPixelRef::setImmutable() { 1.276 + fIsImmutable = true; 1.277 +} 1.278 + 1.279 +bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) { 1.280 + return this->onReadPixels(dst, subset); 1.281 +} 1.282 + 1.283 +bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { 1.284 + return false; 1.285 +} 1.286 + 1.287 +SkData* SkPixelRef::onRefEncodedData() { 1.288 + return NULL; 1.289 +} 1.290 + 1.291 +size_t SkPixelRef::getAllocatedSizeInBytes() const { 1.292 + return 0; 1.293 +} 1.294 + 1.295 +/////////////////////////////////////////////////////////////////////////////// 1.296 + 1.297 +#ifdef SK_BUILD_FOR_ANDROID 1.298 +void SkPixelRef::globalRef(void* data) { 1.299 + this->ref(); 1.300 +} 1.301 + 1.302 +void SkPixelRef::globalUnref() { 1.303 + this->unref(); 1.304 +} 1.305 +#endif