reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 1 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 2 | * Copyright 2006 The Android Open Source Project |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 3 | * |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 6 | */ |
| 7 | |
| 8 | #ifndef SkFlattenable_DEFINED |
| 9 | #define SkFlattenable_DEFINED |
| 10 | |
| 11 | #include "SkRefCnt.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 12 | |
commit-bot@chromium.org | 8b0e8ac | 2014-01-30 18:58:24 +0000 | [diff] [blame] | 13 | class SkReadBuffer; |
| 14 | class SkWriteBuffer; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 15 | |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 16 | #define SK_SUPPORT_LEGACY_DEEPFLATTENING |
| 17 | |
| 18 | /* |
| 19 | * Flattening is straight-forward: |
| 20 | * 1. call getFactory() so we have a function-ptr to recreate the subclass |
| 21 | * 2. call flatten(buffer) to write out enough data for the factory to read |
| 22 | * |
| 23 | * Unflattening is easy for the caller: new_instance = factory(buffer) |
| 24 | * |
| 25 | * The complexity of supporting this is as follows. |
| 26 | * |
| 27 | * If your subclass wants to control unflattening, use this macro in your declaration: |
| 28 | * SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS |
| 29 | * This will provide a getFactory(), and require that the subclass implements CreateProc. |
| 30 | * |
| 31 | * For older buffers (before the DEEPFLATTENING change, the macros below declare |
| 32 | * a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep, |
| 33 | * then it calls through to a (usually protected) constructor, passing the buffer. |
| 34 | * If the buffer is newer, then it directly calls the "real" factory: CreateProc. |
| 35 | */ |
djsollen@google.com | a2ca41e | 2012-03-23 19:00:34 +0000 | [diff] [blame] | 36 | |
| 37 | #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables(); |
| 38 | |
| 39 | #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \ |
| 40 | void flattenable::InitializeFlattenables() { |
| 41 | |
caryclark@google.com | d26147a | 2011-12-15 14:16:43 +0000 | [diff] [blame] | 42 | #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \ |
| 43 | } |
| 44 | |
djsollen@google.com | ba28d03 | 2012-03-26 17:57:35 +0000 | [diff] [blame] | 45 | #define SK_DECLARE_UNFLATTENABLE_OBJECT() \ |
robertphillips@google.com | c2eae47 | 2013-10-21 12:26:10 +0000 | [diff] [blame] | 46 | virtual Factory getFactory() const SK_OVERRIDE { return NULL; } |
djsollen@google.com | ba28d03 | 2012-03-26 17:57:35 +0000 | [diff] [blame] | 47 | |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 48 | #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING |
| 49 | #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ |
| 50 | SkFlattenable::Registrar(#flattenable, flattenable::DeepCreateProc, \ |
| 51 | flattenable::GetFlattenableType()); |
| 52 | |
| 53 | #define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ |
| 54 | private: \ |
| 55 | static SkFlattenable* CreateProc(SkReadBuffer&); \ |
| 56 | static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) { \ |
| 57 | if (NeedsDeepUnflatten(buffer)) { \ |
| 58 | return SkNEW_ARGS(flattenable, (buffer)); \ |
| 59 | } \ |
| 60 | return CreateProc(buffer); \ |
| 61 | } \ |
| 62 | friend class SkPrivateEffectInitializer; \ |
| 63 | public: \ |
| 64 | virtual Factory getFactory() const SK_OVERRIDE {return DeepCreateProc;} |
| 65 | #else |
| 66 | #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ |
| 67 | SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \ |
| 68 | flattenable::GetFlattenableType()); |
| 69 | |
| 70 | #define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ |
| 71 | private: \ |
| 72 | static SkFlattenable* CreateProc(SkReadBuffer&); \ |
| 73 | friend class SkPrivateEffectInitializer; \ |
| 74 | public: \ |
| 75 | virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } |
| 76 | #endif |
| 77 | |
| 78 | // If your subclass will *never* need to be unflattened, declare this. |
| 79 | #define SK_DECLARE_NOT_FLATTENABLE_PROCS(flattenable) \ |
| 80 | virtual Factory getFactory() const SK_OVERRIDE { return ReturnNullCreateProc; } |
djsollen@google.com | ba28d03 | 2012-03-26 17:57:35 +0000 | [diff] [blame] | 81 | |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 82 | /** For SkFlattenable derived objects with a valid type |
| 83 | This macro should only be used in base class objects in core |
| 84 | */ |
| 85 | #define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \ |
| 86 | static Type GetFlattenableType() { \ |
| 87 | return k##flattenable##_Type; \ |
| 88 | } |
| 89 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 90 | /** \class SkFlattenable |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 91 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 92 | SkFlattenable is the base class for objects that need to be flattened |
| 93 | into a data stream for either transport or as part of the key to the |
| 94 | font cache. |
| 95 | */ |
ctguil@chromium.org | 7ffb1b2 | 2011-03-15 21:27:08 +0000 | [diff] [blame] | 96 | class SK_API SkFlattenable : public SkRefCnt { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 97 | public: |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 98 | enum Type { |
| 99 | kSkColorFilter_Type, |
| 100 | kSkDrawLooper_Type, |
| 101 | kSkImageFilter_Type, |
| 102 | kSkMaskFilter_Type, |
| 103 | kSkPathEffect_Type, |
| 104 | kSkPixelRef_Type, |
| 105 | kSkRasterizer_Type, |
| 106 | kSkShader_Type, |
commit-bot@chromium.org | 83f23d8 | 2014-05-22 12:27:41 +0000 | [diff] [blame] | 107 | kSkUnused_Type, // used to be SkUnitMapper |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 108 | kSkXfermode_Type, |
| 109 | }; |
| 110 | |
robertphillips@google.com | 15e9d3e | 2012-06-21 20:25:03 +0000 | [diff] [blame] | 111 | SK_DECLARE_INST_COUNT(SkFlattenable) |
| 112 | |
commit-bot@chromium.org | 8b0e8ac | 2014-01-30 18:58:24 +0000 | [diff] [blame] | 113 | typedef SkFlattenable* (*Factory)(SkReadBuffer&); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 114 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 115 | SkFlattenable() {} |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 116 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 117 | /** Implement this to return a factory function pointer that can be called |
| 118 | to recreate your class given a buffer (previously written to by your |
| 119 | override of flatten(). |
| 120 | */ |
robertphillips@google.com | c2eae47 | 2013-10-21 12:26:10 +0000 | [diff] [blame] | 121 | virtual Factory getFactory() const = 0; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 122 | |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 123 | /** Returns the name of the object's class |
| 124 | */ |
| 125 | const char* getTypeName() const { return FactoryToName(getFactory()); } |
| 126 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 127 | static Factory NameToFactory(const char name[]); |
| 128 | static const char* FactoryToName(Factory); |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 129 | static bool NameToType(const char name[], Type* type); |
| 130 | |
| 131 | static void Register(const char name[], Factory, Type); |
djsollen@google.com | a2ca41e | 2012-03-23 19:00:34 +0000 | [diff] [blame] | 132 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 133 | class Registrar { |
| 134 | public: |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 135 | Registrar(const char name[], Factory factory, Type type) { |
| 136 | SkFlattenable::Register(name, factory, type); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 137 | } |
| 138 | }; |
djsollen@google.com | a2ca41e | 2012-03-23 19:00:34 +0000 | [diff] [blame] | 139 | |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 140 | /** |
| 141 | * Override this if your subclass needs to record data that it will need to recreate itself |
| 142 | * from its CreateProc (returned by getFactory()). |
djsollen@google.com | 5492424 | 2012-03-29 15:18:04 +0000 | [diff] [blame] | 143 | */ |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 144 | virtual void flatten(SkWriteBuffer&) const {} |
commit-bot@chromium.org | 8b0e8ac | 2014-01-30 18:58:24 +0000 | [diff] [blame] | 145 | |
| 146 | protected: |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 147 | #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING |
| 148 | static bool NeedsDeepUnflatten(const SkReadBuffer&); |
commit-bot@chromium.org | 8b0e8ac | 2014-01-30 18:58:24 +0000 | [diff] [blame] | 149 | SkFlattenable(SkReadBuffer&) {} |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 150 | #endif |
| 151 | |
| 152 | static SkFlattenable* ReturnNullCreateProc(SkReadBuffer&) { |
| 153 | return NULL; |
| 154 | } |
caryclark@google.com | d26147a | 2011-12-15 14:16:43 +0000 | [diff] [blame] | 155 | |
| 156 | private: |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 157 | static void InitializeFlattenablesIfNeeded(); |
caryclark@google.com | 9d0c6ec | 2011-12-20 20:26:56 +0000 | [diff] [blame] | 158 | |
| 159 | friend class SkGraphics; |
robertphillips@google.com | 15e9d3e | 2012-06-21 20:25:03 +0000 | [diff] [blame] | 160 | |
| 161 | typedef SkRefCnt INHERITED; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 162 | }; |
| 163 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 164 | #endif |