• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SkData;
14 class SkReadBuffer;
15 class SkWriteBuffer;
16 
17 struct SkSerialProcs;
18 struct SkDeserialProcs;
19 
20 /*
21  *  Flattening is straight-forward:
22  *      1. call getFactory() so we have a function-ptr to recreate the subclass
23  *      2. call flatten(buffer) to write out enough data for the factory to read
24  *
25  *  Unflattening is easy for the caller: new_instance = factory(buffer)
26  *
27  *  The complexity of supporting this is as follows.
28  *
29  *  If your subclass wants to control unflattening, use this macro in your declaration:
30  *      SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
31  *  This will provide a getFactory(), and require that the subclass implements CreateProc.
32  *
33  *  For older buffers (before the DEEPFLATTENING change, the macros below declare
34  *  a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
35  *  then it calls through to a (usually protected) constructor, passing the buffer.
36  *  If the buffer is newer, then it directly calls the "real" factory: CreateProc.
37  */
38 
39 #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
40 
41 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
42     void flattenable::InitializeFlattenables() {
43 
44 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
45     }
46 
47 #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
48     SkFlattenable::Register(#flattenable, flattenable::CreateProc, \
49                             flattenable::GetFlattenableType());
50 
51 #define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
52     private:                                                                \
53     static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);                        \
54     friend class SkFlattenable::PrivateInitializer;                         \
55     public:                                                                 \
56     Factory getFactory() const override { return CreateProc; }
57 
58 /** For SkFlattenable derived objects with a valid type
59     This macro should only be used in base class objects in core
60   */
61 #define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
62     static Type GetFlattenableType() {          \
63         return k##flattenable##_Type;           \
64     }                                           \
65     Type getFlattenableType() const override {  \
66         return k##flattenable##_Type;           \
67     }                                           \
68     static sk_sp<flattenable> Deserialize(const void* data, size_t size,                \
69                                           const SkDeserialProcs* procs = nullptr) {     \
70         return sk_sp<flattenable>(static_cast<flattenable*>(                            \
71                                   SkFlattenable::Deserialize(                           \
72                                   k##flattenable##_Type, data, size, procs).release()));\
73     }
74 
75 /** \class SkFlattenable
76 
77  SkFlattenable is the base class for objects that need to be flattened
78  into a data stream for either transport or as part of the key to the
79  font cache.
80  */
81 class SK_API SkFlattenable : public SkRefCnt {
82 public:
83     enum Type {
84         kSkColorFilter_Type,
85         kSkDrawable_Type,
86         kSkDrawLooper_Type,
87         kSkImageFilter_Type,
88         kSkMaskFilter_Type,
89         kSkPathEffect_Type,
90         kSkPixelRef_Type,
91         kSkUnused_Type4,    // used to be SkRasterizer
92         kSkShaderBase_Type,
93         kSkUnused_Type,     // used to be SkUnitMapper
94         kSkUnused_Type2,
95         kSkUnused_Type3,    // used to be SkNormalSource
96     };
97 
98     typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
99 
SkFlattenable()100     SkFlattenable() {}
101 
102     /** Implement this to return a factory function pointer that can be called
103      to recreate your class given a buffer (previously written to by your
104      override of flatten().
105      */
106     virtual Factory getFactory() const = 0;
107 
108     /**
109      *  Returns the name of the object's class.
110      *
111      *  Subclasses should override this function if they intend to provide
112      *  support for flattening without using the global registry.
113      *
114      *  If the flattenable is registered, there is no need to override.
115      */
getTypeName()116     virtual const char* getTypeName() const { return FactoryToName(getFactory()); }
117 
118     static Factory NameToFactory(const char name[]);
119     static const char* FactoryToName(Factory);
120     static bool NameToType(const char name[], Type* type);
121 
122     static void Register(const char name[], Factory, Type);
123 
124     /**
125      *  Override this if your subclass needs to record data that it will need to recreate itself
126      *  from its CreateProc (returned by getFactory()).
127      *
128      *  DEPRECATED public : will move to protected ... use serialize() instead
129      */
flatten(SkWriteBuffer &)130     virtual void flatten(SkWriteBuffer&) const {}
131 
132     virtual Type getFlattenableType() const = 0;
133 
134     //
135     // public ways to serialize / deserialize
136     //
137     sk_sp<SkData> serialize(const SkSerialProcs* = nullptr) const;
138     static sk_sp<SkFlattenable> Deserialize(Type, const void* data, size_t length,
139                                             const SkDeserialProcs* procs = nullptr);
140 
141 protected:
142     class PrivateInitializer {
143     public:
144         static void InitCore();
145         static void InitEffects();
146     };
147 
148 private:
149     static void InitializeFlattenablesIfNeeded();
150     static void Finalize();
151 
152     friend class SkGraphics;
153 
154     typedef SkRefCnt INHERITED;
155 };
156 
157 #endif
158