FilterSupport.h (15159B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef __FilterSupport_h 8 #define __FilterSupport_h 9 10 #include "mozilla/gfx/2D.h" 11 #include "mozilla/gfx/Matrix.h" 12 #include "mozilla/gfx/Point.h" 13 #include "mozilla/gfx/Rect.h" 14 #include "nsRegion.h" 15 #include "nsTArray.h" 16 17 namespace mozilla { 18 namespace gfx { 19 class FilterPrimitiveDescription; 20 class FilterNode; 21 struct FilterDescription; 22 } // namespace gfx 23 } // namespace mozilla 24 25 namespace mozilla { 26 namespace gfx { 27 namespace FilterWrappers { 28 extern sRGBColor SRGBToLinearRGB(const sRGBColor& color); 29 extern already_AddRefed<FilterNode> Clear(DrawTarget* aDT); 30 extern already_AddRefed<FilterNode> ForSurface( 31 DrawTarget* aDT, SourceSurface* aSurface, const IntPoint& aSurfacePosition); 32 } // namespace FilterWrappers 33 34 // Morphology Operators 35 const unsigned short SVG_OPERATOR_UNKNOWN = 0; 36 const unsigned short SVG_OPERATOR_ERODE = 1; 37 const unsigned short SVG_OPERATOR_DILATE = 2; 38 39 // ColorMatrix types 40 const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0; 41 const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX = 1; 42 const unsigned short SVG_FECOLORMATRIX_TYPE_SATURATE = 2; 43 const unsigned short SVG_FECOLORMATRIX_TYPE_HUE_ROTATE = 3; 44 const unsigned short SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA = 4; 45 // ColorMatrix types for CSS filters 46 const unsigned short SVG_FECOLORMATRIX_TYPE_SEPIA = 5; 47 48 // ComponentTransfer types 49 const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0; 50 const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1; 51 const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2; 52 const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3; 53 const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4; 54 const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5; 55 const unsigned short SVG_FECOMPONENTTRANSFER_SAME_AS_R = 6; 56 57 // Blend Mode Values 58 const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0; 59 const unsigned short SVG_FEBLEND_MODE_NORMAL = 1; 60 const unsigned short SVG_FEBLEND_MODE_MULTIPLY = 2; 61 const unsigned short SVG_FEBLEND_MODE_SCREEN = 3; 62 const unsigned short SVG_FEBLEND_MODE_DARKEN = 4; 63 const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5; 64 const unsigned short SVG_FEBLEND_MODE_OVERLAY = 6; 65 const unsigned short SVG_FEBLEND_MODE_COLOR_DODGE = 7; 66 const unsigned short SVG_FEBLEND_MODE_COLOR_BURN = 8; 67 const unsigned short SVG_FEBLEND_MODE_HARD_LIGHT = 9; 68 const unsigned short SVG_FEBLEND_MODE_SOFT_LIGHT = 10; 69 const unsigned short SVG_FEBLEND_MODE_DIFFERENCE = 11; 70 const unsigned short SVG_FEBLEND_MODE_EXCLUSION = 12; 71 const unsigned short SVG_FEBLEND_MODE_HUE = 13; 72 const unsigned short SVG_FEBLEND_MODE_SATURATION = 14; 73 const unsigned short SVG_FEBLEND_MODE_COLOR = 15; 74 const unsigned short SVG_FEBLEND_MODE_LUMINOSITY = 16; 75 76 // Edge Mode Values 77 const unsigned short SVG_EDGEMODE_UNKNOWN = 0; 78 const unsigned short SVG_EDGEMODE_DUPLICATE = 1; 79 const unsigned short SVG_EDGEMODE_WRAP = 2; 80 const unsigned short SVG_EDGEMODE_NONE = 3; 81 82 // Channel Selectors 83 const unsigned short SVG_CHANNEL_UNKNOWN = 0; 84 const unsigned short SVG_CHANNEL_R = 1; 85 const unsigned short SVG_CHANNEL_G = 2; 86 const unsigned short SVG_CHANNEL_B = 3; 87 const unsigned short SVG_CHANNEL_A = 4; 88 89 // Turbulence Types 90 const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN = 0; 91 const unsigned short SVG_TURBULENCE_TYPE_FRACTALNOISE = 1; 92 const unsigned short SVG_TURBULENCE_TYPE_TURBULENCE = 2; 93 94 // Composite Operators 95 const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0; 96 const unsigned short SVG_FECOMPOSITE_OPERATOR_OVER = 1; 97 const unsigned short SVG_FECOMPOSITE_OPERATOR_IN = 2; 98 const unsigned short SVG_FECOMPOSITE_OPERATOR_OUT = 3; 99 const unsigned short SVG_FECOMPOSITE_OPERATOR_ATOP = 4; 100 const unsigned short SVG_FECOMPOSITE_OPERATOR_XOR = 5; 101 const unsigned short SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6; 102 const unsigned short SVG_FECOMPOSITE_OPERATOR_LIGHTER = 7; 103 104 struct FilterAttribute; 105 106 // Limits 107 const float kMaxStdDeviation = 500; 108 109 // Simple PrimitiveAttributes: 110 111 struct EmptyAttributes { 112 bool operator==(const EmptyAttributes& aOther) const { return true; } 113 }; 114 115 struct BlendAttributes { 116 uint32_t mBlendMode; 117 118 bool operator==(const BlendAttributes& aOther) const { 119 return mBlendMode == aOther.mBlendMode; 120 } 121 }; 122 123 struct MorphologyAttributes { 124 uint32_t mOperator; 125 Size mRadii; 126 127 bool operator==(const MorphologyAttributes& aOther) const { 128 return mOperator == aOther.mOperator && mRadii == aOther.mRadii; 129 } 130 }; 131 132 struct FloodAttributes { 133 sRGBColor mColor; 134 135 bool operator==(const FloodAttributes& aOther) const { 136 return mColor == aOther.mColor; 137 } 138 }; 139 140 struct TileAttributes { 141 bool operator==(const TileAttributes& aOther) const { return true; } 142 }; 143 144 struct OpacityAttributes { 145 float mOpacity; 146 147 bool operator==(const OpacityAttributes& aOther) const { 148 return mOpacity == aOther.mOpacity; 149 } 150 }; 151 152 struct OffsetAttributes { 153 IntPoint mValue; 154 155 bool operator==(const OffsetAttributes& aOther) const { 156 return mValue == aOther.mValue; 157 } 158 }; 159 160 struct DisplacementMapAttributes { 161 float mScale; 162 uint32_t mXChannel; 163 uint32_t mYChannel; 164 165 bool operator==(const DisplacementMapAttributes& aOther) const { 166 return mScale == aOther.mScale && mXChannel == aOther.mXChannel && 167 mYChannel == aOther.mYChannel; 168 } 169 }; 170 171 struct TurbulenceAttributes { 172 IntPoint mOffset; 173 Size mBaseFrequency; 174 float mSeed; 175 uint32_t mOctaves; 176 bool mStitchable; 177 uint32_t mType; 178 179 bool operator==(const TurbulenceAttributes& aOther) const { 180 return mOffset == aOther.mOffset && 181 mBaseFrequency == aOther.mBaseFrequency && mSeed == aOther.mSeed && 182 mOctaves == aOther.mOctaves && mStitchable == aOther.mStitchable && 183 mType == aOther.mType; 184 } 185 }; 186 187 struct MergeAttributes { 188 bool operator==(const MergeAttributes& aOther) const { return true; } 189 }; 190 191 struct ImageAttributes { 192 uint32_t mFilter; 193 uint32_t mInputIndex; 194 Matrix mTransform; 195 196 bool operator==(const ImageAttributes& aOther) const { 197 return mFilter == aOther.mFilter && mInputIndex == aOther.mInputIndex && 198 mTransform.ExactlyEquals(aOther.mTransform); 199 } 200 }; 201 202 struct GaussianBlurAttributes { 203 Size mStdDeviation; 204 205 bool operator==(const GaussianBlurAttributes& aOther) const { 206 return mStdDeviation == aOther.mStdDeviation; 207 } 208 }; 209 210 struct DropShadowAttributes { 211 Size mStdDeviation; 212 Point mOffset; 213 sRGBColor mColor; 214 215 bool operator==(const DropShadowAttributes& aOther) const { 216 return mStdDeviation == aOther.mStdDeviation && mOffset == aOther.mOffset && 217 mColor == aOther.mColor; 218 } 219 }; 220 221 struct ToAlphaAttributes { 222 bool operator==(const ToAlphaAttributes& aOther) const { return true; } 223 }; 224 225 // Complex PrimitiveAttributes: 226 227 class ImplicitlyCopyableFloatArray : public CopyableTArray<float> { 228 public: 229 ImplicitlyCopyableFloatArray() = default; 230 231 ImplicitlyCopyableFloatArray(ImplicitlyCopyableFloatArray&& aOther) = default; 232 233 ImplicitlyCopyableFloatArray& operator=( 234 ImplicitlyCopyableFloatArray&& aOther) = default; 235 236 ImplicitlyCopyableFloatArray(const ImplicitlyCopyableFloatArray& aOther) = 237 default; 238 239 ImplicitlyCopyableFloatArray& operator=( 240 const ImplicitlyCopyableFloatArray& aOther) = default; 241 }; 242 243 struct ColorMatrixAttributes { 244 uint32_t mType; 245 ImplicitlyCopyableFloatArray mValues; 246 247 bool operator==(const ColorMatrixAttributes& aOther) const { 248 return mType == aOther.mType && mValues == aOther.mValues; 249 } 250 }; 251 252 // If the types for G and B are SVG_FECOMPONENTTRANSFER_SAME_AS_R, 253 // use the R channel values - this lets us avoid copies. 254 const uint32_t kChannelROrRGB = 0; 255 const uint32_t kChannelG = 1; 256 const uint32_t kChannelB = 2; 257 const uint32_t kChannelA = 3; 258 259 const uint32_t kComponentTransferSlopeIndex = 0; 260 const uint32_t kComponentTransferInterceptIndex = 1; 261 262 const uint32_t kComponentTransferAmplitudeIndex = 0; 263 const uint32_t kComponentTransferExponentIndex = 1; 264 const uint32_t kComponentTransferOffsetIndex = 2; 265 266 struct ComponentTransferAttributes { 267 uint8_t mTypes[4]; 268 ImplicitlyCopyableFloatArray mValues[4]; 269 270 bool operator==(const ComponentTransferAttributes& aOther) const { 271 return mTypes[0] == aOther.mTypes[0] && mTypes[1] == aOther.mTypes[1] && 272 mTypes[2] == aOther.mTypes[2] && mTypes[3] == aOther.mTypes[3] && 273 mValues[0] == aOther.mValues[0] && mValues[1] == aOther.mValues[1] && 274 mValues[2] == aOther.mValues[2] && mValues[3] == aOther.mValues[3]; 275 } 276 }; 277 278 struct ConvolveMatrixAttributes { 279 IntSize mKernelSize; 280 ImplicitlyCopyableFloatArray mKernelMatrix; 281 float mDivisor; 282 float mBias; 283 IntPoint mTarget; 284 uint32_t mEdgeMode; 285 Size mKernelUnitLength; 286 bool mPreserveAlpha; 287 288 bool operator==(const ConvolveMatrixAttributes& aOther) const { 289 return mKernelSize == aOther.mKernelSize && 290 mKernelMatrix == aOther.mKernelMatrix && 291 mDivisor == aOther.mDivisor && mBias == aOther.mBias && 292 mTarget == aOther.mTarget && mEdgeMode == aOther.mEdgeMode && 293 mKernelUnitLength == aOther.mKernelUnitLength && 294 mPreserveAlpha == aOther.mPreserveAlpha; 295 } 296 }; 297 298 struct CompositeAttributes { 299 uint32_t mOperator; 300 ImplicitlyCopyableFloatArray mCoefficients; 301 302 bool operator==(const CompositeAttributes& aOther) const { 303 return mOperator == aOther.mOperator && 304 mCoefficients == aOther.mCoefficients; 305 } 306 }; 307 308 enum class LightType { 309 None = 0, 310 Point, 311 Spot, 312 Distant, 313 Max, 314 }; 315 316 const uint32_t kDistantLightAzimuthIndex = 0; 317 const uint32_t kDistantLightElevationIndex = 1; 318 const uint32_t kDistantLightNumAttributes = 2; 319 320 const uint32_t kPointLightPositionXIndex = 0; 321 const uint32_t kPointLightPositionYIndex = 1; 322 const uint32_t kPointLightPositionZIndex = 2; 323 const uint32_t kPointLightNumAttributes = 3; 324 325 const uint32_t kSpotLightPositionXIndex = 0; 326 const uint32_t kSpotLightPositionYIndex = 1; 327 const uint32_t kSpotLightPositionZIndex = 2; 328 const uint32_t kSpotLightPointsAtXIndex = 3; 329 const uint32_t kSpotLightPointsAtYIndex = 4; 330 const uint32_t kSpotLightPointsAtZIndex = 5; 331 const uint32_t kSpotLightFocusIndex = 6; 332 const uint32_t kSpotLightLimitingConeAngleIndex = 7; 333 const uint32_t kSpotLightNumAttributes = 8; 334 335 struct LightingAttributes { 336 LightType mLightType; 337 ImplicitlyCopyableFloatArray mLightValues; 338 float mSurfaceScale; 339 Size mKernelUnitLength; 340 sRGBColor mColor; 341 float mLightingConstant; 342 float mSpecularExponent; 343 344 bool operator==(const LightingAttributes& aOther) const { 345 return mLightType == aOther.mLightType && 346 mLightValues == aOther.mLightValues && 347 mSurfaceScale == aOther.mSurfaceScale && 348 mKernelUnitLength == aOther.mKernelUnitLength && 349 mColor == aOther.mColor; 350 } 351 }; 352 353 struct DiffuseLightingAttributes : public LightingAttributes {}; 354 355 struct SpecularLightingAttributes : public LightingAttributes {}; 356 357 enum class ColorSpace { SRGB, LinearRGB, Max }; 358 359 enum class AlphaModel { Unpremultiplied, Premultiplied }; 360 361 class ColorModel { 362 public: 363 static ColorModel PremulSRGB() { 364 return ColorModel(ColorSpace::SRGB, AlphaModel::Premultiplied); 365 } 366 367 ColorModel(ColorSpace aColorSpace, AlphaModel aAlphaModel) 368 : mColorSpace(aColorSpace), mAlphaModel(aAlphaModel) {} 369 ColorModel() 370 : mColorSpace(ColorSpace::SRGB), mAlphaModel(AlphaModel::Premultiplied) {} 371 bool operator==(const ColorModel& aOther) const { 372 return mColorSpace == aOther.mColorSpace && 373 mAlphaModel == aOther.mAlphaModel; 374 } 375 376 // Used to index FilterCachedColorModels::mFilterForColorModel. 377 uint8_t ToIndex() const { 378 return static_cast<uint8_t>(static_cast<uint8_t>(mColorSpace) << 1) | 379 static_cast<uint8_t>(mAlphaModel); 380 } 381 382 ColorSpace mColorSpace; 383 AlphaModel mAlphaModel; 384 }; 385 386 already_AddRefed<FilterNode> FilterNodeGraphFromDescription( 387 DrawTarget* aDT, const FilterDescription& aFilter, 388 const Rect& aResultNeededRect, FilterNode* aSourceGraphic, 389 const IntRect& aSourceGraphicRect, FilterNode* aFillPaint, 390 FilterNode* aStrokePaint, 391 nsTArray<RefPtr<SourceSurface>>& aAdditionalImages); 392 393 /** 394 * The methods of this class are not on FilterDescription because 395 * FilterDescription is designed as a simple value holder that can be used 396 * on any thread. 397 */ 398 class FilterSupport { 399 public: 400 /** 401 * Draw the filter described by aFilter. All rect parameters are in filter 402 * space coordinates. aRenderRect specifies the part of the filter output 403 * that will be drawn at (0, 0) into the draw target aDT, subject to the 404 * current transform on aDT but with no additional scaling. 405 * The source filter nodes must match their corresponding rect in size. 406 * aAdditionalImages carries the images that are referenced by the 407 * eImageInputIndex attribute on any image primitives in the filter. 408 */ 409 static void RenderFilterDescription( 410 DrawTarget* aDT, const FilterDescription& aFilter, 411 const Rect& aRenderRect, RefPtr<FilterNode> aSourceGraphic, 412 const IntRect& aSourceGraphicRect, RefPtr<FilterNode> aFillPaint, 413 const IntRect& aFillPaintRect, RefPtr<FilterNode> aStrokePaint, 414 const IntRect& aStrokePaintRect, 415 nsTArray<RefPtr<SourceSurface>>& aAdditionalImages, 416 const Point& aDestPoint, const DrawOptions& aOptions = DrawOptions()); 417 418 /** 419 * Computes the region that changes in the filter output due to a change in 420 * input. This is primarily needed when an individual piece of content inside 421 * a filtered container element changes. 422 */ 423 static nsIntRegion ComputeResultChangeRegion( 424 const FilterDescription& aFilter, const nsIntRegion& aSourceGraphicChange, 425 const nsIntRegion& aFillPaintChange, 426 const nsIntRegion& aStrokePaintChange); 427 428 /** 429 * Computes the regions that need to be supplied in the filter inputs when 430 * painting aResultNeededRegion of the filter output. 431 */ 432 static void ComputeSourceNeededRegions( 433 const FilterDescription& aFilter, const nsIntRegion& aResultNeededRegion, 434 nsIntRegion& aSourceGraphicNeededRegion, 435 nsIntRegion& aFillPaintNeededRegion, 436 nsIntRegion& aStrokePaintNeededRegion); 437 438 /** 439 * Computes the size of the filter output. 440 */ 441 static nsIntRegion ComputePostFilterExtents( 442 const FilterDescription& aFilter, 443 const nsIntRegion& aSourceGraphicExtents); 444 445 /** 446 * Computes the size of a single FilterPrimitiveDescription's output given a 447 * set of input extents. 448 */ 449 static nsIntRegion PostFilterExtentsForPrimitive( 450 const FilterPrimitiveDescription& aDescription, 451 const nsTArray<nsIntRegion>& aInputExtents); 452 }; 453 454 /** 455 * Create a 4x5 color matrix for the different ways to specify color matrices 456 * in SVG. 457 * 458 * Return false if the input is invalid or if the resulting matrix is the 459 * identity. 460 */ 461 bool ComputeColorMatrix(const ColorMatrixAttributes& aMatrixAttributes, 462 float aOutMatrix[20]); 463 464 } // namespace gfx 465 } // namespace mozilla 466 467 #endif // __FilterSupport_h