d445b2
# HG changeset patch
d445b2
# Parent  36563351309ddbc6c29559ba50a41d005f925abb
d445b2
Skia does not support big endian. The places to fix are too numerous and upstream (skia, not Mozilla)
d445b2
has no interest in maintaining big endian.
d445b2
So here we try to swizzle the input for skia, so that skia always works on LE, and when it comes
d445b2
out again, we transform back to BE.
d445b2
d445b2
diff -r 36563351309d gfx/2d/ConvolutionFilter.cpp
d445b2
--- a/gfx/2d/ConvolutionFilter.cpp	Mon Sep 09 17:59:28 2019 +0200
d445b2
+++ b/gfx/2d/ConvolutionFilter.cpp	Tue Sep 10 08:25:13 2019 +0200
d445b2
@@ -35,9 +35,38 @@
d445b2
   return true;
d445b2
 }
d445b2
 
d445b2
+static void ByteSwapArray(uint8_t *u8Array, int32_t size) {
d445b2
+    uint32_t *array = reinterpret_cast<uint32_t*>(u8Array);
d445b2
+    for (int pxl = 0; pxl < size; ++pxl) {
d445b2
+        // Use an endian swap to move the bytes, i.e. BGRA -> ARGB.
d445b2
+        uint32_t rgba = array[pxl];
d445b2
+        array[pxl] = NativeEndian::swapToLittleEndian(rgba);
d445b2
+    }
d445b2
+}
d445b2
+
d445b2
 void ConvolutionFilter::ConvolveHorizontally(const uint8_t* aSrc, uint8_t* aDst,
d445b2
                                              bool aHasAlpha) {
d445b2
+#if MOZ_BIG_ENDIAN
d445b2
+    int outputSize = mFilter->numValues();
d445b2
+
d445b2
+    // Input size isn't handed in, so we have to calculate it quickly
d445b2
+    int inputSize = 0;
d445b2
+    for (int xx = 0; xx < outputSize; ++xx) {
d445b2
+        // Get the filter that determines the current output pixel.
d445b2
+        int filterOffset, filterLength;
d445b2
+        mFilter->FilterForValue(xx, &filterOffset, &filterLength);
d445b2
+        inputSize = std::max(inputSize, filterOffset + filterLength);
d445b2
+    }
d445b2
+
d445b2
+    ByteSwapArray((uint8_t*)aSrc, inputSize);
d445b2
+#endif
d445b2
+
d445b2
   SkOpts::convolve_horizontally(aSrc, *mFilter, aDst, aHasAlpha);
d445b2
+
d445b2
+#if MOZ_BIG_ENDIAN
d445b2
+    ByteSwapArray((uint8_t*)aSrc, inputSize);
d445b2
+    ByteSwapArray(aDst, outputSize);
d445b2
+#endif
d445b2
 }
d445b2
 
d445b2
 void ConvolutionFilter::ConvolveVertically(uint8_t* const* aSrc, uint8_t* aDst,
d445b2
@@ -49,8 +78,26 @@
d445b2
   int32_t filterLength;
d445b2
   auto filterValues =
d445b2
       mFilter->FilterForValue(aRowIndex, &filterOffset, &filterLength);
d445b2
+
d445b2
+#if MOZ_BIG_ENDIAN
d445b2
+  for (int filterY = 0; filterY < filterLength; filterY++) {
d445b2
+      // Skia only knows LE, so we have to swizzle the input
d445b2
+    ByteSwapArray(aSrc[filterY], aRowSize);
d445b2
+  }
d445b2
+#endif
d445b2
+
d445b2
   SkOpts::convolve_vertically(filterValues, filterLength, aSrc, aRowSize, aDst,
d445b2
                               aHasAlpha);
d445b2
+
d445b2
+#if MOZ_BIG_ENDIAN
d445b2
+  // After skia is finished, we swizzle back to BE, in case
d445b2
+  // the input is used again somewhere else
d445b2
+  for (int filterY = 0; filterY < filterLength; filterY++) {
d445b2
+    ByteSwapArray(aSrc[filterY], aRowSize);
d445b2
+  }
d445b2
+  // The destination array as well
d445b2
+  ByteSwapArray(aDst, aRowSize);
d445b2
+#endif
d445b2
 }
d445b2
 
d445b2
 /* ConvolutionFilter::ComputeResizeFactor is derived from Skia's
d445b2
diff -r 36563351309d gfx/skia/skia/include/core/SkPreConfig.h
d445b2
--- a/gfx/skia/skia/include/core/SkPreConfig.h	Mon Sep 09 17:59:28 2019 +0200
d445b2
+++ b/gfx/skia/skia/include/core/SkPreConfig.h	Tue Sep 10 08:25:13 2019 +0200
d445b2
@@ -73,7 +73,7 @@
d445b2
       defined(__ppc__) || defined(__hppa) || \
d445b2
       defined(__PPC__) || defined(__PPC64__) || \
d445b2
       defined(_MIPSEB) || defined(__ARMEB__) || \
d445b2
-      defined(__s390__) || \
d445b2
+      defined(__s390__) || defined(__s390x__) || \
d445b2
       (defined(__sh__) && defined(__BIG_ENDIAN__)) || \
d445b2
       (defined(__ia64) && defined(__BIG_ENDIAN__))
d445b2
          #define SK_CPU_BENDIAN