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) { |