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