diff options
author | 2014-08-21 07:59:51 -0700 | |
---|---|---|
committer | 2014-08-21 07:59:51 -0700 | |
commit | 9fa60daad4d5f54c0dbe3dbcc7608a8f6d721187 (patch) | |
tree | 59cc3af7f1a48aec372c05ca29a2fbef703bceb8 /include/core/SkFlattenable.h | |
parent | 5d74806b478a884bd763aee7e3e33cff1c506e50 (diff) |
Simplify flattening to just write enough to call the factory/public-constructor for the class. We want to *not* rely on private constructors, and not rely on calling through the inheritance hierarchy for either flattening or unflattening(CreateProc).
Refactoring pattern:
1. guard the existing constructor(readbuffer) with the legacy build-flag
2. If you are a instancable subclass, implement CreateProc(readbuffer) to create a new instances from the buffer params (or return NULL).
If you're a shader subclass
1. You must read/write the local matrix if your class accepts that in its factory/constructor, else ignore it.
R=robertphillips@google.com, mtklein@google.com, senorblanco@google.com, senorblanco@chromium.org, sugoi@chromium.org
Author: reed@google.com
Review URL: https://codereview.chromium.org/395603002
Diffstat (limited to 'include/core/SkFlattenable.h')
-rw-r--r-- | include/core/SkFlattenable.h | 78 |
1 files changed, 64 insertions, 14 deletions
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h index f6d377a9d7..679f640d3c 100644 --- a/include/core/SkFlattenable.h +++ b/include/core/SkFlattenable.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,7 +5,6 @@ * found in the LICENSE file. */ - #ifndef SkFlattenable_DEFINED #define SkFlattenable_DEFINED @@ -15,9 +13,26 @@ class SkReadBuffer; class SkWriteBuffer; -#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ - SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \ - flattenable::GetFlattenableType()); +#define SK_SUPPORT_LEGACY_DEEPFLATTENING + +/* + * Flattening is straight-forward: + * 1. call getFactory() so we have a function-ptr to recreate the subclass + * 2. call flatten(buffer) to write out enough data for the factory to read + * + * Unflattening is easy for the caller: new_instance = factory(buffer) + * + * The complexity of supporting this is as follows. + * + * If your subclass wants to control unflattening, use this macro in your declaration: + * SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS + * This will provide a getFactory(), and require that the subclass implements CreateProc. + * + * For older buffers (before the DEEPFLATTENING change, the macros below declare + * a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep, + * then it calls through to a (usually protected) constructor, passing the buffer. + * If the buffer is newer, then it directly calls the "real" factory: CreateProc. + */ #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables(); @@ -30,11 +45,39 @@ class SkWriteBuffer; #define SK_DECLARE_UNFLATTENABLE_OBJECT() \ virtual Factory getFactory() const SK_OVERRIDE { return NULL; } -#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ - virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } \ - static SkFlattenable* CreateProc(SkReadBuffer& buffer) { \ - return SkNEW_ARGS(flattenable, (buffer)); \ - } +#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING +#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ + SkFlattenable::Registrar(#flattenable, flattenable::DeepCreateProc, \ + flattenable::GetFlattenableType()); + +#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ + private: \ + static SkFlattenable* CreateProc(SkReadBuffer&); \ + static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) { \ + if (NeedsDeepUnflatten(buffer)) { \ + return SkNEW_ARGS(flattenable, (buffer)); \ + } \ + return CreateProc(buffer); \ + } \ + friend class SkPrivateEffectInitializer; \ + public: \ + virtual Factory getFactory() const SK_OVERRIDE {return DeepCreateProc;} +#else +#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ + SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \ + flattenable::GetFlattenableType()); + +#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ + private: \ + static SkFlattenable* CreateProc(SkReadBuffer&); \ + friend class SkPrivateEffectInitializer; \ + public: \ + virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } +#endif + +// If your subclass will *never* need to be unflattened, declare this. +#define SK_DECLARE_NOT_FLATTENABLE_PROCS(flattenable) \ + virtual Factory getFactory() const SK_OVERRIDE { return ReturnNullCreateProc; } /** For SkFlattenable derived objects with a valid type This macro should only be used in base class objects in core @@ -94,14 +137,21 @@ public: } }; - /** Override this to write data specific to your subclass into the buffer, - being sure to call your super-class' version first. This data will later - be passed to your Factory function, returned by getFactory(). + /** + * Override this if your subclass needs to record data that it will need to recreate itself + * from its CreateProc (returned by getFactory()). */ - virtual void flatten(SkWriteBuffer&) const; + virtual void flatten(SkWriteBuffer&) const {} protected: +#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING + static bool NeedsDeepUnflatten(const SkReadBuffer&); SkFlattenable(SkReadBuffer&) {} +#endif + + static SkFlattenable* ReturnNullCreateProc(SkReadBuffer&) { + return NULL; + } private: static void InitializeFlattenablesIfNeeded(); |