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 struct Entry { 52 const char* fName; 53 SkFlattenable::Factory fFactory; 54 SkFlattenable::Type fType; 55 }; 56 57 static int gCount = 0; 58 static Entry gEntries[128]; 59 60 void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) { 61 SkASSERT(name); 62 SkASSERT(factory); 63 SkASSERT(gCount < (int)SK_ARRAY_COUNT(gEntries)); 64 65 gEntries[gCount].fName = name; 66 gEntries[gCount].fFactory = factory; 67 gEntries[gCount].fType = type; 68 gCount += 1; 69 } 70 71 #ifdef SK_DEBUG 72 static void report_no_entries(const char* functionName) { 73 if (!gCount) { 74 SkDebugf("%s has no registered name/factory/type entries." 75 " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries", 76 functionName); 77 } 78 } 79 #endif 80 81 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { 82 InitializeFlattenablesIfNeeded(); 83 #ifdef SK_DEBUG 84 report_no_entries(__FUNCTION__); 85 #endif 86 const Entry* entries = gEntries; 87 for (int i = gCount - 1; i >= 0; --i) { 88 if (strcmp(entries[i].fName, name) == 0) { 89 return entries[i].fFactory; 90 } 91 } 92 return nullptr; 93 } 94 95 bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) { 96 SkASSERT(type); 97 InitializeFlattenablesIfNeeded(); 98 #ifdef SK_DEBUG 99 report_no_entries(__FUNCTION__); 100 #endif 101 const Entry* entries = gEntries; 102 for (int i = gCount - 1; i >= 0; --i) { 103 if (strcmp(entries[i].fName, name) == 0) { 104 *type = entries[i].fType; 105 return true; 106 } 107 } 108 return false; 109 } 110 111 const char* SkFlattenable::FactoryToName(Factory fact) { 112 InitializeFlattenablesIfNeeded(); 113 #ifdef SK_DEBUG 114 report_no_entries(__FUNCTION__); 115 #endif 116 const Entry* entries = gEntries; 117 for (int i = gCount - 1; i >= 0; --i) { 118 if (entries[i].fFactory == fact) { 119 return entries[i].fName; 120 } 121 } 122 return nullptr; 123 } 124