SkFlattenable.cpp revision 2b2ede3e713065e1bac461787b0aafb03eaf871f
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 "SkTypeface.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 23SkFlattenableReadBuffer::SkFlattenableReadBuffer() { 24 fRCArray = NULL; 25 fRCCount = 0; 26 27 fTFArray = NULL; 28 fTFCount = 0; 29 30 fFactoryTDArray = NULL; 31 fFactoryArray = NULL; 32 fFactoryCount = 0; 33} 34 35/////////////////////////////////////////////////////////////////////////////// 36 37SkFlattenableWriteBuffer::SkFlattenableWriteBuffer() { 38 fFlags = (Flags)0; 39 fRCSet = NULL; 40 fTFSet = NULL; 41 fFactorySet = NULL; 42} 43 44SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() { 45 SkSafeUnref(fRCSet); 46 SkSafeUnref(fTFSet); 47 SkSafeUnref(fFactorySet); 48} 49 50SkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) { 51 SkRefCnt_SafeAssign(fRCSet, rec); 52 return rec; 53} 54 55SkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { 56 SkRefCnt_SafeAssign(fTFSet, rec); 57 return rec; 58} 59 60SkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { 61 SkRefCnt_SafeAssign(fFactorySet, rec); 62 return rec; 63} 64 65void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) { 66 SkASSERT(!isCrossProcess()); 67 if (NULL == obj || NULL == fRCSet) { 68 this->write32(0); 69 } else { 70 this->write32(fRCSet->add(obj)); 71 } 72} 73 74void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) { 75 if (NULL == obj || NULL == fTFSet) { 76 this->write32(0); 77 } else { 78 this->write32(fTFSet->add(obj)); 79 } 80} 81 82/////////////////////////////////////////////////////////////////////////////// 83 84SkRefCntSet::~SkRefCntSet() { 85 // call this now, while our decPtr() is sill in scope 86 this->reset(); 87} 88 89void SkRefCntSet::incPtr(void* ptr) { 90 ((SkRefCnt*)ptr)->ref(); 91} 92 93void SkRefCntSet::decPtr(void* ptr) { 94 ((SkRefCnt*)ptr)->unref(); 95} 96 97/////////////////////////////////////////////////////////////////////////////// 98/////////////////////////////////////////////////////////////////////////////// 99/////////////////////////////////////////////////////////////////////////////// 100 101#define MAX_PAIR_COUNT 64 102 103struct Pair { 104 const char* fName; 105 SkFlattenable::Factory fFactory; 106}; 107 108static int gCount; 109static Pair gPairs[MAX_PAIR_COUNT]; 110 111void SkFlattenable::Register(const char name[], Factory factory) { 112 SkASSERT(name); 113 SkASSERT(factory); 114 115 static bool gOnce; 116 if (!gOnce) { 117 gCount = 0; 118 gOnce = true; 119 } 120 121 SkASSERT(gCount < MAX_PAIR_COUNT); 122 123 gPairs[gCount].fName = name; 124 gPairs[gCount].fFactory = factory; 125 gCount += 1; 126} 127 128#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 129static void report_no_entries(const char* functionName) { 130 if (!gCount) { 131 SkDebugf("%s has no registered name/factory pairs." 132 " Call SkGraphics::Init() at process initialization time.", 133 functionName); 134 } 135} 136#endif 137 138SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { 139#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 140 report_no_entries(__FUNCTION__); 141#endif 142 const Pair* pairs = gPairs; 143 for (int i = gCount - 1; i >= 0; --i) { 144 if (strcmp(pairs[i].fName, name) == 0) { 145 return pairs[i].fFactory; 146 } 147 } 148 return NULL; 149} 150 151const char* SkFlattenable::FactoryToName(Factory fact) { 152#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 153 report_no_entries(__FUNCTION__); 154#endif 155 const Pair* pairs = gPairs; 156 for (int i = gCount - 1; i >= 0; --i) { 157 if (pairs[i].fFactory == fact) { 158 return pairs[i].fName; 159 } 160 } 161 return NULL; 162} 163