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