void-packages/srcpkgs/webkit2gtk/patches/be-imagebufferbackend.patch

250 lines
11 KiB
Diff

Original source: Jacek Piszczek <jacek.piszczek@runbox.com>
diff --git a/Source/WebCore/platform/graphics/PixelBufferConversion.cpp b/Source/WebCore/platform/graphics/PixelBufferConversion.cpp
index 9acf304d..618b7b26 100644
--- a/Source/WebCore/platform/graphics/PixelBufferConversion.cpp
+++ b/Source/WebCore/platform/graphics/PixelBufferConversion.cpp
@@ -140,9 +140,17 @@ static void convertImagePixelsAccelerated(const ConstPixelBufferConversionView&
enum class PixelFormatConversion { None, Permute };
template<PixelFormatConversion pixelFormatConversion>
+#if CPU(BIG_ENDIAN)
+static void convertSinglePixelPremultipliedToPremultiplied(PixelFormat sourcePixelFormat, const uint8_t* sourcePixel, PixelFormat destinationPixelFormat, uint8_t* destinationPixel)
+#else
static void convertSinglePixelPremultipliedToPremultiplied(const uint8_t* sourcePixel, uint8_t* destinationPixel)
+#endif
{
+#if CPU(BIG_ENDIAN)
+ uint8_t alpha = sourcePixel[sourcePixelFormat == PixelFormat::ARGB8 ? 0 : 3];
+#else
uint8_t alpha = sourcePixel[3];
+#endif
if (!alpha) {
reinterpret_cast<uint32_t*>(destinationPixel)[0] = 0;
return;
@@ -151,23 +158,81 @@ static void convertSinglePixelPremultipliedToPremultiplied(const uint8_t* source
if constexpr (pixelFormatConversion == PixelFormatConversion::None)
reinterpret_cast<uint32_t*>(destinationPixel)[0] = reinterpret_cast<const uint32_t*>(sourcePixel)[0];
else {
+#if CPU(BIG_ENDIAN)
+ // Swap pixel channels ARGB <-> RGBA.
+ if (destinationPixelFormat == PixelFormat::ARGB8)
+ {
+ destinationPixel[0] = sourcePixel[3];
+ destinationPixel[1] = sourcePixel[0];
+ destinationPixel[2] = sourcePixel[1];
+ destinationPixel[3] = sourcePixel[2];
+ }
+ else
+ {
+ destinationPixel[0] = sourcePixel[1];
+ destinationPixel[1] = sourcePixel[2];
+ destinationPixel[2] = sourcePixel[3];
+ destinationPixel[3] = sourcePixel[0];
+ }
+#else
// Swap pixel channels BGRA <-> RGBA.
destinationPixel[0] = sourcePixel[2];
destinationPixel[1] = sourcePixel[1];
destinationPixel[2] = sourcePixel[0];
destinationPixel[3] = sourcePixel[3];
+#endif
}
}
template<PixelFormatConversion pixelFormatConversion>
+#if CPU(BIG_ENDIAN)
+static void convertSinglePixelPremultipliedToUnpremultiplied(PixelFormat sourcePixelFormat, const uint8_t* sourcePixel, PixelFormat destinationPixelFormat, uint8_t* destinationPixel)
+#else
static void convertSinglePixelPremultipliedToUnpremultiplied(const uint8_t* sourcePixel, uint8_t* destinationPixel)
+#endif
{
+#if CPU(BIG_ENDIAN)
+ uint8_t alpha = sourcePixel[sourcePixelFormat == PixelFormat::ARGB8 ? 0 : 3];
+#else
uint8_t alpha = sourcePixel[3];
+#endif
if (!alpha || alpha == 255) {
+#if CPU(BIG_ENDIAN)
+ convertSinglePixelPremultipliedToPremultiplied<pixelFormatConversion>(sourcePixelFormat, sourcePixel, destinationPixelFormat, destinationPixel);
+#else
convertSinglePixelPremultipliedToPremultiplied<pixelFormatConversion>(sourcePixel, destinationPixel);
+#endif
return;
}
+#if CPU(BIG_ENDIAN)
+ UNUSED_PARAM(destinationPixelFormat);
+ if constexpr (pixelFormatConversion == PixelFormatConversion::None) {
+ if (sourcePixelFormat == PixelFormat::ARGB8) {
+ destinationPixel[0] = alpha;
+ destinationPixel[1] = (sourcePixel[1] * 255) / alpha;
+ destinationPixel[2] = (sourcePixel[2] * 255) / alpha;
+ destinationPixel[3] = (sourcePixel[3] * 255) / alpha;
+ } else {
+ destinationPixel[0] = (sourcePixel[0] * 255) / alpha;
+ destinationPixel[1] = (sourcePixel[1] * 255) / alpha;
+ destinationPixel[2] = (sourcePixel[2] * 255) / alpha;
+ destinationPixel[3] = alpha;
+ }
+ } else {
+ if (sourcePixelFormat == PixelFormat::ARGB8) {
+ destinationPixel[0] = (sourcePixel[1] * 255) / alpha;
+ destinationPixel[1] = (sourcePixel[2] * 255) / alpha;
+ destinationPixel[2] = (sourcePixel[3] * 255) / alpha;
+ destinationPixel[3] = alpha;
+ } else {
+ destinationPixel[0] = alpha;
+ destinationPixel[1] = (sourcePixel[0] * 255) / alpha;
+ destinationPixel[2] = (sourcePixel[1] * 255) / alpha;
+ destinationPixel[3] = (sourcePixel[2] * 255) / alpha;
+ }
+ }
+#else
if constexpr (pixelFormatConversion == PixelFormatConversion::None) {
destinationPixel[0] = (sourcePixel[0] * 255) / alpha;
destinationPixel[1] = (sourcePixel[1] * 255) / alpha;
@@ -180,17 +245,58 @@ static void convertSinglePixelPremultipliedToUnpremultiplied(const uint8_t* sour
destinationPixel[2] = (sourcePixel[0] * 255) / alpha;
destinationPixel[3] = alpha;
}
+#endif
}
template<PixelFormatConversion pixelFormatConversion>
+#if CPU(BIG_ENDIAN)
+static void convertSinglePixelUnpremultipliedToPremultiplied(PixelFormat sourcePixelFormat, const uint8_t* sourcePixel, PixelFormat destinationPixelFormat, uint8_t* destinationPixel)
+#else
static void convertSinglePixelUnpremultipliedToPremultiplied(const uint8_t* sourcePixel, uint8_t* destinationPixel)
+#endif
{
+#if CPU(BIG_ENDIAN)
+ uint8_t alpha = sourcePixel[sourcePixelFormat == PixelFormat::ARGB8 ? 0 : 3];
+#else
uint8_t alpha = sourcePixel[3];
+#endif
if (!alpha || alpha == 255) {
+#if CPU(BIG_ENDIAN)
+ convertSinglePixelPremultipliedToPremultiplied<pixelFormatConversion>(sourcePixelFormat, sourcePixel, destinationPixelFormat, destinationPixel);
+#else
convertSinglePixelPremultipliedToPremultiplied<pixelFormatConversion>(sourcePixel, destinationPixel);
+#endif
return;
}
+#if CPU(BIG_ENDIAN)
+ UNUSED_PARAM(destinationPixelFormat);
+ if constexpr (pixelFormatConversion == PixelFormatConversion::None) {
+ if (sourcePixelFormat == PixelFormat::ARGB8) {
+ destinationPixel[0] = alpha;
+ destinationPixel[1] = (sourcePixel[1] * alpha + 254) / 255;
+ destinationPixel[2] = (sourcePixel[2] * alpha + 254) / 255;
+ destinationPixel[3] = (sourcePixel[3] * alpha + 254) / 255;
+ } else {
+ destinationPixel[0] = (sourcePixel[0] * alpha + 254) / 255;
+ destinationPixel[1] = (sourcePixel[1] * alpha + 254) / 255;
+ destinationPixel[2] = (sourcePixel[2] * alpha + 254) / 255;
+ destinationPixel[3] = alpha;
+ }
+ } else {
+ if (sourcePixelFormat == PixelFormat::ARGB8) {
+ destinationPixel[0] = (sourcePixel[1] * alpha + 254) / 255;
+ destinationPixel[1] = (sourcePixel[2] * alpha + 254) / 255;
+ destinationPixel[2] = (sourcePixel[3] * alpha + 254) / 255;
+ destinationPixel[3] = alpha;
+ } else {
+ destinationPixel[0] = alpha;
+ destinationPixel[1] = (sourcePixel[0] * alpha + 254) / 255;
+ destinationPixel[2] = (sourcePixel[1] * alpha + 254) / 255;
+ destinationPixel[3] = (sourcePixel[2] * alpha + 254) / 255;
+ }
+ }
+#else
if constexpr (pixelFormatConversion == PixelFormatConversion::None) {
destinationPixel[0] = (sourcePixel[0] * alpha + 254) / 255;
destinationPixel[1] = (sourcePixel[1] * alpha + 254) / 255;
@@ -203,23 +309,49 @@ static void convertSinglePixelUnpremultipliedToPremultiplied(const uint8_t* sour
destinationPixel[2] = (sourcePixel[0] * alpha + 254) / 255;
destinationPixel[3] = alpha;
}
+#endif
}
template<PixelFormatConversion pixelFormatConversion>
+#if CPU(BIG_ENDIAN)
+static void convertSinglePixelUnpremultipliedToUnpremultiplied(PixelFormat sourcePixelFormat, const uint8_t* sourcePixel, PixelFormat destinationPixelFormat, uint8_t* destinationPixel)
+#else
static void convertSinglePixelUnpremultipliedToUnpremultiplied(const uint8_t* sourcePixel, uint8_t* destinationPixel)
+#endif
{
if constexpr (pixelFormatConversion == PixelFormatConversion::None)
reinterpret_cast<uint32_t*>(destinationPixel)[0] = reinterpret_cast<const uint32_t*>(sourcePixel)[0];
else {
+#if CPU(BIG_ENDIAN)
+ UNUSED_PARAM(sourcePixelFormat);
+ // Swap pixel channels ARGB <-> RGBA.
+ if (destinationPixelFormat == PixelFormat::ARGB8) {
+ destinationPixel[0] = sourcePixel[3];
+ destinationPixel[1] = sourcePixel[0];
+ destinationPixel[2] = sourcePixel[1];
+ destinationPixel[3] = sourcePixel[2];
+ }
+ else {
+ destinationPixel[0] = sourcePixel[1];
+ destinationPixel[1] = sourcePixel[2];
+ destinationPixel[2] = sourcePixel[3];
+ destinationPixel[3] = sourcePixel[0];
+ }
+#else
// Swap pixel channels BGRA <-> RGBA.
destinationPixel[0] = sourcePixel[2];
destinationPixel[1] = sourcePixel[1];
destinationPixel[2] = sourcePixel[0];
destinationPixel[3] = sourcePixel[3];
+#endif
}
}
+#if CPU(BIG_ENDIAN)
+template<void (*convertFunctor)(PixelFormat, const uint8_t*, PixelFormat, uint8_t*)>
+#else
template<void (*convertFunctor)(const uint8_t*, uint8_t*)>
+#endif
static void convertImagePixelsUnaccelerated(const ConstPixelBufferConversionView& source, const PixelBufferConversionView& destination, const IntSize& destinationSize)
{
const uint8_t* sourceRows = source.rows;
@@ -228,7 +360,11 @@ static void convertImagePixelsUnaccelerated(const ConstPixelBufferConversionView
size_t bytesPerRow = destinationSize.width() * 4;
for (int y = 0; y < destinationSize.height(); ++y) {
for (size_t x = 0; x < bytesPerRow; x += 4)
+#if CPU(BIG_ENDIAN)
+ convertFunctor(source.format.pixelFormat, &sourceRows[x], destination.format.pixelFormat, &destinationRows[x]);
+#else
convertFunctor(&sourceRows[x], &destinationRows[x]);
+#endif
sourceRows += source.bytesPerRow;
destinationRows += destination.bytesPerRow;
}
@@ -237,6 +373,7 @@ static void convertImagePixelsUnaccelerated(const ConstPixelBufferConversionView
void convertImagePixels(const ConstPixelBufferConversionView& source, const PixelBufferConversionView& destination, const IntSize& destinationSize)
{
// We don't currently support converting pixel data with non-8-bit buffers.
+ // BGRA8 is actually ARGB8 on BIG_ENDIAN.
ASSERT(source.format.pixelFormat == PixelFormat::RGBA8 || source.format.pixelFormat == PixelFormat::BGRA8);
ASSERT(destination.format.pixelFormat == PixelFormat::RGBA8 || destination.format.pixelFormat == PixelFormat::BGRA8);
diff --git a/Source/WebCore/platform/graphics/PixelFormat.h b/Source/WebCore/platform/graphics/PixelFormat.h
index 1ca711b8..4a7168f8 100644
--- a/Source/WebCore/platform/graphics/PixelFormat.h
+++ b/Source/WebCore/platform/graphics/PixelFormat.h
@@ -33,6 +33,9 @@ namespace WebCore {
enum class PixelFormat : uint8_t {
RGBA8,
BGRA8,
+#if CPU(BIG_ENDIAN)
+ ARGB8 = BGRA8, // BGRA will actually be ARGB on BIG_ENDIAN
+#endif
RGB10,
RGB10A8,
};