SkFlattenable.h revision 8811e40850ac3310c17fe8cdaffe72817a5e317d
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
13class SkReadBuffer;
14class SkWriteBuffer;
15
16class 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 */
70class SK_API SkFlattenable : public SkRefCnt {
71public:
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        kSkShader_Type,
82        kSkUnused_Type,     // used to be SkUnitMapper
83        kSkXfermode_Type,
84        kNormalSource_Type,
85    };
86
87    typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
88
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     */
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     */
117    virtual void flatten(SkWriteBuffer&) const {}
118
119protected:
120    class PrivateInitializer {
121    public:
122        static void InitCore();
123        static void InitEffects();
124    };
125
126private:
127    static void InitializeFlattenablesIfNeeded();
128
129    friend class SkGraphics;
130
131    typedef SkRefCnt INHERITED;
132};
133
134#endif
135