Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkFlattenable_DEFINED
      9 #define SkFlattenable_DEFINED
     10 
     11 #include "SkRefCnt.h"
     12 
     13 class SkReadBuffer;
     14 class SkWriteBuffer;
     15 
     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  */
     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 
     42 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
     43     }
     44 
     45 #define SK_DECLARE_UNFLATTENABLE_OBJECT() \
     46     virtual Factory getFactory() const SK_OVERRIDE { return NULL; }
     47 
     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; }
     81 
     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 
     90 /** \class SkFlattenable
     91 
     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  */
     96 class SK_API SkFlattenable : public SkRefCnt {
     97 public:
     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,
    107         kSkUnused_Type,     // used to be SkUnitMapper
    108         kSkXfermode_Type,
    109     };
    110 
    111     SK_DECLARE_INST_COUNT(SkFlattenable)
    112 
    113     typedef SkFlattenable* (*Factory)(SkReadBuffer&);
    114 
    115     SkFlattenable() {}
    116 
    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      */
    121     virtual Factory getFactory() const = 0;
    122 
    123     /** Returns the name of the object's class
    124       */
    125     const char* getTypeName() const { return FactoryToName(getFactory()); }
    126 
    127     static Factory NameToFactory(const char name[]);
    128     static const char* FactoryToName(Factory);
    129     static bool NameToType(const char name[], Type* type);
    130 
    131     static void Register(const char name[], Factory, Type);
    132 
    133     class Registrar {
    134     public:
    135         Registrar(const char name[], Factory factory, Type type) {
    136             SkFlattenable::Register(name, factory, type);
    137         }
    138     };
    139 
    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()).
    143      */
    144     virtual void flatten(SkWriteBuffer&) const {}
    145 
    146 protected:
    147 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
    148     static bool NeedsDeepUnflatten(const SkReadBuffer&);
    149     SkFlattenable(SkReadBuffer&) {}
    150 #endif
    151 
    152     static SkFlattenable* ReturnNullCreateProc(SkReadBuffer&) {
    153         return NULL;
    154     }
    155 
    156 private:
    157     static void InitializeFlattenablesIfNeeded();
    158 
    159     friend class SkGraphics;
    160 
    161     typedef SkRefCnt INHERITED;
    162 };
    163 
    164 #endif
    165