aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core/SkFlattenable.h
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2014-08-21 07:59:51 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-21 07:59:51 -0700
commit9fa60daad4d5f54c0dbe3dbcc7608a8f6d721187 (patch)
tree59cc3af7f1a48aec372c05ca29a2fbef703bceb8 /include/core/SkFlattenable.h
parent5d74806b478a884bd763aee7e3e33cff1c506e50 (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.h78
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();