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