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