Bug 1620479 - Add a clip to the draw target in non-native theme to make skia more deterministic. r=jrmuizel
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 06 Mar 2020 02:47:59 +0000
changeset 517189 4b2de38456f25d1cf817fdd798a61820029120ba
parent 517188 fa1dd2a86d113c462f84d1891ec50ae109f0df8d
child 517190 e62a98a8ac047f61299d6d24b455e7c1ffe069b0
push id109288
push userealvarez@mozilla.com
push dateFri, 06 Mar 2020 02:48:41 +0000
treeherderautoland@4b2de38456f2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1620479
milestone75.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 1620479 - Add a clip to the draw target in non-native theme to make skia more deterministic. r=jrmuizel See the comment for the sadness. Otherwise there was quite a lot of fuzz to annotate. Differential Revision: https://phabricator.services.mozilla.com/D65666
widget/nsNativeBasicTheme.cpp
--- a/widget/nsNativeBasicTheme.cpp
+++ b/widget/nsNativeBasicTheme.cpp
@@ -143,16 +143,34 @@ static Rect FixAspectRatio(const Rect& a
     auto diff = rect.height - rect.width;
     rect.height = rect.width;
     rect.y += diff / 2;
   }
 
   return rect;
 }
 
+// This pushes and pops a clip rect to the draw target.
+//
+// This is done to reduce fuzz in places where we may have antialiasing, because
+// skia is not clip-invariant: given different clips, it does not guarantee the
+// same result, even if the painted content doesn't intersect the clips.
+//
+// This is a bit sad, overall, but...
+struct MOZ_RAII AutoClipRect {
+  AutoClipRect(DrawTarget& aDt, const Rect& aRect) : mDt(aDt) {
+    mDt.PushClipRect(aRect);
+  }
+
+  ~AutoClipRect() { mDt.PopClip(); }
+
+ private:
+  DrawTarget& mDt;
+};
+
 static void PaintRoundedRectWithBorder(DrawTarget* aDrawTarget,
                                        const Rect& aRect,
                                        const Color& aBackgroundColor,
                                        const Color& aBorderColor,
                                        CSSCoord aBorderWidth, CSSCoord aRadius,
                                        uint32_t aDpi) {
   const LayoutDeviceCoord borderWidth(aBorderWidth * aDpi);
   const LayoutDeviceCoord radius(aRadius * aDpi);
@@ -535,16 +553,17 @@ nsNativeBasicTheme::DrawWidgetBackground
                                          StyleAppearance aAppearance,
                                          const nsRect& aRect,
                                          const nsRect& /* aDirtyRect */) {
   DrawTarget* dt = aContext->GetDrawTarget();
   const nscoord twipsPerPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
   EventStates eventState = GetContentState(aFrame, aAppearance);
 
   Rect devPxRect = NSRectToSnappedRect(aRect, twipsPerPixel, *dt);
+  AutoClipRect clip(*dt, devPxRect);
 
   if (aAppearance == StyleAppearance::MozMenulistArrowButton) {
     bool isHTML = IsHTMLContent(aFrame);
     nsIFrame* parentFrame = aFrame->GetParent();
     bool isMenulist = !isHTML && parentFrame->IsMenuFrame();
     // HTML select and XUL menulist dropdown buttons get state from the
     // parent.
     if (isHTML || isMenulist) {