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