• 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 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 sk_sp<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         kSkDrawable_Type,
75         kSkDrawLooper_Type,
76         kSkImageFilter_Type,
77         kSkMaskFilter_Type,
78         kSkPathEffect_Type,
79         kSkPixelRef_Type,
80         kSkRasterizer_Type,
81         kSkShaderBase_Type,
82         kSkUnused_Type,     // used to be SkUnitMapper
83         kSkUnused_Xfermode_Type,
84         kSkNormalSource_Type,
85     };
86 
87     typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
88 
SkFlattenable()89     SkFlattenable() {}
90 
91     /** Implement this to return a factory function pointer that can be called
92      to recreate your class given a buffer (previously written to by your
93      override of flatten().
94      */
95     virtual Factory getFactory() const = 0;
96 
97     /**
98      *  Returns the name of the object's class.
99      *
100      *  Subclasses should override this function if they intend to provide
101      *  support for flattening without using the global registry.
102      *
103      *  If the flattenable is registered, there is no need to override.
104      */
getTypeName()105     virtual const char* getTypeName() const { return FactoryToName(getFactory()); }
106 
107     static Factory NameToFactory(const char name[]);
108     static const char* FactoryToName(Factory);
109     static bool NameToType(const char name[], Type* type);
110 
111     static void Register(const char name[], Factory, Type);
112 
113     /**
114      *  Override this if your subclass needs to record data that it will need to recreate itself
115      *  from its CreateProc (returned by getFactory()).
116      */
flatten(SkWriteBuffer &)117     virtual void flatten(SkWriteBuffer&) const {}
118 
119 protected:
120     class PrivateInitializer {
121     public:
122         static void InitCore();
123         static void InitEffects();
124     };
125 
126 private:
127     static void InitializeFlattenablesIfNeeded();
128 
129     friend class SkGraphics;
130 
131     typedef SkRefCnt INHERITED;
132 };
133 
134 #endif
135