SkFlattenable.cpp revision c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cf
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 11SK_DEFINE_INST_COUNT(SkFlattenable) 12 13/////////////////////////////////////////////////////////////////////////////// 14 15void SkFlattenable::flatten(SkFlattenableWriteBuffer&) const 16{ 17 /* we don't write anything at the moment, but this allows our subclasses 18 to not know that, since we want them to always call INHERITED::flatten() 19 in their code. 20 */ 21} 22 23/////////////////////////////////////////////////////////////////////////////// 24 25SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {} 26 27uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) { 28 uint32_t index = fFactorySet.find(factory); 29 if (index > 0) { 30 return index; 31 } 32 const char* name = SkFlattenable::FactoryToName(factory); 33 if (NULL == name) { 34 return 0; 35 } 36 *fNames.append() = name; 37 return fFactorySet.add(factory); 38} 39 40const char* SkNamedFactorySet::getNextAddedFactoryName() { 41 if (fNextAddedFactory < fNames.count()) { 42 return fNames[fNextAddedFactory++]; 43 } 44 return NULL; 45} 46 47/////////////////////////////////////////////////////////////////////////////// 48 49SkRefCntSet::~SkRefCntSet() { 50 // call this now, while our decPtr() is sill in scope 51 this->reset(); 52} 53 54void SkRefCntSet::incPtr(void* ptr) { 55 ((SkRefCnt*)ptr)->ref(); 56} 57 58void SkRefCntSet::decPtr(void* ptr) { 59 ((SkRefCnt*)ptr)->unref(); 60} 61 62/////////////////////////////////////////////////////////////////////////////// 63/////////////////////////////////////////////////////////////////////////////// 64/////////////////////////////////////////////////////////////////////////////// 65 66#define MAX_ENTRY_COUNT 1024 67 68struct Entry { 69 const char* fName; 70 SkFlattenable::Factory fFactory; 71 SkFlattenable::Type fType; 72}; 73 74static int gCount; 75static Entry gEntries[MAX_ENTRY_COUNT]; 76 77void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) { 78 SkASSERT(name); 79 SkASSERT(factory); 80 81 static bool gOnce = false; 82 if (!gOnce) { 83 gCount = 0; 84 gOnce = true; 85 } 86 87 SkASSERT(gCount < MAX_ENTRY_COUNT); 88 89 gEntries[gCount].fName = name; 90 gEntries[gCount].fFactory = factory; 91 gEntries[gCount].fType = type; 92 gCount += 1; 93} 94 95#ifdef SK_DEBUG 96static void report_no_entries(const char* functionName) { 97 if (!gCount) { 98 SkDebugf("%s has no registered name/factory/type entries." 99 " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries", 100 functionName); 101 } 102} 103#endif 104 105SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { 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 return entries[i].fFactory; 114 } 115 } 116 return NULL; 117} 118 119bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) { 120 SkASSERT(NULL != type); 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 (strcmp(entries[i].fName, name) == 0) { 128 *type = entries[i].fType; 129 return true; 130 } 131 } 132 return false; 133} 134 135const char* SkFlattenable::FactoryToName(Factory fact) { 136 InitializeFlattenablesIfNeeded(); 137#ifdef SK_DEBUG 138 report_no_entries(__FUNCTION__); 139#endif 140 const Entry* entries = gEntries; 141 for (int i = gCount - 1; i >= 0; --i) { 142 if (entries[i].fFactory == fact) { 143 return entries[i].fName; 144 } 145 } 146 return NULL; 147} 148