Home | History | Annotate | Download | only in core
      1 #include "SkPixelRef.h"
      2 #include "SkFlattenable.h"
      3 #include "SkThread.h"
      4 
      5 static SkMutex  gPixelRefMutex;
      6 static int32_t  gPixelRefGenerationID;
      7 
      8 SkPixelRef::SkPixelRef(SkMutex* mutex) {
      9     if (NULL == mutex) {
     10         mutex = &gPixelRefMutex;
     11     }
     12     fMutex = mutex;
     13     fPixels = NULL;
     14     fColorTable = NULL; // we do not track ownership of this
     15     fLockCount = 0;
     16     fGenerationID = 0;  // signal to rebuild
     17     fIsImmutable = false;
     18 }
     19 
     20 SkPixelRef::SkPixelRef(SkFlattenableReadBuffer& buffer, SkMutex* mutex) {
     21     if (NULL == mutex) {
     22         mutex = &gPixelRefMutex;
     23     }
     24     fMutex = mutex;
     25     fPixels = NULL;
     26     fColorTable = NULL; // we do not track ownership of this
     27     fLockCount = 0;
     28     fGenerationID = 0;  // signal to rebuild
     29     fIsImmutable = buffer.readBool();
     30 }
     31 
     32 void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
     33     buffer.writeBool(fIsImmutable);
     34 }
     35 
     36 void SkPixelRef::lockPixels() {
     37     SkAutoMutexAcquire  ac(*fMutex);
     38 
     39     if (1 == ++fLockCount) {
     40         fPixels = this->onLockPixels(&fColorTable);
     41     }
     42 }
     43 
     44 void SkPixelRef::unlockPixels() {
     45     SkAutoMutexAcquire  ac(*fMutex);
     46 
     47     SkASSERT(fLockCount > 0);
     48     if (0 == --fLockCount) {
     49         this->onUnlockPixels();
     50         fPixels = NULL;
     51         fColorTable = NULL;
     52     }
     53 }
     54 
     55 uint32_t SkPixelRef::getGenerationID() const {
     56     uint32_t genID = fGenerationID;
     57     if (0 == genID) {
     58         // do a loop in case our global wraps around, as we never want to
     59         // return a 0
     60         do {
     61             genID = sk_atomic_inc(&gPixelRefGenerationID) + 1;
     62         } while (0 == genID);
     63         fGenerationID = genID;
     64     }
     65     return genID;
     66 }
     67 
     68 void SkPixelRef::notifyPixelsChanged() {
     69 #ifdef SK_DEBUG
     70     if (fIsImmutable) {
     71         SkDebugf("========== notifyPixelsChanged called on immutable pixelref");
     72     }
     73 #endif
     74     // this signals us to recompute this next time around
     75     fGenerationID = 0;
     76 }
     77 
     78 void SkPixelRef::setImmutable() {
     79     fIsImmutable = true;
     80 }
     81 
     82 ///////////////////////////////////////////////////////////////////////////////
     83 
     84 #define MAX_PAIR_COUNT  16
     85 
     86 struct Pair {
     87     const char*          fName;
     88     SkPixelRef::Factory  fFactory;
     89 };
     90 
     91 static int gCount;
     92 static Pair gPairs[MAX_PAIR_COUNT];
     93 
     94 void SkPixelRef::Register(const char name[], Factory factory) {
     95     SkASSERT(name);
     96     SkASSERT(factory);
     97 
     98     static bool gOnce;
     99     if (!gOnce) {
    100         gCount = 0;
    101         gOnce = true;
    102     }
    103 
    104     SkASSERT(gCount < MAX_PAIR_COUNT);
    105 
    106     gPairs[gCount].fName = name;
    107     gPairs[gCount].fFactory = factory;
    108     gCount += 1;
    109 }
    110 
    111 SkPixelRef::Factory SkPixelRef::NameToFactory(const char name[]) {
    112     const Pair* pairs = gPairs;
    113     for (int i = gCount - 1; i >= 0; --i) {
    114         if (strcmp(pairs[i].fName, name) == 0) {
    115             return pairs[i].fFactory;
    116         }
    117     }
    118     return NULL;
    119 }
    120 
    121 const char* SkPixelRef::FactoryToName(Factory fact) {
    122     const Pair* pairs = gPairs;
    123     for (int i = gCount - 1; i >= 0; --i) {
    124         if (pairs[i].fFactory == fact) {
    125             return pairs[i].fName;
    126         }
    127     }
    128     return NULL;
    129 }
    130 
    131