From 45276bbb7c7c8f1285fb1fc2b7c24873c0e9085a Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sun, 28 Dec 2025 23:18:26 +0800 Subject: [PATCH] [Feat] (MG_Util/PixelStoreProcessor): properly handle BGRA to RGBA swizzle --- .../MG_Util/Texture/PixelStoreProcessor.cpp | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp b/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp index 775c853a..21aa49eb 100644 --- a/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp +++ b/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp @@ -42,6 +42,40 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { bytes += rowBytes; } } + + static Uint8 GetSwizzledChannelValue(Uint8* pixel, TextureSwizzleParam param) { + switch (param) { + case TextureSwizzleParam::Red: + return pixel[0]; + case TextureSwizzleParam::Green: + return pixel[1]; + case TextureSwizzleParam::Blue: + return pixel[2]; + case TextureSwizzleParam::Alpha: + return pixel[3]; + case TextureSwizzleParam::Zero: + return 0; + case TextureSwizzleParam::One: + return 0xFF; + default: + return 0xBD; + } + } + + // assume 8 bit per channel + // swizzle.size() == channel count + static void ProcessColorSwizzle(void* data, SizeT pixelCount, const Vector& swizzle) { + const auto bpp = swizzle.size(); + Uint8* bytes = static_cast(data); + static Uint8 pixelScratch[4]; + for (SizeT i = 0; i < pixelCount; ++i) { + Uint8* pixel = bytes + i * bpp; + for (SizeT ch = 0; ch < bpp; ++ch) { + pixelScratch[ch] = GetSwizzledChannelValue(pixel, swizzle[ch]); + } + Memcpy(pixel, pixelScratch, bpp); + } + } void* ProcessTexturePixelsDataUnpack(const void* inputPixels, const PixelStoreParameters& params, TextureInternalFormat targetInternalFormat, TextureInputFormat textureInputFormat, TexturePixelDataType inputDataType, @@ -90,14 +124,29 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { for (Int y = 0; y < copyHeight; ++y) { Memcpy(layerDst, layerSrc, static_cast(copyWidth) * pixelSize); - + if (params.SwapBytes && pixelSize > 1) { + MGLOG_D("%s: SwapBytes", __func__); SwapBytes(layerDst, pixelSize, static_cast(copyWidth)); } if (params.LSBFirst && isBitmap) { + MGLOG_D("%s: LSBFirst", __func__); ProcessLSBFirst(layerDst, static_cast(copyWidth), 1); } + + if (textureInputFormat == TextureInputFormat::BGRA && targetInternalFormat == TextureInternalFormat::RGBA8) { + MGLOG_D("%s: Swizzle (BGRA)", __func__); + MGLOG_D("%s: pixel0 before = %x", __func__, *((Uint32*)layerDst)); + ProcessColorSwizzle(layerDst, static_cast(copyWidth), { + TextureSwizzleParam::Green, + TextureSwizzleParam::Blue, + TextureSwizzleParam::Alpha, + TextureSwizzleParam::Red + }); + MGLOG_D("%s: pixel0 after = %x", __func__, *((Uint32*)layerDst)); + } else + MGLOG_D("%s: pixel0 = %x", __func__, *((Uint32*)layerDst)); layerSrc += inputStride; layerDst += static_cast(copyWidth) * pixelSize;