SkFlattenable.h revision ba28d03e94dc221d6a803bf2a84a420b9159255c
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 /** Override this to write data specific to your subclass into the buffer, 79 being sure to call your super-class' version first. This data will later 80 be passed to your Factory function, returned by getFactory(). 81 */ 82 virtual void flatten(SkFlattenableWriteBuffer&); 83 84 static Factory NameToFactory(const char name[]); 85 static const char* FactoryToName(Factory); 86 static void Register(const char name[], Factory); 87 88 class Registrar { 89 public: 90 Registrar(const char name[], Factory factory) { 91 SkFlattenable::Register(name, factory); 92 } 93 }; 94 95protected: 96 SkFlattenable(SkFlattenableReadBuffer&) {} 97 98private: 99#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 100 static void InitializeFlattenables(); 101#endif 102 103 friend class SkGraphics; 104}; 105 106// helpers for matrix and region 107 108class SkMatrix; 109extern void SkReadMatrix(SkReader32*, SkMatrix*); 110extern void SkWriteMatrix(SkWriter32*, const SkMatrix&); 111 112class SkRegion; 113extern void SkReadRegion(SkReader32*, SkRegion*); 114extern void SkWriteRegion(SkWriter32*, const SkRegion&); 115 116/////////////////////////////////////////////////////////////////////////////// 117/////////////////////////////////////////////////////////////////////////////// 118 119class SkTypeface; 120 121class SkFlattenableReadBuffer : public SkReader32 { 122public: 123 SkFlattenableReadBuffer(); 124 explicit SkFlattenableReadBuffer(const void* data); 125 SkFlattenableReadBuffer(const void* data, size_t size); 126 127 void setRefCntArray(SkRefCnt* array[], int count) { 128 fRCArray = array; 129 fRCCount = count; 130 } 131 132 void setTypefaceArray(SkTypeface* array[], int count) { 133 fTFArray = array; 134 fTFCount = count; 135 } 136 137 /** 138 * Call this with a pre-loaded array of Factories, in the same order as 139 * were created/written by the writer. SkPicture uses this. 140 */ 141 void setFactoryPlayback(SkFlattenable::Factory array[], int count) { 142 fFactoryTDArray = NULL; 143 fFactoryArray = array; 144 fFactoryCount = count; 145 } 146 147 /** 148 * Call this with an initially empty array, so the reader can cache each 149 * factory it sees by name. Used by the pipe code in conjunction with 150 * the writer's kInlineFactoryNames_Flag. 151 */ 152 void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) { 153 fFactoryTDArray = array; 154 fFactoryArray = NULL; 155 fFactoryCount = 0; 156 } 157 158 SkTypeface* readTypeface(); 159 SkRefCnt* readRefCnt(); 160 void* readFunctionPtr(); 161 SkFlattenable* readFlattenable(); 162 163private: 164 SkRefCnt** fRCArray; 165 int fRCCount; 166 167 SkTypeface** fTFArray; 168 int fTFCount; 169 170 SkTDArray<SkFlattenable::Factory>* fFactoryTDArray; 171 SkFlattenable::Factory* fFactoryArray; 172 int fFactoryCount; 173 174 typedef SkReader32 INHERITED; 175}; 176 177/////////////////////////////////////////////////////////////////////////////// 178 179#include "SkPtrRecorder.h" 180 181/** 182 * Subclass of SkTPtrSet specialed to call ref() and unref() when the 183 * base class's incPtr() and decPtr() are called. This makes it a valid owner 184 * of each ptr, which is released when the set is reset or destroyed. 185 */ 186class SkRefCntSet : public SkTPtrSet<SkRefCnt*> { 187public: 188 virtual ~SkRefCntSet(); 189 190protected: 191 // overrides 192 virtual void incPtr(void*); 193 virtual void decPtr(void*); 194}; 195 196class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {}; 197 198class SkFlattenableWriteBuffer : public SkWriter32 { 199public: 200 SkFlattenableWriteBuffer(size_t minSize); 201 virtual ~SkFlattenableWriteBuffer(); 202 203 void writeTypeface(SkTypeface*); 204 void writeRefCnt(SkRefCnt*); 205 void writeFunctionPtr(void*); 206 void writeFlattenable(SkFlattenable* flattenable); 207 208 SkRefCntSet* getTypefaceRecorder() const { return fTFSet; } 209 SkRefCntSet* setTypefaceRecorder(SkRefCntSet*); 210 211 SkRefCntSet* getRefCntRecorder() const { return fRCSet; } 212 SkRefCntSet* setRefCntRecorder(SkRefCntSet*); 213 214 SkFactorySet* getFactoryRecorder() const { return fFactorySet; } 215 SkFactorySet* setFactoryRecorder(SkFactorySet*); 216 217 enum Flags { 218 kCrossProcess_Flag = 0x01, 219 /** 220 * Instructs the writer to inline Factory names as there are seen the 221 * first time (after that we store an index). The pipe code uses this. 222 */ 223 kInlineFactoryNames_Flag = 0x02, 224 }; 225 Flags getFlags() const { return (Flags)fFlags; } 226 void setFlags(Flags flags) { fFlags = flags; } 227 228 bool isCrossProcess() const { 229 return SkToBool(fFlags & kCrossProcess_Flag); 230 } 231 bool inlineFactoryNames() const { 232 return SkToBool(fFlags & kInlineFactoryNames_Flag); 233 } 234 235 bool persistBitmapPixels() const { 236 return (fFlags & kCrossProcess_Flag) != 0; 237 } 238 239 bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; } 240 241private: 242 uint32_t fFlags; 243 SkRefCntSet* fTFSet; 244 SkRefCntSet* fRCSet; 245 SkFactorySet* fFactorySet; 246 247 typedef SkWriter32 INHERITED; 248}; 249 250#endif 251 252