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_PAIR_COUNT 1024 67 68struct Pair { 69 const char* fName; 70 SkFlattenable::Factory fFactory; 71}; 72 73static int gCount; 74static Pair gPairs[MAX_PAIR_COUNT]; 75 76void SkFlattenable::Register(const char name[], Factory factory) { 77 SkASSERT(name); 78 SkASSERT(factory); 79 80 static bool gOnce; 81 if (!gOnce) { 82 gCount = 0; 83 gOnce = true; 84 } 85 86 SkASSERT(gCount < MAX_PAIR_COUNT); 87 88 gPairs[gCount].fName = name; 89 gPairs[gCount].fFactory = factory; 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 pairs." 97 " Call SkGraphics::Init() at process initialization time.", 98 functionName); 99 } 100} 101#endif 102 103SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { 104#ifdef SK_DEBUG 105 report_no_entries(__FUNCTION__); 106#endif 107 const Pair* pairs = gPairs; 108 for (int i = gCount - 1; i >= 0; --i) { 109 if (strcmp(pairs[i].fName, name) == 0) { 110 return pairs[i].fFactory; 111 } 112 } 113 return NULL; 114} 115 116const char* SkFlattenable::FactoryToName(Factory fact) { 117#ifdef SK_DEBUG 118 report_no_entries(__FUNCTION__); 119#endif 120 const Pair* pairs = gPairs; 121 for (int i = gCount - 1; i >= 0; --i) { 122 if (pairs[i].fFactory == fact) { 123 return pairs[i].fName; 124 } 125 } 126 return NULL; 127} 128