1 Flattenables 2 ============ 3 4 Many objects in Skia, such as `SkShaders` and other effects on `SkPaint`, need to be 5 flattened into a data stream for either transport or as part of the key to the 6 font cache. Classes for these objects should derive from `SkFlattenable` or one of 7 its subclasses. If you create a new flattenable class, you need to make sure you 8 do a few things so that it will work on all platforms: 9 10 1: Override the method `flatten` (the default scope is protected): 11 12 <!--?prettify?--> 13 ~~~~ 14 virtual void flatten(SkFlattenableWriteBuffer& buffer) const override { 15 this->INHERITED::flatten(buffer); 16 // Write any private data that needs to be stored to recreate this object 17 } 18 ~~~~ 19 20 2: Override the (protected) constructor that creates an object from an 21 `SkFlattenableReadBuffer`: 22 23 <!--?prettify?--> 24 ~~~~ 25 SkNewClass(SkFlattenableReadBuffer& buffer) 26 : INHERITED(buffer) { 27 // Read the data from the buffer in the same order as it was written to the 28 // SkFlattenableWriteBuffer and construct the new object 29 } 30 ~~~~ 31 32 3: Declare a set of deserialization procs for your object in the class declaration: 33 We have a macro for this: 34 35 <!--?prettify?--> 36 ~~~~ 37 public: 38 39 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNewClass) 40 ~~~~ 41 42 4: If your class is declared in a `.cpp` file or in a private header file, create a 43 function to register its group: 44 This occurs in cases where the classes are hidden behind a factory, like many effects 45 and shaders are. Then in the parent class header file (such as `SkGradientShader`) you 46 need to add: 47 48 <!--?prettify?--> 49 ~~~~ 50 public: 51 52 SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() 53 ~~~~ 54 55 Then in the cpp file you define all the members of the group together: 56 57 <!--?prettify?--> 58 ~~~~ 59 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGroupClass) 60 61 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMemberClass1) 62 63 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMemberClass2) 64 65 // etc 66 67 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 68 ~~~~ 69 70 71 5: Register your flattenable with the global registrar: 72 You need to add one line to `SkFlattenable::InitalizeFlattenables()`. To register the 73 flattenable in a Skia build, that function is defined in `SkGlobalInitialization_default.cpp`. 74 For Chromium, it is in `SkGlobalInitialization_chromium.cpp`. 75 For a single flattenable add 76 77 <!--?prettify?--> 78 ~~~~ 79 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNewClass) 80 ~~~~ 81 82 For a group, add 83 84 <!--?prettify?--> 85 ~~~~ 86 SkGroupClass::InitializeFlattenables(); 87 ~~~~ 88 89