1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/src/FilterSupport.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,447 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef __FilterSupport_h 1.10 +#define __FilterSupport_h 1.11 + 1.12 +#include "mozilla/Attributes.h" 1.13 +#include "mozilla/RefPtr.h" 1.14 +#include "mozilla/TypedEnum.h" 1.15 +#include "mozilla/gfx/Rect.h" 1.16 +#include "mozilla/gfx/Matrix.h" 1.17 +#include "nsClassHashtable.h" 1.18 +#include "nsTArray.h" 1.19 +#include "nsRegion.h" 1.20 + 1.21 +namespace mozilla { 1.22 +namespace gfx { 1.23 + 1.24 +// Morphology Operators 1.25 +const unsigned short SVG_OPERATOR_UNKNOWN = 0; 1.26 +const unsigned short SVG_OPERATOR_ERODE = 1; 1.27 +const unsigned short SVG_OPERATOR_DILATE = 2; 1.28 + 1.29 +// ColorMatrix types 1.30 +const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0; 1.31 +const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX = 1; 1.32 +const unsigned short SVG_FECOLORMATRIX_TYPE_SATURATE = 2; 1.33 +const unsigned short SVG_FECOLORMATRIX_TYPE_HUE_ROTATE = 3; 1.34 +const unsigned short SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA = 4; 1.35 + 1.36 +// ComponentTransfer types 1.37 +const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0; 1.38 +const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1; 1.39 +const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2; 1.40 +const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3; 1.41 +const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4; 1.42 +const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5; 1.43 + 1.44 +// Blend Mode Values 1.45 +const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0; 1.46 +const unsigned short SVG_FEBLEND_MODE_NORMAL = 1; 1.47 +const unsigned short SVG_FEBLEND_MODE_MULTIPLY = 2; 1.48 +const unsigned short SVG_FEBLEND_MODE_SCREEN = 3; 1.49 +const unsigned short SVG_FEBLEND_MODE_DARKEN = 4; 1.50 +const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5; 1.51 + 1.52 +// Edge Mode Values 1.53 +const unsigned short SVG_EDGEMODE_UNKNOWN = 0; 1.54 +const unsigned short SVG_EDGEMODE_DUPLICATE = 1; 1.55 +const unsigned short SVG_EDGEMODE_WRAP = 2; 1.56 +const unsigned short SVG_EDGEMODE_NONE = 3; 1.57 + 1.58 +// Channel Selectors 1.59 +const unsigned short SVG_CHANNEL_UNKNOWN = 0; 1.60 +const unsigned short SVG_CHANNEL_R = 1; 1.61 +const unsigned short SVG_CHANNEL_G = 2; 1.62 +const unsigned short SVG_CHANNEL_B = 3; 1.63 +const unsigned short SVG_CHANNEL_A = 4; 1.64 + 1.65 +// Turbulence Types 1.66 +const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN = 0; 1.67 +const unsigned short SVG_TURBULENCE_TYPE_FRACTALNOISE = 1; 1.68 +const unsigned short SVG_TURBULENCE_TYPE_TURBULENCE = 2; 1.69 + 1.70 +// Composite Operators 1.71 +const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0; 1.72 +const unsigned short SVG_FECOMPOSITE_OPERATOR_OVER = 1; 1.73 +const unsigned short SVG_FECOMPOSITE_OPERATOR_IN = 2; 1.74 +const unsigned short SVG_FECOMPOSITE_OPERATOR_OUT = 3; 1.75 +const unsigned short SVG_FECOMPOSITE_OPERATOR_ATOP = 4; 1.76 +const unsigned short SVG_FECOMPOSITE_OPERATOR_XOR = 5; 1.77 +const unsigned short SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6; 1.78 + 1.79 +enum AttributeName { 1.80 + eBlendBlendmode = 0, 1.81 + eMorphologyRadii, 1.82 + eMorphologyOperator, 1.83 + eColorMatrixType, 1.84 + eColorMatrixValues, 1.85 + eFloodColor, 1.86 + eTileSourceRect, 1.87 + eComponentTransferFunctionR, 1.88 + eComponentTransferFunctionG, 1.89 + eComponentTransferFunctionB, 1.90 + eComponentTransferFunctionA, 1.91 + eComponentTransferFunctionType, 1.92 + eComponentTransferFunctionTableValues, 1.93 + eComponentTransferFunctionSlope, 1.94 + eComponentTransferFunctionIntercept, 1.95 + eComponentTransferFunctionAmplitude, 1.96 + eComponentTransferFunctionExponent, 1.97 + eComponentTransferFunctionOffset, 1.98 + eConvolveMatrixKernelSize, 1.99 + eConvolveMatrixKernelMatrix, 1.100 + eConvolveMatrixDivisor, 1.101 + eConvolveMatrixBias, 1.102 + eConvolveMatrixTarget, 1.103 + eConvolveMatrixEdgeMode, 1.104 + eConvolveMatrixKernelUnitLength, 1.105 + eConvolveMatrixPreserveAlpha, 1.106 + eOffsetOffset, 1.107 + eDropShadowStdDeviation, 1.108 + eDropShadowOffset, 1.109 + eDropShadowColor, 1.110 + eDisplacementMapScale, 1.111 + eDisplacementMapXChannel, 1.112 + eDisplacementMapYChannel, 1.113 + eTurbulenceOffset, 1.114 + eTurbulenceBaseFrequency, 1.115 + eTurbulenceNumOctaves, 1.116 + eTurbulenceSeed, 1.117 + eTurbulenceStitchable, 1.118 + eTurbulenceType, 1.119 + eCompositeOperator, 1.120 + eCompositeCoefficients, 1.121 + eGaussianBlurStdDeviation, 1.122 + eLightingLight, 1.123 + eLightingSurfaceScale, 1.124 + eLightingKernelUnitLength, 1.125 + eLightingColor, 1.126 + eDiffuseLightingDiffuseConstant, 1.127 + eSpecularLightingSpecularConstant, 1.128 + eSpecularLightingSpecularExponent, 1.129 + eLightType, 1.130 + eLightTypeNone, 1.131 + eLightTypePoint, 1.132 + eLightTypeSpot, 1.133 + eLightTypeDistant, 1.134 + ePointLightPosition, 1.135 + eSpotLightPosition, 1.136 + eSpotLightPointsAt, 1.137 + eSpotLightFocus, 1.138 + eSpotLightLimitingConeAngle, 1.139 + eDistantLightAzimuth, 1.140 + eDistantLightElevation, 1.141 + eImageInputIndex, 1.142 + eImageFilter, 1.143 + eImageNativeSize, 1.144 + eImageSubregion, 1.145 + eImageTransform, 1.146 + eLastAttributeName 1.147 +}; 1.148 + 1.149 +class DrawTarget; 1.150 +class SourceSurface; 1.151 +class FilterNode; 1.152 +struct FilterAttribute; 1.153 + 1.154 +MOZ_BEGIN_ENUM_CLASS(AttributeType) 1.155 + eBool, 1.156 + eUint, 1.157 + eFloat, 1.158 + eSize, 1.159 + eIntSize, 1.160 + eIntPoint, 1.161 + eMatrix, 1.162 + eMatrix5x4, 1.163 + ePoint3D, 1.164 + eColor, 1.165 + eAttributeMap, 1.166 + eFloats, 1.167 + Max 1.168 +MOZ_END_ENUM_CLASS(AttributeType) 1.169 + 1.170 +// A class that stores values of different types, keyed by an attribute name. 1.171 +// The Get*() methods assert that they're called for the same type that the 1.172 +// attribute was Set() with. 1.173 +// AttributeMaps can be nested because AttributeMap is a valid attribute type. 1.174 +class AttributeMap MOZ_FINAL { 1.175 +public: 1.176 + AttributeMap(); 1.177 + AttributeMap(const AttributeMap& aOther); 1.178 + AttributeMap& operator=(const AttributeMap& aOther); 1.179 + bool operator==(const AttributeMap& aOther) const; 1.180 + bool operator!=(const AttributeMap& aOther) const 1.181 + { 1.182 + return !(*this == aOther); 1.183 + } 1.184 + ~AttributeMap(); 1.185 + 1.186 + void Set(AttributeName aName, bool aValue); 1.187 + void Set(AttributeName aName, uint32_t aValue); 1.188 + void Set(AttributeName aName, float aValue); 1.189 + void Set(AttributeName aName, const Size& aValue); 1.190 + void Set(AttributeName aName, const IntSize& aValue); 1.191 + void Set(AttributeName aName, const IntPoint& aValue); 1.192 + void Set(AttributeName aName, const Matrix& aValue); 1.193 + void Set(AttributeName aName, const Matrix5x4& aValue); 1.194 + void Set(AttributeName aName, const Point3D& aValue); 1.195 + void Set(AttributeName aName, const Color& aValue); 1.196 + void Set(AttributeName aName, const AttributeMap& aValue); 1.197 + void Set(AttributeName aName, const float* aValues, int32_t aLength); 1.198 + 1.199 + bool GetBool(AttributeName aName) const; 1.200 + uint32_t GetUint(AttributeName aName) const; 1.201 + float GetFloat(AttributeName aName) const; 1.202 + Size GetSize(AttributeName aName) const; 1.203 + IntSize GetIntSize(AttributeName aName) const; 1.204 + IntPoint GetIntPoint(AttributeName aName) const; 1.205 + Matrix GetMatrix(AttributeName aName) const; 1.206 + Matrix5x4 GetMatrix5x4(AttributeName aName) const; 1.207 + Point3D GetPoint3D(AttributeName aName) const; 1.208 + Color GetColor(AttributeName aName) const; 1.209 + AttributeMap GetAttributeMap(AttributeName aName) const; 1.210 + const nsTArray<float>& GetFloats(AttributeName aName) const; 1.211 + 1.212 + typedef bool (*AttributeHandleCallback)(AttributeName aName, AttributeType aType, void* aUserData); 1.213 + void EnumerateRead(AttributeHandleCallback aCallback, void* aUserData) const; 1.214 + uint32_t Count() const; 1.215 + 1.216 +private: 1.217 + mutable nsClassHashtable<nsUint32HashKey, FilterAttribute> mMap; 1.218 +}; 1.219 + 1.220 +MOZ_BEGIN_ENUM_CLASS(ColorSpace) 1.221 + SRGB, 1.222 + LinearRGB, 1.223 + Max 1.224 +MOZ_END_ENUM_CLASS(ColorSpace) 1.225 + 1.226 +MOZ_BEGIN_ENUM_CLASS(AlphaModel) 1.227 + Unpremultiplied, 1.228 + Premultiplied 1.229 +MOZ_END_ENUM_CLASS(AlphaModel) 1.230 + 1.231 +class ColorModel { 1.232 +public: 1.233 + static ColorModel PremulSRGB() 1.234 + { 1.235 + return ColorModel(ColorSpace::SRGB, AlphaModel::Premultiplied); 1.236 + } 1.237 + 1.238 + ColorModel(ColorSpace aColorSpace, AlphaModel aAlphaModel) : 1.239 + mColorSpace(aColorSpace), mAlphaModel(aAlphaModel) {} 1.240 + ColorModel() : 1.241 + mColorSpace(ColorSpace::SRGB), mAlphaModel(AlphaModel::Premultiplied) {} 1.242 + bool operator==(const ColorModel& aOther) const { 1.243 + return mColorSpace == aOther.mColorSpace && 1.244 + mAlphaModel == aOther.mAlphaModel; 1.245 + } 1.246 + 1.247 + // Used to index FilterCachedColorModels::mFilterForColorModel. 1.248 + uint8_t ToIndex() const 1.249 + { 1.250 + return (uint8_t(mColorSpace) << 1) + uint8_t(mAlphaModel); 1.251 + } 1.252 + 1.253 + ColorSpace mColorSpace; 1.254 + AlphaModel mAlphaModel; 1.255 +}; 1.256 + 1.257 +MOZ_BEGIN_ENUM_CLASS(PrimitiveType) 1.258 + Empty = 0, 1.259 + Blend, 1.260 + Morphology, 1.261 + ColorMatrix, 1.262 + Flood, 1.263 + Tile, 1.264 + ComponentTransfer, 1.265 + ConvolveMatrix, 1.266 + Offset, 1.267 + DisplacementMap, 1.268 + Turbulence, 1.269 + Composite, 1.270 + Merge, 1.271 + Image, 1.272 + GaussianBlur, 1.273 + DropShadow, 1.274 + DiffuseLighting, 1.275 + SpecularLighting, 1.276 + Max 1.277 +MOZ_END_ENUM_CLASS(PrimitiveType) 1.278 + 1.279 +/** 1.280 + * A data structure to carry attributes for a given primitive that's part of a 1.281 + * filter. Will be serializable via IPDL, so it must not contain complex 1.282 + * functionality. 1.283 + * Used as part of a FilterDescription. 1.284 + */ 1.285 +class FilterPrimitiveDescription MOZ_FINAL { 1.286 +public: 1.287 + enum { 1.288 + kPrimitiveIndexSourceGraphic = -1, 1.289 + kPrimitiveIndexSourceAlpha = -2, 1.290 + kPrimitiveIndexFillPaint = -3, 1.291 + kPrimitiveIndexStrokePaint = -4 1.292 + }; 1.293 + 1.294 + FilterPrimitiveDescription(); 1.295 + FilterPrimitiveDescription(PrimitiveType aType); 1.296 + FilterPrimitiveDescription(const FilterPrimitiveDescription& aOther); 1.297 + FilterPrimitiveDescription& operator=(const FilterPrimitiveDescription& aOther); 1.298 + 1.299 + PrimitiveType Type() const { return mType; } 1.300 + void SetType(PrimitiveType aType) { mType = aType; } 1.301 + const AttributeMap& Attributes() const { return mAttributes; } 1.302 + AttributeMap& Attributes() { return mAttributes; } 1.303 + 1.304 + IntRect PrimitiveSubregion() const { return mFilterPrimitiveSubregion; } 1.305 + bool IsTainted() const { return mIsTainted; } 1.306 + 1.307 + size_t NumberOfInputs() const { return mInputPrimitives.Length(); } 1.308 + int32_t InputPrimitiveIndex(size_t aInputIndex) const 1.309 + { 1.310 + return aInputIndex < mInputPrimitives.Length() ? 1.311 + mInputPrimitives[aInputIndex] : 0; 1.312 + } 1.313 + 1.314 + ColorSpace InputColorSpace(size_t aInputIndex) const 1.315 + { 1.316 + return aInputIndex < mInputColorSpaces.Length() ? 1.317 + mInputColorSpaces[aInputIndex] : ColorSpace(); 1.318 + } 1.319 + 1.320 + ColorSpace OutputColorSpace() const { return mOutputColorSpace; } 1.321 + 1.322 + void SetPrimitiveSubregion(const IntRect& aRect) 1.323 + { 1.324 + mFilterPrimitiveSubregion = aRect; 1.325 + } 1.326 + 1.327 + void SetIsTainted(bool aIsTainted) 1.328 + { 1.329 + mIsTainted = aIsTainted; 1.330 + } 1.331 + 1.332 + void SetInputPrimitive(size_t aInputIndex, int32_t aInputPrimitiveIndex) 1.333 + { 1.334 + mInputPrimitives.EnsureLengthAtLeast(aInputIndex + 1); 1.335 + mInputPrimitives[aInputIndex] = aInputPrimitiveIndex; 1.336 + } 1.337 + 1.338 + void SetInputColorSpace(size_t aInputIndex, ColorSpace aColorSpace) 1.339 + { 1.340 + mInputColorSpaces.EnsureLengthAtLeast(aInputIndex + 1); 1.341 + mInputColorSpaces[aInputIndex] = aColorSpace; 1.342 + } 1.343 + 1.344 + void SetOutputColorSpace(const ColorSpace& aColorSpace) 1.345 + { 1.346 + mOutputColorSpace = aColorSpace; 1.347 + } 1.348 + 1.349 + bool operator==(const FilterPrimitiveDescription& aOther) const; 1.350 + bool operator!=(const FilterPrimitiveDescription& aOther) const 1.351 + { 1.352 + return !(*this == aOther); 1.353 + } 1.354 + 1.355 +private: 1.356 + PrimitiveType mType; 1.357 + AttributeMap mAttributes; 1.358 + nsTArray<int32_t> mInputPrimitives; 1.359 + IntRect mFilterPrimitiveSubregion; 1.360 + nsTArray<ColorSpace> mInputColorSpaces; 1.361 + ColorSpace mOutputColorSpace; 1.362 + bool mIsTainted; 1.363 +}; 1.364 + 1.365 +/** 1.366 + * A data structure that contains one or more FilterPrimitiveDescriptions. 1.367 + * Designed to be serializable via IPDL, so it must not contain complex 1.368 + * functionality. 1.369 + */ 1.370 +struct FilterDescription MOZ_FINAL { 1.371 + FilterDescription() {} 1.372 + FilterDescription(const nsTArray<FilterPrimitiveDescription>& aPrimitives, 1.373 + const IntRect& aFilterSpaceBounds) 1.374 + : mPrimitives(aPrimitives) 1.375 + , mFilterSpaceBounds(aFilterSpaceBounds) 1.376 + {} 1.377 + 1.378 + bool operator==(const FilterDescription& aOther) const; 1.379 + bool operator!=(const FilterDescription& aOther) const 1.380 + { 1.381 + return !(*this == aOther); 1.382 + } 1.383 + 1.384 + nsTArray<FilterPrimitiveDescription> mPrimitives; 1.385 + IntRect mFilterSpaceBounds; 1.386 +}; 1.387 + 1.388 +/** 1.389 + * The methods of this class are not on FilterDescription because 1.390 + * FilterDescription is designed as a simple value holder that can be used 1.391 + * on any thread. 1.392 + */ 1.393 +class FilterSupport { 1.394 +public: 1.395 + 1.396 + /** 1.397 + * Draw the filter described by aFilter. All rect parameters are in filter 1.398 + * space coordinates. aRenderRect specifies the part of the filter output 1.399 + * that will be drawn at (0, 0) into the draw target aDT, subject to the 1.400 + * current transform on aDT but with no additional scaling. 1.401 + * The source surfaces must match their corresponding rect in size. 1.402 + * aAdditionalImages carries the images that are referenced by the 1.403 + * eImageInputIndex attribute on any image primitives in the filter. 1.404 + */ 1.405 + static void 1.406 + RenderFilterDescription(DrawTarget* aDT, 1.407 + const FilterDescription& aFilter, 1.408 + const Rect& aRenderRect, 1.409 + SourceSurface* aSourceGraphic, 1.410 + const IntRect& aSourceGraphicRect, 1.411 + SourceSurface* aFillPaint, 1.412 + const IntRect& aFillPaintRect, 1.413 + SourceSurface* aStrokePaint, 1.414 + const IntRect& aStrokePaintRect, 1.415 + nsTArray<RefPtr<SourceSurface>>& aAdditionalImages); 1.416 + 1.417 + /** 1.418 + * Computes the region that changes in the filter output due to a change in 1.419 + * input. 1.420 + */ 1.421 + static nsIntRegion 1.422 + ComputeResultChangeRegion(const FilterDescription& aFilter, 1.423 + const nsIntRegion& aSourceGraphicChange, 1.424 + const nsIntRegion& aFillPaintChange, 1.425 + const nsIntRegion& aStrokePaintChange); 1.426 + 1.427 + /** 1.428 + * Computes the regions that need to be supplied in the filter inputs when 1.429 + * painting aResultNeededRegion of the filter output. 1.430 + */ 1.431 + static void 1.432 + ComputeSourceNeededRegions(const FilterDescription& aFilter, 1.433 + const nsIntRegion& aResultNeededRegion, 1.434 + nsIntRegion& aSourceGraphicNeededRegion, 1.435 + nsIntRegion& aFillPaintNeededRegion, 1.436 + nsIntRegion& aStrokePaintNeededRegion); 1.437 + 1.438 + /** 1.439 + * Computes the size of the filter output. 1.440 + */ 1.441 + static nsIntRegion 1.442 + ComputePostFilterExtents(const FilterDescription& aFilter, 1.443 + const nsIntRegion& aSourceGraphicExtents); 1.444 + 1.445 +}; 1.446 + 1.447 +} 1.448 +} 1.449 + 1.450 +#endif // __FilterSupport_h