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 /*
     17  *  Flattening is straight-forward:
     18  *      1. call getFactory() so we have a function-ptr to recreate the subclass
     19  *      2. call flatten(buffer) to write out enough data for the factory to read
     20  *
     21  *  Unflattening is easy for the caller: new_instance = factory(buffer)
     22  *
     23  *  The complexity of supporting this is as follows.
     24  *
     25  *  If your subclass wants to control unflattening, use this macro in your declaration:
     26  *      SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
     27  *  This will provide a getFactory(), and require that the subclass implements CreateProc.
     28  *
     29  *  For older buffers (before the DEEPFLATTENING change, the macros below declare
     30  *  a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
     31  *  then it calls through to a (usually protected) constructor, passing the buffer.
     32  *  If the buffer is newer, then it directly calls the "real" factory: CreateProc.
     33  */
     34 
     35 #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
     36 
     37 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
     38     void flattenable::InitializeFlattenables() {
     39 
     40 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
     41     }
     42 
     43 #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
     44     SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \
     45                              flattenable::GetFlattenableType());
     46 
     47 #define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
     48     private:                                                                \
     49     static SkFlattenable* CreateProc(SkReadBuffer&);                        \
     50     friend class SkPrivateEffectInitializer;                                \
     51     public:                                                                 \
     52     Factory getFactory() const override { return CreateProc; }
     53 
     54 /** For SkFlattenable derived objects with a valid type
     55     This macro should only be used in base class objects in core
     56   */
     57 #define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
     58     static Type GetFlattenableType() { \
     59         return k##flattenable##_Type; \
     60     }
     61 
     62 /** \class SkFlattenable
     63 
     64  SkFlattenable is the base class for objects that need to be flattened
     65  into a data stream for either transport or as part of the key to the
     66  font cache.
     67  */
     68 class SK_API SkFlattenable : public SkRefCnt {
     69 public:
     70     enum Type {
     71         kSkColorFilter_Type,
     72         kSkDrawLooper_Type,
     73         kSkImageFilter_Type,
     74         kSkMaskFilter_Type,
     75         kSkPathEffect_Type,
     76         kSkPixelRef_Type,
     77         kSkRasterizer_Type,
     78         kSkShader_Type,
     79         kSkUnused_Type,     // used to be SkUnitMapper
     80         kSkXfermode_Type,
     81     };
     82 
     83     SK_DECLARE_INST_COUNT(SkFlattenable)
     84 
     85     typedef SkFlattenable* (*Factory)(SkReadBuffer&);
     86 
     87     SkFlattenable() {}
     88 
     89     /** Implement this to return a factory function pointer that can be called
     90      to recreate your class given a buffer (previously written to by your
     91      override of flatten().
     92      */
     93     virtual Factory getFactory() const = 0;
     94 
     95     /** Returns the name of the object's class
     96       */
     97     const char* getTypeName() const { return FactoryToName(getFactory()); }
     98 
     99     static Factory NameToFactory(const char name[]);
    100     static const char* FactoryToName(Factory);
    101     static bool NameToType(const char name[], Type* type);
    102 
    103     static void Register(const char name[], Factory, Type);
    104 
    105     class Registrar {
    106     public:
    107         Registrar(const char name[], Factory factory, Type type) {
    108             SkFlattenable::Register(name, factory, type);
    109         }
    110     };
    111 
    112     /**
    113      *  Override this if your subclass needs to record data that it will need to recreate itself
    114      *  from its CreateProc (returned by getFactory()).
    115      */
    116     virtual void flatten(SkWriteBuffer&) const {}
    117 
    118 private:
    119     static void InitializeFlattenablesIfNeeded();
    120 
    121     friend class SkGraphics;
    122 
    123     typedef SkRefCnt INHERITED;
    124 };
    125 
    126 #endif
    127