SkFlattenable.cpp revision 0c3e5fe728ce4b8606819ee919a4b82f4d9efc85
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 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 25SkFlattenableReadBuffer::SkFlattenableReadBuffer() { 26 fRCArray = NULL; 27 fRCCount = 0; 28 29 fTFArray = NULL; 30 fTFCount = 0; 31 32 fFactoryTDArray = NULL; 33 fFactoryArray = NULL; 34 fFactoryCount = 0; 35 36 // Set default values. These should be explicitly set by our client 37 // via setFlags() if the buffer came from serialization. 38 fFlags = 0; 39#ifdef SK_SCALAR_IS_FLOAT 40 fFlags |= kScalarIsFloat_Flag; 41#endif 42 if (8 == sizeof(void*)) { 43 fFlags |= kPtrIs64Bit_Flag; 44 } 45} 46 47/////////////////////////////////////////////////////////////////////////////// 48 49SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {} 50 51uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) { 52 uint32_t index = fFactorySet.find(factory); 53 if (index > 0) { 54 return index; 55 } 56 const char* name = SkFlattenable::FactoryToName(factory); 57 if (NULL == name) { 58 return 0; 59 } 60 *fNames.append() = name; 61 return fFactorySet.add(factory); 62} 63 64const char* SkNamedFactorySet::getNextAddedFactoryName() { 65 if (fNextAddedFactory < fNames.count()) { 66 return fNames[fNextAddedFactory++]; 67 } 68 return NULL; 69} 70 71/////////////////////////////////////////////////////////////////////////////// 72 73SkFlattenableWriteBuffer::SkFlattenableWriteBuffer() { 74 fFlags = (Flags)0; 75 fRCSet = NULL; 76 fTFSet = NULL; 77 fFactorySet = NULL; 78 fNamedFactorySet = NULL; 79} 80 81SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() { 82 SkSafeUnref(fRCSet); 83 SkSafeUnref(fTFSet); 84 SkSafeUnref(fFactorySet); 85 SkSafeUnref(fNamedFactorySet); 86} 87 88SkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) { 89 SkRefCnt_SafeAssign(fRCSet, rec); 90 return rec; 91} 92 93SkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { 94 SkRefCnt_SafeAssign(fTFSet, rec); 95 return rec; 96} 97 98SkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { 99 SkRefCnt_SafeAssign(fFactorySet, rec); 100 if (fNamedFactorySet != NULL) { 101 fNamedFactorySet->unref(); 102 fNamedFactorySet = NULL; 103 } 104 return rec; 105} 106 107SkNamedFactorySet* SkFlattenableWriteBuffer::setNamedFactoryRecorder( 108 SkNamedFactorySet* rec) { 109 SkRefCnt_SafeAssign(fNamedFactorySet, rec); 110 if (fFactorySet != NULL) { 111 fFactorySet->unref(); 112 fFactorySet = NULL; 113 } 114 return rec; 115} 116 117void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) { 118 SkASSERT(!isCrossProcess()); 119 if (NULL == obj || NULL == fRCSet) { 120 this->write32(0); 121 } else { 122 this->write32(fRCSet->add(obj)); 123 } 124} 125 126void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) { 127 if (NULL == obj || NULL == fTFSet) { 128 this->write32(0); 129 } else { 130 this->write32(fTFSet->add(obj)); 131 } 132} 133 134/////////////////////////////////////////////////////////////////////////////// 135 136SkRefCntSet::~SkRefCntSet() { 137 // call this now, while our decPtr() is sill in scope 138 this->reset(); 139} 140 141void SkRefCntSet::incPtr(void* ptr) { 142 ((SkRefCnt*)ptr)->ref(); 143} 144 145void SkRefCntSet::decPtr(void* ptr) { 146 ((SkRefCnt*)ptr)->unref(); 147} 148 149/////////////////////////////////////////////////////////////////////////////// 150/////////////////////////////////////////////////////////////////////////////// 151/////////////////////////////////////////////////////////////////////////////// 152 153#define MAX_PAIR_COUNT 1024 154 155struct Pair { 156 const char* fName; 157 SkFlattenable::Factory fFactory; 158}; 159 160static int gCount; 161static Pair gPairs[MAX_PAIR_COUNT]; 162 163void SkFlattenable::Register(const char name[], Factory factory) { 164 SkASSERT(name); 165 SkASSERT(factory); 166 167 static bool gOnce; 168 if (!gOnce) { 169 gCount = 0; 170 gOnce = true; 171 } 172 173 SkASSERT(gCount < MAX_PAIR_COUNT); 174 175 gPairs[gCount].fName = name; 176 gPairs[gCount].fFactory = factory; 177 gCount += 1; 178} 179 180#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 181static void report_no_entries(const char* functionName) { 182 if (!gCount) { 183 SkDebugf("%s has no registered name/factory pairs." 184 " Call SkGraphics::Init() at process initialization time.", 185 functionName); 186 } 187} 188#endif 189 190SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { 191#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 192 report_no_entries(__FUNCTION__); 193#endif 194 const Pair* pairs = gPairs; 195 for (int i = gCount - 1; i >= 0; --i) { 196 if (strcmp(pairs[i].fName, name) == 0) { 197 return pairs[i].fFactory; 198 } 199 } 200 return NULL; 201} 202 203const char* SkFlattenable::FactoryToName(Factory fact) { 204#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 205 report_no_entries(__FUNCTION__); 206#endif 207 const Pair* pairs = gPairs; 208 for (int i = gCount - 1; i >= 0; --i) { 209 if (pairs[i].fFactory == fact) { 210 return pairs[i].fName; 211 } 212 } 213 return NULL; 214} 215