116 lines
4.9 KiB
Diff
116 lines
4.9 KiB
Diff
|
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));
|
||
|
}
|
||
|
|