Bug 1480620. Clip the filter source rect to the transformed DrawTarget bounds. r=mstange draft
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Wed, 01 Aug 2018 21:26:40 -0400
changeset 826429 e3b182c0824ffaba13f6b8c9499c92e439956e45
parent 826324 a5165f1d9ee39236eafa78cb052b204b28404fad
push id118331
push userbmo:jmuizelaar@mozilla.com
push dateFri, 03 Aug 2018 20:36:29 +0000
reviewersmstange
bugs1480620
milestone63.0a1
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
gfx/2d/DrawTargetOffset.cpp
--- 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)
 {