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