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