SkFlattenable.h revision 4bdfb8c9d6482a56c7212034a6f73046227ed023
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 "SkReader32.h" 15#include "SkTDArray.h" 16#include "SkWriter32.h" 17 18class SkBitmap; 19class SkFlattenableReadBuffer; 20class SkFlattenableWriteBuffer; 21class SkPath; 22struct SkPoint; 23class SkString; 24 25#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 26 27#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \ 28 static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \ 29 flattenable::CreateProc); 30#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ 31 static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \ 32 flattenable::CreateProc); 33 34#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() 35#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) 36#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 37 38#else 39 40#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) 41#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ 42 SkFlattenable::Registrar(#flattenable, flattenable::CreateProc); 43 44#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables(); 45 46#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \ 47 void flattenable::InitializeFlattenables() { 48 49#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \ 50 } 51 52#endif 53 54#define SK_DECLARE_UNFLATTENABLE_OBJECT() \ 55 virtual Factory getFactory() SK_OVERRIDE { return NULL; }; \ 56 57#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ 58 virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }; \ 59 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \ 60 return SkNEW_ARGS(flattenable, (buffer)); \ 61 } 62 63/** \class SkFlattenable 64 65 SkFlattenable is the base class for objects that need to be flattened 66 into a data stream for either transport or as part of the key to the 67 font cache. 68 */ 69class SK_API SkFlattenable : public SkRefCnt { 70public: 71 typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&); 72 73 SkFlattenable() {} 74 75 /** Implement this to return a factory function pointer that can be called 76 to recreate your class given a buffer (previously written to by your 77 override of flatten(). 78 */ 79 virtual Factory getFactory() = 0; 80 81 static Factory NameToFactory(const char name[]); 82 static const char* FactoryToName(Factory); 83 static void Register(const char name[], Factory); 84 85 class Registrar { 86 public: 87 Registrar(const char name[], Factory factory) { 88 SkFlattenable::Register(name, factory); 89 } 90 }; 91 92protected: 93 SkFlattenable(SkFlattenableReadBuffer&) {} 94 /** Override this to write data specific to your subclass into the buffer, 95 being sure to call your super-class' version first. This data will later 96 be passed to your Factory function, returned by getFactory(). 97 */ 98 virtual void flatten(SkFlattenableWriteBuffer&) const; 99 100private: 101#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 102 static void InitializeFlattenables(); 103#endif 104 105 friend class SkGraphics; 106 friend class SkFlattenableWriteBuffer; 107}; 108 109// helpers for matrix and region 110 111class SkMatrix; 112extern void SkReadMatrix(SkReader32*, SkMatrix*); 113extern void SkWriteMatrix(SkWriter32*, const SkMatrix&); 114 115class SkRegion; 116extern void SkReadRegion(SkReader32*, SkRegion*); 117extern void SkWriteRegion(SkWriter32*, const SkRegion&); 118 119/////////////////////////////////////////////////////////////////////////////// 120/////////////////////////////////////////////////////////////////////////////// 121 122class SkTypeface; 123 124class SkFlattenableReadBuffer { 125public: 126 SkFlattenableReadBuffer(); 127 virtual ~SkFlattenableReadBuffer() {} 128 129 130 virtual uint8_t readU8() = 0; 131 virtual uint16_t readU16() = 0; 132 virtual uint32_t readU32() = 0; 133 virtual void read(void* dst, size_t size) = 0; 134 virtual bool readBool() = 0; 135 virtual int32_t readInt() = 0; 136 virtual SkScalar readScalar() = 0; 137 virtual const void* skip(size_t size) = 0; 138 139 virtual int32_t readS32() { return readInt(); } 140 template <typename T> const T& skipT() { 141 SkASSERT(SkAlign4(sizeof(T)) == sizeof(T)); 142 return *(const T*)this->skip(sizeof(T)); 143 } 144 145 virtual void readMatrix(SkMatrix*) = 0; 146 virtual void readPath(SkPath*) = 0; 147 virtual void readPoint(SkPoint*) = 0; 148 149 // helper function for classes with const SkPoint members 150 SkPoint readPoint() { 151 SkPoint point; 152 this->readPoint(&point); 153 return point; 154 } 155 156 void setRefCntArray(SkRefCnt* array[], int count) { 157 fRCArray = array; 158 fRCCount = count; 159 } 160 161 void setTypefaceArray(SkTypeface* array[], int count) { 162 fTFArray = array; 163 fTFCount = count; 164 } 165 166 /** 167 * Call this with a pre-loaded array of Factories, in the same order as 168 * were created/written by the writer. SkPicture uses this. 169 */ 170 void setFactoryPlayback(SkFlattenable::Factory array[], int count) { 171 fFactoryTDArray = NULL; 172 fFactoryArray = array; 173 fFactoryCount = count; 174 } 175 176 /** 177 * Call this with an initially empty array, so the reader can cache each 178 * factory it sees by name. Used by the pipe code in conjunction with 179 * the writer's kInlineFactoryNames_Flag. 180 */ 181 void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) { 182 fFactoryTDArray = array; 183 fFactoryArray = NULL; 184 fFactoryCount = 0; 185 } 186 187 virtual SkTypeface* readTypeface() = 0; 188 virtual SkRefCnt* readRefCnt() = 0; 189 virtual void* readFunctionPtr() = 0; 190 virtual SkFlattenable* readFlattenable() = 0; 191 192protected: 193 SkRefCnt** fRCArray; 194 int fRCCount; 195 196 SkTypeface** fTFArray; 197 int fTFCount; 198 199 SkTDArray<SkFlattenable::Factory>* fFactoryTDArray; 200 SkFlattenable::Factory* fFactoryArray; 201 int fFactoryCount; 202}; 203 204/////////////////////////////////////////////////////////////////////////////// 205 206#include "SkPtrRecorder.h" 207 208/** 209 * Subclass of SkTPtrSet specialed to call ref() and unref() when the 210 * base class's incPtr() and decPtr() are called. This makes it a valid owner 211 * of each ptr, which is released when the set is reset or destroyed. 212 */ 213class SkRefCntSet : public SkTPtrSet<SkRefCnt*> { 214public: 215 virtual ~SkRefCntSet(); 216 217protected: 218 // overrides 219 virtual void incPtr(void*); 220 virtual void decPtr(void*); 221}; 222 223class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {}; 224 225class SkFlattenableWriteBuffer { 226public: 227 SkFlattenableWriteBuffer(); 228 virtual ~SkFlattenableWriteBuffer(); 229 230 // deprecated naming convention that will be removed after callers are updated 231 virtual bool writeBool(bool value) = 0; 232 virtual void writeInt(int32_t value) = 0; 233 virtual void write8(int32_t value) = 0; 234 virtual void write16(int32_t value) = 0; 235 virtual void write32(int32_t value) = 0; 236 virtual void writeScalar(SkScalar value) = 0; 237 virtual void writeMul4(const void* values, size_t size) = 0; 238 239 virtual void writePad(const void* src, size_t size) = 0; 240 virtual void writeString(const char* str, size_t len = (size_t)-1) = 0; 241 virtual uint32_t* reserve(size_t size) = 0; 242 virtual void flatten(void* dst) = 0; 243 virtual uint32_t size() = 0; 244 virtual void write(const void* values, size_t size) = 0; 245 virtual void writeRect(const SkRect& rect) = 0; 246 virtual size_t readFromStream(SkStream*, size_t length) = 0; 247 248 virtual void writeMatrix(const SkMatrix& matrix) = 0; 249 virtual void writePath(const SkPath& path) = 0; 250 virtual void writePoint(const SkPoint& point) = 0; 251 252 virtual bool writeToStream(SkWStream*) = 0; 253 254 virtual void writeFunctionPtr(void*)= 0; 255 virtual void writeFlattenable(SkFlattenable* flattenable)= 0; 256 257 void writeTypeface(SkTypeface*); 258 void writeRefCnt(SkRefCnt* obj); 259 260 SkRefCntSet* getTypefaceRecorder() const { return fTFSet; } 261 SkRefCntSet* setTypefaceRecorder(SkRefCntSet*); 262 263 SkRefCntSet* getRefCntRecorder() const { return fRCSet; } 264 SkRefCntSet* setRefCntRecorder(SkRefCntSet*); 265 266 SkFactorySet* getFactoryRecorder() const { return fFactorySet; } 267 SkFactorySet* setFactoryRecorder(SkFactorySet*); 268 269 enum Flags { 270 kCrossProcess_Flag = 0x01, 271 /** 272 * Instructs the writer to inline Factory names as there are seen the 273 * first time (after that we store an index). The pipe code uses this. 274 */ 275 kInlineFactoryNames_Flag = 0x02, 276 /** 277 * Instructs the writer to always serialize bitmap pixel data. 278 */ 279 kForceFlattenBitmapPixels_Flag = 0x04 280 }; 281 282 uint32_t getFlags() const { return fFlags; } 283 void setFlags(uint32_t flags) { fFlags = flags; } 284 285 bool isCrossProcess() const { 286 return SkToBool(fFlags & kCrossProcess_Flag); 287 } 288 bool inlineFactoryNames() const { 289 return SkToBool(fFlags & kInlineFactoryNames_Flag); 290 } 291 292 bool persistBitmapPixels() const { 293 return (fFlags & (kCrossProcess_Flag | kForceFlattenBitmapPixels_Flag)) != 0; 294 } 295 296 bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; } 297 298protected: 299 300 // A helper function so that each subclass does not have to be a friend of 301 // SkFlattenable. 302 void flattenObject(SkFlattenable* obj, SkFlattenableWriteBuffer& buffer) { 303 obj->flatten(buffer); 304 } 305 306 uint32_t fFlags; 307 SkRefCntSet* fTFSet; 308 SkRefCntSet* fRCSet; 309 SkFactorySet* fFactorySet; 310}; 311 312#endif 313 314