Source code

Revision control

Copy as Markdown

Other Tools

/* 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 <vector>
#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<SourceSurface> 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<RefPtr<FilterNodeWebgl>> mInputFilters;
std::vector<RefPtr<SourceSurface>> mInputSurfaces;
uint32_t mInputMask = 0;
FilterType mType;
RefPtr<FilterNodeSoftware> mSoftwareFilter;
friend class DrawTargetWebgl;
explicit FilterNodeWebgl(FilterType aType);
static already_AddRefed<FilterNodeWebgl> 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<SourceSurface> 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<SourceSurface> 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<Path> 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<SourceSurface> DrawChild(FilterNodeWebgl* aParent,
DrawTargetWebgl* aDT,
const Rect& aSourceRect,
const DrawOptions& aOptions,
Point& aSurfaceOffset,
DeviceColor& aColor) override;
private:
RefPtr<Path> mPath;
GeneralPattern mPattern;
IntRect mSourceRect;
Matrix mDestTransform;
DrawOptions mOptions;
Maybe<StrokeOptions> mStrokeOptions;
UniquePtr<Float[]> 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<Float> mTableR;
std::vector<Float> mTableG;
std::vector<Float> mTableB;
std::vector<Float> 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<SourceSurface> 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<SourceSurface> 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_ */