Bug 1522021. Propagate input size to CreateSimilarDrawTarget for filters. r=mstange

This lets us avoid drawing the complete input for ever tile when
drawing filters into a tile.

Differential Revision: https://phabricator.services.mozilla.com/D17686

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jeff Muizelaar 2019-01-27 23:36:04 +00:00
parent a7c263d04d
commit 0c609e94c7
13 changed files with 625 additions and 188 deletions

View File

@ -1310,6 +1310,20 @@ class DrawTarget : public external::AtomicRefCounted<DrawTarget> {
virtual already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
const IntSize &aSize, SurfaceFormat aFormat) const = 0;
/**
* Create a DrawTarget whose snapshot is optimized for use with this
* DrawTarget and aFilter.
* @param aSource is the FilterNode that that will be attached to this
* surface.
* @param aSourceRect is the source rect that will be passed to DrawFilter
* @param aDestPoint is the dest point that will be passed to DrawFilter.
*/
virtual already_AddRefed<DrawTarget> CreateSimilarDrawTargetForFilter(
const IntSize &aSize, SurfaceFormat aFormat, FilterNode *aFilter,
FilterNode *aSource, const Rect &aSourceRect, const Point &aDestPoint) {
return CreateSimilarDrawTarget(aSize, aFormat);
}
/**
* Returns false if CreateSimilarDrawTarget would return null with the same
* parameters. May return true even in cases where CreateSimilarDrawTarget

View File

@ -554,6 +554,25 @@ RefPtr<DrawTarget> DrawTargetRecording::CreateClippedDrawTarget(
return similarDT;
}
already_AddRefed<DrawTarget>
DrawTargetRecording::CreateSimilarDrawTargetForFilter(
const IntSize &aMaxSize, SurfaceFormat aFormat, FilterNode *aFilter,
FilterNode *aSource, const Rect &aSourceRect, const Point &aDestPoint) {
RefPtr<DrawTarget> similarDT;
if (mFinalDT->CanCreateSimilarDrawTarget(aMaxSize, aFormat)) {
similarDT = new DrawTargetRecording(this, aMaxSize, aFormat);
mRecorder->RecordEvent(RecordedCreateDrawTargetForFilter(
this, similarDT.get(), aMaxSize, aFormat, aFilter, aSource, aSourceRect,
aDestPoint));
} else if (XRE_IsContentProcess()) {
// See CreateSimilarDrawTarget
MOZ_CRASH(
"Content-process DrawTargetRecording can't create requested clipped "
"drawtarget");
}
return similarDT.forget();
}
already_AddRefed<PathBuilder> DrawTargetRecording::CreatePathBuilder(
FillRule aFillRule) const {
RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule);

View File

@ -304,6 +304,10 @@ class DrawTargetRecording : public DrawTarget {
const IntSize &aMaxSize, const Matrix &aTransform,
SurfaceFormat aFormat) const override;
virtual already_AddRefed<DrawTarget> CreateSimilarDrawTargetForFilter(
const IntSize &aSize, SurfaceFormat aFormat, FilterNode *aFilter,
FilterNode *aSource, const Rect &aSourceRect,
const Point &aDestPoint) override;
/*
* Create a path builder with the specified fillmode.
*

View File

@ -665,6 +665,33 @@ void FilterNodeSoftware::RequestRect(const IntRect &aRect) {
RequestFromInputsForRect(aRect);
}
IntRect FilterNodeSoftware::MapInputRectToSource(uint32_t aInputEnumIndex,
const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
int32_t inputIndex = InputIndex(aInputEnumIndex);
if (inputIndex < 0) {
gfxDevCrash(LogReason::FilterInputError)
<< "Invalid input " << inputIndex << " vs. " << NumberOfSetInputs();
return aMax;
}
if ((uint32_t)inputIndex < NumberOfSetInputs()) {
RefPtr<FilterNodeSoftware> filter = mInputFilters[inputIndex];
// If we have any input filters call into them to do the mapping,
// otherwise we can assume an input surface will be used
// and just return aRect.
if (filter) {
return filter->MapRectToSource(aRect, aMax, aSourceNode);
}
}
// We have an input surface instead of a filter
// so check if we're the target node.
if (this == aSourceNode) {
return aRect;
}
return IntRect();
}
void FilterNodeSoftware::RequestInputRect(uint32_t aInputEnumIndex,
const IntRect &aRect) {
if (aRect.Overflows()) {
@ -1051,6 +1078,14 @@ void FilterNodeBlendSoftware::RequestFromInputsForRect(const IntRect &aRect) {
RequestInputRect(IN_BLEND_IN2, aRect);
}
IntRect FilterNodeBlendSoftware::MapRectToSource(const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
IntRect result = MapInputRectToSource(IN_BLEND_IN, aRect, aMax, aSourceNode);
result.OrWith(MapInputRectToSource(IN_BLEND_IN2, aRect, aMax, aSourceNode));
return result;
}
IntRect FilterNodeBlendSoftware::GetOutputRectInRect(const IntRect &aRect) {
return GetInputRectInRect(IN_BLEND_IN, aRect)
.Union(GetInputRectInRect(IN_BLEND_IN2, aRect))
@ -1103,6 +1138,28 @@ IntRect FilterNodeTransformSoftware::SourceRectForOutputRect(
return GetInputRectInRect(IN_TRANSFORM_IN, neededIntRect);
}
IntRect FilterNodeTransformSoftware::MapRectToSource(const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
if (aRect.IsEmpty()) {
return IntRect();
}
Matrix inverted(mMatrix);
if (!inverted.Invert()) {
return aMax;
}
Rect neededRect = inverted.TransformBounds(Rect(aRect));
neededRect.RoundOut();
IntRect neededIntRect;
if (!neededRect.ToIntRect(&neededIntRect)) {
return aMax;
}
return MapInputRectToSource(IN_TRANSFORM_IN, neededIntRect, aMax,
aSourceNode);
}
already_AddRefed<DataSourceSurface> FilterNodeTransformSoftware::Render(
const IntRect &aRect) {
IntRect srcRect = SourceRectForOutputRect(aRect);
@ -1458,6 +1515,11 @@ void FilterNodeColorMatrixSoftware::RequestFromInputsForRect(
RequestInputRect(IN_COLOR_MATRIX_IN, aRect);
}
IntRect FilterNodeColorMatrixSoftware::MapRectToSource(
const IntRect &aRect, const IntRect &aMax, FilterNode *aSourceNode) {
return MapInputRectToSource(IN_COLOR_MATRIX_IN, aRect, aMax, aSourceNode);
}
IntRect FilterNodeColorMatrixSoftware::GetOutputRectInRect(
const IntRect &aRect) {
if (mMatrix._54 > 0.0f) {
@ -1546,6 +1608,12 @@ already_AddRefed<DataSourceSurface> FilterNodeFloodSoftware::GetOutput(
return Render(aRect);
}
IntRect FilterNodeFloodSoftware::MapRectToSource(const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
return IntRect();
}
IntRect FilterNodeFloodSoftware::GetOutputRectInRect(const IntRect &aRect) {
if (mColor.a == 0.0f) {
return IntRect();
@ -1816,6 +1884,11 @@ void FilterNodeComponentTransferSoftware::RequestFromInputsForRect(
RequestInputRect(IN_TRANSFER_IN, aRect);
}
IntRect FilterNodeComponentTransferSoftware::MapRectToSource(
const IntRect &aRect, const IntRect &aMax, FilterNode *aSourceNode) {
return MapInputRectToSource(IN_TRANSFER_IN, aRect, aMax, aSourceNode);
}
IntRect FilterNodeComponentTransferSoftware::GetOutputRectInRect(
const IntRect &aRect) {
if (mDisableA) {
@ -2461,6 +2534,12 @@ void FilterNodeConvolveMatrixSoftware::RequestFromInputsForRect(
RequestInputRect(IN_CONVOLVE_MATRIX_IN, InflatedSourceRect(aRect));
}
IntRect FilterNodeConvolveMatrixSoftware::MapRectToSource(
const IntRect &aRect, const IntRect &aMax, FilterNode *aSourceNode) {
return MapInputRectToSource(IN_CONVOLVE_MATRIX_IN, InflatedSourceRect(aRect),
aMax, aSourceNode);
}
IntRect FilterNodeConvolveMatrixSoftware::InflatedSourceRect(
const IntRect &aDestRect) {
if (aDestRect.IsEmpty()) {
@ -2611,6 +2690,16 @@ void FilterNodeDisplacementMapSoftware::RequestFromInputsForRect(
RequestInputRect(IN_DISPLACEMENT_MAP_IN2, aRect);
}
IntRect FilterNodeDisplacementMapSoftware::MapRectToSource(
const IntRect &aRect, const IntRect &aMax, FilterNode *aSourceNode) {
IntRect result =
MapInputRectToSource(IN_DISPLACEMENT_MAP_IN,
InflatedSourceOrDestRect(aRect), aMax, aSourceNode);
result.OrWith(
MapInputRectToSource(IN_DISPLACEMENT_MAP_IN2, aRect, aMax, aSourceNode));
return result;
}
IntRect FilterNodeDisplacementMapSoftware::InflatedSourceOrDestRect(
const IntRect &aDestOrSourceRect) {
IntRect sourceOrDestRect = aDestOrSourceRect;
@ -2699,6 +2788,12 @@ IntRect FilterNodeTurbulenceSoftware::GetOutputRectInRect(
return aRect.Intersect(mRenderRect);
}
IntRect FilterNodeTurbulenceSoftware::MapRectToSource(const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
return IntRect();
}
FilterNodeArithmeticCombineSoftware::FilterNodeArithmeticCombineSoftware()
: mK1(0), mK2(0), mK3(0), mK4(0) {}
@ -2762,6 +2857,15 @@ void FilterNodeArithmeticCombineSoftware::RequestFromInputsForRect(
RequestInputRect(IN_ARITHMETIC_COMBINE_IN2, aRect);
}
IntRect FilterNodeArithmeticCombineSoftware::MapRectToSource(
const IntRect &aRect, const IntRect &aMax, FilterNode *aSourceNode) {
IntRect result =
MapInputRectToSource(IN_ARITHMETIC_COMBINE_IN, aRect, aMax, aSourceNode);
result.OrWith(MapInputRectToSource(IN_ARITHMETIC_COMBINE_IN2, aRect, aMax,
aSourceNode));
return result;
}
IntRect FilterNodeArithmeticCombineSoftware::GetOutputRectInRect(
const IntRect &aRect) {
if (mK4 > 0.0f) {
@ -2848,6 +2952,17 @@ void FilterNodeCompositeSoftware::RequestFromInputsForRect(
}
}
IntRect FilterNodeCompositeSoftware::MapRectToSource(const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
IntRect result;
for (size_t inputIndex = 0; inputIndex < NumberOfSetInputs(); inputIndex++) {
result.OrWith(MapInputRectToSource(IN_COMPOSITE_IN_START + inputIndex,
aRect, aMax, aSourceNode));
}
return result;
}
IntRect FilterNodeCompositeSoftware::GetOutputRectInRect(const IntRect &aRect) {
IntRect rect;
for (size_t inputIndex = 0; inputIndex < NumberOfSetInputs(); inputIndex++) {
@ -2945,6 +3060,13 @@ void FilterNodeBlurXYSoftware::RequestFromInputsForRect(const IntRect &aRect) {
RequestInputRect(IN_GAUSSIAN_BLUR_IN, InflatedSourceOrDestRect(aRect));
}
IntRect FilterNodeBlurXYSoftware::MapRectToSource(const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
return MapInputRectToSource(
IN_GAUSSIAN_BLUR_IN, InflatedSourceOrDestRect(aRect), aMax, aSourceNode);
}
IntRect FilterNodeBlurXYSoftware::InflatedSourceOrDestRect(
const IntRect &aDestRect) {
Size sigmaXY = StdDeviationXY();
@ -3047,6 +3169,13 @@ void FilterNodeCropSoftware::RequestFromInputsForRect(const IntRect &aRect) {
RequestInputRect(IN_CROP_IN, aRect.Intersect(mCropRect));
}
IntRect FilterNodeCropSoftware::MapRectToSource(const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
return MapInputRectToSource(IN_CROP_IN, aRect.Intersect(mCropRect), aMax,
aSourceNode);
}
IntRect FilterNodeCropSoftware::GetOutputRectInRect(const IntRect &aRect) {
return GetInputRectInRect(IN_CROP_IN, aRect).Intersect(mCropRect);
}
@ -3072,6 +3201,11 @@ void FilterNodePremultiplySoftware::RequestFromInputsForRect(
RequestInputRect(IN_PREMULTIPLY_IN, aRect);
}
IntRect FilterNodePremultiplySoftware::MapRectToSource(
const IntRect &aRect, const IntRect &aMax, FilterNode *aSourceNode) {
return MapInputRectToSource(IN_PREMULTIPLY_IN, aRect, aMax, aSourceNode);
}
IntRect FilterNodePremultiplySoftware::GetOutputRectInRect(
const IntRect &aRect) {
return GetInputRectInRect(IN_PREMULTIPLY_IN, aRect);
@ -3098,6 +3232,11 @@ void FilterNodeUnpremultiplySoftware::RequestFromInputsForRect(
RequestInputRect(IN_UNPREMULTIPLY_IN, aRect);
}
IntRect FilterNodeUnpremultiplySoftware::MapRectToSource(
const IntRect &aRect, const IntRect &aMax, FilterNode *aSourceNode) {
return MapInputRectToSource(IN_UNPREMULTIPLY_IN, aRect, aMax, aSourceNode);
}
IntRect FilterNodeUnpremultiplySoftware::GetOutputRectInRect(
const IntRect &aRect) {
return GetInputRectInRect(IN_UNPREMULTIPLY_IN, aRect);
@ -3129,6 +3268,12 @@ void FilterNodeOpacitySoftware::RequestFromInputsForRect(const IntRect &aRect) {
RequestInputRect(IN_OPACITY_IN, aRect);
}
IntRect FilterNodeOpacitySoftware::MapRectToSource(const IntRect &aRect,
const IntRect &aMax,
FilterNode *aSourceNode) {
return MapInputRectToSource(IN_OPACITY_IN, aRect, aMax, aSourceNode);
}
IntRect FilterNodeOpacitySoftware::GetOutputRectInRect(const IntRect &aRect) {
return GetInputRectInRect(IN_OPACITY_IN, aRect);
}
@ -3412,6 +3557,15 @@ void FilterNodeLightingSoftware<
RequestInputRect(IN_LIGHTING_IN, srcRect);
}
template <typename LightType, typename LightingType>
IntRect FilterNodeLightingSoftware<LightType, LightingType>::MapRectToSource(
const IntRect &aRect, const IntRect &aMax, FilterNode *aSourceNode) {
IntRect srcRect = aRect;
srcRect.Inflate(ceil(mKernelUnitLength.width),
ceil(mKernelUnitLength.height));
return MapInputRectToSource(IN_LIGHTING_IN, srcRect, aMax, aSourceNode);
}
template <typename LightType, typename LightingType>
template <typename CoordType>
already_AddRefed<DataSourceSurface>

View File

@ -149,12 +149,18 @@ class FilterNodeSoftware : public FilterNode,
* Returns the intersection of the input filter's or surface's output rect
* with aInRect.
*/
IntRect GetInputRectInRect(uint32_t aInputEnumIndex, const IntRect& aInRect);
IntRect GetInputRectInRect(uint32_t aInputEnumIndex, const IntRect &aInRect);
/**
* Calls RequestRect on the specified input, if it's a filter.
*/
void RequestInputRect(uint32_t aInputEnumIndex, const IntRect& aRect);
void RequestInputRect(uint32_t aInputEnumIndex, const IntRect &aRect);
/**
* Calls MapRectToSource on the specified input, if it's a filter.
*/
IntRect MapInputRectToSource(uint32_t aInputEnumIndex, const IntRect &aRect,
const IntRect &aMax, FilterNode *aSourceNode);
/**
* Returns the number of set input filters or surfaces. Needed for filters
@ -225,18 +231,20 @@ class FilterNodeTransformSoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTransformSoftware, override)
FilterNodeTransformSoftware();
virtual const char* GetName() override { return "Transform"; }
virtual const char *GetName() override { return "Transform"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, uint32_t aGraphicsFilter) override;
virtual void SetAttribute(uint32_t aIndex, const Matrix& aMatrix) override;
virtual void SetAttribute(uint32_t aIndex, const Matrix &aMatrix) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
IntRect SourceRectForOutputRect(const IntRect& aRect);
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
IntRect SourceRectForOutputRect(const IntRect &aRect);
private:
Matrix mMatrix;
@ -247,16 +255,18 @@ class FilterNodeBlendSoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlendSoftware, override)
FilterNodeBlendSoftware();
virtual const char* GetName() override { return "Blend"; }
virtual const char *GetName() override { return "Blend"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, uint32_t aBlendMode) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
private:
BlendMode mBlendMode;
@ -267,17 +277,17 @@ class FilterNodeMorphologySoftware : public FilterNodeSoftware {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeMorphologySoftware,
override)
FilterNodeMorphologySoftware();
virtual const char* GetName() override { return "Morphology"; }
virtual const char *GetName() override { return "Morphology"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, const IntSize& aRadii) override;
virtual void SetAttribute(uint32_t aIndex, const IntSize &aRadii) override;
virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
private:
IntSize mRadii;
@ -288,17 +298,19 @@ class FilterNodeColorMatrixSoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeColorMatrixSoftware,
override)
virtual const char* GetName() override { return "ColorMatrix"; }
virtual const char *GetName() override { return "ColorMatrix"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, const Matrix5x4& aMatrix) override;
virtual void SetAttribute(uint32_t aIndex, const Matrix5x4 &aMatrix) override;
virtual void SetAttribute(uint32_t aIndex, uint32_t aAlphaMode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
private:
Matrix5x4 mMatrix;
@ -308,16 +320,18 @@ class FilterNodeColorMatrixSoftware : public FilterNodeSoftware {
class FilterNodeFloodSoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeFloodSoftware, override)
virtual const char* GetName() override { return "Flood"; }
virtual const char *GetName() override { return "Flood"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, const Color& aColor) override;
virtual void SetAttribute(uint32_t aIndex, const Color &aColor) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> GetOutput(
const IntRect& aRect) override;
const IntRect &aRect) override;
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
private:
Color mColor;
@ -326,17 +340,17 @@ class FilterNodeFloodSoftware : public FilterNodeSoftware {
class FilterNodeTileSoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTileSoftware, override)
virtual const char* GetName() override { return "Tile"; }
virtual const char *GetName() override { return "Tile"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex,
const IntRect& aSourceRect) override;
const IntRect &aSourceRect) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
private:
IntRect mSourceRect;
@ -353,13 +367,15 @@ class FilterNodeComponentTransferSoftware : public FilterNodeSoftware {
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, bool aDisable) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
virtual void GenerateLookupTable(ptrdiff_t aComponent,
uint8_t aTables[4][256], bool aDisabled);
virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) = 0;
@ -482,36 +498,38 @@ class FilterNodeConvolveMatrixSoftware : public FilterNodeSoftware {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeConvolveMatrixSoftware,
override)
FilterNodeConvolveMatrixSoftware();
virtual const char* GetName() override { return "ConvolveMatrix"; }
virtual const char *GetName() override { return "ConvolveMatrix"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex,
const IntSize& aKernelSize) override;
virtual void SetAttribute(uint32_t aIndex, const Float* aMatrix,
const IntSize &aKernelSize) override;
virtual void SetAttribute(uint32_t aIndex, const Float *aMatrix,
uint32_t aSize) override;
virtual void SetAttribute(uint32_t aIndex, Float aValue) override;
virtual void SetAttribute(uint32_t aIndex,
const Size& aKernelUnitLength) override;
const Size &aKernelUnitLength) override;
virtual void SetAttribute(uint32_t aIndex,
const IntRect& aSourceRect) override;
virtual void SetAttribute(uint32_t aIndex, const IntPoint& aTarget) override;
const IntRect &aSourceRect) override;
virtual void SetAttribute(uint32_t aIndex, const IntPoint &aTarget) override;
virtual void SetAttribute(uint32_t aIndex, uint32_t aEdgeMode) override;
virtual void SetAttribute(uint32_t aIndex, bool aPreserveAlpha) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
private:
template <typename CoordType>
already_AddRefed<DataSourceSurface> DoRender(const IntRect& aRect,
already_AddRefed<DataSourceSurface> DoRender(const IntRect &aRect,
CoordType aKernelUnitLengthX,
CoordType aKernelUnitLengthY);
IntRect InflatedSourceRect(const IntRect& aDestRect);
IntRect InflatedDestRect(const IntRect& aSourceRect);
IntRect InflatedSourceRect(const IntRect &aDestRect);
IntRect InflatedDestRect(const IntRect &aSourceRect);
IntSize mKernelSize;
std::vector<Float> mKernelMatrix;
@ -529,20 +547,22 @@ class FilterNodeDisplacementMapSoftware : public FilterNodeSoftware {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDisplacementMapSoftware,
override)
FilterNodeDisplacementMapSoftware();
virtual const char* GetName() override { return "DisplacementMap"; }
virtual const char *GetName() override { return "DisplacementMap"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, Float aScale) override;
virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
private:
IntRect InflatedSourceOrDestRect(const IntRect& aDestOrSourceRect);
IntRect InflatedSourceOrDestRect(const IntRect &aDestOrSourceRect);
Float mScale;
ColorChannel mChannelX;
@ -554,18 +574,20 @@ class FilterNodeTurbulenceSoftware : public FilterNodeSoftware {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTurbulenceSoftware,
override)
FilterNodeTurbulenceSoftware();
virtual const char* GetName() override { return "Turbulence"; }
virtual const char *GetName() override { return "Turbulence"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, const Size& aSize) override;
virtual void SetAttribute(uint32_t aIndex, const Size &aSize) override;
virtual void SetAttribute(uint32_t aIndex,
const IntRect& aRenderRect) override;
const IntRect &aRenderRect) override;
virtual void SetAttribute(uint32_t aIndex, bool aStitchable) override;
virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
private:
@ -582,17 +604,19 @@ class FilterNodeArithmeticCombineSoftware : public FilterNodeSoftware {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeArithmeticCombineSoftware,
override)
FilterNodeArithmeticCombineSoftware();
virtual const char* GetName() override { return "ArithmeticCombine"; }
virtual const char *GetName() override { return "ArithmeticCombine"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, const Float* aFloat,
virtual void SetAttribute(uint32_t aIndex, const Float *aFloat,
uint32_t aSize) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
private:
Float mK1;
@ -605,16 +629,18 @@ class FilterNodeCompositeSoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCompositeSoftware, override)
FilterNodeCompositeSoftware();
virtual const char* GetName() override { return "Composite"; }
virtual const char *GetName() override { return "Composite"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
private:
CompositeOperator mOperator;
@ -627,11 +653,13 @@ class FilterNodeBlurXYSoftware : public FilterNodeSoftware {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlurXYSoftware, override)
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
IntRect InflatedSourceOrDestRect(const IntRect& aDestRect);
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
IntRect InflatedSourceOrDestRect(const IntRect &aDestRect);
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
// Implemented by subclasses.
virtual Size StdDeviationXY() = 0;
@ -642,7 +670,7 @@ class FilterNodeGaussianBlurSoftware : public FilterNodeBlurXYSoftware {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeGaussianBlurSoftware,
override)
FilterNodeGaussianBlurSoftware();
virtual const char* GetName() override { return "GaussianBlur"; }
virtual const char *GetName() override { return "GaussianBlur"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, Float aStdDeviation) override;
@ -658,7 +686,7 @@ class FilterNodeDirectionalBlurSoftware : public FilterNodeBlurXYSoftware {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDirectionalBlurSoftware,
override)
FilterNodeDirectionalBlurSoftware();
virtual const char* GetName() override { return "DirectionalBlur"; }
virtual const char *GetName() override { return "DirectionalBlur"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, Float aStdDeviation) override;
virtual void SetAttribute(uint32_t aIndex, uint32_t aBlurDirection) override;
@ -674,16 +702,18 @@ class FilterNodeDirectionalBlurSoftware : public FilterNodeBlurXYSoftware {
class FilterNodeCropSoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCropSoftware, override)
virtual const char* GetName() override { return "Crop"; }
virtual const char *GetName() override { return "Crop"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, const Rect& aSourceRect) override;
virtual void SetAttribute(uint32_t aIndex, const Rect &aSourceRect) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
private:
IntRect mCropRect;
@ -693,43 +723,49 @@ class FilterNodePremultiplySoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodePremultiplySoftware,
override)
virtual const char* GetName() override { return "Premultiply"; }
virtual const char *GetName() override { return "Premultiply"; }
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
};
class FilterNodeUnpremultiplySoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeUnpremultiplySoftware,
override)
virtual const char* GetName() override { return "Unpremultiply"; }
virtual const char *GetName() override { return "Unpremultiply"; }
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
};
class FilterNodeOpacitySoftware : public FilterNodeSoftware {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeOpacitySoftware, override)
virtual const char* GetName() override { return "Opacity"; }
virtual const char *GetName() override { return "Opacity"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, Float aValue) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
Float mValue = 1.0f;
};
@ -740,27 +776,29 @@ class FilterNodeLightingSoftware : public FilterNodeSoftware {
#if defined(MOZILLA_INTERNAL_API) && \
(defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING))
// Helpers for refcounted
virtual const char* typeName() const override { return mTypeName; }
virtual const char *typeName() const override { return mTypeName; }
virtual size_t typeSize() const override { return sizeof(*this); }
#endif
explicit FilterNodeLightingSoftware(const char* aTypeName);
virtual const char* GetName() override { return "Lighting"; }
explicit FilterNodeLightingSoftware(const char *aTypeName);
virtual const char *GetName() override { return "Lighting"; }
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, Float) override;
virtual void SetAttribute(uint32_t aIndex, const Size&) override;
virtual void SetAttribute(uint32_t aIndex, const Point3D&) override;
virtual void SetAttribute(uint32_t aIndex, const Color&) override;
virtual void SetAttribute(uint32_t aIndex, const Size &) override;
virtual void SetAttribute(uint32_t aIndex, const Point3D &) override;
virtual void SetAttribute(uint32_t aIndex, const Color &) override;
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) override;
protected:
virtual already_AddRefed<DataSourceSurface> Render(
const IntRect& aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
const IntRect &aRect) override;
virtual IntRect GetOutputRectInRect(const IntRect &aRect) override;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
virtual void RequestFromInputsForRect(const IntRect& aRect) override;
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
private:
template <typename CoordType>
already_AddRefed<DataSourceSurface> DoRender(const IntRect& aRect,
already_AddRefed<DataSourceSurface> DoRender(const IntRect &aRect,
CoordType aKernelUnitLengthX,
CoordType aKernelUnitLengthY);
@ -772,7 +810,7 @@ class FilterNodeLightingSoftware : public FilterNodeSoftware {
Color mColor;
#if defined(MOZILLA_INTERNAL_API) && \
(defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING))
const char* mTypeName;
const char *mTypeName;
#endif
};

View File

@ -425,6 +425,14 @@ class FilterNode : public external::AtomicRefCounted<FilterNode> {
MOZ_CRASH("GFX: FilterNode");
}
/** Maps a rectangle in filter space back to a rectangle in the space of
* aSourceNode's first input. aSourceNode should not have an input
* assigned when calling this function. */
virtual IntRect MapRectToSource(const IntRect &aRect, const IntRect &aMax,
FilterNode *aSourceNode) {
return aMax;
}
protected:
friend class Factory;

View File

@ -239,6 +239,7 @@ class RecordedEvent {
FILTERNODESETINPUT,
CREATESIMILARDRAWTARGET,
CREATECLIPPEDDRAWTARGET,
CREATEDRAWTARGETFORFILTER,
FONTDATA,
FONTDESC,
PUSHLAYER,
@ -257,12 +258,15 @@ class RecordedEvent {
static std::string GetEventName(EventType aType);
/**
* Play back this event using the translator. Note that derived classes should
* only return false when there is a fatal error, as it will probably mean the
* Play back this event using the translator. Note that derived classes
* should
* only return false when there is a fatal error, as it will probably mean
* the
* translation will abort.
* @param aTranslator Translator to be used for retrieving other referenced
* objects and making playback decisions.
* @return true unless a fatal problem has occurred and playback should abort.
* @return true unless a fatal problem has occurred and playback should
* abort.
*/
virtual bool PlayEvent(Translator *aTranslator) const { return true; }

View File

@ -198,6 +198,51 @@ class RecordedCreateClippedDrawTarget
MOZ_IMPLICIT RecordedCreateClippedDrawTarget(S &aStream);
};
class RecordedCreateDrawTargetForFilter
: public RecordedDrawingEvent<RecordedCreateDrawTargetForFilter> {
public:
RecordedCreateDrawTargetForFilter(DrawTarget *aDT, ReferencePtr aRefPtr,
const IntSize &aMaxSize,
SurfaceFormat aFormat, FilterNode *aFilter,
FilterNode *aSource,
const Rect &aSourceRect,
const Point &aDestPoint)
: RecordedDrawingEvent(CREATEDRAWTARGETFORFILTER, aDT),
mRefPtr(aRefPtr),
mMaxSize(aMaxSize),
mFormat(aFormat),
mFilter(aFilter),
mSource(aSource),
mSourceRect(aSourceRect),
mDestPoint(aDestPoint) {}
virtual bool PlayEvent(Translator *aTranslator) const override;
template <class S>
void Record(S &aStream) const;
virtual void OutputSimpleEventInfo(
std::stringstream &aStringStream) const override;
virtual std::string GetName() const override {
return "CreateSimilarDrawTargetForFilter";
}
virtual ReferencePtr GetObjectRef() const override { return mRefPtr; }
ReferencePtr mRefPtr;
IntSize mMaxSize;
SurfaceFormat mFormat;
ReferencePtr mFilter;
ReferencePtr mSource;
Rect mSourceRect;
Point mDestPoint;
private:
friend class RecordedEvent;
template <class S>
MOZ_IMPLICIT RecordedCreateDrawTargetForFilter(S &aStream);
};
class RecordedFillRect : public RecordedDrawingEvent<RecordedFillRect> {
public:
RecordedFillRect(DrawTarget *aDT, const Rect &aRect, const Pattern &aPattern,
@ -1895,6 +1940,62 @@ inline void RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(
<< mSize.height << ")";
}
inline bool RecordedCreateDrawTargetForFilter::PlayEvent(
Translator *aTranslator) const {
IntRect baseRect = aTranslator->LookupDrawTarget(mDT)->GetRect();
auto maxRect = IntRect(IntPoint(0, 0), mMaxSize);
auto clone = aTranslator->LookupDrawTarget(mDT)->GetTransform();
bool invertible = clone.Invert();
// mSourceRect is in filter space. The filter outputs from mSourceRect need
// to be drawn at mDestPoint in user space.
Rect userSpaceSource = Rect(mDestPoint, mSourceRect.Size());
if (invertible) {
// Try to reduce the source rect so that it's not much bigger
// than the draw target. The result is not minimal. Examples
// are left as an exercise for the reader.
auto destRect = IntRectToRect(baseRect);
Rect userSpaceBounds = clone.TransformBounds(destRect);
userSpaceSource = userSpaceSource.Intersect(userSpaceBounds);
}
// Compute how much we moved the top-left of the source rect by, and use that
// to compute the new dest point, and move our intersected source rect back
// into the (new) filter space.
Point shift = userSpaceSource.TopLeft() - mDestPoint;
Rect filterSpaceSource =
Rect(mSourceRect.TopLeft() + shift, userSpaceSource.Size());
baseRect = RoundedOut(filterSpaceSource);
IntRect transformedRect =
aTranslator->LookupFilterNode(mFilter)->MapRectToSource(
baseRect, maxRect, aTranslator->LookupFilterNode(mSource));
// Intersect with maxRect to make sure we didn't end up with something bigger
transformedRect = transformedRect.Intersect(maxRect);
// If we end up with an empty rect make it 1x1 so that things don't break.
if (transformedRect.IsEmpty()) {
transformedRect = IntRect(0, 0, 1, 1);
}
RefPtr<DrawTarget> newDT =
aTranslator->GetReferenceDrawTarget()->CreateSimilarDrawTarget(
transformedRect.Size(), mFormat);
newDT =
gfx::Factory::CreateOffsetDrawTarget(newDT, transformedRect.TopLeft());
// If we couldn't create a DrawTarget this will probably cause us to crash
// with nullptr later in the playback, so return false to abort.
if (!newDT) {
return false;
}
aTranslator->AddDrawTarget(mRefPtr, newDT);
return true;
}
inline bool RecordedCreateClippedDrawTarget::PlayEvent(
Translator *aTranslator) const {
const IntRect baseRect = aTranslator->GetReferenceDrawTarget()->GetRect();
@ -1948,6 +2049,35 @@ inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo(
aStringStream << "[" << mRefPtr << "] CreateClippedDrawTarget ()";
}
template <class S>
void RecordedCreateDrawTargetForFilter::Record(S &aStream) const {
RecordedDrawingEvent::Record(aStream);
WriteElement(aStream, mRefPtr);
WriteElement(aStream, mMaxSize);
WriteElement(aStream, mFormat);
WriteElement(aStream, mFilter);
WriteElement(aStream, mSource);
WriteElement(aStream, mSourceRect);
WriteElement(aStream, mDestPoint);
}
template <class S>
RecordedCreateDrawTargetForFilter::RecordedCreateDrawTargetForFilter(S &aStream)
: RecordedDrawingEvent(CREATEDRAWTARGETFORFILTER, aStream) {
ReadElement(aStream, mRefPtr);
ReadElement(aStream, mMaxSize);
ReadElement(aStream, mFormat);
ReadElement(aStream, mFilter);
ReadElement(aStream, mSource);
ReadElement(aStream, mSourceRect);
ReadElement(aStream, mDestPoint);
}
inline void RecordedCreateDrawTargetForFilter::OutputSimpleEventInfo(
std::stringstream &aStringStream) const {
aStringStream << "[" << mRefPtr << "] CreateDrawTargetForFilter ()";
}
struct GenericPattern {
GenericPattern(const PatternStorage &aStorage, Translator *aTranslator)
: mPattern(nullptr), mTranslator(aTranslator) {
@ -3419,50 +3549,51 @@ inline void RecordedFilterNodeSetInput::OutputSimpleEventInfo(
case _typeenum: \
return new _class(aStream)
#define FOR_EACH_EVENT(f) \
f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \
f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \
f(FILLRECT, RecordedFillRect); \
f(STROKERECT, RecordedStrokeRect); \
f(STROKELINE, RecordedStrokeLine); \
f(CLEARRECT, RecordedClearRect); \
f(COPYSURFACE, RecordedCopySurface); \
f(SETTRANSFORM, RecordedSetTransform); \
f(PUSHCLIPRECT, RecordedPushClipRect); \
f(PUSHCLIP, RecordedPushClip); \
f(POPCLIP, RecordedPopClip); \
f(FILL, RecordedFill); \
f(FILLGLYPHS, RecordedFillGlyphs); \
f(MASK, RecordedMask); \
f(STROKE, RecordedStroke); \
f(DRAWSURFACE, RecordedDrawSurface); \
f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
f(DRAWFILTER, RecordedDrawFilter); \
f(PATHCREATION, RecordedPathCreation); \
f(PATHDESTRUCTION, RecordedPathDestruction); \
f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
f(FILTERNODECREATION, RecordedFilterNodeCreation); \
f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
f(SNAPSHOT, RecordedSnapshot); \
f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
f(MASKSURFACE, RecordedMaskSurface); \
f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \
f(FONTDATA, RecordedFontData); \
f(FONTDESC, RecordedFontDescriptor); \
f(PUSHLAYER, RecordedPushLayer); \
f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \
f(POPLAYER, RecordedPopLayer); \
f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
f(INTOLUMINANCE, RecordedIntoLuminanceSource); \
#define FOR_EACH_EVENT(f) \
f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \
f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \
f(FILLRECT, RecordedFillRect); \
f(STROKERECT, RecordedStrokeRect); \
f(STROKELINE, RecordedStrokeLine); \
f(CLEARRECT, RecordedClearRect); \
f(COPYSURFACE, RecordedCopySurface); \
f(SETTRANSFORM, RecordedSetTransform); \
f(PUSHCLIPRECT, RecordedPushClipRect); \
f(PUSHCLIP, RecordedPushClip); \
f(POPCLIP, RecordedPopClip); \
f(FILL, RecordedFill); \
f(FILLGLYPHS, RecordedFillGlyphs); \
f(MASK, RecordedMask); \
f(STROKE, RecordedStroke); \
f(DRAWSURFACE, RecordedDrawSurface); \
f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
f(DRAWFILTER, RecordedDrawFilter); \
f(PATHCREATION, RecordedPathCreation); \
f(PATHDESTRUCTION, RecordedPathDestruction); \
f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
f(FILTERNODECREATION, RecordedFilterNodeCreation); \
f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
f(SNAPSHOT, RecordedSnapshot); \
f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
f(MASKSURFACE, RecordedMaskSurface); \
f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \
f(CREATEDRAWTARGETFORFILTER, RecordedCreateDrawTargetForFilter); \
f(FONTDATA, RecordedFontData); \
f(FONTDESC, RecordedFontDescriptor); \
f(PUSHLAYER, RecordedPushLayer); \
f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \
f(POPLAYER, RecordedPopLayer); \
f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
f(INTOLUMINANCE, RecordedIntoLuminanceSource); \
f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation);
template <class S>

View File

@ -209,7 +209,7 @@ static already_AddRefed<FilterNode> GaussianBlur(DrawTarget* aDT,
return nullptr;
}
static already_AddRefed<FilterNode> Clear(DrawTarget* aDT) {
already_AddRefed<FilterNode> Clear(DrawTarget* aDT) {
RefPtr<FilterNode> filter = aDT->CreateFilter(FilterType::FLOOD);
if (filter) {
filter->SetAttribute(ATT_FLOOD_COLOR, Color(0, 0, 0, 0));
@ -218,9 +218,9 @@ static already_AddRefed<FilterNode> Clear(DrawTarget* aDT) {
return nullptr;
}
static already_AddRefed<FilterNode> ForSurface(
DrawTarget* aDT, SourceSurface* aSurface,
const IntPoint& aSurfacePosition) {
already_AddRefed<FilterNode> ForSurface(DrawTarget* aDT,
SourceSurface* aSurface,
const IntPoint& aSurfacePosition) {
RefPtr<FilterNode> filter = aDT->CreateFilter(FilterType::TRANSFORM);
if (filter) {
filter->SetAttribute(
@ -1204,12 +1204,11 @@ static AlphaModel OutputAlphaModelForPrimitive(
}
// Returns the output FilterNode, in premultiplied sRGB space.
static already_AddRefed<FilterNode> FilterNodeGraphFromDescription(
already_AddRefed<FilterNode> FilterNodeGraphFromDescription(
DrawTarget* aDT, const FilterDescription& aFilter,
const Rect& aResultNeededRect, SourceSurface* aSourceGraphic,
const IntRect& aSourceGraphicRect, SourceSurface* aFillPaint,
const IntRect& aFillPaintRect, SourceSurface* aStrokePaint,
const IntRect& aStrokePaintRect,
const Rect& aResultNeededRect, FilterNode* aSourceGraphic,
const IntRect& aSourceGraphicRect, FilterNode* aFillPaint,
FilterNode* aStrokePaint,
nsTArray<RefPtr<SourceSurface>>& aAdditionalImages) {
const nsTArray<FilterPrimitiveDescription>& primitives = aFilter.mPrimitives;
MOZ_RELEASE_ASSERT(!primitives.IsEmpty());
@ -1249,17 +1248,12 @@ static already_AddRefed<FilterNode> FilterNodeGraphFromDescription(
if (!inputFilter) {
RefPtr<FilterNode> sourceFilterNode;
nsTArray<SourceSurface*> primitiveSurfaces;
nsTArray<IntRect> primitiveSurfaceRects;
RefPtr<SourceSurface> surf =
ElementForIndex(inputIndex, primitiveSurfaces, aSourceGraphic,
nsTArray<FilterNode*> primitiveFilters;
RefPtr<FilterNode> filt =
ElementForIndex(inputIndex, primitiveFilters, aSourceGraphic,
aFillPaint, aStrokePaint);
IntRect surfaceRect = ElementForIndex(
inputIndex, primitiveSurfaceRects, aSourceGraphicRect,
aFillPaintRect, aStrokePaintRect);
if (surf) {
IntPoint offset = surfaceRect.TopLeft();
sourceFilterNode = FilterWrappers::ForSurface(aDT, surf, offset);
if (filt) {
sourceFilterNode = filt;
// Clip the original SourceGraphic to the first filter region if the
// surface isn't already sized appropriately.
@ -1324,9 +1318,22 @@ void FilterSupport::RenderFilterDescription(
SourceSurface* aStrokePaint, const IntRect& aStrokePaintRect,
nsTArray<RefPtr<SourceSurface>>& aAdditionalImages, const Point& aDestPoint,
const DrawOptions& aOptions) {
RefPtr<FilterNode> sourceGraphic, fillPaint, strokePaint;
if (aSourceGraphic) {
sourceGraphic = FilterWrappers::ForSurface(aDT, aSourceGraphic,
aSourceGraphicRect.TopLeft());
}
if (aFillPaint) {
fillPaint =
FilterWrappers::ForSurface(aDT, aFillPaint, aFillPaintRect.TopLeft());
}
if (aStrokePaint) {
strokePaint = FilterWrappers::ForSurface(aDT, aStrokePaint,
aStrokePaintRect.TopLeft());
}
RefPtr<FilterNode> resultFilter = FilterNodeGraphFromDescription(
aDT, aFilter, aRenderRect, aSourceGraphic, aSourceGraphicRect, aFillPaint,
aFillPaintRect, aStrokePaint, aStrokePaintRect, aAdditionalImages);
aDT, aFilter, aRenderRect, sourceGraphic, aSourceGraphicRect, fillPaint,
strokePaint, aAdditionalImages);
if (!resultFilter) {
gfxWarning() << "Filter is NULL.";
return;

View File

@ -9,12 +9,12 @@
#include "mozilla/Attributes.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/gfx/Rect.h"
#include "nsClassHashtable.h"
#include "nsTArray.h"
#include "nsRegion.h"
#include "nsTArray.h"
namespace mozilla {
namespace gfx {
@ -28,6 +28,11 @@ extern const float gsRGBToLinearRGBMap[256];
namespace mozilla {
namespace gfx {
namespace FilterWrappers {
extern already_AddRefed<FilterNode> Clear(DrawTarget* aDT);
extern already_AddRefed<FilterNode> ForSurface(
DrawTarget* aDT, SourceSurface* aSurface, const IntPoint& aSurfacePosition);
} // namespace FilterWrappers
// Morphology Operators
const unsigned short SVG_OPERATOR_UNKNOWN = 0;
@ -499,6 +504,13 @@ struct FilterDescription final {
nsTArray<FilterPrimitiveDescription> mPrimitives;
};
already_AddRefed<FilterNode> FilterNodeGraphFromDescription(
DrawTarget* aDT, const FilterDescription& aFilter,
const Rect& aResultNeededRect, FilterNode* aSourceGraphic,
const IntRect& aSourceGraphicRect, FilterNode* aFillPaint,
FilterNode* aStrokePaint,
nsTArray<RefPtr<SourceSurface>>& aAdditionalImages);
/**
* The methods of this class are not on FilterDescription because
* FilterDescription is designed as a simple value holder that can be used

View File

@ -104,7 +104,7 @@ fuzzy-if(skiaContent,0-1,0-400) == feDisplacementMap-alpha-01.svg pass.svg
fuzzy(0-2,0-500) == feDisplacementMap-colour-01.svg feDisplacementMap-colour-01-ref.svg
== feDisplacementMap-scale-01.svg pass.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-2,0-25) fuzzy-if(webrender,16-16,14033-15367) == feDropShadow-01.svg feDropShadow-01-ref.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-2,0-25) fuzzy-if(webrender,56-57,14033-15368) == feDropShadow-01.svg feDropShadow-01-ref.svg
== feFlood-color-01.svg pass.svg

View File

@ -11,22 +11,23 @@
#include "mozilla/UniquePtr.h"
// Keep others in (case-insensitive) order:
#include "FilterSupport.h"
#include "ImgDrawResult.h"
#include "SVGContentUtils.h"
#include "gfx2DGlue.h"
#include "gfxContext.h"
#include "gfxPlatform.h"
#include "gfxPrefs.h"
#include "gfxUtils.h"
#include "mozilla/Unused.h"
#include "mozilla/gfx/Filters.h"
#include "mozilla/gfx/Helpers.h"
#include "mozilla/gfx/PatternHelpers.h"
#include "nsSVGDisplayableFrame.h"
#include "nsCSSFilterInstance.h"
#include "nsSVGDisplayableFrame.h"
#include "nsSVGFilterInstance.h"
#include "nsSVGFilterPaintCallback.h"
#include "nsSVGUtils.h"
#include "SVGContentUtils.h"
#include "FilterSupport.h"
#include "mozilla/Unused.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -614,7 +615,10 @@ void nsFilterInstance::BuildSourcePaints(imgDrawingParams& aImgParams) {
}
void nsFilterInstance::BuildSourceImage(DrawTarget* aDest,
imgDrawingParams& aImgParams) {
imgDrawingParams& aImgParams,
FilterNode* aFilter,
FilterNode* aSource,
const Rect& aSourceRect) {
MOZ_ASSERT(mTargetFrame);
nsIntRect neededRect = mSourceGraphic.mNeededBounds;
@ -622,8 +626,9 @@ void nsFilterInstance::BuildSourceImage(DrawTarget* aDest,
return;
}
RefPtr<DrawTarget> offscreenDT = aDest->CreateSimilarDrawTarget(
neededRect.Size(), SurfaceFormat::B8G8R8A8);
RefPtr<DrawTarget> offscreenDT = aDest->CreateSimilarDrawTargetForFilter(
neededRect.Size(), SurfaceFormat::B8G8R8A8, aFilter, aSource, aSourceRect,
Point(0, 0));
if (!offscreenDT || !offscreenDT->IsValid()) {
return;
}
@ -682,15 +687,53 @@ void nsFilterInstance::Render(gfxContext* aCtx, imgDrawingParams& aImgParams,
ComputeNeededBoxes();
BuildSourceImage(aCtx->GetDrawTarget(), aImgParams);
BuildSourcePaints(aImgParams);
Rect renderRect = IntRectToRect(filterRect);
RefPtr<DrawTarget> dt = aCtx->GetDrawTarget();
FilterSupport::RenderFilterDescription(
aCtx->GetDrawTarget(), mFilterDescription, IntRectToRect(filterRect),
mSourceGraphic.mSourceSurface, mSourceGraphic.mSurfaceRect,
mFillPaint.mSourceSurface, mFillPaint.mSurfaceRect,
mStrokePaint.mSourceSurface, mStrokePaint.mSurfaceRect, mInputImages,
Point(0, 0), DrawOptions(aOpacity));
BuildSourcePaints(aImgParams);
RefPtr<FilterNode> sourceGraphic, fillPaint, strokePaint;
if (mFillPaint.mSourceSurface) {
fillPaint = FilterWrappers::ForSurface(dt, mFillPaint.mSourceSurface,
mFillPaint.mSurfaceRect.TopLeft());
}
if (mStrokePaint.mSourceSurface) {
strokePaint = FilterWrappers::ForSurface(
dt, mStrokePaint.mSourceSurface, mStrokePaint.mSurfaceRect.TopLeft());
}
// We make the sourceGraphic filter but don't set its inputs until after so
// that we can make the sourceGraphic size depend on the filter chain
sourceGraphic = dt->CreateFilter(FilterType::TRANSFORM);
if (sourceGraphic) {
// Make sure we set the translation before calling BuildSourceImage
// so that CreateSimilarDrawTargetForFilter works properly
IntPoint offset = mSourceGraphic.mNeededBounds.TopLeft();
sourceGraphic->SetAttribute(ATT_TRANSFORM_MATRIX,
Matrix::Translation(offset.x, offset.y));
}
RefPtr<FilterNode> resultFilter = FilterNodeGraphFromDescription(
aCtx->GetDrawTarget(), mFilterDescription, renderRect, sourceGraphic,
mSourceGraphic.mSurfaceRect, fillPaint, strokePaint, mInputImages);
if (!resultFilter) {
gfxWarning() << "Filter is NULL.";
return;
}
BuildSourceImage(aCtx->GetDrawTarget(), aImgParams, resultFilter,
sourceGraphic, renderRect);
if (sourceGraphic) {
if (mSourceGraphic.mSourceSurface) {
sourceGraphic->SetInput(IN_TRANSFORM_IN, mSourceGraphic.mSourceSurface);
} else {
RefPtr<FilterNode> clear = FilterWrappers::Clear(aCtx->GetDrawTarget());
sourceGraphic->SetInput(IN_TRANSFORM_IN, clear);
}
}
aCtx->GetDrawTarget()->DrawFilter(resultFilter, renderRect, Point(0, 0),
DrawOptions(aOpacity));
}
nsRegion nsFilterInstance::ComputePostFilterDirtyRegion() {

View File

@ -240,7 +240,10 @@ class nsFilterInstance {
* Creates the SourceSurface for the SourceGraphic graph node, paints its
* contents, and assigns it to mSourceGraphic.mSourceSurface.
*/
void BuildSourceImage(DrawTarget* aDest, imgDrawingParams& aImgParams);
void BuildSourceImage(DrawTarget* aDest, imgDrawingParams& aImgParams,
mozilla::gfx::FilterNode* aFilter,
mozilla::gfx::FilterNode* aSource,
const mozilla::gfx::Rect& aSourceRect);
/**
* Build the list of FilterPrimitiveDescriptions that describes the filter's