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