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