Home | History | Annotate | Download | only in core
      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 "SkFlattenable.h"
      9 #include "SkPtrRecorder.h"
     10 
     11 ///////////////////////////////////////////////////////////////////////////////
     12 
     13 void SkFlattenable::flatten(SkWriteBuffer&) const
     14 {
     15     /*  we don't write anything at the moment, but this allows our subclasses
     16         to not know that, since we want them to always call INHERITED::flatten()
     17         in their code.
     18     */
     19 }
     20 
     21 ///////////////////////////////////////////////////////////////////////////////
     22 
     23 SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
     24 
     25 uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) {
     26     uint32_t index = fFactorySet.find(factory);
     27     if (index > 0) {
     28         return index;
     29     }
     30     const char* name = SkFlattenable::FactoryToName(factory);
     31     if (NULL == name) {
     32         return 0;
     33     }
     34     *fNames.append() = name;
     35     return fFactorySet.add(factory);
     36 }
     37 
     38 const char* SkNamedFactorySet::getNextAddedFactoryName() {
     39     if (fNextAddedFactory < fNames.count()) {
     40         return fNames[fNextAddedFactory++];
     41     }
     42     return NULL;
     43 }
     44 
     45 ///////////////////////////////////////////////////////////////////////////////
     46 
     47 SkRefCntSet::~SkRefCntSet() {
     48     // call this now, while our decPtr() is sill in scope
     49     this->reset();
     50 }
     51 
     52 void SkRefCntSet::incPtr(void* ptr) {
     53     ((SkRefCnt*)ptr)->ref();
     54 }
     55 
     56 void SkRefCntSet::decPtr(void* ptr) {
     57     ((SkRefCnt*)ptr)->unref();
     58 }
     59 
     60 ///////////////////////////////////////////////////////////////////////////////
     61 ///////////////////////////////////////////////////////////////////////////////
     62 ///////////////////////////////////////////////////////////////////////////////
     63 
     64 #define MAX_ENTRY_COUNT  1024
     65 
     66 struct Entry {
     67     const char*             fName;
     68     SkFlattenable::Factory  fFactory;
     69     SkFlattenable::Type     fType;
     70 };
     71 
     72 static int gCount;
     73 static Entry gEntries[MAX_ENTRY_COUNT];
     74 
     75 void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) {
     76     SkASSERT(name);
     77     SkASSERT(factory);
     78 
     79     static bool gOnce = false;
     80     if (!gOnce) {
     81         gCount = 0;
     82         gOnce = true;
     83     }
     84 
     85     SkASSERT(gCount < MAX_ENTRY_COUNT);
     86 
     87     gEntries[gCount].fName = name;
     88     gEntries[gCount].fFactory = factory;
     89     gEntries[gCount].fType = type;
     90     gCount += 1;
     91 }
     92 
     93 #ifdef SK_DEBUG
     94 static void report_no_entries(const char* functionName) {
     95     if (!gCount) {
     96         SkDebugf("%s has no registered name/factory/type entries."
     97                  " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries",
     98                  functionName);
     99     }
    100 }
    101 #endif
    102 
    103 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
    104     InitializeFlattenablesIfNeeded();
    105 #ifdef SK_DEBUG
    106     report_no_entries(__FUNCTION__);
    107 #endif
    108     const Entry* entries = gEntries;
    109     for (int i = gCount - 1; i >= 0; --i) {
    110         if (strcmp(entries[i].fName, name) == 0) {
    111             return entries[i].fFactory;
    112         }
    113     }
    114     return NULL;
    115 }
    116 
    117 bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) {
    118     SkASSERT(NULL != type);
    119     InitializeFlattenablesIfNeeded();
    120 #ifdef SK_DEBUG
    121     report_no_entries(__FUNCTION__);
    122 #endif
    123     const Entry* entries = gEntries;
    124     for (int i = gCount - 1; i >= 0; --i) {
    125         if (strcmp(entries[i].fName, name) == 0) {
    126             *type = entries[i].fType;
    127             return true;
    128         }
    129     }
    130     return false;
    131 }
    132 
    133 const char* SkFlattenable::FactoryToName(Factory fact) {
    134     InitializeFlattenablesIfNeeded();
    135 #ifdef SK_DEBUG
    136     report_no_entries(__FUNCTION__);
    137 #endif
    138     const Entry* entries = gEntries;
    139     for (int i = gCount - 1; i >= 0; --i) {
    140         if (entries[i].fFactory == fact) {
    141             return entries[i].fName;
    142         }
    143     }
    144     return NULL;
    145 }
    146