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(SkFlattenableWriteBuffer&) 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