Bug 1480620. Clip the filter source rect to the transformed DrawTarget bounds. r=mstange
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Wed, 01 Aug 2018 21:26:40 -0400
changeset 430443 89a67ef04c61a3f01146f082676259e2ac585fbf
parent 430442 a360d3b8f76c660e1bf17193f3fe5389d1e9d0c9
child 430444 00ff83d23238b770a947bb407ec1afe39c3010b5
push id34405
push userncsoregi@mozilla.com
push dateWed, 08 Aug 2018 09:57:26 +0000
treeherdermozilla-central@c65991f3fa10 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1480620
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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)
 {