Bug 1480620. Clip the filter source rect to the transformed DrawTarget bounds. r=mstange
This lets us avoid filtering the entire source image when we only need a small portion of it.
This makes a big performance difference with tiled blob images with WebRender.
MozReview-Commit-ID: EbMZ7ZJEeCe
--- a/gfx/2d/DrawTargetOffset.cpp
+++ b/gfx/2d/DrawTargetOffset.cpp
@@ -68,23 +68,43 @@ DrawTargetOffset::DetachAllSnapshots()
#define OFFSET_COMMAND5(command, type1, type2, type3, type4, type5) \
void \
DrawTargetOffset::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
{ \
mDrawTarget->command(arg1, arg2, arg3, arg4, arg5); \
}
OFFSET_COMMAND(Flush)
-OFFSET_COMMAND4(DrawFilter, FilterNode*, const Rect&, const Point&, const DrawOptions&)
OFFSET_COMMAND1(ClearRect, const Rect&)
OFFSET_COMMAND4(MaskSurface, const Pattern&, SourceSurface*, Point, const DrawOptions&)
OFFSET_COMMAND4(FillGlyphs, ScaledFont*, const GlyphBuffer&, const Pattern&, const DrawOptions&)
OFFSET_COMMAND3(Mask, const Pattern&, const Pattern&, const DrawOptions&)
void
+DrawTargetOffset::DrawFilter(FilterNode* aNode, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions)
+{
+ auto clone = mTransform;
+ bool invertible = clone.Invert();
+ auto src = aSourceRect;
+ 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 = Rect(mOrigin.x,
+ mOrigin.y,
+ mDrawTarget->GetSize().width,
+ mDrawTarget->GetSize().height);
+ auto dtBounds = clone.TransformBounds(destRect);
+ src = aSourceRect.Intersect(dtBounds);
+ }
+ auto shift = src.TopLeft() - aSourceRect.TopLeft();
+ mDrawTarget->DrawFilter(aNode, src, aDestPoint + shift, aOptions);
+}
+
+void
DrawTargetOffset::PushClip(const Path* aPath)
{
mDrawTarget->PushClip(aPath);
}
void
DrawTargetOffset::PushClipRect(const Rect& aRect)
{