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 169fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_SUPPORT_LEGACY_DEEPFLATTENING 179fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 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 45ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com#define SK_DECLARE_UNFLATTENABLE_OBJECT() \ 46c2eae4795478ab134a2315b1a9ff2c5de1d049e4robertphillips@google.com virtual Factory getFactory() const SK_OVERRIDE { return NULL; } 47ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 489fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 499fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ 509fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkFlattenable::Registrar(#flattenable, flattenable::DeepCreateProc, \ 519fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed flattenable::GetFlattenableType()); 529fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 539fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ 549fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed private: \ 559fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed static SkFlattenable* CreateProc(SkReadBuffer&); \ 569fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) { \ 579fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (NeedsDeepUnflatten(buffer)) { \ 589fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkNEW_ARGS(flattenable, (buffer)); \ 599fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } \ 609fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return CreateProc(buffer); \ 619fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } \ 629fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed friend class SkPrivateEffectInitializer; \ 639fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed public: \ 649fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed virtual Factory getFactory() const SK_OVERRIDE {return DeepCreateProc;} 659fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#else 669fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ 679fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \ 689fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed flattenable::GetFlattenableType()); 699fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 709fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ 719fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed private: \ 729fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed static SkFlattenable* CreateProc(SkReadBuffer&); \ 739fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed friend class SkPrivateEffectInitializer; \ 749fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed public: \ 759fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } 769fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 779fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 789fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed// If your subclass will *never* need to be unflattened, declare this. 799fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_DECLARE_NOT_FLATTENABLE_PROCS(flattenable) \ 809fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed virtual Factory getFactory() const SK_OVERRIDE { return ReturnNullCreateProc; } 81ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 82c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org/** For SkFlattenable derived objects with a valid type 83c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org This macro should only be used in base class objects in core 84c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org */ 85c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \ 86c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org static Type GetFlattenableType() { \ 87c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org return k##flattenable##_Type; \ 88c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org } 89c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkFlattenable 91fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable is the base class for objects that need to be flattened 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com into a data stream for either transport or as part of the key to the 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com font cache. 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 967ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkFlattenable : public SkRefCnt { 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 98c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org enum Type { 99c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkColorFilter_Type, 100c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkDrawLooper_Type, 101c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkImageFilter_Type, 102c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkMaskFilter_Type, 103c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkPathEffect_Type, 104c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkPixelRef_Type, 105c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkRasterizer_Type, 106c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkShader_Type, 10783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org kSkUnused_Type, // used to be SkUnitMapper 108c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org kSkXfermode_Type, 109c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org }; 110c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org 11115e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com SK_DECLARE_INST_COUNT(SkFlattenable) 11215e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 1138b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org typedef SkFlattenable* (*Factory)(SkReadBuffer&); 114fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable() {} 116fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Implement this to return a factory function pointer that can be called 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to recreate your class given a buffer (previously written to by your 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com override of flatten(). 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 121c2eae4795478ab134a2315b1a9ff2c5de1d049e4robertphillips@google.com virtual Factory getFactory() const = 0; 122fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 123c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org /** Returns the name of the object's class 124c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org */ 125c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org const char* getTypeName() const { return FactoryToName(getFactory()); } 126c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static Factory NameToFactory(const char name[]); 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const char* FactoryToName(Factory); 129c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org static bool NameToType(const char name[], Type* type); 130c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org 131c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org static void Register(const char name[], Factory, Type); 132a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com class Registrar { 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 135c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org Registrar(const char name[], Factory factory, Type type) { 136c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org SkFlattenable::Register(name, factory, type); 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 139a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com 1409fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed /** 1419fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * Override this if your subclass needs to record data that it will need to recreate itself 1429fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * from its CreateProc (returned by getFactory()). 14354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com */ 1449fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed virtual void flatten(SkWriteBuffer&) const {} 1458b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 1468b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgprotected: 1479fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 1489fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed static bool NeedsDeepUnflatten(const SkReadBuffer&); 1498b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkFlattenable(SkReadBuffer&) {} 1509fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 1519fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 1529fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed static SkFlattenable* ReturnNullCreateProc(SkReadBuffer&) { 1539fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return NULL; 1549fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 155d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com 156d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comprivate: 157c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org static void InitializeFlattenablesIfNeeded(); 1589d0c6ecb8440e8e546881a4ff850eb6333f24541caryclark@google.com 1599d0c6ecb8440e8e546881a4ff850eb6333f24541caryclark@google.com friend class SkGraphics; 16015e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 16115e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com typedef SkRefCnt INHERITED; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 165