firefox: add a real fix for the swizzlerow BE crash
This commit is contained in:
parent
c48cf123ba
commit
892146e923
2 changed files with 115 additions and 73 deletions
115
srcpkgs/firefox/patches/fix-be-swizzlerow.patch
Normal file
115
srcpkgs/firefox/patches/fix-be-swizzlerow.patch
Normal file
|
@ -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<ShouldSwapRB(SurfaceFormat::R8G8B8, aDstFormat)>)
|
||||
|
||||
+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<uint32_t*>(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));
|
||||
}
|
||||
|
|
@ -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<uint8_t*>(aColormap);
|
||||
mSwizzleFn(data, data, aColors);
|
||||
+#endif
|
||||
}
|
||||
|
||||
LexerResult nsGIFDecoder2::DoDecode(SourceBufferIterator& aIterator,
|
Loading…
Add table
Reference in a new issue