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 SkReadBuffer;
14 class SkWriteBuffer;
15 
16 class SkPrivateEffectInitializer;
17 
18 /*
19  *  Flattening is straight-forward:
20  *      1. call getFactory() so we have a function-ptr to recreate the subclass
21  *      2. call flatten(buffer) to write out enough data for the factory to read
22  *
23  *  Unflattening is easy for the caller: new_instance = factory(buffer)
24  *
25  *  The complexity of supporting this is as follows.
26  *
27  *  If your subclass wants to control unflattening, use this macro in your declaration:
28  *      SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
29  *  This will provide a getFactory(), and require that the subclass implements CreateProc.
30  *
31  *  For older buffers (before the DEEPFLATTENING change, the macros below declare
32  *  a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
33  *  then it calls through to a (usually protected) constructor, passing the buffer.
34  *  If the buffer is newer, then it directly calls the "real" factory: CreateProc.
35  */
36 
37 #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
38 
39 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
40     void flattenable::InitializeFlattenables() {
41 
42 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
43     }
44 
45 #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
46     SkFlattenable::Register(#flattenable, flattenable::CreateProc, \
47                             flattenable::GetFlattenableType());
48 
49 #define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
50     private:                                                                \
51     static SkFlattenable* CreateProc(SkReadBuffer&);                        \
52     friend class SkFlattenable::PrivateInitializer;                         \
53     public:                                                                 \
54     Factory getFactory() const override { return CreateProc; }
55 
56 /** For SkFlattenable derived objects with a valid type
57     This macro should only be used in base class objects in core
58   */
59 #define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
60     static Type GetFlattenableType() { \
61         return k##flattenable##_Type; \
62     }
63 
64 /** \class SkFlattenable
65 
66  SkFlattenable is the base class for objects that need to be flattened
67  into a data stream for either transport or as part of the key to the
68  font cache.
69  */
70 class SK_API SkFlattenable : public SkRefCnt {
71 public:
72     enum Type {
73         kSkColorFilter_Type,
74         kSkDrawLooper_Type,
75         kSkImageFilter_Type,
76         kSkMaskFilter_Type,
77         kSkPathEffect_Type,
78         kSkPixelRef_Type,
79         kSkRasterizer_Type,
80         kSkShader_Type,
81         kSkUnused_Type,     // used to be SkUnitMapper
82         kSkXfermode_Type,
83     };
84 
85     typedef SkFlattenable* (*Factory)(SkReadBuffer&);
86 
SkFlattenable()87     SkFlattenable() {}
88 
89     /** Implement this to return a factory function pointer that can be called
90      to recreate your class given a buffer (previously written to by your
91      override of flatten().
92      */
93     virtual Factory getFactory() const = 0;
94 
95     /** Returns the name of the object's class
96       */
getTypeName()97     const char* getTypeName() const { return FactoryToName(getFactory()); }
98 
99     static Factory NameToFactory(const char name[]);
100     static const char* FactoryToName(Factory);
101     static bool NameToType(const char name[], Type* type);
102 
103     static void Register(const char name[], Factory, Type);
104 
105     /**
106      *  Override this if your subclass needs to record data that it will need to recreate itself
107      *  from its CreateProc (returned by getFactory()).
108      */
flatten(SkWriteBuffer &)109     virtual void flatten(SkWriteBuffer&) const {}
110 
111 protected:
112     class PrivateInitializer {
113     public:
114         static void InitCore();
115         static void InitEffects();
116     };
117 
118 private:
119     static void InitializeFlattenablesIfNeeded();
120 
121     friend class SkGraphics;
122 
123     typedef SkRefCnt INHERITED;
124 };
125 
126 #endif
127