aboutsummaryrefslogtreecommitdiffhomepage
path: root/site/dev/contrib/flatten.md
blob: 0b3663f560b654a9785c062fbbf8f99c46e1fb93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
Flattenables
============

Many objects in Skia, such as `SkShaders` and other effects on `SkPaint`, need to be 
flattened into a data stream for either transport or as part of the key to the 
font cache. Classes for these objects should derive from `SkFlattenable` or one of 
its subclasses. If you create a new flattenable class, you need to make sure you 
do a few things so that it will work on all platforms:

1: Override the method `flatten` (the default scope is protected):

<!--?prettify?-->
~~~~
virtual void flatten(SkFlattenableWriteBuffer& buffer) const override {
    this->INHERITED::flatten(buffer);
    // Write any private data that needs to be stored to recreate this object
}
~~~~

2: Override the (protected) constructor that creates an object from an 
`SkFlattenableReadBuffer`:

<!--?prettify?-->
~~~~
SkNewClass(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer) {
    // Read the data from the buffer in the same order as it was written to the
    // SkFlattenableWriteBuffer and construct the new object
}
~~~~

3: Declare a set of deserialization procs for your object in the class declaration:
We have a macro for this:

<!--?prettify?-->
~~~~
public:

SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNewClass)
~~~~

4: If your class is declared in a `.cpp` file or in a private header file, create a 
function to register its group:
This occurs in cases where the classes are hidden behind a factory, like many effects 
and shaders are.  Then in the parent class header file (such as `SkGradientShader`) you 
need to add:

<!--?prettify?-->
~~~~
public:

SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
~~~~

Then in the cpp file you define all the members of the group together:

<!--?prettify?-->
~~~~
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGroupClass)

    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMemberClass1)

    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMemberClass2)

    // etc

SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
~~~~


5: Register your flattenable with the global registrar:
You need to add one line to `SkFlattenable::InitalizeFlattenables()`. To register the 
flattenable in a Skia build, that function is defined in `SkGlobalInitialization_default.cpp`. 
For Chromium, it is in `SkGlobalInitialization_chromium.cpp`.
For a single flattenable add

<!--?prettify?-->
~~~~
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNewClass)
~~~~

For a group, add

<!--?prettify?-->
~~~~
SkGroupClass::InitializeFlattenables();
~~~~