/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZILLA_GFX_FILTERNODEWEBGL_H_ #define MOZILLA_GFX_FILTERNODEWEBGL_H_ #include #include "mozilla/gfx/Filters.h" #include "mozilla/gfx/PatternHelpers.h" namespace mozilla::gfx { class DrawTargetWebgl; class FilterNodeSoftware; /** * FilterNodeWebgl wraps a FilterNodeSoftware for most operations that * are not yet accelerated. To provide acceleration, this must be subclassed * to override an optimized implementation for particular operations. */ class FilterNodeWebgl : public FilterNode { public: ~FilterNodeWebgl() override; FilterBackend GetBackendType() override { return FILTER_BACKEND_WEBGL; } FilterType GetType() const { return mType; } bool ReserveInputIndex(uint32_t aIndex); bool SetInputAccel(uint32_t aIndex, SourceSurface* aSurface); bool SetInputSoftware(uint32_t aIndex, SourceSurface* aSurface); void SetInput(uint32_t aIndex, SourceSurface* aSurface) override; void SetInput(uint32_t aIndex, FilterNode* aFilter) override; void SetAttribute(uint32_t aIndex, bool) override; void SetAttribute(uint32_t aIndex, uint32_t) override; void SetAttribute(uint32_t aIndex, Float) override; void SetAttribute(uint32_t aIndex, const Size&) override; void SetAttribute(uint32_t aIndex, const IntSize&) override; void SetAttribute(uint32_t aIndex, const IntPoint&) override; void SetAttribute(uint32_t aIndex, const Rect&) override; void SetAttribute(uint32_t aIndex, const IntRect&) override; void SetAttribute(uint32_t aIndex, const Point&) override; void SetAttribute(uint32_t aIndex, const Matrix&) override; void SetAttribute(uint32_t aIndex, const Matrix5x4&) override; void SetAttribute(uint32_t aIndex, const Point3D&) override; void SetAttribute(uint32_t aIndex, const DeviceColor&) override; void SetAttribute(uint32_t aIndex, const Float* aValues, uint32_t aSize) override; IntRect MapRectToSource(const IntRect& aRect, const IntRect& aMax, FilterNode* aSourceNode) override; // Draw the root of a filter chain. Any filter drawing originates here. virtual void Draw(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent = nullptr); // Speculatively draw part of a filter chain, only if it can be accelerated. // On success, it return true. Instead of falling back, nothing is drawn and // it returns false. virtual bool DrawAccel(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent = nullptr) { return false; } // Draw a child filter and return a surface that can be processed by a parent // filter. This will try to accelerate the filter if possible, but implements // a fallback if not. virtual already_AddRefed DrawChild( FilterNodeWebgl* aParent, DrawTargetWebgl* aDT, const Rect& aSourceRect, const DrawOptions& aOptions, Point& aSurfaceOffset, DeviceColor& aColor); // This handles deferred filter inputs that should not be resolved to surfaces // until right before drawing. Accelerated filters must ensure they call this // to resolve these inputs before using them for drawing. virtual void ResolveInputs(DrawTargetWebgl* aDT, bool aAccel, FilterNodeWebgl* aParent = nullptr) {} // Recursively resolve all inputs in the filter chain. void ResolveAllInputs(DrawTargetWebgl* aDT, FilterNodeWebgl* aParent); protected: std::vector> mInputFilters; std::vector> mInputSurfaces; uint32_t mInputMask = 0; FilterType mType; RefPtr mSoftwareFilter; friend class DrawTargetWebgl; explicit FilterNodeWebgl(FilterType aType); static already_AddRefed Create(FilterType aType); size_t NumberOfSetInputs() const { return std::max(mInputSurfaces.size(), mInputFilters.size()); } virtual int32_t InputIndex(uint32_t aInputEnumIndex) const; IntRect MapInputRectToSource(uint32_t aInputEnumIndex, const IntRect& aRect, const IntRect& aMax, FilterNode* aSourceNode); }; class FilterNodeCropWebgl : public FilterNodeWebgl { public: FilterNodeCropWebgl() : FilterNodeWebgl(FilterType::CROP) {} void SetAttribute(uint32_t aIndex, const Rect& aValue) override; IntRect MapRectToSource(const IntRect& aRect, const IntRect& aMax, FilterNode* aSourceNode) override; void Draw(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; bool DrawAccel(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; already_AddRefed DrawChild(FilterNodeWebgl* aParent, DrawTargetWebgl* aDT, const Rect& aSourceRect, const DrawOptions& aOptions, Point& aSurfaceOffset, DeviceColor& aColor) override; private: IntRect mCropRect; int32_t InputIndex(uint32_t aInputEnumIndex) const override; }; class FilterNodeTransformWebgl : public FilterNodeWebgl { public: FilterNodeTransformWebgl() : FilterNodeWebgl(FilterType::TRANSFORM) {} void SetAttribute(uint32_t aIndex, uint32_t aValue) override; void SetAttribute(uint32_t aIndex, const Matrix& aValue) override; IntRect MapRectToSource(const IntRect& aRect, const IntRect& aMax, FilterNode* aSourceNode) override; void Draw(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; already_AddRefed DrawChild(FilterNodeWebgl* aParent, DrawTargetWebgl* aDT, const Rect& aSourceRect, const DrawOptions& aOptions, Point& aSurfaceOffset, DeviceColor& aColor) override; protected: Matrix mMatrix; SamplingFilter mSamplingFilter = SamplingFilter::GOOD; int32_t InputIndex(uint32_t aInputEnumIndex) const override; }; class FilterNodeDeferInputWebgl : public FilterNodeTransformWebgl { public: FilterNodeDeferInputWebgl(RefPtr aPath, const Pattern& aPattern, const IntRect& aSourceRect, const Matrix& aDestTransform, const DrawOptions& aOptions, const StrokeOptions* aStrokeOptions); void ResolveInputs(DrawTargetWebgl* aDT, bool aAccel, FilterNodeWebgl* aParent) override; void Draw(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; already_AddRefed DrawChild(FilterNodeWebgl* aParent, DrawTargetWebgl* aDT, const Rect& aSourceRect, const DrawOptions& aOptions, Point& aSurfaceOffset, DeviceColor& aColor) override; private: RefPtr mPath; GeneralPattern mPattern; IntRect mSourceRect; Matrix mDestTransform; DrawOptions mOptions; Maybe mStrokeOptions; UniquePtr mDashPatternStorage; }; class FilterNodeGaussianBlurWebgl : public FilterNodeWebgl { public: FilterNodeGaussianBlurWebgl() : FilterNodeWebgl(FilterType::GAUSSIAN_BLUR) {} void SetAttribute(uint32_t aIndex, float aValue) override; IntRect MapRectToSource(const IntRect& aRect, const IntRect& aMax, FilterNode* aSourceNode) override; void Draw(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; private: float mStdDeviation = 0; int32_t InputIndex(uint32_t aInputEnumIndex) const override; }; class FilterNodeColorMatrixWebgl : public FilterNodeWebgl { public: FilterNodeColorMatrixWebgl() : FilterNodeWebgl(FilterType::COLOR_MATRIX) {} void SetAttribute(uint32_t aIndex, const Matrix5x4& aValue) override; void SetAttribute(uint32_t aIndex, uint32_t aValue) override; bool DrawAccel(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; protected: Matrix5x4 mMatrix; AlphaMode mAlphaMode; int32_t InputIndex(uint32_t aInputEnumIndex) const override; }; class FilterNodeComponentTransferWebgl : public FilterNodeWebgl { public: explicit FilterNodeComponentTransferWebgl(FilterType aType) : FilterNodeWebgl(aType), mDisableR(true), mDisableG(true), mDisableB(true), mDisableA(true) {} void SetAttribute(uint32_t aIndex, bool aValue) override; bool DrawAccel(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; virtual bool ToColorMatrix(Matrix5x4& aMatrix) const { return false; } protected: bool mDisableR : 1; bool mDisableG : 1; bool mDisableB : 1; bool mDisableA : 1; int32_t InputIndex(uint32_t aInputEnumIndex) const override; }; class FilterNodeLinearTransferWebgl : public FilterNodeComponentTransferWebgl { public: FilterNodeLinearTransferWebgl() : FilterNodeComponentTransferWebgl(FilterType::LINEAR_TRANSFER) {} using FilterNodeComponentTransferWebgl::SetAttribute; void SetAttribute(uint32_t aIndex, Float aValue) override; bool ToColorMatrix(Matrix5x4& aMatrix) const override; protected: DeviceColor mSlope; DeviceColor mIntercept; }; class FilterNodeTableTransferWebgl : public FilterNodeComponentTransferWebgl { public: FilterNodeTableTransferWebgl() : FilterNodeComponentTransferWebgl(FilterType::TABLE_TRANSFER) {} using FilterNodeComponentTransferWebgl::SetAttribute; void SetAttribute(uint32_t aIndex, const Float* aValues, uint32_t aSize) override; bool ToColorMatrix(Matrix5x4& aMatrix) const override; protected: std::vector mTableR; std::vector mTableG; std::vector mTableB; std::vector mTableA; }; class FilterNodePremultiplyWebgl : public FilterNodeWebgl { public: FilterNodePremultiplyWebgl() : FilterNodeWebgl(FilterType::PREMULTIPLY) {} void Draw(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; protected: int32_t InputIndex(uint32_t aInputEnumIndex) const override; }; class FilterNodeUnpremultiplyWebgl : public FilterNodeWebgl { public: FilterNodeUnpremultiplyWebgl() : FilterNodeWebgl(FilterType::UNPREMULTIPLY) {} already_AddRefed DrawChild(FilterNodeWebgl* aParent, DrawTargetWebgl* aDT, const Rect& aSourceRect, const DrawOptions& aOptions, Point& aSurfaceOffset, DeviceColor& aColor) override; protected: int32_t InputIndex(uint32_t aInputEnumIndex) const override; }; class FilterNodeOpacityWebgl : public FilterNodeWebgl { public: FilterNodeOpacityWebgl() : FilterNodeWebgl(FilterType::OPACITY) {} void SetAttribute(uint32_t aIndex, Float aValue) override; void Draw(DrawTargetWebgl* aDT, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions, FilterNodeWebgl* aParent) override; already_AddRefed DrawChild(FilterNodeWebgl* aParent, DrawTargetWebgl* aDT, const Rect& aSourceRect, const DrawOptions& aOptions, Point& aSurfaceOffset, DeviceColor& aColor) override; protected: Float mValue = 1.0f; int32_t InputIndex(uint32_t aInputEnumIndex) const override; }; } // namespace mozilla::gfx #endif /* MOZILLA_GFX_FILTERNODEWEBGL_H_ */