From e9459cd5b6a9f266216259205158bd543b21c21f Mon Sep 17 00:00:00 2001 From: q66 Date: Mon, 17 Feb 2020 02:54:15 +0100 Subject: [PATCH] firefox: add skia BE patches + add workaround to prevent BE crashes --- .../firefox/patches/hack-be-swizzlerow.patch | 73 ++++++++++++++++ srcpkgs/firefox/patches/skia-sucks1.patch | 84 +++++++++++++++++++ srcpkgs/firefox/patches/skia-sucks2.patch | 44 ++++++++++ srcpkgs/firefox/patches/skia-sucks3.patch | 30 +++++++ 4 files changed, 231 insertions(+) create mode 100644 srcpkgs/firefox/patches/hack-be-swizzlerow.patch create mode 100644 srcpkgs/firefox/patches/skia-sucks1.patch create mode 100644 srcpkgs/firefox/patches/skia-sucks2.patch create mode 100644 srcpkgs/firefox/patches/skia-sucks3.patch diff --git a/srcpkgs/firefox/patches/hack-be-swizzlerow.patch b/srcpkgs/firefox/patches/hack-be-swizzlerow.patch new file mode 100644 index 0000000000..3420dced23 --- /dev/null +++ b/srcpkgs/firefox/patches/hack-be-swizzlerow.patch @@ -0,0 +1,73 @@ +Since this code is broken on BE at this point (OS_RGBA resolves to an +unhandled thing), temporarily revert to the code present in firefox-esr + +Upstream issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1616030 + +--- image/decoders/nsGIFDecoder2.cpp ++++ image/decoders/nsGIFDecoder2.cpp +@@ -418,10 +418,65 @@ void nsGIFDecoder2::ConvertColormap(uint32_t* aColormap, uint32_t aColors) { + } + } + ++ // since SwizzleRow is broken on BE right now for OS_RGBA, temporarily ++ // restore this code to whatever it was before the rework... ++#if MOZ_BIG_ENDIAN() ++ ++#define BLOCK_RGB_TO_FRGB(from, to) \ ++do { \ ++ uint32_t m0 = ((uint32_t*)from)[0], m1 = ((uint32_t*)from)[1], \ ++ m2 = ((uint32_t*)from)[2], \ ++ p0, p1, p2, p3; \ ++ p0 = 0xFF000000 | ((m0) >> 8); \ ++ p1 = 0xFF000000 | ((m0) << 16) | ((m1) >> 16); \ ++ p2 = 0xFF000000 | ((m1) << 8) | ((m2) >> 24); \ ++ p3 = 0xFF000000 | (m2); \ ++ to[0] = p0; \ ++ to[1] = p1; \ ++ to[2] = p2; \ ++ to[3] = p3; \ ++} while(0) ++ ++ // Convert from the GIF's RGB format to the Cairo format. ++ // Work from end to begin, because of the in-place expansion ++ uint8_t* from = ((uint8_t*)aColormap) + 3 * aColors; ++ uint32_t* to = aColormap + aColors; ++ ++ // Convert color entries to Cairo format ++ ++ // set up for loops below ++ if (!aColors) { ++ return; ++ } ++ uint32_t c = aColors; ++ ++ // copy as bytes until source pointer is 32-bit-aligned ++ // NB: can't use 32-bit reads, they might read off the end of the buffer ++ for (; (NS_PTR_TO_UINT32(from) & 0x3) && c; --c) { ++ from -= 3; ++ *--to = gfxPackedPixel(0xFF, from[0], from[1], from[2]); ++ } ++ ++ // bulk copy of pixels. ++ while (c >= 4) { ++ from -= 12; ++ to -= 4; ++ c -= 4; ++ BLOCK_RGB_TO_FRGB(from, to); ++ } ++ ++ // copy remaining pixel(s) ++ // NB: can't use 32-bit reads, they might read off the end of the buffer ++ while (c--) { ++ from -= 3; ++ *--to = gfxPackedPixel(0xFF, from[0], from[1], from[2]); ++ } ++#else + // Expand color table from RGB to BGRA. + MOZ_ASSERT(mSwizzleFn); + uint8_t* data = reinterpret_cast(aColormap); + mSwizzleFn(data, data, aColors); ++#endif + } + + LexerResult nsGIFDecoder2::DoDecode(SourceBufferIterator& aIterator, diff --git a/srcpkgs/firefox/patches/skia-sucks1.patch b/srcpkgs/firefox/patches/skia-sucks1.patch new file mode 100644 index 0000000000..223c9b14e6 --- /dev/null +++ b/srcpkgs/firefox/patches/skia-sucks1.patch @@ -0,0 +1,84 @@ +# HG changeset patch +# Parent 548d0a2f3a22bfac32ec0c3921c6c969c8bf32a9 + +diff -r 548d0a2f3a22 gfx/2d/ConvolutionFilter.cpp +--- gfx/2d/ConvolutionFilter.cpp Mon Jul 22 16:57:54 2019 +0200 ++++ gfx/2d/ConvolutionFilter.cpp Thu Jul 25 14:27:59 2019 +0200 +@@ -35,9 +35,38 @@ + return true; + } + ++static void ByteSwapArray(uint8_t *u8Array, int32_t size) { ++ uint32_t *array = reinterpret_cast(u8Array); ++ for (int pxl = 0; pxl < size; ++pxl) { ++ // Use an endian swap to move the bytes, i.e. BGRA -> ARGB. ++ uint32_t rgba = array[pxl]; ++ array[pxl] = NativeEndian::swapToLittleEndian(rgba); ++ } ++} ++ + void ConvolutionFilter::ConvolveHorizontally(const uint8_t* aSrc, uint8_t* aDst, + bool aHasAlpha) { ++#ifdef MOZ_BIG_ENDIAN ++ int outputSize = mFilter->numValues(); ++ ++ // Input size isn't handed in, so we have to calculate it quickly ++ int inputSize = 0; ++ for (int xx = 0; xx < outputSize; ++xx) { ++ // Get the filter that determines the current output pixel. ++ int filterOffset, filterLength; ++ mFilter->FilterForValue(xx, &filterOffset, &filterLength); ++ inputSize = std::max(inputSize, filterOffset + filterLength); ++ } ++ ++ ByteSwapArray((uint8_t*)aSrc, inputSize); ++#endif ++ + SkOpts::convolve_horizontally(aSrc, *mFilter, aDst, aHasAlpha); ++ ++#ifdef MOZ_BIG_ENDIAN ++ ByteSwapArray((uint8_t*)aSrc, inputSize); ++ ByteSwapArray(aDst, outputSize); ++#endif + } + + void ConvolutionFilter::ConvolveVertically(uint8_t* const* aSrc, uint8_t* aDst, +@@ -49,8 +78,26 @@ + int32_t filterLength; + auto filterValues = + mFilter->FilterForValue(aRowIndex, &filterOffset, &filterLength); ++ ++#ifdef MOZ_BIG_ENDIAN ++ for (int filterY = 0; filterY < filterLength; filterY++) { ++ // Skia only knows LE, so we have to swizzle the input ++ ByteSwapArray(aSrc[filterY], aRowSize); ++ } ++#endif ++ + SkOpts::convolve_vertically(filterValues, filterLength, aSrc, aRowSize, aDst, + aHasAlpha); ++ ++#ifdef MOZ_BIG_ENDIAN ++ // After skia is finished, we swizzle back to BE, in case ++ // the input is used again somewhere else ++ for (int filterY = 0; filterY < filterLength; filterY++) { ++ ByteSwapArray(aSrc[filterY], aRowSize); ++ } ++ // The destination array as well ++ ByteSwapArray(aDst, aRowSize); ++#endif + } + + /* ConvolutionFilter::ComputeResizeFactor is derived from Skia's +diff -r 548d0a2f3a22 gfx/skia/skia/include/core/SkPreConfig.h +--- gfx/skia/skia/include/core/SkPreConfig.h Mon Jul 22 16:57:54 2019 +0200 ++++ gfx/skia/skia/include/core/SkPreConfig.h Thu Jul 25 14:27:59 2019 +0200 +@@ -73,7 +73,7 @@ + defined(__ppc__) || defined(__hppa) || \ + defined(__PPC__) || defined(__PPC64__) || \ + defined(_MIPSEB) || defined(__ARMEB__) || \ +- defined(__s390__) || \ ++ defined(__s390__) || defined(__s390x__) || \ + (defined(__sh__) && defined(__BIG_ENDIAN__)) || \ + (defined(__ia64) && defined(__BIG_ENDIAN__)) + #define SK_CPU_BENDIAN diff --git a/srcpkgs/firefox/patches/skia-sucks2.patch b/srcpkgs/firefox/patches/skia-sucks2.patch new file mode 100644 index 0000000000..207b3cf673 --- /dev/null +++ b/srcpkgs/firefox/patches/skia-sucks2.patch @@ -0,0 +1,44 @@ +# HG changeset patch +# Parent aecb4600e5da17443b224c79eee178c1d8e155e3 +For FF68, AntiAliasing of XULTexts seem to be broken on big endian (s390x). Text and icons of the sandwich-menu to the +right of the address bar, as well as plugin-windows appears transparant, which usually means unreadable (white on white). + +diff -r aecb4600e5da gfx/skia/skia/include/private/SkNx.h +--- gfx/skia/skia/include/private/SkNx.h Tue Aug 20 09:46:55 2019 +0200 ++++ gfx/skia/skia/include/private/SkNx.h Mon Sep 09 10:04:06 2019 +0200 +@@ -238,7 +238,18 @@ + AI SkNx operator*(const SkNx& y) const { return fVal * y.fVal; } + AI SkNx operator/(const SkNx& y) const { return fVal / y.fVal; } + ++ // On Big endian the commented out variant doesn't work, ++ // and honestly, I have no idea why it exists in the first place. ++ // The reason its broken is, I think, that it defaults to the double-variant of ToBits() ++ // which gets a 64-bit integer, and FromBits returns 32-bit, ++ // cutting off the wrong half again. ++ // Overall, I see no reason to have ToBits and FromBits at all (even for floats/doubles). ++ // Still we are only "fixing" this for big endian and leave little endian alone (never touch a running system) ++#ifdef SK_CPU_BENDIAN ++ AI SkNx operator&(const SkNx& y) const { return fVal & y.fVal; } ++#else + AI SkNx operator&(const SkNx& y) const { return FromBits(ToBits(fVal) & ToBits(y.fVal)); } ++#endif + AI SkNx operator|(const SkNx& y) const { return FromBits(ToBits(fVal) | ToBits(y.fVal)); } + AI SkNx operator^(const SkNx& y) const { return FromBits(ToBits(fVal) ^ ToBits(y.fVal)); } + +diff -r aecb4600e5da gfx/skia/skia/src/opts/SkBlitMask_opts.h +--- gfx/skia/skia/src/opts/SkBlitMask_opts.h Tue Aug 20 09:46:55 2019 +0200 ++++ gfx/skia/skia/src/opts/SkBlitMask_opts.h Mon Sep 09 10:04:06 2019 +0200 +@@ -203,7 +203,13 @@ + // ~~~> + // a = 1*aa + d(1-1*aa) = aa + d(1-aa) + // c = 0*aa + d(1-1*aa) = d(1-aa) ++ ++ // For big endian we have to swap the alpha-mask from 0,0,0,255 to 255,0,0,0 ++#ifdef SK_CPU_BENDIAN ++ return Sk4px(Sk16b(aa) & Sk16b(255,0,0,0, 255,0,0,0, 255,0,0,0, 255,0,0,0)) ++#else + return Sk4px(Sk16b(aa) & Sk16b(0,0,0,255, 0,0,0,255, 0,0,0,255, 0,0,0,255)) ++#endif + + d.approxMulDiv255(aa.inv()); + }; + while (h --> 0) { diff --git a/srcpkgs/firefox/patches/skia-sucks3.patch b/srcpkgs/firefox/patches/skia-sucks3.patch new file mode 100644 index 0000000000..d95b81698e --- /dev/null +++ b/srcpkgs/firefox/patches/skia-sucks3.patch @@ -0,0 +1,30 @@ +# HG changeset patch +# Parent 46ea866ca3acb8bb5e1709ceb799b9c94f591dec +Problem description: Tab-titles that are too long to fit into a tab get faded out. + On big endian this is broken and instead of fading out, the + tab gets white and the font transparent, leading to an unreadable + tab-title +Solution: This is not a real solution, but a hack. The real solution would have been + to byte-swap the correct buffer, but I could not find it. + So the next best thing is to deactivate the fading-effect. Now all tab-titles + are readable, albeit not as pretty to look at as they could be. +Side-effects: I have not yet found an unwanted side-effect. + +diff -r 46ea866ca3ac -r 6ef20eee3f8f gfx/2d/DrawTargetSkia.cpp +--- gfx/2d/DrawTargetSkia.cpp Tue Oct 22 12:27:22 2019 +0200 ++++ gfx/2d/DrawTargetSkia.cpp Thu Oct 31 09:11:56 2019 +0100 +@@ -1861,6 +1861,14 @@ + SkCanvas::kPreserveLCDText_SaveLayerFlag | + (aCopyBackground ? SkCanvas::kInitWithPrevious_SaveLayerFlag : 0)); + ++#if MOZ_BIG_ENDIAN ++ // Pushing a layer where an aMask is defined produces wrong output. ++ // We _should_ endian swap the data, but I couldn't find a workable way to do so ++ // Therefore I deactivate those layers in the meantime. ++ // The result is: Tab-titles that are longer than the available space should be faded out. ++ // The fading doesn't work, so we deactivate the fading-effect here. ++ if (!aMask) ++#endif + mCanvas->saveLayer(saveRec); + + SetPermitSubpixelAA(aOpaque);