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