Chromium Code Reviews| Index: include/core/SkFlattenable.h |
| diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h |
| index 58e69fd416cb049b56d881942f6f77ebb676e93d..2a78befcc2865ddbe8580ba71eb870c4b9c5b79a 100644 |
| --- a/include/core/SkFlattenable.h |
| +++ b/include/core/SkFlattenable.h |
| @@ -29,12 +29,94 @@ class SkFlattenableWriteBuffer; |
| #define SK_DECLARE_UNFLATTENABLE_OBJECT() \ |
| virtual Factory getFactory() SK_OVERRIDE { return NULL; } |
| -#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ |
| +/** For SkFlattenable derived objects that can be serialized without type checking |
| + */ |
| +#define SK_DEFINE_FLATTENABLE_SERIALIZABLE(flattenable) \ |
| virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } \ |
| static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \ |
| return SkNEW_ARGS(flattenable, (buffer)); \ |
| } |
| +/** For SkFlattenable derived objects that need type checking |
| + */ |
| +#define SK_DEFINE_FLATTENABLE_TYPE_CHECKING(flattenable) \ |
| + static bool IsA(SkFlattenable::Type type) { \ |
| + return (flattenable::GetType() == type) || INHERITED::IsA(type); \ |
| + } \ |
| + virtual SkFlattenable::Type getFlattenableType() SK_OVERRIDE { \ |
| + return flattenable::GetType(); \ |
| + } |
| + |
| +/** For SkFlattenable derived objects with a valid type |
| + This macros would typically be used by virtual classes, which need a type, but can't |
| + be constructed or serialized directly without going through a derived class |
| + */ |
| +#define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \ |
| + static SkFlattenable::Type GetType() { \ |
| + return SkFlattenable::k##flattenable##_Type; \ |
| + } \ |
| + SK_DEFINE_FLATTENABLE_TYPE_CHECKING(flattenable) |
| + |
| +/** For SkFlattenable derived objects defined outside of skia (sample code, gms, etc). |
| + Since these external object won't go through the secure deserialization, they are not given |
| + a "Type" in the SkFlattenable::Type enum and there is no need to modify SkFlattenable.h |
| + to add these derived classes. Note that the type is set to SkFlattenable::kNone_Type here. |
| + */ |
| +#define SK_DEFINE_FLATTENABLE_EXTERN(flattenable) \ |
| + SK_DEFINE_FLATTENABLE_SERIALIZABLE(flattenable) \ |
| + static SkFlattenable::Type GetType() { \ |
| + return SkFlattenable::kNone_Type; \ |
| + } \ |
| + SK_DEFINE_FLATTENABLE_TYPE_CHECKING(flattenable) |
| + |
| +/** For SkFlattenable derived objects defined within the skia library |
| + */ |
| +#define SK_DEFINE_FLATTENABLE_SERIALIZABLE_TYPE(flattenable) \ |
| + SK_DEFINE_FLATTENABLE_SERIALIZABLE(flattenable) \ |
| + SK_DEFINE_FLATTENABLE_TYPE(flattenable) |
| + |
| +/** Deprecated, remove once noone is using it anymore |
| + */ |
| +#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ |
| + SK_DEFINE_FLATTENABLE_SERIALIZABLE_TYPE(flattenable) |
| + |
| +/** Only for SkFlattenable derived objects that have implementations hidden in a cpp file |
| + This isn't used directly outside of SkFlattenable.h |
| + */ |
| +#define SK_DECLARE_FLATTENABLE_BASE() \ |
| + static SkFlattenable::Factory GetFactory(SkFlattenable::Type); \ |
| + static SkFlattenable::TypeCheck GetTypeCheck(SkFlattenable::Type); |
| + |
| +/** This is for an instantiatable SkFlattenable derived class |
| + with derived classes available in header files |
| + */ |
| +#define SK_DECLARE_FLATTENABLE_GROUP_TYPE(flattenable) \ |
| + SK_DEFINE_FLATTENABLE_TYPE(flattenable) \ |
| + SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() |
| + |
| +/** This is for an instantiatable SkFlattenable derived class |
| + with derived classes local to a cpp file |
| + */ |
| +#define SK_DECLARE_FLATTENABLE_BASE_SERIALIZABLE_TYPE(flattenable) \ |
| + SK_DECLARE_FLATTENABLE_BASE() \ |
| + SK_DEFINE_FLATTENABLE_SERIALIZABLE(flattenable) \ |
| + SK_DEFINE_FLATTENABLE_TYPE(flattenable) |
| + |
| +/** This is for an uninstantiatable/virtual SkFlattenable derived class |
| + with derived classes local to a cpp file |
| + */ |
| +#define SK_DECLARE_FLATTENABLE_GROUP_BASE_TYPE(flattenable) \ |
| + SK_DECLARE_FLATTENABLE_BASE() \ |
| + SK_DEFINE_FLATTENABLE_TYPE(flattenable) \ |
| + SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() |
| + |
| +/** This is for a non SkFlattenable class (used as a namespace, essentially) |
| + with SkFlattenable derived classes local to a cpp file |
| + */ |
| +#define SK_DECLARE_FLATTENABLE_GROUP_BASE() \ |
| + SK_DECLARE_FLATTENABLE_BASE() \ |
| + SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() |
| + |
| /** \class SkFlattenable |
| SkFlattenable is the base class for objects that need to be flattened |
| @@ -43,9 +125,125 @@ class SkFlattenableWriteBuffer; |
| */ |
| class SK_API SkFlattenable : public SkRefCnt { |
| public: |
| + |
| + /** This is an APPEND ONLY ENUM. Reordering this will break all previously |
| + serialized streams / files using the validating read / write buffer. |
| + |
| + All the types listed here must provide the necessary functionality to |
| + perform type checking and must be stable across binary versions. |
| + */ |
| + enum Type { |
|
reed1
2013/10/03 08:41:09
*if* we have to have an enumeration of known subcl
|
| + kNone_Type, |
| + kSkFlattenable_Type, |
| + kBATShader_Type, |
| + kCompositeImageFilter_Type, |
| + kFloodImageFilter_Type, |
| + kOffsetImageFilter_Type, |
| + kSk2DPathEffect_Type, |
| + kSk3DShader_Type, |
| + kSkAnnotation_Type, |
| + kSkArithmeticMode_scalar_Type, |
| + kSkAvoidXfermode_Type, |
| + kSkBicubicImageFilter_Type, |
| + kSkBitmapProcShader_Type, |
| + kSkBitmapSource_Type, |
| + kSkBlurDrawLooper_Type, |
| + kSkBlurImageFilter_Type, |
| + kSkBlurMaskFilterImpl_Type, |
| + kSkClearXfermode_Type, |
| + kSkColorFilter_Type, |
| + kSkColorFilterImageFilter_Type, |
| + kSkColorMatrixFilter_Type, |
| + kSkColorShader_Type, |
| + kSkColorTable_Type, |
| + kSkComposeImageFilter_Type, |
| + kSkComposePathEffect_Type, |
| + kSkComposeShader_Type, |
| + kSkCornerPathEffect_Type, |
| + kSkCosineMapper_Type, |
| + kSkData_Type, |
| + kSkDataPixelRef_Type, |
| + kSkDataSet_Type, |
| + kSkDataTable_Type, |
| + kSkDiffuseLightingImageFilter_Type, |
| + kSkDilateImageFilter_Type, |
| + kSkDiscreteMapper_Type, |
| + kSkDiscretePathEffect_Type, |
| + kSkDisplacementMapEffect_Type, |
| + kSkDistantLight_Type, |
| + kSkDownSampleImageFilter_Type, |
| + kSkDrawLooper_Type, |
| + kSkDropShadowImageFilter_Type, |
| + kSkDstInXfermode_Type, |
| + kSkDstOutXfermode_Type, |
| + kSkEmbossMaskFilter_Type, |
| + kSkEmptyShader_Type, |
| + kSkErodeImageFilter_Type, |
| + kSkFilterShader_Type, |
| + kSkImageFilter_Type, |
| + kSkImageRef_GlobalPool_Type, |
| + kSkKernel33MaskFilter_Type, |
| + kSkLayerDrawLooper_Type, |
| + kSkLayerRasterizer_Type, |
| + kSkLerpXfermode_Type, |
| + kSkLight_Type, |
| + kSkLightingColorFilter_Type, |
| + kSkLightingColorFilter_JustAdd_Type, |
| + kSkLightingColorFilter_JustMul_Type, |
| + kSkLightingColorFilter_NoPin_Type, |
| + kSkLightingColorFilter_SingleMul_Type, |
| + kSkLightingImageFilter_Type, |
| + kSkLinearGradient_Type, |
| + kSkLine2DPathEffect_Type, |
| + kSkLumaMaskXfermode_Type, |
| + kSkLumaMaskXfermodeSrcOver_Type, |
| + kSkMagnifierImageFilter_Type, |
| + kSkMallocPixelRef_Type, |
| + kSkMaskFilter_Type, |
| + kSkMatrixConvolutionImageFilter_Type, |
| + kSkMergeImageFilter_Type, |
| + kSkModeColorFilter_Type, |
| + kSkOffsetImageFilter_Type, |
| + kSkPathEffect_Type, |
| + kSkPath1DPathEffect_Type, |
| + kSkPath2DPathEffect_Type, |
| + kSkPerlinNoiseShader_Type, |
| + kSkPixelRef_Type, |
| + kSkPixelXorXfermode_Type, |
| + kSkPointLight_Type, |
| + kSkProcCoeffXfermode_Type, |
| + kSkProcXfermode_Type, |
| + kSkRadialGradient_Type, |
| + kSkRasterizer_Type, |
| + kSkRectShaderImageFilter_Type, |
| + kSkShader_Type, |
| + kSkSpecularLightingImageFilter_Type, |
| + kSkSpotLight_Type, |
| + kSkSrcXfermode_Type, |
| + kSkStippleMaskFilter_Type, |
| + kSkSumPathEffect_Type, |
| + kSkSweepGradient_Type, |
| + kSkTable_ColorFilter_Type, |
| + kSkTableMaskFilter_Type, |
| + kSkTileImageFilter_Type, |
| + kSkTransparentShader_Type, |
| + kSkTriColorShader_Type, |
| + kSkTwoPointConicalGradient_Type, |
| + kSkTwoPointRadialGradient_Type, |
| + kSkUnitMapper_Type, |
| + kSkXfermode_Type, |
| + kSkXfermodeImageFilter_Type, |
| + kSrc_SkModeColorFilter_Type, |
| + kSrcOver_SkModeColorFilter_Type, |
| + kTileImageFilter_Type, |
| + // New values go here. This is an APPEND ONLY ENUM. Do not insert values alphabetically. |
| + kTypeCount |
| + }; |
| + |
| SK_DECLARE_INST_COUNT(SkFlattenable) |
| typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&); |
| + typedef bool (*TypeCheck)(SkFlattenable::Type); |
| SkFlattenable() {} |
| @@ -59,6 +257,41 @@ public: |
| static const char* FactoryToName(Factory); |
| static void Register(const char name[], Factory); |
| + /** Returns the class id |
| + GetType methods on classes descending from SkFlattenable should return the |
| + SkFlattenable::Type associated with that class, or SkFlattenable::kNoneType if |
| + they're not part of the subset of SkFlattenables that can be used with |
| + SkFlattenable::TypeToFactory(). Typycally, SK_DEFINE_FLATTENABLE_TYPE() will |
| + define GetType(), getFlattenableType() and IsA() in the derived class. |
| + * Note that SK_DEFINE_FLATTENABLE_TYPE() is included in other macros that include |
| + the "_TYPE" suffix, so most classes will have these declared by default. |
| + External classes can use SK_DEFINE_FLATTENABLE_EXTERN(), which will do the same, |
| + but set the class type to SkFlattenable::kNone_Type. |
| + */ |
| + static SkFlattenable::Type GetType() { |
| + return SkFlattenable::kSkFlattenable_Type; |
| + } |
| + |
| + /** Returns the class id of an object |
| + */ |
| + virtual SkFlattenable::Type getFlattenableType() = 0; |
| + |
| + /** Returns whether the current object is of the given type |
| + */ |
| + static bool IsA(SkFlattenable::Type type) { |
| + return (GetType() == type); |
| + } |
| + |
| + /** Returns the factory function required to create the given type |
| + */ |
| + static Factory TypeToFactory(Type type); |
| + |
| + /** Checks if typeA is a typeB |
| + * For example, if typeA is kSkImageFilter and typeB is kSkFlattenable, this would return true |
| + * Inversely, if typeA is kSkFlattenable and typeB is kSkImageFilter, this would return false |
| + */ |
| + static bool TypeIsA(SkFlattenable::Type typeA, SkFlattenable::Type typeB); |
| + |
| class Registrar { |
| public: |
| Registrar(const char name[], Factory factory) { |