Bug 1622113 - Ensure the skip rect end is aligned to a 4-byte boundary. r=mstange
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sat, 21 Mar 2020 00:19:23 +0000
changeset 586725 8b146f14ae8bbcf7ebeafbb03637edb789eea735
parent 586724 49ad9716f04392825764d00d5f53506df597d69d
child 586726 af918311202c58cf2e007aebfb0fbc4928f657b6
push id2321
push userffxbld-merge
push dateMon, 27 Apr 2020 16:26:39 +0000
treeherdermozilla-release@38a505a56ec4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1622113
milestone76.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 1622113 - Ensure the skip rect end is aligned to a 4-byte boundary. r=mstange So that accesses that use mSkipRect.XMost() - 4 or - 16 are aligned to a 4-byte boundary. Not doing so would crash on some architectures due to a SIGBUS. Differential Revision: https://phabricator.services.mozilla.com/D66748
gfx/2d/Blur.cpp
gfx/2d/Blur.h
--- a/gfx/2d/Blur.cpp
+++ b/gfx/2d/Blur.cpp
@@ -6,16 +6,17 @@
 
 #include "Blur.h"
 
 #include <algorithm>
 #include <math.h>
 #include <string.h>
 
 #include "mozilla/CheckedInt.h"
+#include "NumericTools.h"
 
 #include "2D.h"
 #include "DataSurfaceHelpers.h"
 #include "Tools.h"
 
 #ifdef USE_NEON
 #  include "mozilla/arm.h"
 #endif
@@ -502,21 +503,30 @@ void AlphaBoxBlur::Init(const Rect& aRec
   if (aSkipRect) {
     // If we get passed a skip rect, we can lower the amount of
     // blurring/spreading we need to do. We convert it to IntRect to avoid
     // expensive int<->float conversions if we were to use Rect instead.
     Rect skipRect = *aSkipRect;
     skipRect.Deflate(Size(aBlurRadius + aSpreadRadius));
     mSkipRect = RoundedIn(skipRect);
     mSkipRect = mSkipRect.Intersect(mRect);
-    if (mSkipRect.IsEqualInterior(mRect)) return;
+    if (mSkipRect.IsEqualInterior(mRect)) {
+      return;
+    }
 
     mSkipRect -= mRect.TopLeft();
+    // Ensure the skip rect is 4-pixel-aligned in the x axis, so that all our
+    // accesses later are aligned as well, see bug 1622113.
+    mSkipRect.SetLeftEdge(RoundUpToMultiple(mSkipRect.X(), 4));
+    mSkipRect.SetRightEdge(RoundDownToMultiple(mSkipRect.XMost(), 4));
+    if (mSkipRect.IsEmpty()) {
+      mSkipRect = IntRect();
+    }
   } else {
-    mSkipRect = IntRect(0, 0, 0, 0);
+    mSkipRect = IntRect();
   }
 
   CheckedInt<int32_t> stride = RoundUpToMultipleOf4(mRect.Width());
   if (stride.isValid()) {
     mStride = stride.value();
 
     // We need to leave room for an additional 3 bytes for a potential overrun
     // in our blurring code.
--- a/gfx/2d/Blur.h
+++ b/gfx/2d/Blur.h
@@ -145,16 +145,18 @@ class GFX2D_API AlphaBoxBlur final {
                    uint32_t* aIntegralImage, size_t aIntegralImageStride) const;
 #endif
 
   static CheckedInt<int32_t> RoundUpToMultipleOf4(int32_t aVal);
 
   /**
    * A rect indicating the area where blurring is unnecessary, and the blur
    * algorithm should skip over it.
+   *
+   * This is guaranteed to be 4-pixel aligned in the x axis.
    */
   IntRect mSkipRect;
 
   /**
    * The device-space rectangle the the backing 8-bit alpha surface covers.
    */
   IntRect mRect;