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