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