337 lines
13 KiB
C++
337 lines
13 KiB
C++
/* 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 = ALPHA_MODE_PREMULTIPLIED;
|
|
|
|
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_ */
|