Home | History | Annotate | Download | only in contrib
      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