From 892146e9232c8535229168be6ca2357bba3abc0b Mon Sep 17 00:00:00 2001 From: q66 Date: Sat, 7 Mar 2020 05:18:29 +0100 Subject: [PATCH] firefox: add a real fix for the swizzlerow BE crash --- .../firefox/patches/fix-be-swizzlerow.patch | 115 ++++++++++++++++++ .../firefox/patches/hack-be-swizzlerow.patch | 73 ----------- 2 files changed, 115 insertions(+), 73 deletions(-) create mode 100644 srcpkgs/firefox/patches/fix-be-swizzlerow.patch delete mode 100644 srcpkgs/firefox/patches/hack-be-swizzlerow.patch diff --git a/srcpkgs/firefox/patches/fix-be-swizzlerow.patch b/srcpkgs/firefox/patches/fix-be-swizzlerow.patch new file mode 100644 index 00000000000..03ada9295eb --- /dev/null +++ b/srcpkgs/firefox/patches/fix-be-swizzlerow.patch @@ -0,0 +1,115 @@ +https://phabricator.services.mozilla.com/D65797 +https://bugzilla.mozilla.org/show_bug.cgi?id=1616030 + +diff --git a/gfx/2d/Swizzle.cpp b/gfx/2d/Swizzle.cpp +--- gfx/2d/Swizzle.cpp ++++ gfx/2d/Swizzle.cpp +@@ -892,7 +892,11 @@ + uint8_t r = src[aSwapRB ? 2 : 0]; + uint8_t g = src[1]; + uint8_t b = src[aSwapRB ? 0 : 2]; ++#if MOZ_LITTLE_ENDIAN() + *--dst = 0xFF000000 | (b << 16) | (g << 8) | r; ++#else ++ *--dst = 0x000000FF | (b << 8) | (g << 16) | (r << 24); ++#endif + src -= 3; + } + } +@@ -906,6 +910,28 @@ + SurfaceFormat::R8G8B8, aDstFormat, \ + UnpackRowRGB24) + ++static void UnpackRowRGB24_To_ARGB(const uint8_t* aSrc, uint8_t* aDst, ++ int32_t aLength) { ++ // Because we are expanding, we can only process the data back to front in ++ // case we are performing this in place. ++ const uint8_t* src = aSrc + 3 * (aLength - 1); ++ uint32_t* dst = reinterpret_cast(aDst + 4 * aLength); ++ while (src >= aSrc) { ++ uint8_t r = src[0]; ++ uint8_t g = src[1]; ++ uint8_t b = src[2]; ++#if MOZ_LITTLE_ENDIAN() ++ *--dst = 0x000000FF | (r << 8) | (g << 16) | (b << 24); ++#else ++ *--dst = 0xFF000000 | (r << 24) | (g << 16) | b; ++#endif ++ src -= 3; ++ } ++} ++ ++#define UNPACK_ROW_RGB_TO_ARGB(aDstFormat) \ ++ FORMAT_CASE_ROW(SurfaceFormat::R8G8B8, aDstFormat, UnpackRowRGB24_To_ARGB) ++ + bool SwizzleData(const uint8_t* aSrc, int32_t aSrcStride, + SurfaceFormat aSrcFormat, uint8_t* aDst, int32_t aDstStride, + SurfaceFormat aDstFormat, const IntSize& aSize) { +@@ -1071,16 +1097,36 @@ + SWIZZLE_ROW_FALLBACK(SurfaceFormat::R8G8B8X8, SurfaceFormat::B8G8R8X8) + SWIZZLE_ROW_FALLBACK(SurfaceFormat::R8G8B8A8, SurfaceFormat::B8G8R8X8) + SWIZZLE_ROW_FALLBACK(SurfaceFormat::R8G8B8X8, SurfaceFormat::B8G8R8A8) ++ SWIZZLE_ROW_FALLBACK(SurfaceFormat::R8G8B8A8, SurfaceFormat::A8R8G8B8) ++ SWIZZLE_ROW_FALLBACK(SurfaceFormat::R8G8B8X8, SurfaceFormat::X8R8G8B8) ++ ++ SWIZZLE_ROW_FALLBACK(SurfaceFormat::A8R8G8B8, SurfaceFormat::R8G8B8A8) ++ SWIZZLE_ROW_FALLBACK(SurfaceFormat::X8R8G8B8, SurfaceFormat::R8G8B8X8) ++ SWIZZLE_ROW_FALLBACK(SurfaceFormat::A8R8G8B8, SurfaceFormat::R8G8B8X8) ++ SWIZZLE_ROW_FALLBACK(SurfaceFormat::X8R8G8B8, SurfaceFormat::R8G8B8A8) + + SWIZZLE_ROW_OPAQUE(SurfaceFormat::B8G8R8A8, SurfaceFormat::B8G8R8X8) + SWIZZLE_ROW_OPAQUE(SurfaceFormat::B8G8R8X8, SurfaceFormat::B8G8R8A8) + SWIZZLE_ROW_OPAQUE(SurfaceFormat::R8G8B8A8, SurfaceFormat::R8G8B8X8) + SWIZZLE_ROW_OPAQUE(SurfaceFormat::R8G8B8X8, SurfaceFormat::R8G8B8A8) ++ SWIZZLE_ROW_OPAQUE(SurfaceFormat::A8R8G8B8, SurfaceFormat::X8R8G8B8) ++ SWIZZLE_ROW_OPAQUE(SurfaceFormat::X8R8G8B8, SurfaceFormat::A8R8G8B8) ++ ++ SWIZZLE_ROW_SWAP(SurfaceFormat::B8G8R8A8, SurfaceFormat::A8R8G8B8) ++ SWIZZLE_ROW_SWAP(SurfaceFormat::B8G8R8A8, SurfaceFormat::X8R8G8B8) ++ SWIZZLE_ROW_SWAP(SurfaceFormat::B8G8R8X8, SurfaceFormat::X8R8G8B8) ++ SWIZZLE_ROW_SWAP(SurfaceFormat::B8G8R8X8, SurfaceFormat::A8R8G8B8) ++ SWIZZLE_ROW_SWAP(SurfaceFormat::A8R8G8B8, SurfaceFormat::B8G8R8A8) ++ SWIZZLE_ROW_SWAP(SurfaceFormat::A8R8G8B8, SurfaceFormat::B8G8R8X8) ++ SWIZZLE_ROW_SWAP(SurfaceFormat::X8R8G8B8, SurfaceFormat::B8G8R8X8) ++ SWIZZLE_ROW_SWAP(SurfaceFormat::X8R8G8B8, SurfaceFormat::B8G8R8A8) + + UNPACK_ROW_RGB(SurfaceFormat::R8G8B8X8) + UNPACK_ROW_RGB(SurfaceFormat::R8G8B8A8) + UNPACK_ROW_RGB(SurfaceFormat::B8G8R8X8) + UNPACK_ROW_RGB(SurfaceFormat::B8G8R8A8) ++ UNPACK_ROW_RGB_TO_ARGB(SurfaceFormat::A8R8G8B8) ++ UNPACK_ROW_RGB_TO_ARGB(SurfaceFormat::X8R8G8B8) + + default: + break; +diff --git a/gfx/tests/gtest/TestSwizzle.cpp b/gfx/tests/gtest/TestSwizzle.cpp +--- gfx/tests/gtest/TestSwizzle.cpp ++++ gfx/tests/gtest/TestSwizzle.cpp +@@ -219,6 +219,12 @@ + 15, 14, 13, 255, 18, 17, 16, 255, 21, 20, 19, 255, 24, 23, 22, 255, + 27, 26, 25, 255, 30, 29, 28, 255, 33, 32, 31, 255, 36, 35, 34, 255, + }; ++ const uint8_t check_unpack_xrgb[16 * 4] = { ++ 255, 0, 254, 253, 255, 255, 0, 0, 255, 0, 0, 0, 255, 3, 2, 1, ++ 255, 9, 0, 127, 255, 4, 5, 6, 255, 9, 8, 7, 255, 10, 11, 12, ++ 255, 13, 14, 15, 255, 16, 17, 18, 255, 19, 20, 21, 255, 22, 23, 24, ++ 255, 25, 26, 27, 255, 28, 29, 30, 255, 31, 32, 33, 255, 34, 35, 36, ++ }; + + SwizzleRowFn func = + SwizzleRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::R8G8B8A8); +@@ -246,4 +252,13 @@ + memcpy(out_unpack, in_rgb, sizeof(in_rgb)); + func(out_unpack, out_unpack, 16); + EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_rgbx)); ++ ++ func = SwizzleRow(SurfaceFormat::R8G8B8, SurfaceFormat::X8R8G8B8); ++ func(in_rgb, out_unpack, 16); ++ EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_xrgb)); ++ ++ memset(out_unpack, 0xE5, sizeof(out_unpack)); ++ memcpy(out_unpack, in_rgb, sizeof(in_rgb)); ++ func(out_unpack, out_unpack, 16); ++ EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_xrgb)); + } + diff --git a/srcpkgs/firefox/patches/hack-be-swizzlerow.patch b/srcpkgs/firefox/patches/hack-be-swizzlerow.patch deleted file mode 100644 index 3420dced23e..00000000000 --- a/srcpkgs/firefox/patches/hack-be-swizzlerow.patch +++ /dev/null @@ -1,73 +0,0 @@ -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,