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
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 2544b03..54e1efe 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -61,7 +61,9 @@
     };
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkTable_ColorFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
@@ -70,6 +72,8 @@
     uint8_t fStorage[256 * 4];
     unsigned fFlags;
 
+    friend class SkTableColorFilter;
+
     typedef SkColorFilter INHERITED;
 };
 
@@ -168,19 +172,62 @@
 #include "SkPackBits.h"
 
 void SkTable_ColorFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
     uint8_t storage[5*256];
     int count = gCountNibBits[fFlags & 0xF];
     size_t size = SkPackBits::Pack8(fStorage, count * 256, storage);
     SkASSERT(size <= sizeof(storage));
 
-//    SkDebugf("raw %d packed %d\n", count * 256, size);
-
-    buffer.writeInt(fFlags);
+    buffer.write32(fFlags);
     buffer.writeByteArray(storage, size);
 }
 
+SkFlattenable* SkTable_ColorFilter::CreateProc(SkReadBuffer& buffer) {
+    const int flags = buffer.read32();
+    const size_t count = gCountNibBits[flags & 0xF];
+    SkASSERT(count <= 4);
+
+    uint8_t packedStorage[5*256];
+    size_t packedSize = buffer.getArrayCount();
+    if (!buffer.validate(packedSize <= sizeof(packedStorage))) {
+        return NULL;
+    }
+    if (!buffer.readByteArray(packedStorage, packedSize)) {
+        return NULL;
+    }
+
+    uint8_t unpackedStorage[4*256];
+    size_t unpackedSize = SkPackBits::Unpack8(packedStorage, packedSize, unpackedStorage);
+    // now check that we got the size we expected
+    if (!buffer.validate(unpackedSize != count*256)) {
+        return NULL;
+    }
+
+    const uint8_t* a = NULL;
+    const uint8_t* r = NULL;
+    const uint8_t* g = NULL;
+    const uint8_t* b = NULL;
+    const uint8_t* ptr = unpackedStorage;
+
+    if (flags & kA_Flag) {
+        a = ptr;
+        ptr += 256;
+    }
+    if (flags & kR_Flag) {
+        r = ptr;
+        ptr += 256;
+    }
+    if (flags & kG_Flag) {
+        g = ptr;
+        ptr += 256;
+    }
+    if (flags & kB_Flag) {
+        b = ptr;
+        ptr += 256;
+    }
+    return SkTableColorFilter::CreateARGB(a, r, g, b);
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkTable_ColorFilter::SkTable_ColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {
     fBitmap = NULL;
 
@@ -199,6 +246,7 @@
     SkDEBUGCODE(size_t count = gCountNibBits[fFlags & 0xF]);
     SkASSERT(raw == count * 256);
 }
+#endif
 
 bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
     if (table) {