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