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