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