SkFlattenable.h revision 54924243c1b65b3ee6d8fa064b50a9b1bb2a19a5
1 2/* 3 * Copyright 2006 The Android Open Source Project 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 9 10#ifndef SkFlattenable_DEFINED 11#define SkFlattenable_DEFINED 12 13#include "SkRefCnt.h" 14#include "SkBitmap.h" 15#include "SkReader32.h" 16#include "SkTDArray.h" 17#include "SkWriter32.h" 18 19class SkFlattenableReadBuffer; 20class SkFlattenableWriteBuffer; 21class SkString; 22 23#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 24 25#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \ 26 static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \ 27 flattenable::CreateProc); 28#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ 29 static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \ 30 flattenable::CreateProc); 31 32#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() 33#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) 34#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 35 36#else 37 38#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) 39#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ 40 SkFlattenable::Registrar(#flattenable, flattenable::CreateProc); 41 42#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables(); 43 44#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \ 45 void flattenable::InitializeFlattenables() { 46 47#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \ 48 } 49 50#endif 51 52#define SK_DECLARE_UNFLATTENABLE_OBJECT() \ 53 virtual Factory getFactory() SK_OVERRIDE { return NULL; }; \ 54 55#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ 56 virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }; \ 57 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \ 58 return SkNEW_ARGS(flattenable, (buffer)); \ 59 } 60 61/** \class SkFlattenable 62 63 SkFlattenable is the base class for objects that need to be flattened 64 into a data stream for either transport or as part of the key to the 65 font cache. 66 */ 67class SK_API SkFlattenable : public SkRefCnt { 68public: 69 typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&); 70 71 SkFlattenable() {} 72 73 /** Implement this to return a factory function pointer that can be called 74 to recreate your class given a buffer (previously written to by your 75 override of flatten(). 76 */ 77 virtual Factory getFactory() = 0; 78 79 static Factory NameToFactory(const char name[]); 80 static const char* FactoryToName(Factory); 81 static void Register(const char name[], Factory); 82 83 class Registrar { 84 public: 85 Registrar(const char name[], Factory factory) { 86 SkFlattenable::Register(name, factory); 87 } 88 }; 89 90protected: 91 SkFlattenable(SkFlattenableReadBuffer&) {} 92 /** Override this to write data specific to your subclass into the buffer, 93 being sure to call your super-class' version first. This data will later 94 be passed to your Factory function, returned by getFactory(). 95 */ 96 virtual void flatten(SkFlattenableWriteBuffer&) const; 97 98private: 99#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 100 static void InitializeFlattenables(); 101#endif 102 103 friend class SkGraphics; 104 friend class SkFlattenableWriteBuffer; 105}; 106 107// helpers for matrix and region 108 109class SkMatrix; 110extern void SkReadMatrix(SkReader32*, SkMatrix*); 111extern void SkWriteMatrix(SkWriter32*, const SkMatrix&); 112 113class SkRegion; 114extern void SkReadRegion(SkReader32*, SkRegion*); 115extern void SkWriteRegion(SkWriter32*, const SkRegion&); 116 117/////////////////////////////////////////////////////////////////////////////// 118/////////////////////////////////////////////////////////////////////////////// 119 120class SkTypeface; 121 122class SkFlattenableReadBuffer : public SkReader32 { 123public: 124 SkFlattenableReadBuffer(); 125 explicit SkFlattenableReadBuffer(const void* data); 126 SkFlattenableReadBuffer(const void* data, size_t size); 127 128 void setRefCntArray(SkRefCnt* array[], int count) { 129 fRCArray = array; 130 fRCCount = count; 131 } 132 133 void setTypefaceArray(SkTypeface* array[], int count) { 134 fTFArray = array; 135 fTFCount = count; 136 } 137 138 /** 139 * Call this with a pre-loaded array of Factories, in the same order as 140 * were created/written by the writer. SkPicture uses this. 141 */ 142 void setFactoryPlayback(SkFlattenable::Factory array[], int count) { 143 fFactoryTDArray = NULL; 144 fFactoryArray = array; 145 fFactoryCount = count; 146 } 147 148 /** 149 * Call this with an initially empty array, so the reader can cache each 150 * factory it sees by name. Used by the pipe code in conjunction with 151 * the writer's kInlineFactoryNames_Flag. 152 */ 153 void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) { 154 fFactoryTDArray = array; 155 fFactoryArray = NULL; 156 fFactoryCount = 0; 157 } 158 159 SkTypeface* readTypeface(); 160 SkRefCnt* readRefCnt(); 161 void* readFunctionPtr(); 162 SkFlattenable* readFlattenable(); 163 164private: 165 SkRefCnt** fRCArray; 166 int fRCCount; 167 168 SkTypeface** fTFArray; 169 int fTFCount; 170 171 SkTDArray<SkFlattenable::Factory>* fFactoryTDArray; 172 SkFlattenable::Factory* fFactoryArray; 173 int fFactoryCount; 174 175 typedef SkReader32 INHERITED; 176}; 177 178/////////////////////////////////////////////////////////////////////////////// 179 180#include "SkPtrRecorder.h" 181 182/** 183 * Subclass of SkTPtrSet specialed to call ref() and unref() when the 184 * base class's incPtr() and decPtr() are called. This makes it a valid owner 185 * of each ptr, which is released when the set is reset or destroyed. 186 */ 187class SkRefCntSet : public SkTPtrSet<SkRefCnt*> { 188public: 189 virtual ~SkRefCntSet(); 190 191protected: 192 // overrides 193 virtual void incPtr(void*); 194 virtual void decPtr(void*); 195}; 196 197class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {}; 198 199class SkFlattenableWriteBuffer : public SkWriter32 { 200public: 201 SkFlattenableWriteBuffer(size_t minSize); 202 virtual ~SkFlattenableWriteBuffer(); 203 204 void writeTypeface(SkTypeface*); 205 void writeRefCnt(SkRefCnt*); 206 void writeFunctionPtr(void*); 207 void writeFlattenable(SkFlattenable* flattenable); 208 209 SkRefCntSet* getTypefaceRecorder() const { return fTFSet; } 210 SkRefCntSet* setTypefaceRecorder(SkRefCntSet*); 211 212 SkRefCntSet* getRefCntRecorder() const { return fRCSet; } 213 SkRefCntSet* setRefCntRecorder(SkRefCntSet*); 214 215 SkFactorySet* getFactoryRecorder() const { return fFactorySet; } 216 SkFactorySet* setFactoryRecorder(SkFactorySet*); 217 218 enum Flags { 219 kCrossProcess_Flag = 0x01, 220 /** 221 * Instructs the writer to inline Factory names as there are seen the 222 * first time (after that we store an index). The pipe code uses this. 223 */ 224 kInlineFactoryNames_Flag = 0x02, 225 }; 226 Flags getFlags() const { return (Flags)fFlags; } 227 void setFlags(Flags flags) { fFlags = flags; } 228 229 bool isCrossProcess() const { 230 return SkToBool(fFlags & kCrossProcess_Flag); 231 } 232 bool inlineFactoryNames() const { 233 return SkToBool(fFlags & kInlineFactoryNames_Flag); 234 } 235 236 bool persistBitmapPixels() const { 237 return (fFlags & kCrossProcess_Flag) != 0; 238 } 239 240 bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; } 241 242private: 243 uint32_t fFlags; 244 SkRefCntSet* fTFSet; 245 SkRefCntSet* fRCSet; 246 SkFactorySet* fFactorySet; 247 248 typedef SkWriter32 INHERITED; 249}; 250 251#endif 252 253