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