Added 10-bit pixel formats in addition to SDL_PIXELFORMAT_ARGB2101010

Added SDL_PIXELFORMAT_XRGB2101010, SDL_PIXELFORMAT_XBGR2101010, SDL_PIXELFORMAT_ABGR2101010

Fixes https://github.com/libsdl-org/SDL/issues/3553
This commit is contained in:
Sam Lantinga 2023-11-06 00:21:26 -08:00
parent 3e4d7e48b0
commit f7d40b7594
7 changed files with 124 additions and 17 deletions

View file

@ -190,6 +190,10 @@ typedef enum
(SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \ (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \
(SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA)))) (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA))))
#define SDL_ISPIXELFORMAT_10BIT(format) \
((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED32) && \
(SDL_PIXELLAYOUT(format) == SDL_PACKEDLAYOUT_2101010))
/* The flag is set to 1 because 0x1? is not in the printable ASCII range */ /* The flag is set to 1 because 0x1? is not in the printable ASCII range */
#define SDL_ISPIXELFORMAT_FOURCC(format) \ #define SDL_ISPIXELFORMAT_FOURCC(format) \
((format) && (SDL_PIXELFLAG(format) != 1)) ((format) && (SDL_PIXELFLAG(format) != 1))
@ -291,9 +295,18 @@ typedef enum
SDL_PIXELFORMAT_BGRA8888 = SDL_PIXELFORMAT_BGRA8888 =
SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA,
SDL_PACKEDLAYOUT_8888, 32, 4), SDL_PACKEDLAYOUT_8888, 32, 4),
SDL_PIXELFORMAT_XRGB2101010 =
SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB,
SDL_PACKEDLAYOUT_2101010, 32, 4),
SDL_PIXELFORMAT_XBGR2101010 =
SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR,
SDL_PACKEDLAYOUT_2101010, 32, 4),
SDL_PIXELFORMAT_ARGB2101010 = SDL_PIXELFORMAT_ARGB2101010 =
SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB,
SDL_PACKEDLAYOUT_2101010, 32, 4), SDL_PACKEDLAYOUT_2101010, 32, 4),
SDL_PIXELFORMAT_ABGR2101010 =
SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR,
SDL_PACKEDLAYOUT_2101010, 32, 4),
/* Aliases for RGBA byte arrays of color data, for the current platform */ /* Aliases for RGBA byte arrays of color data, for the current platform */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN #if SDL_BYTEORDER == SDL_BIG_ENDIAN

View file

@ -260,6 +260,14 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface);
a = (a * 3) / 255; \ a = (a * 3) / 255; \
Pixel = (a << 30) | (r << 20) | (g << 10) | b; \ Pixel = (a << 30) | (r << 20) | (g << 10) | b; \
} }
#define ABGR2101010_FROM_RGBA(Pixel, r, g, b, a) \
{ \
r = r ? ((r << 2) | 0x3) : 0; \
g = g ? ((g << 2) | 0x3) : 0; \
b = b ? ((b << 2) | 0x3) : 0; \
a = (a * 3) / 255; \
Pixel = (a << 30) | (b << 20) | (g << 10) | r; \
}
#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \ #define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \
{ \ { \
switch (bpp) { \ switch (bpp) { \
@ -352,6 +360,13 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface);
b = ((Pixel >> 2) & 0xFF); \ b = ((Pixel >> 2) & 0xFF); \
a = SDL_expand_byte[6][(Pixel >> 30)]; \ a = SDL_expand_byte[6][(Pixel >> 30)]; \
} }
#define RGBA_FROM_ABGR2101010(Pixel, r, g, b, a) \
{ \
r = ((Pixel >> 2) & 0xFF); \
g = ((Pixel >> 12) & 0xFF); \
b = ((Pixel >> 22) & 0xFF); \
a = SDL_expand_byte[6][(Pixel >> 30)]; \
}
#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \ #define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \
do { \ do { \
switch (bpp) { \ switch (bpp) { \

View file

@ -2327,8 +2327,8 @@ static void BlitNtoN(SDL_BlitInfo *info)
#if HAVE_FAST_WRITE_INT8 #if HAVE_FAST_WRITE_INT8
/* Blit with permutation: 4->4 */ /* Blit with permutation: 4->4 */
if (srcbpp == 4 && dstbpp == 4 && if (srcbpp == 4 && dstbpp == 4 &&
srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 && !SDL_ISPIXELFORMAT_10BIT(srcfmt->format) &&
dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) { !SDL_ISPIXELFORMAT_10BIT(dstfmt->format)) {
/* Find the appropriate permutation */ /* Find the appropriate permutation */
int alpha_channel, p0, p1, p2, p3; int alpha_channel, p0, p1, p2, p3;
@ -2356,7 +2356,7 @@ static void BlitNtoN(SDL_BlitInfo *info)
/* Blit with permutation: 4->3 */ /* Blit with permutation: 4->3 */
if (srcbpp == 4 && dstbpp == 3 && if (srcbpp == 4 && dstbpp == 3 &&
srcfmt->format != SDL_PIXELFORMAT_ARGB2101010) { !SDL_ISPIXELFORMAT_10BIT(srcfmt->format)) {
/* Find the appropriate permutation */ /* Find the appropriate permutation */
int p0, p1, p2, p3; int p0, p1, p2, p3;
@ -2382,7 +2382,7 @@ static void BlitNtoN(SDL_BlitInfo *info)
#if HAVE_FAST_WRITE_INT8 #if HAVE_FAST_WRITE_INT8
/* Blit with permutation: 3->4 */ /* Blit with permutation: 3->4 */
if (srcbpp == 3 && dstbpp == 4 && if (srcbpp == 3 && dstbpp == 4 &&
dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) { !SDL_ISPIXELFORMAT_10BIT(dstfmt->format)) {
/* Find the appropriate permutation */ /* Find the appropriate permutation */
int alpha_channel, p0, p1, p2, p3; int alpha_channel, p0, p1, p2, p3;
@ -2445,8 +2445,8 @@ static void BlitNtoNCopyAlpha(SDL_BlitInfo *info)
#if HAVE_FAST_WRITE_INT8 #if HAVE_FAST_WRITE_INT8
/* Blit with permutation: 4->4 */ /* Blit with permutation: 4->4 */
if (srcbpp == 4 && dstbpp == 4 && if (srcbpp == 4 && dstbpp == 4 &&
srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 && !SDL_ISPIXELFORMAT_10BIT(srcfmt->format) &&
dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) { !SDL_ISPIXELFORMAT_10BIT(dstfmt->format)) {
/* Find the appropriate permutation */ /* Find the appropriate permutation */
int p0, p1, p2, p3; int p0, p1, p2, p3;
@ -2651,8 +2651,8 @@ static void BlitNtoNKey(SDL_BlitInfo *info)
#if HAVE_FAST_WRITE_INT8 #if HAVE_FAST_WRITE_INT8
/* Blit with permutation: 4->4 */ /* Blit with permutation: 4->4 */
if (srcbpp == 4 && dstbpp == 4 && if (srcbpp == 4 && dstbpp == 4 &&
srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 && !SDL_ISPIXELFORMAT_10BIT(srcfmt->format) &&
dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) { !SDL_ISPIXELFORMAT_10BIT(dstfmt->format)) {
/* Find the appropriate permutation */ /* Find the appropriate permutation */
int alpha_channel, p0, p1, p2, p3; int alpha_channel, p0, p1, p2, p3;
@ -2760,7 +2760,7 @@ static void BlitNtoNKey(SDL_BlitInfo *info)
/* Blit with permutation: 4->3 */ /* Blit with permutation: 4->3 */
if (srcbpp == 4 && dstbpp == 3 && if (srcbpp == 4 && dstbpp == 3 &&
srcfmt->format != SDL_PIXELFORMAT_ARGB2101010) { !SDL_ISPIXELFORMAT_10BIT(srcfmt->format)) {
/* Find the appropriate permutation */ /* Find the appropriate permutation */
int p0, p1, p2, p3; int p0, p1, p2, p3;
@ -2789,7 +2789,7 @@ static void BlitNtoNKey(SDL_BlitInfo *info)
#if HAVE_FAST_WRITE_INT8 #if HAVE_FAST_WRITE_INT8
/* Blit with permutation: 3->4 */ /* Blit with permutation: 3->4 */
if (srcbpp == 3 && dstbpp == 4 && if (srcbpp == 3 && dstbpp == 4 &&
dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) { !SDL_ISPIXELFORMAT_10BIT(dstfmt->format)) {
#if SDL_BYTEORDER == SDL_LIL_ENDIAN #if SDL_BYTEORDER == SDL_LIL_ENDIAN
Uint8 k0 = ckey & 0xFF; Uint8 k0 = ckey & 0xFF;
@ -2909,8 +2909,8 @@ static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info)
#if HAVE_FAST_WRITE_INT8 #if HAVE_FAST_WRITE_INT8
/* Blit with permutation: 4->4 */ /* Blit with permutation: 4->4 */
if (srcbpp == 4 && dstbpp == 4 && if (srcbpp == 4 && dstbpp == 4 &&
srcfmt->format != SDL_PIXELFORMAT_ARGB2101010 && !SDL_ISPIXELFORMAT_10BIT(srcfmt->format) &&
dstfmt->format != SDL_PIXELFORMAT_ARGB2101010) { !SDL_ISPIXELFORMAT_10BIT(dstfmt->format)) {
/* Find the appropriate permutation */ /* Find the appropriate permutation */
int p0, p1, p2, p3; int p0, p1, p2, p3;

View file

@ -30,7 +30,7 @@
#define FORMAT_HAS_NO_ALPHA(format) format < 0 #define FORMAT_HAS_NO_ALPHA(format) format < 0
static int detect_format(SDL_PixelFormat *pf) static int detect_format(SDL_PixelFormat *pf)
{ {
if (pf->format == SDL_PIXELFORMAT_ARGB2101010) { if (SDL_ISPIXELFORMAT_10BIT(pf->format)) {
return FORMAT_2101010; return FORMAT_2101010;
} else if (pf->Amask) { } else if (pf->Amask) {
return FORMAT_ALPHA; return FORMAT_ALPHA;
@ -88,9 +88,27 @@ void SDL_Blit_Slow(SDL_BlitInfo *info)
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB); DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
srcA = 0xFF; srcA = 0xFF;
} else { } else {
/* SDL_PIXELFORMAT_ARGB2101010 */ /* 10-bit pixel format */
srcpixel = *((Uint32 *)(src)); srcpixel = *((Uint32 *)(src));
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA); switch (src_fmt->format) {
case SDL_PIXELFORMAT_XRGB2101010:
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA);
srcA = 0xFF;
break;
case SDL_PIXELFORMAT_XBGR2101010:
RGBA_FROM_ABGR2101010(srcpixel, srcR, srcG, srcB, srcA);
srcA = 0xFF;
break;
case SDL_PIXELFORMAT_ARGB2101010:
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA);
break;
case SDL_PIXELFORMAT_ABGR2101010:
RGBA_FROM_ABGR2101010(srcpixel, srcR, srcG, srcB, srcA);
break;
default:
srcR = srcG = srcB = srcA = 0;
break;
}
} }
if (flags & SDL_COPY_COLORKEY) { if (flags & SDL_COPY_COLORKEY) {
@ -189,9 +207,25 @@ void SDL_Blit_Slow(SDL_BlitInfo *info)
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB); ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
} else { } else {
/* SDL_PIXELFORMAT_ARGB2101010 */ /* 10-bit pixel format */
Uint32 pixel; Uint32 pixel;
ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA); switch (dst_fmt->format) {
case SDL_PIXELFORMAT_XRGB2101010:
dstA = 0xFF;
SDL_FALLTHROUGH;
case SDL_PIXELFORMAT_ARGB2101010:
ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA);
break;
case SDL_PIXELFORMAT_XBGR2101010:
dstA = 0xFF;
SDL_FALLTHROUGH;
case SDL_PIXELFORMAT_ABGR2101010:
ABGR2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA);
break;
default:
pixel = 0;
break;
}
*(Uint32 *)dst = pixel; *(Uint32 *)dst = pixel;
} }
posx += incx; posx += incx;

View file

@ -117,7 +117,10 @@ const char *SDL_GetPixelFormatName(Uint32 format)
CASE(SDL_PIXELFORMAT_RGBA8888) CASE(SDL_PIXELFORMAT_RGBA8888)
CASE(SDL_PIXELFORMAT_ABGR8888) CASE(SDL_PIXELFORMAT_ABGR8888)
CASE(SDL_PIXELFORMAT_BGRA8888) CASE(SDL_PIXELFORMAT_BGRA8888)
CASE(SDL_PIXELFORMAT_XRGB2101010)
CASE(SDL_PIXELFORMAT_XBGR2101010)
CASE(SDL_PIXELFORMAT_ARGB2101010) CASE(SDL_PIXELFORMAT_ARGB2101010)
CASE(SDL_PIXELFORMAT_ABGR2101010)
CASE(SDL_PIXELFORMAT_YV12) CASE(SDL_PIXELFORMAT_YV12)
CASE(SDL_PIXELFORMAT_IYUV) CASE(SDL_PIXELFORMAT_IYUV)
CASE(SDL_PIXELFORMAT_YUY2) CASE(SDL_PIXELFORMAT_YUY2)
@ -440,6 +443,20 @@ Uint32 SDL_GetPixelFormatEnumForMasks(int bpp, Uint32 Rmask, Uint32 Gmask, Uint3
#endif #endif
} }
break; break;
case 30:
if (Rmask == 0x3FF00000 &&
Gmask == 0x000FFC00 &&
Bmask == 0x000003FF &&
Amask == 0x00000000) {
return SDL_PIXELFORMAT_XRGB2101010;
}
if (Rmask == 0x000003FF &&
Gmask == 0x000FFC00 &&
Bmask == 0x3FF00000 &&
Amask == 0x00000000) {
return SDL_PIXELFORMAT_XBGR2101010;
}
break;
case 32: case 32:
if (Rmask == 0) { if (Rmask == 0) {
return SDL_PIXELFORMAT_XRGB8888; return SDL_PIXELFORMAT_XRGB8888;
@ -492,12 +509,31 @@ Uint32 SDL_GetPixelFormatEnumForMasks(int bpp, Uint32 Rmask, Uint32 Gmask, Uint3
Amask == 0x000000FF) { Amask == 0x000000FF) {
return SDL_PIXELFORMAT_BGRA8888; return SDL_PIXELFORMAT_BGRA8888;
} }
if (Rmask == 0x3FF00000 &&
Gmask == 0x000FFC00 &&
Bmask == 0x000003FF &&
Amask == 0x00000000) {
return SDL_PIXELFORMAT_XRGB2101010;
}
if (Rmask == 0x000003FF &&
Gmask == 0x000FFC00 &&
Bmask == 0x3FF00000 &&
Amask == 0x00000000) {
return SDL_PIXELFORMAT_XBGR2101010;
}
if (Rmask == 0x3FF00000 && if (Rmask == 0x3FF00000 &&
Gmask == 0x000FFC00 && Gmask == 0x000FFC00 &&
Bmask == 0x000003FF && Bmask == 0x000003FF &&
Amask == 0xC0000000) { Amask == 0xC0000000) {
return SDL_PIXELFORMAT_ARGB2101010; return SDL_PIXELFORMAT_ARGB2101010;
} }
if (Rmask == 0x000003FF &&
Gmask == 0x000FFC00 &&
Bmask == 0x3FF00000 &&
Amask == 0xC0000000) {
return SDL_PIXELFORMAT_ABGR2101010;
}
break;
} }
return SDL_PIXELFORMAT_UNKNOWN; return SDL_PIXELFORMAT_UNKNOWN;
} }

View file

@ -39,7 +39,10 @@ static const Uint32 g_AllFormats[] = {
SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGBA8888,
SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ABGR8888,
SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGRA8888,
SDL_PIXELFORMAT_XRGB2101010,
SDL_PIXELFORMAT_XBGR2101010,
SDL_PIXELFORMAT_ARGB2101010, SDL_PIXELFORMAT_ARGB2101010,
SDL_PIXELFORMAT_ABGR2101010,
SDL_PIXELFORMAT_YV12, SDL_PIXELFORMAT_YV12,
SDL_PIXELFORMAT_IYUV, SDL_PIXELFORMAT_IYUV,
SDL_PIXELFORMAT_YUY2, SDL_PIXELFORMAT_YUY2,
@ -81,7 +84,10 @@ static const char *g_AllFormatsVerbose[] = {
"SDL_PIXELFORMAT_RGBA8888", "SDL_PIXELFORMAT_RGBA8888",
"SDL_PIXELFORMAT_ABGR8888", "SDL_PIXELFORMAT_ABGR8888",
"SDL_PIXELFORMAT_BGRA8888", "SDL_PIXELFORMAT_BGRA8888",
"SDL_PIXELFORMAT_XRGB2101010",
"SDL_PIXELFORMAT_XBGR2101010",
"SDL_PIXELFORMAT_ARGB2101010", "SDL_PIXELFORMAT_ARGB2101010",
"SDL_PIXELFORMAT_ABGR2101010",
"SDL_PIXELFORMAT_YV12", "SDL_PIXELFORMAT_YV12",
"SDL_PIXELFORMAT_IYUV", "SDL_PIXELFORMAT_IYUV",
"SDL_PIXELFORMAT_YUY2", "SDL_PIXELFORMAT_YUY2",

View file

@ -327,7 +327,10 @@ static int surface_testCompleteSurfaceConversion(void *arg)
SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGBA8888,
SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ABGR8888,
SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGRA8888,
SDL_PIXELFORMAT_XRGB2101010,
SDL_PIXELFORMAT_XBGR2101010,
SDL_PIXELFORMAT_ARGB2101010, SDL_PIXELFORMAT_ARGB2101010,
SDL_PIXELFORMAT_ABGR2101010,
}; };
SDL_Surface *face = NULL, *cvt1, *cvt2, *final; SDL_Surface *face = NULL, *cvt1, *cvt2, *final;
SDL_PixelFormat *fmt1, *fmt2; SDL_PixelFormat *fmt1, *fmt2;