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 13void 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 23SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {} 24 25uint32_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 38const char* SkNamedFactorySet::getNextAddedFactoryName() { 39 if (fNextAddedFactory < fNames.count()) { 40 return fNames[fNextAddedFactory++]; 41 } 42 return NULL; 43} 44 45/////////////////////////////////////////////////////////////////////////////// 46 47SkRefCntSet::~SkRefCntSet() { 48 // call this now, while our decPtr() is sill in scope 49 this->reset(); 50} 51 52void SkRefCntSet::incPtr(void* ptr) { 53 ((SkRefCnt*)ptr)->ref(); 54} 55 56void SkRefCntSet::decPtr(void* ptr) { 57 ((SkRefCnt*)ptr)->unref(); 58} 59 60/////////////////////////////////////////////////////////////////////////////// 61/////////////////////////////////////////////////////////////////////////////// 62/////////////////////////////////////////////////////////////////////////////// 63 64#define MAX_ENTRY_COUNT 1024 65 66struct Entry { 67 const char* fName; 68 SkFlattenable::Factory fFactory; 69 SkFlattenable::Type fType; 70}; 71 72static int gCount; 73static Entry gEntries[MAX_ENTRY_COUNT]; 74 75void 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 94static 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 103SkFlattenable::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 117bool 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 133const 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