SkFlattenable.h revision 6dd8cf144ecbc395dc12bd5f775bbeee04b9d38c
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
138b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgclass SkReadBuffer;
148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgclass SkWriteBuffer;
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
16ab374cf894f136418ad573dfb5da4fcb48f47db0mtkleinclass SkPrivateEffectInitializer;
17ab374cf894f136418ad573dfb5da4fcb48f47db0mtklein
189fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed/*
199fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  Flattening is straight-forward:
209fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *      1. call getFactory() so we have a function-ptr to recreate the subclass
219fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *      2. call flatten(buffer) to write out enough data for the factory to read
229fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *
239fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  Unflattening is easy for the caller: new_instance = factory(buffer)
249fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *
259fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  The complexity of supporting this is as follows.
269fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *
279fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  If your subclass wants to control unflattening, use this macro in your declaration:
289fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *      SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
299fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  This will provide a getFactory(), and require that the subclass implements CreateProc.
309fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *
319fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  For older buffers (before the DEEPFLATTENING change, the macros below declare
329fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
339fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  then it calls through to a (usually protected) constructor, passing the buffer.
349fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed *  If the buffer is newer, then it directly calls the "real" factory: CreateProc.
359fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed */
36d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
37a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
38d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
39d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
40a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com    void flattenable::InitializeFlattenables() {
41a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com
42d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
43d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    }
44d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
459fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
463b37545bc594a96de45eba62dea0ce478750f2a9mtklein    SkFlattenable::Register(#flattenable, flattenable::CreateProc, \
473b37545bc594a96de45eba62dea0ce478750f2a9mtklein                            flattenable::GetFlattenableType());
489fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
499fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
509fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    private:                                                                \
5160c9b58b3214b0154c931656e91e39b230e987d8reed    static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);                        \
526054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed    friend class SkFlattenable::PrivateInitializer;                         \
539fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    public:                                                                 \
5436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    Factory getFactory() const override { return CreateProc; }
559fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
563b37545bc594a96de45eba62dea0ce478750f2a9mtklein/** For SkFlattenable derived objects with a valid type
573b37545bc594a96de45eba62dea0ce478750f2a9mtklein    This macro should only be used in base class objects in core
583b37545bc594a96de45eba62dea0ce478750f2a9mtklein  */
593b37545bc594a96de45eba62dea0ce478750f2a9mtklein#define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
603b37545bc594a96de45eba62dea0ce478750f2a9mtklein    static Type GetFlattenableType() { \
613b37545bc594a96de45eba62dea0ce478750f2a9mtklein        return k##flattenable##_Type; \
623b37545bc594a96de45eba62dea0ce478750f2a9mtklein    }
633b37545bc594a96de45eba62dea0ce478750f2a9mtklein
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkFlattenable
65fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable is the base class for objects that need to be flattened
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com into a data stream for either transport or as part of the key to the
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com font cache.
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
707ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkFlattenable : public SkRefCnt {
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
723b37545bc594a96de45eba62dea0ce478750f2a9mtklein    enum Type {
733b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkColorFilter_Type,
74edf7fcd8b9e339800edb61ae422f8b6c1b77c3e8msarett        kSkDrawable_Type,
753b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkDrawLooper_Type,
763b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkImageFilter_Type,
773b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkMaskFilter_Type,
783b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkPathEffect_Type,
793b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkPixelRef_Type,
803b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkRasterizer_Type,
814aed13889bd9085337e0d4c20df28686687b833bFlorin Malita        kSkShaderBase_Type,
823b37545bc594a96de45eba62dea0ce478750f2a9mtklein        kSkUnused_Type,     // used to be SkUnitMapper
836dd8cf144ecbc395dc12bd5f775bbeee04b9d38cRobert Phillips        kSkUnused_Type2,
846dd8cf144ecbc395dc12bd5f775bbeee04b9d38cRobert Phillips        kSkUnused_Type3,    // used to be SkNormalSource
853b37545bc594a96de45eba62dea0ce478750f2a9mtklein    };
863b37545bc594a96de45eba62dea0ce478750f2a9mtklein
8760c9b58b3214b0154c931656e91e39b230e987d8reed    typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
88fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable() {}
90fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Implement this to return a factory function pointer that can be called
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     to recreate your class given a buffer (previously written to by your
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     override of flatten().
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
95c2eae4795478ab134a2315b1a9ff2c5de1d049e4robertphillips@google.com    virtual Factory getFactory() const = 0;
96fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
97a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett    /**
98a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *  Returns the name of the object's class.
99a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *
100a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *  Subclasses should override this function if they intend to provide
101a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *  support for flattening without using the global registry.
102a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *
103a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     *  If the flattenable is registered, there is no need to override.
104a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett     */
105a3b3b238f507a6ec7f43febc6bf0bb17e04e770fmsarett    virtual const char* getTypeName() const { return FactoryToName(getFactory()); }
106c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static Factory NameToFactory(const char name[]);
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static const char* FactoryToName(Factory);
1093b37545bc594a96de45eba62dea0ce478750f2a9mtklein    static bool NameToType(const char name[], Type* type);
110c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org
1113b37545bc594a96de45eba62dea0ce478750f2a9mtklein    static void Register(const char name[], Factory, Type);
112a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com
1139fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    /**
1149fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed     *  Override this if your subclass needs to record data that it will need to recreate itself
1159fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed     *  from its CreateProc (returned by getFactory()).
11654924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com     */
1179fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    virtual void flatten(SkWriteBuffer&) const {}
1188b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org
1196054d686e6fecc7261eeb328f27e9e16cd1d3b1ereedprotected:
1206054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed    class PrivateInitializer {
1216054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed    public:
1226054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed        static void InitCore();
1236054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed        static void InitEffects();
1246054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed    };
1256054d686e6fecc7261eeb328f27e9e16cd1d3b1ereed
126d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comprivate:
127c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    static void InitializeFlattenablesIfNeeded();
1289d0c6ecb8440e8e546881a4ff850eb6333f24541caryclark@google.com
1299d0c6ecb8440e8e546881a4ff850eb6333f24541caryclark@google.com    friend class SkGraphics;
13015e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
13115e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com    typedef SkRefCnt INHERITED;
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
135