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