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