1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkFlattenable_DEFINED 9 #define SkFlattenable_DEFINED 10 11 #include "SkRefCnt.h" 12 13 class SkData; 14 class SkReadBuffer; 15 class SkWriteBuffer; 16 17 struct SkSerialProcs; 18 struct SkDeserialProcs; 19 20 /* 21 * Flattening is straight-forward: 22 * 1. call getFactory() so we have a function-ptr to recreate the subclass 23 * 2. call flatten(buffer) to write out enough data for the factory to read 24 * 25 * Unflattening is easy for the caller: new_instance = factory(buffer) 26 * 27 * The complexity of supporting this is as follows. 28 * 29 * If your subclass wants to control unflattening, use this macro in your declaration: 30 * SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS 31 * This will provide a getFactory(), and require that the subclass implements CreateProc. 32 * 33 * For older buffers (before the DEEPFLATTENING change, the macros below declare 34 * a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep, 35 * then it calls through to a (usually protected) constructor, passing the buffer. 36 * If the buffer is newer, then it directly calls the "real" factory: CreateProc. 37 */ 38 39 #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables(); 40 41 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \ 42 void flattenable::InitializeFlattenables() { 43 44 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \ 45 } 46 47 #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ 48 SkFlattenable::Register(#flattenable, flattenable::CreateProc, \ 49 flattenable::GetFlattenableType()); 50 51 #define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ 52 private: \ 53 static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&); \ 54 friend class SkFlattenable::PrivateInitializer; \ 55 public: \ 56 Factory getFactory() const override { return CreateProc; } 57 58 /** For SkFlattenable derived objects with a valid type 59 This macro should only be used in base class objects in core 60 */ 61 #define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \ 62 static Type GetFlattenableType() { \ 63 return k##flattenable##_Type; \ 64 } \ 65 Type getFlattenableType() const override { \ 66 return k##flattenable##_Type; \ 67 } \ 68 static sk_sp<flattenable> Deserialize(const void* data, size_t size, \ 69 const SkDeserialProcs* procs = nullptr) { \ 70 return sk_sp<flattenable>(static_cast<flattenable*>( \ 71 SkFlattenable::Deserialize( \ 72 k##flattenable##_Type, data, size, procs).release()));\ 73 } 74 75 /** \class SkFlattenable 76 77 SkFlattenable is the base class for objects that need to be flattened 78 into a data stream for either transport or as part of the key to the 79 font cache. 80 */ 81 class SK_API SkFlattenable : public SkRefCnt { 82 public: 83 enum Type { 84 kSkColorFilter_Type, 85 kSkDrawable_Type, 86 kSkDrawLooper_Type, 87 kSkImageFilter_Type, 88 kSkMaskFilter_Type, 89 kSkPathEffect_Type, 90 kSkPixelRef_Type, 91 kSkUnused_Type4, // used to be SkRasterizer 92 kSkShaderBase_Type, 93 kSkUnused_Type, // used to be SkUnitMapper 94 kSkUnused_Type2, 95 kSkUnused_Type3, // used to be SkNormalSource 96 }; 97 98 typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&); 99 SkFlattenable()100 SkFlattenable() {} 101 102 /** Implement this to return a factory function pointer that can be called 103 to recreate your class given a buffer (previously written to by your 104 override of flatten(). 105 */ 106 virtual Factory getFactory() const = 0; 107 108 /** 109 * Returns the name of the object's class. 110 * 111 * Subclasses should override this function if they intend to provide 112 * support for flattening without using the global registry. 113 * 114 * If the flattenable is registered, there is no need to override. 115 */ getTypeName()116 virtual const char* getTypeName() const { return FactoryToName(getFactory()); } 117 118 static Factory NameToFactory(const char name[]); 119 static const char* FactoryToName(Factory); 120 static bool NameToType(const char name[], Type* type); 121 122 static void Register(const char name[], Factory, Type); 123 124 /** 125 * Override this if your subclass needs to record data that it will need to recreate itself 126 * from its CreateProc (returned by getFactory()). 127 * 128 * DEPRECATED public : will move to protected ... use serialize() instead 129 */ flatten(SkWriteBuffer &)130 virtual void flatten(SkWriteBuffer&) const {} 131 132 virtual Type getFlattenableType() const = 0; 133 134 // 135 // public ways to serialize / deserialize 136 // 137 sk_sp<SkData> serialize(const SkSerialProcs* = nullptr) const; 138 static sk_sp<SkFlattenable> Deserialize(Type, const void* data, size_t length, 139 const SkDeserialProcs* procs = nullptr); 140 141 protected: 142 class PrivateInitializer { 143 public: 144 static void InitCore(); 145 static void InitEffects(); 146 }; 147 148 private: 149 static void InitializeFlattenablesIfNeeded(); 150 static void Finalize(); 151 152 friend class SkGraphics; 153 154 typedef SkRefCnt INHERITED; 155 }; 156 157 #endif 158