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 class SkPrivateEffectInitializer;
     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_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
     46     SkFlattenable::Register(#flattenable, flattenable::CreateProc, \
     47                             flattenable::GetFlattenableType());
     48 
     49 #define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
     50     private:                                                                \
     51     static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);                        \
     52     friend class SkFlattenable::PrivateInitializer;                         \
     53     public:                                                                 \
     54     Factory getFactory() const override { return CreateProc; }
     55 
     56 /** For SkFlattenable derived objects with a valid type
     57     This macro should only be used in base class objects in core
     58   */
     59 #define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
     60     static Type GetFlattenableType() { \
     61         return k##flattenable##_Type; \
     62     }
     63 
     64 /** \class SkFlattenable
     65 
     66  SkFlattenable is the base class for objects that need to be flattened
     67  into a data stream for either transport or as part of the key to the
     68  font cache.
     69  */
     70 class SK_API SkFlattenable : public SkRefCnt {
     71 public:
     72     enum Type {
     73         kSkColorFilter_Type,
     74         kSkDrawable_Type,
     75         kSkDrawLooper_Type,
     76         kSkImageFilter_Type,
     77         kSkMaskFilter_Type,
     78         kSkPathEffect_Type,
     79         kSkPixelRef_Type,
     80         kSkRasterizer_Type,
     81         kSkShader_Type,
     82         kSkUnused_Type,     // used to be SkUnitMapper
     83         kSkXfermode_Type,
     84         kSkNormalSource_Type,
     85     };
     86 
     87     typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
     88 
     89     SkFlattenable() {}
     90 
     91     /** Implement this to return a factory function pointer that can be called
     92      to recreate your class given a buffer (previously written to by your
     93      override of flatten().
     94      */
     95     virtual Factory getFactory() const = 0;
     96 
     97     /**
     98      *  Returns the name of the object's class.
     99      *
    100      *  Subclasses should override this function if they intend to provide
    101      *  support for flattening without using the global registry.
    102      *
    103      *  If the flattenable is registered, there is no need to override.
    104      */
    105     virtual const char* getTypeName() const { return FactoryToName(getFactory()); }
    106 
    107     static Factory NameToFactory(const char name[]);
    108     static const char* FactoryToName(Factory);
    109     static bool NameToType(const char name[], Type* type);
    110 
    111     static void Register(const char name[], Factory, Type);
    112 
    113     /**
    114      *  Override this if your subclass needs to record data that it will need to recreate itself
    115      *  from its CreateProc (returned by getFactory()).
    116      */
    117     virtual void flatten(SkWriteBuffer&) const {}
    118 
    119 protected:
    120     class PrivateInitializer {
    121     public:
    122         static void InitCore();
    123         static void InitEffects();
    124     };
    125 
    126 private:
    127     static void InitializeFlattenablesIfNeeded();
    128 
    129     friend class SkGraphics;
    130 
    131     typedef SkRefCnt INHERITED;
    132 };
    133 
    134 #endif
    135