2015-01-21 20:05:47 +00:00
|
|
|
Flattenables
|
|
|
|
============
|
|
|
|
|
2018-01-10 14:55:05 +00:00
|
|
|
Many objects in Skia, such as `SkShaders` and other effects on `SkPaint`, need to be
|
2015-01-21 20:05:47 +00:00
|
|
|
flattened into a data stream for either transport or as part of the key to the
|
2018-01-10 14:55:05 +00:00
|
|
|
font cache. Classes for these objects should derive from `SkFlattenable` or one of
|
2015-01-21 20:05:47 +00:00
|
|
|
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:
|
|
|
|
|
2018-01-10 14:55:05 +00:00
|
|
|
1: Override the method `flatten` (the default scope is protected):
|
2015-01-21 20:05:47 +00:00
|
|
|
|
|
|
|
<!--?prettify?-->
|
|
|
|
~~~~
|
2015-03-26 01:17:31 +00:00
|
|
|
virtual void flatten(SkFlattenableWriteBuffer& buffer) const override {
|
2015-01-21 20:05:47 +00:00
|
|
|
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
|
2018-01-10 14:55:05 +00:00
|
|
|
`SkFlattenableReadBuffer`:
|
2015-01-21 20:05:47 +00:00
|
|
|
|
|
|
|
<!--?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)
|
|
|
|
~~~~
|
|
|
|
|
2018-01-10 14:55:05 +00:00
|
|
|
4: If your class is declared in a `.cpp` file or in a private header file, create a
|
2015-01-21 20:05:47 +00:00
|
|
|
function to register its group:
|
|
|
|
This occurs in cases where the classes are hidden behind a factory, like many effects
|
2018-01-10 14:55:05 +00:00
|
|
|
and shaders are. Then in the parent class header file (such as `SkGradientShader`) you
|
2015-01-21 20:05:47 +00:00
|
|
|
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:
|
2018-01-10 14:55:05 +00:00
|
|
|
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`.
|
2015-01-21 20:05:47 +00:00
|
|
|
For a single flattenable add
|
|
|
|
|
|
|
|
<!--?prettify?-->
|
|
|
|
~~~~
|
|
|
|
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNewClass)
|
|
|
|
~~~~
|
|
|
|
|
|
|
|
For a group, add
|
|
|
|
|
|
|
|
<!--?prettify?-->
|
|
|
|
~~~~
|
|
|
|
SkGroupClass::InitializeFlattenables();
|
|
|
|
~~~~
|
|
|
|
|