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