review framebuffer blit/copy
This greatly simplifies the framebuffer blit/copy logic while now supporting all pixel formats. It is slightly slower in debug builds, but this path is mainly kept for compatibility anyway. The `copy_fast` version is still used for the "normal" cases when presenting to the screen.
This commit is contained in:
parent
1d62a2569f
commit
84dc84cfca
542
src/external/rlsw.h
vendored
542
src/external/rlsw.h
vendored
|
|
@ -1509,6 +1509,172 @@ static inline void sw_pixel_get_color8(uint8_t *color, const void *pixels, uint3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_GRAYSCALE(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint8_t gray = (uint8_t)(color[0]*77 + color[1]*150 + color[2]*29) >> 8; // luminance
|
||||||
|
((uint8_t*)pixels)[offset] = gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_GRAYALPHA(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint8_t *dst = &((uint8_t*)pixels)[offset*2];
|
||||||
|
dst[0] = (uint8_t)(color[0]*77 + color[1]*150 + color[2]*29) >> 8;
|
||||||
|
dst[1] = color[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R3G3B2(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint8_t pixel = ((color[0]*7/255) & 0x07) << 5 // R (3 bits)
|
||||||
|
| ((color[1]*7/255) & 0x07) << 2 // G (3 bits)
|
||||||
|
| ((color[2]*3/255) & 0x03); // B (2 bits)
|
||||||
|
((uint8_t*)pixels)[offset] = pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R5G6B5(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint16_t pixel = ((color[0]*31/255) & 0x1F) << 11 // R (5 bits)
|
||||||
|
| ((color[1]*63/255) & 0x3F) << 5 // G (6 bits)
|
||||||
|
| ((color[2]*31/255) & 0x1F); // B (5 bits)
|
||||||
|
((uint16_t*)pixels)[offset] = pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R8G8B8(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint8_t *dst = &((uint8_t*)pixels)[offset*3];
|
||||||
|
dst[0] = color[0];
|
||||||
|
dst[1] = color[1];
|
||||||
|
dst[2] = color[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R5G5B5A1(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint16_t pixel = ((color[0]*31/255) & 0x1F) << 11 // R (5 bits)
|
||||||
|
| ((color[1]*31/255) & 0x1F) << 6 // G (5 bits)
|
||||||
|
| ((color[2]*31/255) & 0x1F) << 1 // B (5 bits)
|
||||||
|
| ((color[3] > 127) ? 1 : 0); // A (1 bit)
|
||||||
|
((uint16_t*)pixels)[offset] = pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R4G4B4A4(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint16_t pixel = ((color[0]*15/255) & 0x0F) << 12 // R (4 bits)
|
||||||
|
| ((color[1]*15/255) & 0x0F) << 8 // G (4 bits)
|
||||||
|
| ((color[2]*15/255) & 0x0F) << 4 // B (4 bits)
|
||||||
|
| ((color[3]*15/255) & 0x0F); // A (4 bits)
|
||||||
|
((uint16_t*)pixels)[offset] = pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R8G8B8A8(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint8_t *dst = &((uint8_t*)pixels)[offset*4];
|
||||||
|
dst[0] = color[0];
|
||||||
|
dst[1] = color[1];
|
||||||
|
dst[2] = color[2];
|
||||||
|
dst[3] = color[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R32(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
float gray = (color[0]*77 + color[1]*150 + color[2]*29) / (255.0f*256.0f);
|
||||||
|
((float*)pixels)[offset] = gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R32G32B32(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
float *dst = &((float*)pixels)[offset*3];
|
||||||
|
dst[0] = color[0]*SW_INV_255;
|
||||||
|
dst[1] = color[1]*SW_INV_255;
|
||||||
|
dst[2] = color[2]*SW_INV_255;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R32G32B32A32(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
float *dst = &((float*)pixels)[offset*4];
|
||||||
|
dst[0] = color[0]*SW_INV_255;
|
||||||
|
dst[1] = color[1]*SW_INV_255;
|
||||||
|
dst[2] = color[2]*SW_INV_255;
|
||||||
|
dst[3] = color[3]*SW_INV_255;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R16(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
float gray = (color[0]*77 + color[1]*150 + color[2]*29) / (255.0f*256.0f);
|
||||||
|
((uint16_t*)pixels)[offset] = sw_float_to_half(gray);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R16G16B16(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint16_t *dst = &((uint16_t*)pixels)[offset*3];
|
||||||
|
dst[0] = sw_float_to_half(color[0]*SW_INV_255);
|
||||||
|
dst[1] = sw_float_to_half(color[1]*SW_INV_255);
|
||||||
|
dst[2] = sw_float_to_half(color[2]*SW_INV_255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8_R16G16B16A16(void *pixels, const uint8_t *color, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint16_t *dst = &((uint16_t*)pixels)[offset*4];
|
||||||
|
dst[0] = sw_float_to_half(color[0]*SW_INV_255);
|
||||||
|
dst[1] = sw_float_to_half(color[1]*SW_INV_255);
|
||||||
|
dst[2] = sw_float_to_half(color[2]*SW_INV_255);
|
||||||
|
dst[3] = sw_float_to_half(color[3]*SW_INV_255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_set_color8(void *pixels, const uint8_t *color, uint32_t offset, sw_pixelformat_t format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case SW_PIXELFORMAT_COLOR_GRAYSCALE:
|
||||||
|
sw_pixel_set_color8_GRAYSCALE(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_GRAYALPHA:
|
||||||
|
sw_pixel_set_color8_GRAYALPHA(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R3G3B2:
|
||||||
|
sw_pixel_set_color8_R3G3B2(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R5G6B5:
|
||||||
|
sw_pixel_set_color8_R5G6B5(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R8G8B8:
|
||||||
|
sw_pixel_set_color8_R8G8B8(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R5G5B5A1:
|
||||||
|
sw_pixel_set_color8_R5G5B5A1(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R4G4B4A4:
|
||||||
|
sw_pixel_set_color8_R4G4B4A4(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R8G8B8A8:
|
||||||
|
sw_pixel_set_color8_R8G8B8A8(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R32:
|
||||||
|
sw_pixel_set_color8_R32(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R32G32B32:
|
||||||
|
sw_pixel_set_color8_R32G32B32(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R32G32B32A32:
|
||||||
|
sw_pixel_set_color8_R32G32B32A32(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R16:
|
||||||
|
sw_pixel_set_color8_R16(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R16G16B16:
|
||||||
|
sw_pixel_set_color8_R16G16B16(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
case SW_PIXELFORMAT_COLOR_R16G16B16A16:
|
||||||
|
sw_pixel_set_color8_R16G16B16A16(pixels, color, offset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SW_PIXELFORMAT_UNKNOWN:
|
||||||
|
case SW_PIXELFORMAT_DEPTH_D8:
|
||||||
|
case SW_PIXELFORMAT_DEPTH_D16:
|
||||||
|
case SW_PIXELFORMAT_DEPTH_D32:
|
||||||
|
case SW_PIXELFORMAT_COUNT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_get_color_GRAYSCALE(float *color, const void *pixels, uint32_t offset)
|
static inline void sw_pixel_get_color_GRAYSCALE(float *color, const void *pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
float gray = ((const uint8_t*)pixels)[offset]*SW_INV_255;
|
float gray = ((const uint8_t*)pixels)[offset]*SW_INV_255;
|
||||||
|
|
@ -2202,271 +2368,88 @@ static inline void sw_framebuffer_copy_fast(void* dst)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int size = pixelCount * SW_FRAMEBUFFER_COLOR_SIZE;
|
int size = pixelCount * SW_FRAMEBUFFER_COLOR_SIZE;
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++) d[i] = src[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_framebuffer_copy(int x, int y, int w, int h, void *dst, sw_pixelformat_t format)
|
||||||
|
{
|
||||||
|
int dstPixelSize = SW_PIXELFORMAT_SIZE[format];
|
||||||
|
int stride = RLSW.framebuffer.width;
|
||||||
|
|
||||||
|
const uint8_t *src = RLSW.framebuffer.color.pixels;
|
||||||
|
src += (y*stride + x) * SW_FRAMEBUFFER_COLOR_SIZE;
|
||||||
|
uint8_t *d = dst;
|
||||||
|
|
||||||
|
for (int iy = 0; iy < h; iy++)
|
||||||
{
|
{
|
||||||
d[i] = src[i];
|
const uint8_t *line = src;
|
||||||
|
uint8_t *dline = d;
|
||||||
|
|
||||||
|
for (int ix = 0; ix < w; ix++)
|
||||||
|
{
|
||||||
|
uint8_t color[4];
|
||||||
|
SW_FRAMEBUFFER_COLOR8_GET(color, line, 0);
|
||||||
|
|
||||||
|
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
||||||
|
if (format == SW_PIXELFORMAT_COLOR_R8G8B8A8 || format == SW_PIXELFORMAT_COLOR_R8G8B8)
|
||||||
|
{
|
||||||
|
uint8_t tmp = color[0]; color[0] = color[2]; color[2] = tmp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sw_pixel_set_color8(dline, color, 0, format);
|
||||||
|
line += SW_FRAMEBUFFER_COLOR_SIZE;
|
||||||
|
dline += dstPixelSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
src += stride * SW_FRAMEBUFFER_COLOR_SIZE;
|
||||||
|
d += w * dstPixelSize;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_FRAMEBUFFER_COPY_BEGIN(name, DST_PTR_T) \
|
static inline void sw_framebuffer_blit(
|
||||||
static inline void sw_framebuffer_copy_to_##name(int x, int y, int w, int h, DST_PTR_T *dst) \
|
int xDst, int yDst, int wDst, int hDst,
|
||||||
{ \
|
int xSrc, int ySrc, int wSrc, int hSrc,
|
||||||
const int stride = RLSW.framebuffer.width; \
|
void *dst, sw_pixelformat_t format)
|
||||||
const uint8_t *src = RLSW.framebuffer.color.pixels; \
|
|
||||||
\
|
|
||||||
src += (y*stride + x) * SW_FRAMEBUFFER_COLOR_SIZE; \
|
|
||||||
\
|
|
||||||
for (int iy = 0; iy < h; iy++) \
|
|
||||||
{ \
|
|
||||||
const uint8_t *line = src; \
|
|
||||||
for (int ix = 0; ix < w; ix++) \
|
|
||||||
{ \
|
|
||||||
uint8_t color[4]; \
|
|
||||||
SW_FRAMEBUFFER_COLOR8_GET(color, line, 0); \
|
|
||||||
|
|
||||||
#define DEFINE_FRAMEBUFFER_COPY_END() \
|
|
||||||
line += SW_FRAMEBUFFER_COLOR_SIZE; \
|
|
||||||
} \
|
|
||||||
src += stride * SW_FRAMEBUFFER_COLOR_SIZE; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_BEGIN(GRAYSCALE, uint8_t)
|
|
||||||
{
|
{
|
||||||
// NTSC grayscale conversion: Y = 0.299R + 0.587G + 0.114B
|
const uint8_t *srcBase = RLSW.framebuffer.color.pixels;
|
||||||
uint8_t gray = (uint8_t)((color[0]*299 + color[1]*587 + color[2]*114 + 500)/1000);
|
int fbWidth = RLSW.framebuffer.width;
|
||||||
*dst++ = gray;
|
int dstPixelSize = SW_PIXELFORMAT_SIZE[format];
|
||||||
|
|
||||||
|
uint32_t xScale = ((uint32_t)wSrc << 16) / (uint32_t)wDst;
|
||||||
|
uint32_t yScale = ((uint32_t)hSrc << 16) / (uint32_t)hDst;
|
||||||
|
|
||||||
|
uint8_t *d = (uint8_t*)dst;
|
||||||
|
|
||||||
|
for (int dy = 0; dy < hDst; dy++)
|
||||||
|
{
|
||||||
|
int sy = (ySrc + (int)(dy * yScale >> 16));
|
||||||
|
const uint8_t *srcLine = srcBase + (sy * fbWidth + xSrc) * SW_FRAMEBUFFER_COLOR_SIZE;
|
||||||
|
uint8_t *dline = d;
|
||||||
|
|
||||||
|
for (int dx = 0; dx < wDst; dx++)
|
||||||
|
{
|
||||||
|
int sx = (int)(dx * xScale >> 16);
|
||||||
|
const uint8_t *pixel = srcLine + sx * SW_FRAMEBUFFER_COLOR_SIZE;
|
||||||
|
|
||||||
|
uint8_t color[4];
|
||||||
|
SW_FRAMEBUFFER_COLOR8_GET(color, pixel, 0);
|
||||||
|
|
||||||
|
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
||||||
|
if (format == SW_PIXELFORMAT_COLOR_R8G8B8A8 || format == SW_PIXELFORMAT_COLOR_R8G8B8)
|
||||||
|
{
|
||||||
|
uint8_t tmp = color[0]; color[0] = color[2]; color[2] = tmp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sw_pixel_set_color8(dline, color, 0, format);
|
||||||
|
dline += dstPixelSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
d += wDst * dstPixelSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DEFINE_FRAMEBUFFER_COPY_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_BEGIN(GRAYALPHA, uint8_t)
|
|
||||||
{
|
|
||||||
// Convert RGB to grayscale using NTSC formula
|
|
||||||
uint8_t gray = (uint8_t)((color[0]*299 + color[1]*587 + color[2]*114 + 500)/1000);
|
|
||||||
|
|
||||||
dst[0] = gray;
|
|
||||||
dst[1] = color[3]; // alpha
|
|
||||||
|
|
||||||
dst += 2;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_BEGIN(R5G6B5, uint16_t)
|
|
||||||
{
|
|
||||||
// Convert 8-bit RGB to 5:6:5 format
|
|
||||||
uint8_t r5 = (color[0]*31 + 127)/255;
|
|
||||||
uint8_t g6 = (color[1]*63 + 127)/255;
|
|
||||||
uint8_t b5 = (color[2]*31 + 127)/255;
|
|
||||||
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
uint16_t rgb565 = (b5 << 11) | (g6 << 5) | r5;
|
|
||||||
#else // RGBA
|
|
||||||
uint16_t rgb565 = (r5 << 11) | (g6 << 5) | b5;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*dst++ = rgb565;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_BEGIN(R8G8B8, uint8_t)
|
|
||||||
{
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
dst[0] = color[2];
|
|
||||||
dst[1] = color[1];
|
|
||||||
dst[2] = color[0];
|
|
||||||
#else // RGBA
|
|
||||||
dst[0] = color[0];
|
|
||||||
dst[1] = color[1];
|
|
||||||
dst[2] = color[2];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dst += 3;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_BEGIN(R5G5B5A1, uint16_t)
|
|
||||||
{
|
|
||||||
uint8_t r5 = (color[0]*31 + 127)/255;
|
|
||||||
uint8_t g5 = (color[1]*31 + 127)/255;
|
|
||||||
uint8_t b5 = (color[2]*31 + 127)/255;
|
|
||||||
uint8_t a1 = (color[3] >= 128)? 1 : 0;
|
|
||||||
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
uint16_t pixel = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
|
|
||||||
#else // RGBA
|
|
||||||
uint16_t pixel = (r5 << 11) | (g5 << 6) | (b5 << 1) | a1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*dst++ = pixel;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_BEGIN(R4G4B4A4, uint16_t)
|
|
||||||
{
|
|
||||||
uint8_t r4 = (color[0]*15 + 127)/255;
|
|
||||||
uint8_t g4 = (color[1]*15 + 127)/255;
|
|
||||||
uint8_t b4 = (color[2]*15 + 127)/255;
|
|
||||||
uint8_t a4 = (color[3]*15 + 127)/255;
|
|
||||||
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
uint16_t pixel = (b4 << 12) | (g4 << 8) | (r4 << 4) | a4;
|
|
||||||
#else // RGBA
|
|
||||||
uint16_t pixel = (r4 << 12) | (g4 << 8) | (b4 << 4) | a4;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*dst++ = pixel;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_BEGIN(R8G8B8A8, uint8_t)
|
|
||||||
{
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
dst[0] = color[2];
|
|
||||||
dst[1] = color[1];
|
|
||||||
dst[2] = color[0];
|
|
||||||
#else // RGBA
|
|
||||||
dst[0] = color[0];
|
|
||||||
dst[1] = color[1];
|
|
||||||
dst[2] = color[2];
|
|
||||||
#endif
|
|
||||||
dst[3] = color[3];
|
|
||||||
|
|
||||||
dst += 4;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_COPY_END()
|
|
||||||
|
|
||||||
#define DEFINE_FRAMEBUFFER_BLIT_BEGIN(name, DST_PTR_T) \
|
|
||||||
static inline void sw_framebuffer_blit_to_##name( \
|
|
||||||
int xDst, int yDst, int wDst, int hDst, \
|
|
||||||
int xSrc, int ySrc, int wSrc, int hSrc, \
|
|
||||||
DST_PTR_T *dst) \
|
|
||||||
{ \
|
|
||||||
const uint8_t *srcBase = RLSW.framebuffer.color.pixels; \
|
|
||||||
const int fbWidth = RLSW.framebuffer.width; \
|
|
||||||
\
|
|
||||||
const uint32_t xScale = ((uint32_t)wSrc << 16)/(uint32_t)wDst; \
|
|
||||||
const uint32_t yScale = ((uint32_t)hSrc << 16)/(uint32_t)hDst; \
|
|
||||||
\
|
|
||||||
for (int dy = 0; dy < hDst; dy++) \
|
|
||||||
{ \
|
|
||||||
uint32_t yFix = ((uint32_t)ySrc << 16) + dy*yScale; \
|
|
||||||
int sy = yFix >> 16; \
|
|
||||||
const uint8_t *srcLine = srcBase + (sy*fbWidth + xSrc) * SW_FRAMEBUFFER_COLOR_SIZE; \
|
|
||||||
\
|
|
||||||
const uint8_t *srcPtr = srcLine; \
|
|
||||||
for (int dx = 0; dx < wDst; dx++) { \
|
|
||||||
uint32_t xFix = dx*xScale; \
|
|
||||||
int sx = xFix >> 16; \
|
|
||||||
const uint8_t *pixel = srcPtr + sx * SW_FRAMEBUFFER_COLOR_SIZE; \
|
|
||||||
uint8_t color[4]; \
|
|
||||||
SW_FRAMEBUFFER_COLOR8_GET(color, pixel, 0); \
|
|
||||||
|
|
||||||
#define DEFINE_FRAMEBUFFER_BLIT_END() \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_BEGIN(GRAYSCALE, uint8_t)
|
|
||||||
{
|
|
||||||
uint8_t gray = (uint8_t)((color[0]*299 + color[1]*587 + color[2]*114 + 500)/1000);
|
|
||||||
*dst++ = gray;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_BEGIN(GRAYALPHA, uint8_t)
|
|
||||||
{
|
|
||||||
uint8_t gray = (uint8_t)((color[0]*299 + color[1]*587 + color[2]*114 + 500)/1000);
|
|
||||||
|
|
||||||
dst[0] = gray;
|
|
||||||
dst[1] = color[3]; // alpha
|
|
||||||
|
|
||||||
dst += 2;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_BEGIN(R5G6B5, uint16_t)
|
|
||||||
{
|
|
||||||
uint8_t r5 = (color[0]*31 + 127)/255;
|
|
||||||
uint8_t g6 = (color[1]*63 + 127)/255;
|
|
||||||
uint8_t b5 = (color[2]*31 + 127)/255;
|
|
||||||
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
uint16_t rgb565 = (b5 << 11) | (g6 << 5) | r5;
|
|
||||||
#else // RGBA
|
|
||||||
uint16_t rgb565 = (r5 << 11) | (g6 << 5) | b5;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*dst++ = rgb565;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_BEGIN(R8G8B8, uint8_t)
|
|
||||||
{
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
dst[0] = color[2];
|
|
||||||
dst[1] = color[1];
|
|
||||||
dst[2] = color[0];
|
|
||||||
#else // RGBA
|
|
||||||
dst[0] = color[0];
|
|
||||||
dst[1] = color[1];
|
|
||||||
dst[2] = color[2];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dst += 3;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_BEGIN(R5G5B5A1, uint16_t)
|
|
||||||
{
|
|
||||||
uint8_t r5 = (color[0]*31 + 127)/255;
|
|
||||||
uint8_t g5 = (color[1]*31 + 127)/255;
|
|
||||||
uint8_t b5 = (color[2]*31 + 127)/255;
|
|
||||||
uint8_t a1 = (color[3] >= 128)? 1 : 0;
|
|
||||||
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
uint16_t pixel = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
|
|
||||||
#else // RGBA
|
|
||||||
uint16_t pixel = (r5 << 11) | (g5 << 6) | (b5 << 1) | a1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*dst++ = pixel;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_BEGIN(R4G4B4A4, uint16_t)
|
|
||||||
{
|
|
||||||
uint8_t r4 = (color[0]*15 + 127)/255;
|
|
||||||
uint8_t g4 = (color[1]*15 + 127)/255;
|
|
||||||
uint8_t b4 = (color[2]*15 + 127)/255;
|
|
||||||
uint8_t a4 = (color[3]*15 + 127)/255;
|
|
||||||
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
uint16_t pixel = (b4 << 12) | (g4 << 8) | (r4 << 4) | a4;
|
|
||||||
#else // RGBA
|
|
||||||
uint16_t pixel = (r4 << 12) | (g4 << 8) | (b4 << 4) | a4;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*dst++ = pixel;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_END()
|
|
||||||
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_BEGIN(R8G8B8A8, uint8_t)
|
|
||||||
{
|
|
||||||
#if SW_FRAMEBUFFER_OUTPUT_BGRA
|
|
||||||
dst[0] = color[2];
|
|
||||||
dst[1] = color[1];
|
|
||||||
dst[2] = color[0];
|
|
||||||
#else // RGBA
|
|
||||||
dst[0] = color[0];
|
|
||||||
dst[1] = color[1];
|
|
||||||
dst[2] = color[2];
|
|
||||||
#endif
|
|
||||||
dst[3] = color[3];
|
|
||||||
|
|
||||||
dst += 4;
|
|
||||||
}
|
|
||||||
DEFINE_FRAMEBUFFER_BLIT_END()
|
|
||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Color blending functionality
|
// Color blending functionality
|
||||||
|
|
@ -4162,26 +4145,10 @@ void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type,
|
||||||
if ((pFormat == SW_FRAMEBUFFER_COLOR_FORMAT) && (x == 0) && (y == 0) && (w == RLSW.framebuffer.width) && (h == RLSW.framebuffer.height))
|
if ((pFormat == SW_FRAMEBUFFER_COLOR_FORMAT) && (x == 0) && (y == 0) && (w == RLSW.framebuffer.width) && (h == RLSW.framebuffer.height))
|
||||||
{
|
{
|
||||||
sw_framebuffer_copy_fast(pixels);
|
sw_framebuffer_copy_fast(pixels);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
switch (pFormat)
|
|
||||||
{
|
{
|
||||||
case SW_PIXELFORMAT_COLOR_GRAYSCALE: sw_framebuffer_copy_to_GRAYSCALE(x, y, w, h, (uint8_t *)pixels); break;
|
sw_framebuffer_copy(x, y, w, h, pixels, pFormat);
|
||||||
case SW_PIXELFORMAT_COLOR_GRAYALPHA: sw_framebuffer_copy_to_GRAYALPHA(x, y, w, h, (uint8_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R5G6B5: sw_framebuffer_copy_to_R5G6B5(x, y, w, h, (uint16_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R8G8B8: sw_framebuffer_copy_to_R8G8B8(x, y, w, h, (uint8_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R5G5B5A1: sw_framebuffer_copy_to_R5G5B5A1(x, y, w, h, (uint16_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R4G4B4A4: sw_framebuffer_copy_to_R4G4B4A4(x, y, w, h, (uint16_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R8G8B8A8: sw_framebuffer_copy_to_R8G8B8A8(x, y, w, h, (uint8_t *)pixels); break;
|
|
||||||
// Below: not implemented
|
|
||||||
case SW_PIXELFORMAT_COLOR_R32:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R32G32B32:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R32G32B32A32:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R16:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R16G16B16:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R16G16B16A16:
|
|
||||||
default: RLSW.errCode = SW_INVALID_ENUM; break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4208,26 +4175,9 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr
|
||||||
{
|
{
|
||||||
swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels);
|
swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
switch (pFormat)
|
|
||||||
{
|
{
|
||||||
case SW_PIXELFORMAT_COLOR_GRAYSCALE: sw_framebuffer_blit_to_GRAYSCALE(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break;
|
sw_framebuffer_blit(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels, pFormat);
|
||||||
case SW_PIXELFORMAT_COLOR_GRAYALPHA: sw_framebuffer_blit_to_GRAYALPHA(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R5G6B5: sw_framebuffer_blit_to_R5G6B5(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint16_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R8G8B8: sw_framebuffer_blit_to_R8G8B8(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R5G5B5A1: sw_framebuffer_blit_to_R5G5B5A1(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint16_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R4G4B4A4: sw_framebuffer_blit_to_R4G4B4A4(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint16_t *)pixels); break;
|
|
||||||
case SW_PIXELFORMAT_COLOR_R8G8B8A8: sw_framebuffer_blit_to_R8G8B8A8(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break;
|
|
||||||
// Below: not implemented
|
|
||||||
case SW_PIXELFORMAT_COLOR_R32:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R32G32B32:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R32G32B32A32:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R16:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R16G16B16:
|
|
||||||
case SW_PIXELFORMAT_COLOR_R16G16B16A16:
|
|
||||||
default:
|
|
||||||
RLSW.errCode = SW_INVALID_ENUM;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user