Added full blit feature support for 8-bit surfaces
Fixes https://github.com/libsdl-org/SDL/issues/8079
This commit is contained in:
@@ -279,9 +279,11 @@ int SDL_CalculateBlit(SDL_Surface *surface)
|
|||||||
SDL_PixelFormat src_format = surface->format;
|
SDL_PixelFormat src_format = surface->format;
|
||||||
SDL_PixelFormat dst_format = dst->format;
|
SDL_PixelFormat dst_format = dst->format;
|
||||||
|
|
||||||
if (!SDL_ISPIXELFORMAT_INDEXED(src_format) &&
|
if ((!SDL_ISPIXELFORMAT_INDEXED(src_format) ||
|
||||||
|
(src_format == SDL_PIXELFORMAT_INDEX8 && surface->internal->palette)) &&
|
||||||
!SDL_ISPIXELFORMAT_FOURCC(src_format) &&
|
!SDL_ISPIXELFORMAT_FOURCC(src_format) &&
|
||||||
!SDL_ISPIXELFORMAT_INDEXED(dst_format) &&
|
(!SDL_ISPIXELFORMAT_INDEXED(dst_format) ||
|
||||||
|
(dst_format == SDL_PIXELFORMAT_INDEX8 && dst->internal->palette)) &&
|
||||||
!SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
|
!SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
|
||||||
blit = SDL_Blit_Slow;
|
blit = SDL_Blit_Slow;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,6 +226,10 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface);
|
|||||||
((b >> (8 - fmt->Bbits)) << fmt->Bshift) | \
|
((b >> (8 - fmt->Bbits)) << fmt->Bshift) | \
|
||||||
fmt->Amask; \
|
fmt->Amask; \
|
||||||
}
|
}
|
||||||
|
#define RGB332_FROM_RGB(Pixel, r, g, b) \
|
||||||
|
{ \
|
||||||
|
Pixel = (Uint8)(((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6)); \
|
||||||
|
}
|
||||||
#define RGB565_FROM_RGB(Pixel, r, g, b) \
|
#define RGB565_FROM_RGB(Pixel, r, g, b) \
|
||||||
{ \
|
{ \
|
||||||
Pixel = (Uint16)(((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); \
|
Pixel = (Uint16)(((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); \
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
SlowBlitPixelAccess_Unknown,
|
||||||
|
SlowBlitPixelAccess_Index8,
|
||||||
SlowBlitPixelAccess_RGB,
|
SlowBlitPixelAccess_RGB,
|
||||||
SlowBlitPixelAccess_RGBA,
|
SlowBlitPixelAccess_RGBA,
|
||||||
SlowBlitPixelAccess_10Bit,
|
SlowBlitPixelAccess_10Bit,
|
||||||
@@ -38,6 +40,8 @@ static SlowBlitPixelAccess GetPixelAccessMethod(SDL_PixelFormat format)
|
|||||||
return SlowBlitPixelAccess_Large;
|
return SlowBlitPixelAccess_Large;
|
||||||
} else if (SDL_ISPIXELFORMAT_10BIT(format)) {
|
} else if (SDL_ISPIXELFORMAT_10BIT(format)) {
|
||||||
return SlowBlitPixelAccess_10Bit;
|
return SlowBlitPixelAccess_10Bit;
|
||||||
|
} else if (format == SDL_PIXELFORMAT_INDEX8) {
|
||||||
|
return SlowBlitPixelAccess_Index8;
|
||||||
} else if (SDL_ISPIXELFORMAT_ALPHA(format)) {
|
} else if (SDL_ISPIXELFORMAT_ALPHA(format)) {
|
||||||
return SlowBlitPixelAccess_RGBA;
|
return SlowBlitPixelAccess_RGBA;
|
||||||
} else {
|
} else {
|
||||||
@@ -63,7 +67,9 @@ void SDL_Blit_Slow(SDL_BlitInfo *info)
|
|||||||
Uint64 posy, posx;
|
Uint64 posy, posx;
|
||||||
Uint64 incy, incx;
|
Uint64 incy, incx;
|
||||||
const SDL_PixelFormatDetails *src_fmt = info->src_fmt;
|
const SDL_PixelFormatDetails *src_fmt = info->src_fmt;
|
||||||
|
const SDL_Palette *src_pal = info->src_pal;
|
||||||
const SDL_PixelFormatDetails *dst_fmt = info->dst_fmt;
|
const SDL_PixelFormatDetails *dst_fmt = info->dst_fmt;
|
||||||
|
const SDL_Palette *dst_pal = info->dst_pal;
|
||||||
int srcbpp = src_fmt->bytes_per_pixel;
|
int srcbpp = src_fmt->bytes_per_pixel;
|
||||||
int dstbpp = dst_fmt->bytes_per_pixel;
|
int dstbpp = dst_fmt->bytes_per_pixel;
|
||||||
SlowBlitPixelAccess src_access;
|
SlowBlitPixelAccess src_access;
|
||||||
@@ -89,6 +95,15 @@ void SDL_Blit_Slow(SDL_BlitInfo *info)
|
|||||||
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
||||||
|
|
||||||
switch (src_access) {
|
switch (src_access) {
|
||||||
|
case SlowBlitPixelAccess_Unknown:
|
||||||
|
break;
|
||||||
|
case SlowBlitPixelAccess_Index8:
|
||||||
|
srcpixel = *src;
|
||||||
|
srcR = src_pal->colors[srcpixel].r;
|
||||||
|
srcG = src_pal->colors[srcpixel].g;
|
||||||
|
srcB = src_pal->colors[srcpixel].b;
|
||||||
|
srcA = src_pal->colors[srcpixel].a;
|
||||||
|
break;
|
||||||
case SlowBlitPixelAccess_RGB:
|
case SlowBlitPixelAccess_RGB:
|
||||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
|
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
|
||||||
srcA = 0xFF;
|
srcA = 0xFF;
|
||||||
@@ -136,6 +151,15 @@ void SDL_Blit_Slow(SDL_BlitInfo *info)
|
|||||||
}
|
}
|
||||||
if ((flags & (SDL_COPY_BLEND | SDL_COPY_BLEND_PREMULTIPLIED | SDL_COPY_ADD | SDL_COPY_ADD_PREMULTIPLIED | SDL_COPY_MOD | SDL_COPY_MUL))) {
|
if ((flags & (SDL_COPY_BLEND | SDL_COPY_BLEND_PREMULTIPLIED | SDL_COPY_ADD | SDL_COPY_ADD_PREMULTIPLIED | SDL_COPY_MOD | SDL_COPY_MUL))) {
|
||||||
switch (dst_access) {
|
switch (dst_access) {
|
||||||
|
case SlowBlitPixelAccess_Unknown:
|
||||||
|
break;
|
||||||
|
case SlowBlitPixelAccess_Index8:
|
||||||
|
dstpixel = *dst;
|
||||||
|
dstR = dst_pal->colors[dstpixel].r;
|
||||||
|
dstG = dst_pal->colors[dstpixel].g;
|
||||||
|
dstB = dst_pal->colors[dstpixel].b;
|
||||||
|
dstA = dst_pal->colors[dstpixel].a;
|
||||||
|
break;
|
||||||
case SlowBlitPixelAccess_RGB:
|
case SlowBlitPixelAccess_RGB:
|
||||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
|
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
|
||||||
dstA = 0xFF;
|
dstA = 0xFF;
|
||||||
@@ -255,6 +279,16 @@ void SDL_Blit_Slow(SDL_BlitInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (dst_access) {
|
switch (dst_access) {
|
||||||
|
case SlowBlitPixelAccess_Unknown:
|
||||||
|
break;
|
||||||
|
case SlowBlitPixelAccess_Index8:
|
||||||
|
RGB332_FROM_RGB(dstpixel, dstR, dstG, dstB);
|
||||||
|
if (info->table) {
|
||||||
|
*dst = info->table[dstpixel];
|
||||||
|
} else {
|
||||||
|
*dst = dstpixel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SlowBlitPixelAccess_RGB:
|
case SlowBlitPixelAccess_RGB:
|
||||||
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
|
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
|
||||||
break;
|
break;
|
||||||
@@ -388,7 +422,7 @@ static Uint16 float_to_half(float a)
|
|||||||
return ir;
|
return ir;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReadFloatPixel(Uint8 *pixels, SlowBlitPixelAccess access, const SDL_PixelFormatDetails *fmt, SDL_Colorspace colorspace, float SDR_white_point,
|
static void ReadFloatPixel(Uint8 *pixels, SlowBlitPixelAccess access, const SDL_PixelFormatDetails *fmt, const SDL_Palette *pal, SDL_Colorspace colorspace, float SDR_white_point,
|
||||||
float *outR, float *outG, float *outB, float *outA)
|
float *outR, float *outG, float *outB, float *outA)
|
||||||
{
|
{
|
||||||
Uint32 pixel;
|
Uint32 pixel;
|
||||||
@@ -397,6 +431,15 @@ static void ReadFloatPixel(Uint8 *pixels, SlowBlitPixelAccess access, const SDL_
|
|||||||
float v[4];
|
float v[4];
|
||||||
|
|
||||||
switch (access) {
|
switch (access) {
|
||||||
|
case SlowBlitPixelAccess_Unknown:
|
||||||
|
break;
|
||||||
|
case SlowBlitPixelAccess_Index8:
|
||||||
|
pixel = *pixels;
|
||||||
|
fR = (float)pal->colors[pixel].r / 255.0f;
|
||||||
|
fG = (float)pal->colors[pixel].g / 255.0f;
|
||||||
|
fB = (float)pal->colors[pixel].b / 255.0f;
|
||||||
|
fA = (float)pal->colors[pixel].a / 255.0f;
|
||||||
|
break;
|
||||||
case SlowBlitPixelAccess_RGB:
|
case SlowBlitPixelAccess_RGB:
|
||||||
DISEMBLE_RGB(pixels, fmt->bytes_per_pixel, fmt, pixel, R, G, B);
|
DISEMBLE_RGB(pixels, fmt->bytes_per_pixel, fmt, pixel, R, G, B);
|
||||||
fR = (float)R / 255.0f;
|
fR = (float)R / 255.0f;
|
||||||
@@ -543,10 +586,11 @@ static void ReadFloatPixel(Uint8 *pixels, SlowBlitPixelAccess access, const SDL_
|
|||||||
*outA = fA;
|
*outA = fA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteFloatPixel(Uint8 *pixels, SlowBlitPixelAccess access, const SDL_PixelFormatDetails *fmt, SDL_Colorspace colorspace, float SDR_white_point,
|
static void WriteFloatPixel(Uint8 *pixels, SlowBlitPixelAccess access, const SDL_PixelFormatDetails *fmt, Uint8 *table, SDL_Colorspace colorspace, float SDR_white_point,
|
||||||
float fR, float fG, float fB, float fA)
|
float fR, float fG, float fB, float fA)
|
||||||
{
|
{
|
||||||
Uint32 R, G, B, A;
|
Uint32 R, G, B, A;
|
||||||
|
Uint32 pixel;
|
||||||
float v[4];
|
float v[4];
|
||||||
|
|
||||||
/* We converted to nits so src and dst are guaranteed to be linear and in the same units */
|
/* We converted to nits so src and dst are guaranteed to be linear and in the same units */
|
||||||
@@ -572,6 +616,19 @@ static void WriteFloatPixel(Uint8 *pixels, SlowBlitPixelAccess access, const SDL
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (access) {
|
switch (access) {
|
||||||
|
case SlowBlitPixelAccess_Unknown:
|
||||||
|
break;
|
||||||
|
case SlowBlitPixelAccess_Index8:
|
||||||
|
R = (Uint8)SDL_roundf(SDL_clamp(fR, 0.0f, 1.0f) * 7.0f);
|
||||||
|
G = (Uint8)SDL_roundf(SDL_clamp(fG, 0.0f, 1.0f) * 7.0f);
|
||||||
|
B = (Uint8)SDL_roundf(SDL_clamp(fB, 0.0f, 1.0f) * 3.0f);
|
||||||
|
pixel = (R << 5) | (G << 2) | B;
|
||||||
|
if (table) {
|
||||||
|
*pixels = table[pixel];
|
||||||
|
} else {
|
||||||
|
*pixels = pixel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SlowBlitPixelAccess_RGB:
|
case SlowBlitPixelAccess_RGB:
|
||||||
R = (Uint8)SDL_roundf(SDL_clamp(fR, 0.0f, 1.0f) * 255.0f);
|
R = (Uint8)SDL_roundf(SDL_clamp(fR, 0.0f, 1.0f) * 255.0f);
|
||||||
G = (Uint8)SDL_roundf(SDL_clamp(fG, 0.0f, 1.0f) * 255.0f);
|
G = (Uint8)SDL_roundf(SDL_clamp(fG, 0.0f, 1.0f) * 255.0f);
|
||||||
@@ -587,7 +644,6 @@ static void WriteFloatPixel(Uint8 *pixels, SlowBlitPixelAccess access, const SDL
|
|||||||
break;
|
break;
|
||||||
case SlowBlitPixelAccess_10Bit:
|
case SlowBlitPixelAccess_10Bit:
|
||||||
{
|
{
|
||||||
Uint32 pixel;
|
|
||||||
switch (fmt->format) {
|
switch (fmt->format) {
|
||||||
case SDL_PIXELFORMAT_XRGB2101010:
|
case SDL_PIXELFORMAT_XRGB2101010:
|
||||||
fA = 1.0f;
|
fA = 1.0f;
|
||||||
@@ -774,7 +830,9 @@ void SDL_Blit_Slow_Float(SDL_BlitInfo *info)
|
|||||||
Uint64 posy, posx;
|
Uint64 posy, posx;
|
||||||
Uint64 incy, incx;
|
Uint64 incy, incx;
|
||||||
const SDL_PixelFormatDetails *src_fmt = info->src_fmt;
|
const SDL_PixelFormatDetails *src_fmt = info->src_fmt;
|
||||||
|
const SDL_Palette *src_pal = info->src_pal;
|
||||||
const SDL_PixelFormatDetails *dst_fmt = info->dst_fmt;
|
const SDL_PixelFormatDetails *dst_fmt = info->dst_fmt;
|
||||||
|
const SDL_Palette *dst_pal = info->dst_pal;
|
||||||
int srcbpp = src_fmt->bytes_per_pixel;
|
int srcbpp = src_fmt->bytes_per_pixel;
|
||||||
int dstbpp = dst_fmt->bytes_per_pixel;
|
int dstbpp = dst_fmt->bytes_per_pixel;
|
||||||
SlowBlitPixelAccess src_access;
|
SlowBlitPixelAccess src_access;
|
||||||
@@ -858,7 +916,7 @@ void SDL_Blit_Slow_Float(SDL_BlitInfo *info)
|
|||||||
srcx = posx >> 16;
|
srcx = posx >> 16;
|
||||||
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
||||||
|
|
||||||
ReadFloatPixel(src, src_access, src_fmt, src_colorspace, src_white_point, &srcR, &srcG, &srcB, &srcA);
|
ReadFloatPixel(src, src_access, src_fmt, src_pal, src_colorspace, src_white_point, &srcR, &srcG, &srcB, &srcA);
|
||||||
|
|
||||||
if (tonemap.op) {
|
if (tonemap.op) {
|
||||||
ApplyTonemap(&tonemap, &srcR, &srcG, &srcB);
|
ApplyTonemap(&tonemap, &srcR, &srcG, &srcB);
|
||||||
@@ -872,7 +930,7 @@ void SDL_Blit_Slow_Float(SDL_BlitInfo *info)
|
|||||||
/* colorkey isn't supported */
|
/* colorkey isn't supported */
|
||||||
}
|
}
|
||||||
if ((flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL))) {
|
if ((flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL))) {
|
||||||
ReadFloatPixel(dst, dst_access, dst_fmt, dst_colorspace, dst_white_point, &dstR, &dstG, &dstB, &dstA);
|
ReadFloatPixel(dst, dst_access, dst_fmt, dst_pal, dst_colorspace, dst_white_point, &dstR, &dstG, &dstB, &dstA);
|
||||||
} else {
|
} else {
|
||||||
/* don't care */
|
/* don't care */
|
||||||
dstR = dstG = dstB = dstA = 0.0f;
|
dstR = dstG = dstB = dstA = 0.0f;
|
||||||
@@ -923,7 +981,7 @@ void SDL_Blit_Slow_Float(SDL_BlitInfo *info)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteFloatPixel(dst, dst_access, dst_fmt, dst_colorspace, dst_white_point, dstR, dstG, dstB, dstA);
|
WriteFloatPixel(dst, dst_access, dst_fmt, info->table, dst_colorspace, dst_white_point, dstR, dstG, dstB, dstA);
|
||||||
|
|
||||||
posx += incx;
|
posx += incx;
|
||||||
dst += dstbpp;
|
dst += dstbpp;
|
||||||
|
|||||||
Reference in New Issue
Block a user