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