18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkFlattenable_DEFINED
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkFlattenable_DEFINED
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRefCnt.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reedclass SkData;
148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgclass SkReadBuffer;
158b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgclass SkWriteBuffer;
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reedstruct SkSerialProcs;
18fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reedstruct SkDeserialProcs;
19ab374cf894f136418ad573dfb5da4fcb48f47db0mtklein
209fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed/*
219fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  Flattening is straight-forward:
229fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *      1. call getFactory() so we have a function-ptr to recreate the subclass
239fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *      2. call flatten(buffer) to write out enough data for the factory to read
249fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *
259fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  Unflattening is easy for the caller: new_instance = factory(buffer)
269fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *
279fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  The complexity of supporting this is as follows.
289fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *
299fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  If your subclass wants to control unflattening, use this macro in your declaration:
309fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *      SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
319fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  This will provide a getFactory(), and require that the subclass implements CreateProc.
329fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *
339fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  For older buffers (before the DEEPFLATTENING change, the macros below declare
349fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
359fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  then it calls through to a (usually protected) constructor, passing the buffer.
369fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  If the buffer is newer, then it directly calls the "real" factory: CreateProc.
379fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed */
38d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
39a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
40d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
41d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
42a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com    void flattenable::InitializeFlattenables() {
43a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com
44d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
45d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    }
46d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
479fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
483b37545bc594a96de45eba62dea0ce478750f2a9mtklein    SkFlattenable::Register(#flattenable, flattenable::CreateProc, \
493b37545bc594a96de45eba62dea0ce478750f2a9mtklein                            flattenable::GetFlattenableType());
509fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
519fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
529fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    private:                                                                \
5360c9b58b3214b0154c931656e91e39b230e987d8reed    static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);                        \
546054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed    friend class SkFlattenable::PrivateInitializer;                         \
559fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    public:                                                                 \
5636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    Factory getFactory() const override { return CreateProc; }
579fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
583b37545bc594a96de45eba62dea0ce478750f2a9mtklein/** For SkFlattenable derived objects with a valid type
593b37545bc594a96de45eba62dea0ce478750f2a9mtklein    This macro should only be used in base class objects in core
603b37545bc594a96de45eba62dea0ce478750f2a9mtklein  */
613b37545bc594a96de45eba62dea0ce478750f2a9mtklein#define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
6258a3fcd4b3a2f7210586f4ec74dde8ac2b231e0fMike Reed    static Type GetFlattenableType() {          \
6358a3fcd4b3a2f7210586f4ec74dde8ac2b231e0fMike Reed        return k##flattenable##_Type;           \
6458a3fcd4b3a2f7210586f4ec74dde8ac2b231e0fMike Reed    }                                           \
6558a3fcd4b3a2f7210586f4ec74dde8ac2b231e0fMike Reed    Type getFlattenableType() const override {  \
6658a3fcd4b3a2f7210586f4ec74dde8ac2b231e0fMike Reed        return k##flattenable##_Type;           \
6792a2cfbcce155a05a34b4afeea7b1d0344effe82Mike Reed    }                                           \
6892a2cfbcce155a05a34b4afeea7b1d0344effe82Mike Reed    static sk_sp<flattenable> Deserialize(const void* data, size_t size,                \
6992a2cfbcce155a05a34b4afeea7b1d0344effe82Mike Reed                                          const SkDeserialProcs* procs = nullptr) {     \
7092a2cfbcce155a05a34b4afeea7b1d0344effe82Mike Reed        return sk_sp<flattenable>(static_cast<flattenable*>(                            \
7192a2cfbcce155a05a34b4afeea7b1d0344effe82Mike Reed                                  SkFlattenable::Deserialize(                           \
7292a2cfbcce155a05a34b4afeea7b1d0344effe82Mike Reed                                  k##flattenable##_Type, data, size, procs).release()));\
733b37545bc594a96de45eba62dea0ce478750f2a9mtklein    }
743b37545bc594a96de45eba62dea0ce478750f2a9mtklein
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkFlattenable
76fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable is the base class for objects that need to be flattened
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com into a data stream for either transport or as part of the key to the
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com font cache.
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
817ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkFlattenable : public SkRefCnt {
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
833b37545bc594a96de45eba62dea0ce478750f2a9mtklein    enum Type {
843b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkColorFilter_Type,
85edf7fcd8b9e339800edb61ae422f8b6c1b77c3e8msarett        kSkDrawable_Type,
863b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkDrawLooper_Type,
873b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkImageFilter_Type,
883b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkMaskFilter_Type,
893b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkPathEffect_Type,
903b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkPixelRef_Type,
918ad91a9bf896d728b905124847d74787aac698a7Mike Reed        kSkUnused_Type4,    // used to be SkRasterizer
924aed13889bd9085337e0d4c20df28686687b833bFlorin Malita        kSkShaderBase_Type,
933b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkUnused_Type,     // used to be SkUnitMapper
946dd8cf144ecbc395dc12bd5f775bbeee04b9d38cRobert Phillips        kSkUnused_Type2,
956dd8cf144ecbc395dc12bd5f775bbeee04b9d38cRobert Phillips        kSkUnused_Type3,    // used to be SkNormalSource
963b37545bc594a96de45eba62dea0ce478750f2a9mtklein    };
973b37545bc594a96de45eba62dea0ce478750f2a9mtklein
9860c9b58b3214b0154c931656e91e39b230e987d8reed    typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
99fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable() {}
101fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Implement this to return a factory function pointer that can be called
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     to recreate your class given a buffer (previously written to by your
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     override of flatten().
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
106c2eae4795478ab134a2315b1a9ff2c5de1d049e4robertphillips@google.com    virtual Factory getFactory() const = 0;
107fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
108a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett    /**
109a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *  Returns the name of the object's class.
110a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *
111a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *  Subclasses should override this function if they intend to provide
112a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *  support for flattening without using the global registry.
113a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *
114a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *  If the flattenable is registered, there is no need to override.
115a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     */
116a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett    virtual const char* getTypeName() const { return FactoryToName(getFactory()); }
117c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static Factory NameToFactory(const char name[]);
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static const char* FactoryToName(Factory);
1203b37545bc594a96de45eba62dea0ce478750f2a9mtklein    static bool NameToType(const char name[], Type* type);
121c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org
1223b37545bc594a96de45eba62dea0ce478750f2a9mtklein    static void Register(const char name[], Factory, Type);
123a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com
1249fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    /**
1259fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed     *  Override this if your subclass needs to record data that it will need to recreate itself
1269fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed     *  from its CreateProc (returned by getFactory()).
127fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed     *
128fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed     *  DEPRECATED public : will move to protected ... use serialize() instead
12954924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com     */
1309fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    virtual void flatten(SkWriteBuffer&) const {}
1318b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org
13258a3fcd4b3a2f7210586f4ec74dde8ac2b231e0fMike Reed    virtual Type getFlattenableType() const = 0;
13358a3fcd4b3a2f7210586f4ec74dde8ac2b231e0fMike Reed
134fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed    //
135fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed    // public ways to serialize / deserialize
136fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed    //
137fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed    sk_sp<SkData> serialize(const SkSerialProcs* = nullptr) const;
138fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed    static sk_sp<SkFlattenable> Deserialize(Type, const void* data, size_t length,
139fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed                                            const SkDeserialProcs* procs = nullptr);
140fadbfcd4aba676d44dfb08de1a83143a1c63b95cMike Reed
1416054d686e6fecc7261eeb328f27e9e16cd1d3b1ereedprotected:
1426054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed    class PrivateInitializer {
1436054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed    public:
1446054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed        static void InitCore();
1456054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed        static void InitEffects();
1466054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed    };
1476054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed
148d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comprivate:
149c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    static void InitializeFlattenablesIfNeeded();
150ad6660a639aba236c9d30485da1cd2bb1292ef83Vladimir Levin    static void Finalize();
1519d0c6ecb8440e8e546881a4ff850eb6333f24541caryclark@google.com
1529d0c6ecb8440e8e546881a4ff850eb6333f24541caryclark@google.com    friend class SkGraphics;
15315e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
15415e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com    typedef SkRefCnt INHERITED;
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
158