gfx/skia/trunk/src/core/SkPixelRef.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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

mercurial