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