Updated and re-enabled surface and render blend mode tests

This commit is contained in:
Sam Lantinga 2024-07-15 13:42:06 -07:00
parent df573391b1
commit a419e2c890
4 changed files with 431 additions and 6083 deletions

File diff suppressed because it is too large Load Diff

View File

@ -25,16 +25,7 @@ typedef struct SDLTest_SurfaceImage_s {
/* Test images */
SDL_Surface *SDLTest_ImageBlit(void);
SDL_Surface *SDLTest_ImageBlitColor(void);
SDL_Surface *SDLTest_ImageBlitAlpha(void);
SDL_Surface *SDLTest_ImageBlitBlend(void);
SDL_Surface *SDLTest_ImageBlitBlendPremultiplied(void);
SDL_Surface *SDLTest_ImageBlitBlendAdd(void);
SDL_Surface *SDLTest_ImageBlitBlendAddPremultiplied(void);
SDL_Surface *SDLTest_ImageBlitBlendMod(void);
SDL_Surface *SDLTest_ImageBlitBlendNone(void);
SDL_Surface *SDLTest_ImageBlitBlendAll(void);
SDL_Surface *SDLTest_ImageFace(void);
SDL_Surface *SDLTest_ImagePrimitives(void);
SDL_Surface *SDLTest_ImagePrimitivesBlend(void);
SDL_Surface *SDLTest_ImageBlendingBackground(void);
SDL_Surface *SDLTest_ImageBlendingSprite(void);

View File

@ -36,10 +36,7 @@ static SDL_Renderer *renderer = NULL;
static int clearScreen(void);
static void compare(SDL_Surface *reference, int allowable_error);
static int hasTexAlpha(void);
static int hasTexColor(void);
static SDL_Texture *loadTestFace(void);
static int hasBlendModes(void);
static int hasDrawColor(void);
static int isSupported(int code);
@ -119,7 +116,7 @@ static int render_testPrimitives(void *arg)
clearScreen();
/* Need drawcolor or just skip test. */
SDLTest_AssertCheck(hasDrawColor(), "_hasDrawColor");
SDLTest_AssertCheck(hasDrawColor(), "hasDrawColor");
/* Draw a rectangle. */
rect.x = 40.0f;
@ -185,149 +182,6 @@ static int render_testPrimitives(void *arg)
return TEST_COMPLETED;
}
/**
* Tests the SDL primitives with alpha for rendering.
*
* \sa SDL_SetRenderDrawColor
* \sa SDL_SetRenderDrawBlendMode
* \sa SDL_RenderFillRect
*/
static int render_testPrimitivesBlend(void *arg)
{
int ret;
int i, j;
SDL_FRect rect;
SDL_Surface *referenceSurface = NULL;
int checkFailCount1;
int checkFailCount2;
int checkFailCount3;
/* Clear surface. */
clearScreen();
/* Need drawcolor and blendmode or just skip test. */
SDLTest_AssertCheck(hasDrawColor(), "_hasDrawColor");
SDLTest_AssertCheck(hasBlendModes(), "_hasBlendModes");
/* Create some rectangles for each blend mode. */
CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 255, 255, 255, 0))
CHECK_FUNC(SDL_SetRenderDrawBlendMode, (renderer, SDL_BLENDMODE_NONE))
CHECK_FUNC(SDL_RenderFillRect, (renderer, NULL))
rect.x = 10.0f;
rect.y = 25.0f;
rect.w = 40.0f;
rect.h = 25.0f;
CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 240, 10, 10, 75))
CHECK_FUNC(SDL_SetRenderDrawBlendMode, (renderer, SDL_BLENDMODE_ADD))
CHECK_FUNC(SDL_RenderFillRect, (renderer, &rect))
rect.x = 30.0f;
rect.y = 40.0f;
rect.w = 45.0f;
rect.h = 15.0f;
CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 10, 240, 10, 100))
CHECK_FUNC(SDL_SetRenderDrawBlendMode, (renderer, SDL_BLENDMODE_BLEND))
CHECK_FUNC(SDL_RenderFillRect, (renderer, &rect))
rect.x = 25.0f;
rect.y = 25.0f;
rect.w = 25.0f;
rect.h = 25.0f;
CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 10, 10, 240, 125))
CHECK_FUNC(SDL_SetRenderDrawBlendMode, (renderer, SDL_BLENDMODE_NONE))
CHECK_FUNC(SDL_RenderFillRect, (renderer, &rect))
/* Draw blended lines, lines for everyone. */
checkFailCount1 = 0;
checkFailCount2 = 0;
checkFailCount3 = 0;
for (i = 0; i < TESTRENDER_SCREEN_W; i += 2) {
ret = SDL_SetRenderDrawColor(renderer, (Uint8)(60 + 2 * i), (Uint8)(240 - 2 * i), 50, (Uint8)(3 * i));
if (ret != 0) {
checkFailCount1++;
}
ret = SDL_SetRenderDrawBlendMode(renderer, (((i / 2) % 3) == 0) ? SDL_BLENDMODE_BLEND : (((i / 2) % 3) == 1) ? SDL_BLENDMODE_ADD
: SDL_BLENDMODE_NONE);
if (ret != 0) {
checkFailCount2++;
}
ret = SDL_RenderLine(renderer, 0.0f, 0.0f, (float)i, 59.0f);
if (ret != 0) {
checkFailCount3++;
}
}
SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetRenderDrawColor, expected: 0, got: %i", checkFailCount1);
SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetRenderDrawBlendMode, expected: 0, got: %i", checkFailCount2);
SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_RenderLine, expected: 0, got: %i", checkFailCount3);
checkFailCount1 = 0;
checkFailCount2 = 0;
checkFailCount3 = 0;
for (i = 0; i < TESTRENDER_SCREEN_H; i += 2) {
ret = SDL_SetRenderDrawColor(renderer, (Uint8)(60 + 2 * i), (Uint8)(240 - 2 * i), 50, (Uint8)(3 * i));
if (ret != 0) {
checkFailCount1++;
}
ret = SDL_SetRenderDrawBlendMode(renderer, (((i / 2) % 3) == 0) ? SDL_BLENDMODE_BLEND : (((i / 2) % 3) == 1) ? SDL_BLENDMODE_ADD
: SDL_BLENDMODE_NONE);
if (ret != 0) {
checkFailCount2++;
}
ret = SDL_RenderLine(renderer, 0.0f, 0.0f, 79.0f, (float)i);
if (ret != 0) {
checkFailCount3++;
}
}
SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetRenderDrawColor, expected: 0, got: %i", checkFailCount1);
SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetRenderDrawBlendMode, expected: 0, got: %i", checkFailCount2);
SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_RenderLine, expected: 0, got: %i", checkFailCount3);
/* Draw points. */
checkFailCount1 = 0;
checkFailCount2 = 0;
checkFailCount3 = 0;
for (j = 0; j < TESTRENDER_SCREEN_H; j += 3) {
for (i = 0; i < TESTRENDER_SCREEN_W; i += 3) {
ret = SDL_SetRenderDrawColor(renderer, (Uint8)(j * 4), (Uint8)(i * 3), (Uint8)(j * 4), (Uint8)(i * 3));
if (ret != 0) {
checkFailCount1++;
}
ret = SDL_SetRenderDrawBlendMode(renderer, ((((i + j) / 3) % 3) == 0) ? SDL_BLENDMODE_BLEND : ((((i + j) / 3) % 3) == 1) ? SDL_BLENDMODE_ADD
: SDL_BLENDMODE_NONE);
if (ret != 0) {
checkFailCount2++;
}
ret = SDL_RenderPoint(renderer, (float)i, (float)j);
if (ret != 0) {
checkFailCount3++;
}
}
}
SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetRenderDrawColor, expected: 0, got: %i", checkFailCount1);
SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetRenderDrawBlendMode, expected: 0, got: %i", checkFailCount2);
SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_RenderPoint, expected: 0, got: %i", checkFailCount3);
/* See if it's the same. */
referenceSurface = SDLTest_ImagePrimitivesBlend();
compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
/* Make current */
SDL_RenderPresent(renderer);
/* Clean up. */
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
return TEST_COMPLETED;
}
/**
* Tests the SDL primitives for rendering within a viewport.
*
@ -392,7 +246,7 @@ static int render_testBlit(void *arg)
clearScreen();
/* Need drawcolor or just skip test. */
SDLTest_AssertCheck(hasDrawColor(), "_hasDrawColor)");
SDLTest_AssertCheck(hasDrawColor(), "hasDrawColor)");
/* Create face surface. */
tface = loadTestFace();
@ -511,306 +365,269 @@ static int render_testBlitColor(void *arg)
return TEST_COMPLETED;
}
/**
* Tests blitting with alpha.
*
* \sa SDL_SetTextureAlphaMod
* \sa SDL_RenderTexture
* \sa SDL_DestroyTexture
*/
static int render_testBlitAlpha(void *arg)
typedef enum TestRenderOperation
{
TEST_RENDER_POINT,
TEST_RENDER_LINE,
TEST_RENDER_RECT,
TEST_RENDER_COPY_XRGB,
TEST_RENDER_COPY_ARGB,
} TestRenderOperation;
/**
* Helper that tests a specific operation and blend mode, -1 for color mod, -2 for alpha mod
*/
static void testBlendModeOperation(TestRenderOperation op, int mode, SDL_PixelFormat dst_format)
{
/* Allow up to 2 delta from theoretical value to account for rounding error.
* We allow 2 rounding errors because the software renderer breaks drawing operations into alpha multiplication and a separate blend operation.
*/
const int MAXIMUM_ERROR = 2;
int ret;
SDL_FRect rect;
SDL_Texture *tface;
SDL_Surface *referenceSurface = NULL;
float tw, th;
float i, j, ni, nj;
int checkFailCount1;
int checkFailCount2;
SDL_Texture *src = NULL;
SDL_Texture *dst;
SDL_Surface *result;
Uint8 srcR = 10, srcG = 128, srcB = 240, srcA = 100;
Uint8 dstR = 128, dstG = 128, dstB = 128, dstA = 128;
Uint8 expectedR, expectedG, expectedB, expectedA;
Uint8 actualR, actualG, actualB, actualA;
int deltaR, deltaG, deltaB, deltaA;
const char *operation = "UNKNOWN";
const char *mode_name = "UNKNOWN";
/* Clear surface. */
clearScreen();
/* Need alpha or just skip test. */
SDLTest_AssertCheck(hasTexAlpha(), "_hasTexAlpha");
/* Create face surface. */
tface = loadTestFace();
SDLTest_AssertCheck(tface != NULL, "Verify loadTestFace() result");
if (tface == NULL) {
return TEST_ABORTED;
/* Create dst surface */
dst = SDL_CreateTexture(renderer, dst_format, SDL_TEXTUREACCESS_TARGET, 3, 3);
SDLTest_AssertCheck(dst != NULL, "Verify dst surface is not NULL");
if (dst == NULL) {
return;
}
/* Constant values. */
CHECK_FUNC(SDL_GetTextureSize, (tface, &tw, &th))
rect.w = tw;
rect.h = th;
ni = TESTRENDER_SCREEN_W - tw;
nj = TESTRENDER_SCREEN_H - th;
/* Set as render target */
SDL_SetRenderTarget(renderer, dst);
/* Test blitting with alpha mod. */
checkFailCount1 = 0;
checkFailCount2 = 0;
for (j = 0; j <= nj; j += 4) {
for (i = 0; i <= ni; i += 4) {
/* Set alpha mod. */
ret = SDL_SetTextureAlphaMod(tface, (Uint8)((255 / ni) * i));
if (ret != 0) {
checkFailCount1++;
}
/* Clear surface. */
if (!SDL_ISPIXELFORMAT_ALPHA(dst_format)) {
dstA = 255;
}
ret = SDL_SetRenderDrawColor(renderer, dstR, dstG, dstB, dstA);
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetRenderDrawColor(), expected: 0, got: %i", ret);
ret = SDL_RenderClear(renderer);
SDLTest_AssertPass("Call to SDL_RenderClear()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_RenderClear, expected: 0, got: %i", ret);
/* Blitting. */
rect.x = i;
rect.y = j;
ret = SDL_RenderTexture(renderer, tface, NULL, &rect);
if (ret != 0) {
checkFailCount2++;
}
if (op == TEST_RENDER_COPY_XRGB || op == TEST_RENDER_COPY_ARGB) {
Uint8 pixels[4];
/* Create src surface */
src = SDL_CreateTexture(renderer, op == TEST_RENDER_COPY_XRGB ? SDL_PIXELFORMAT_RGBX32 : SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, 1, 1);
SDLTest_AssertCheck(src != NULL, "Verify src surface is not NULL");
if (src == NULL) {
return;
}
/* Clear surface. */
if (op == TEST_RENDER_COPY_XRGB) {
srcA = 255;
}
pixels[0] = srcR;
pixels[1] = srcG;
pixels[2] = srcB;
pixels[3] = srcA;
SDL_UpdateTexture(src, NULL, pixels, sizeof(pixels));
/* Set blend mode. */
if (mode >= 0) {
ret = SDL_SetTextureBlendMode(src, (SDL_BlendMode)mode);
SDLTest_AssertPass("Call to SDL_SetTextureBlendMode()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetTextureBlendMode(..., %i), expected: 0, got: %i", mode, ret);
} else {
ret = SDL_SetTextureBlendMode(src, SDL_BLENDMODE_BLEND);
SDLTest_AssertPass("Call to SDL_SetTextureBlendMode()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetTextureBlendMode(..., %i), expected: 0, got: %i", mode, ret);
}
} else {
/* Set draw color */
ret = SDL_SetRenderDrawColor(renderer, srcR, srcG, srcB, srcA);
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetRenderDrawColor(), expected: 0, got: %i", ret);
/* Set blend mode. */
if (mode >= 0) {
ret = SDL_SetRenderDrawBlendMode(renderer, (SDL_BlendMode)mode);
SDLTest_AssertPass("Call to SDL_SetRenderDrawBlendMode()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetRenderDrawBlendMode(..., %i), expected: 0, got: %i", mode, ret);
} else {
ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDLTest_AssertPass("Call to SDL_SetRenderDrawBlendMode()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetRenderDrawBlendMode(..., %i), expected: 0, got: %i", mode, ret);
}
}
SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureAlphaMod, expected: 0, got: %i", checkFailCount1);
SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderTexture, expected: 0, got: %i", checkFailCount2);
/* See if it's the same. */
referenceSurface = SDLTest_ImageBlitAlpha();
compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
/* Make current */
SDL_RenderPresent(renderer);
/* Clean up. */
SDL_DestroyTexture(tface);
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
return TEST_COMPLETED;
}
/**
* Tests a blend mode.
*
* \sa SDL_SetTextureBlendMode
* \sa SDL_RenderTexture
*/
static void
testBlitBlendMode(SDL_Texture *tface, int mode)
{
int ret;
float tw, th;
float i, j, ni, nj;
SDL_FRect rect;
int checkFailCount1;
int checkFailCount2;
/* Clear surface. */
clearScreen();
/* Constant values. */
CHECK_FUNC(SDL_GetTextureSize, (tface, &tw, &th))
rect.w = tw;
rect.h = th;
ni = TESTRENDER_SCREEN_W - tw;
nj = TESTRENDER_SCREEN_H - th;
/* Test blend mode. */
checkFailCount1 = 0;
checkFailCount2 = 0;
for (j = 0; j <= nj; j += 4) {
for (i = 0; i <= ni; i += 4) {
/* Set blend mode. */
ret = SDL_SetTextureBlendMode(tface, (SDL_BlendMode)mode);
if (ret != 0) {
checkFailCount1++;
}
#define FLOAT(X) ((float)X / 255.0f)
switch (mode) {
case -1:
mode_name = "color modulation";
ret = SDL_SetTextureColorMod(src, srcR, srcG, srcB);
SDLTest_AssertCheck(ret == 0, "Validate results from calls to SDL_SetTextureColorMod, expected: 0, got: %i", ret);
expectedR = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcR) * FLOAT(srcR)) * FLOAT(srcA) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcG) * FLOAT(srcG)) * FLOAT(srcA) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcB) * FLOAT(srcB)) * FLOAT(srcA) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
break;
case -2:
mode_name = "alpha modulation";
ret = SDL_SetTextureAlphaMod(src, srcA);
SDLTest_AssertCheck(ret == 0, "Validate results from calls to SDL_SetTextureAlphaMod, expected: 0, got: %i", ret);
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstR) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstG) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstB) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
expectedA = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstA) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
break;
case SDL_BLENDMODE_NONE:
mode_name = "SDL_BLENDMODE_NONE";
expectedR = srcR;
expectedG = srcG;
expectedB = srcB;
expectedA = SDL_ISPIXELFORMAT_ALPHA(dst_format) ? srcA : 255;
break;
case SDL_BLENDMODE_BLEND:
mode_name = "SDL_BLENDMODE_BLEND";
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(srcA) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(srcA) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(srcA) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
break;
case SDL_BLENDMODE_BLEND_PREMULTIPLIED:
mode_name = "SDL_BLENDMODE_BLEND_PREMULTIPLIED";
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
break;
case SDL_BLENDMODE_ADD:
mode_name = "SDL_BLENDMODE_ADD";
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(srcA) + FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(srcA) + FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(srcA) + FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
expectedA = dstA;
break;
case SDL_BLENDMODE_ADD_PREMULTIPLIED:
mode_name = "SDL_BLENDMODE_ADD_PREMULTIPLIED";
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) + FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) + FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) + FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
expectedA = dstA;
break;
case SDL_BLENDMODE_MOD:
mode_name = "SDL_BLENDMODE_MOD";
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
expectedA = dstA;
break;
case SDL_BLENDMODE_MUL:
mode_name = "SDL_BLENDMODE_MUL";
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(dstR) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(dstG) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(dstB) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedA = dstA;
break;
default:
SDLTest_LogError("Invalid blending mode: %d", mode);
return;
}
/* Blitting. */
rect.x = i;
rect.y = j;
ret = SDL_RenderTexture(renderer, tface, NULL, &rect);
if (ret != 0) {
checkFailCount2++;
switch (op) {
case TEST_RENDER_POINT:
operation = "render point";
ret = SDL_RenderPoint(renderer, 0.0f, 0.0f);
SDLTest_AssertCheck(ret == 0, "Validate results from calls to SDL_RenderPoint, expected: 0, got: %i", ret);
break;
case TEST_RENDER_LINE:
operation = "render line";
ret = SDL_RenderLine(renderer, 0.0f, 0.0f, 2.0f, 2.0f);
SDLTest_AssertCheck(ret == 0, "Validate results from calls to SDL_RenderLine, expected: 0, got: %i", ret);
break;
case TEST_RENDER_RECT:
operation = "render rect";
ret = SDL_RenderFillRect(renderer, NULL);
SDLTest_AssertCheck(ret == 0, "Validate results from calls to SDL_RenderFillRect, expected: 0, got: %i", ret);
break;
case TEST_RENDER_COPY_XRGB:
case TEST_RENDER_COPY_ARGB:
operation = (op == TEST_RENDER_COPY_XRGB) ? "render XRGB" : "render ARGB";
ret = SDL_RenderTexture(renderer, src, NULL, NULL);
SDLTest_AssertCheck(ret == 0, "Validate results from calls to SDL_RenderTexture, expected: 0, got: %i", ret);
break;
default:
SDLTest_LogError("Invalid blending operation: %d", op);
return;
}
result = SDL_RenderReadPixels(renderer, NULL);
SDL_ReadSurfacePixel(result, 0, 0, &actualR, &actualG, &actualB, &actualA);
deltaR = SDL_abs((int)actualR - expectedR);
deltaG = SDL_abs((int)actualG - expectedG);
deltaB = SDL_abs((int)actualB - expectedB);
deltaA = SDL_abs((int)actualA - expectedA);
SDLTest_AssertCheck(
deltaR <= MAXIMUM_ERROR &&
deltaG <= MAXIMUM_ERROR &&
deltaB <= MAXIMUM_ERROR &&
deltaA <= MAXIMUM_ERROR,
"Checking %s %s operation results, expected %d,%d,%d,%d, got %d,%d,%d,%d",
operation, mode_name,
expectedR, expectedG, expectedB, expectedA, actualR, actualG, actualB, actualA);
/* Clean up */
SDL_DestroySurface(result);
SDL_DestroyTexture(src);
SDL_DestroyTexture(dst);
}
static void testBlendMode(int mode)
{
const TestRenderOperation operations[] = {
TEST_RENDER_POINT,
TEST_RENDER_LINE,
TEST_RENDER_RECT,
TEST_RENDER_COPY_XRGB,
TEST_RENDER_COPY_ARGB
};
const SDL_PixelFormat dst_formats[] = {
SDL_PIXELFORMAT_XRGB8888, SDL_PIXELFORMAT_ARGB8888
};
int i, j;
for (i = 0; i < SDL_arraysize(operations); ++i) {
for (j = 0; j < SDL_arraysize(dst_formats); ++j) {
TestRenderOperation op = operations[i];
if (mode < 0) {
if (op != TEST_RENDER_COPY_XRGB && op != TEST_RENDER_COPY_ARGB) {
/* Unsupported mode for this operation */
continue;
}
}
testBlendModeOperation(op, mode, dst_formats[j]);
}
}
SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureBlendMode, expected: 0, got: %i", checkFailCount1);
SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderTexture, expected: 0, got: %i", checkFailCount2);
}
/**
* Tests some more blitting routines.
*
* \sa SDL_SetTextureColorMod
* \sa SDL_SetTextureAlphaMod
* \sa SDL_SetTextureBlendMode
* \sa SDL_DestroyTexture
* Tests render operations with blend modes
*/
static int render_testBlitBlend(void *arg)
static int render_testBlendModes(void *arg)
{
int ret;
SDL_FRect rect;
SDL_Texture *tface;
SDL_Surface *referenceSurface = NULL;
float tw, th;
int i, j, ni, nj;
int mode;
int checkFailCount1;
int checkFailCount2;
int checkFailCount3;
int checkFailCount4;
SDLTest_AssertCheck(hasBlendModes(), "_hasBlendModes");
SDLTest_AssertCheck(hasTexColor(), "_hasTexColor");
SDLTest_AssertCheck(hasTexAlpha(), "_hasTexAlpha");
/* Create face surface. */
tface = loadTestFace();
SDLTest_AssertCheck(tface != NULL, "Verify loadTestFace() result");
if (tface == NULL) {
return TEST_ABORTED;
}
/* Constant values. */
CHECK_FUNC(SDL_GetTextureSize, (tface, &tw, &th))
rect.w = tw;
rect.h = th;
ni = TESTRENDER_SCREEN_W - (int)tw;
nj = TESTRENDER_SCREEN_H - (int)th;
/* Set alpha mod. */
CHECK_FUNC(SDL_SetTextureAlphaMod, (tface, 100))
/* Test None. */
testBlitBlendMode(tface, SDL_BLENDMODE_NONE);
referenceSurface = SDLTest_ImageBlitBlendNone();
/* Compare, then Present */
compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
SDL_RenderPresent(renderer);
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
/* Test Blend. */
testBlitBlendMode(tface, SDL_BLENDMODE_BLEND);
referenceSurface = SDLTest_ImageBlitBlend();
/* Compare, then Present */
compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
SDL_RenderPresent(renderer);
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
/* Test Blend Premultiplied. */
testBlitBlendMode(tface, SDL_BLENDMODE_BLEND_PREMULTIPLIED);
referenceSurface = SDLTest_ImageBlitBlendPremultiplied();
/* Compare, then Present */
compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
SDL_RenderPresent(renderer);
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
/* Test Add. */
testBlitBlendMode(tface, SDL_BLENDMODE_ADD);
referenceSurface = SDLTest_ImageBlitBlendAdd();
/* Compare, then Present */
compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
SDL_RenderPresent(renderer);
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
/* Test Add Premultiplied. */
testBlitBlendMode(tface, SDL_BLENDMODE_ADD_PREMULTIPLIED);
referenceSurface = SDLTest_ImageBlitBlendAddPremultiplied();
/* Compare, then Present */
compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
SDL_RenderPresent(renderer);
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
/* Test Mod. */
testBlitBlendMode(tface, SDL_BLENDMODE_MOD);
referenceSurface = SDLTest_ImageBlitBlendMod();
/* Compare, then Present */
compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
SDL_RenderPresent(renderer);
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
/* Clear surface. */
clearScreen();
/* Loop blit. */
checkFailCount1 = 0;
checkFailCount2 = 0;
checkFailCount3 = 0;
checkFailCount4 = 0;
for (j = 0; j <= nj; j += 4) {
for (i = 0; i <= ni; i += 4) {
/* Set color mod. */
ret = SDL_SetTextureColorMod(tface, (Uint8)((255 / nj) * j), (Uint8)((255 / ni) * i), (Uint8)((255 / nj) * j));
if (ret != 0) {
checkFailCount1++;
}
/* Set alpha mod. */
ret = SDL_SetTextureAlphaMod(tface, (Uint8)((100 / ni) * i));
if (ret != 0) {
checkFailCount2++;
}
/* Crazy blending mode magic. */
mode = (int)(i / 4 * j / 4) % 4;
if (mode == 0) {
mode = SDL_BLENDMODE_NONE;
} else if (mode == 1) {
mode = SDL_BLENDMODE_BLEND;
} else if (mode == 2) {
mode = SDL_BLENDMODE_ADD;
} else if (mode == 3) {
mode = SDL_BLENDMODE_MOD;
}
ret = SDL_SetTextureBlendMode(tface, (SDL_BlendMode)mode);
if (ret != 0) {
checkFailCount3++;
}
/* Blitting. */
rect.x = (float)i;
rect.y = (float)j;
ret = SDL_RenderTexture(renderer, tface, NULL, &rect);
if (ret != 0) {
checkFailCount4++;
}
}
}
SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureColorMod, expected: 0, got: %i", checkFailCount1);
SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetTextureAlphaMod, expected: 0, got: %i", checkFailCount2);
SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_SetTextureBlendMode, expected: 0, got: %i", checkFailCount3);
SDLTest_AssertCheck(checkFailCount4 == 0, "Validate results from calls to SDL_RenderTexture, expected: 0, got: %i", checkFailCount4);
/* Clean up. */
SDL_DestroyTexture(tface);
/* Check to see if final image matches. */
referenceSurface = SDLTest_ImageBlitBlendAll();
compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
/* Make current */
SDL_RenderPresent(renderer);
SDL_DestroySurface(referenceSurface);
referenceSurface = NULL;
testBlendMode(-1);
testBlendMode(-2);
testBlendMode(SDL_BLENDMODE_NONE);
testBlendMode(SDL_BLENDMODE_BLEND);
testBlendMode(SDL_BLENDMODE_BLEND_PREMULTIPLIED);
testBlendMode(SDL_BLENDMODE_ADD);
testBlendMode(SDL_BLENDMODE_ADD_PREMULTIPLIED);
testBlendMode(SDL_BLENDMODE_MOD);
testBlendMode(SDL_BLENDMODE_MUL);
return TEST_COMPLETED;
}
@ -1149,94 +966,6 @@ hasDrawColor(void)
return 1;
}
/**
* Test to see if we can vary the blend mode. Helper function.
*
* \sa SDL_SetRenderDrawBlendMode
* \sa SDL_GetRenderDrawBlendMode
*/
static int
hasBlendModes(void)
{
int fail;
int ret;
SDL_BlendMode mode;
fail = 0;
ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_GetRenderDrawBlendMode(renderer, &mode);
if (!isSupported(ret)) {
fail = 1;
}
ret = (mode != SDL_BLENDMODE_BLEND);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND_PREMULTIPLIED );
if (!isSupported(ret))
fail = 1;
ret = SDL_GetRenderDrawBlendMode(renderer, &mode );
if (!isSupported(ret))
fail = 1;
ret = (mode != SDL_BLENDMODE_BLEND_PREMULTIPLIED);
if (!isSupported(ret))
fail = 1;
ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_GetRenderDrawBlendMode(renderer, &mode);
if (!isSupported(ret)) {
fail = 1;
}
ret = (mode != SDL_BLENDMODE_ADD);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD_PREMULTIPLIED);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_GetRenderDrawBlendMode(renderer, &mode);
if (!isSupported(ret)) {
fail = 1;
}
ret = (mode != SDL_BLENDMODE_ADD_PREMULTIPLIED);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_MOD);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_GetRenderDrawBlendMode(renderer, &mode);
if (!isSupported(ret)) {
fail = 1;
}
ret = (mode != SDL_BLENDMODE_MOD);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_GetRenderDrawBlendMode(renderer, &mode);
if (!isSupported(ret)) {
fail = 1;
}
ret = (mode != SDL_BLENDMODE_NONE);
if (!isSupported(ret)) {
fail = 1;
}
return !fail;
}
/**
* Loads the test image 'Face' as texture. Helper function.
*
@ -1263,92 +992,6 @@ loadTestFace(void)
return tface;
}
/**
* Test to see if can set texture color mode. Helper function.
*
* \sa SDL_SetTextureColorMod
* \sa SDL_GetTextureColorMod
* \sa SDL_DestroyTexture
*/
static int
hasTexColor(void)
{
int fail;
int ret;
SDL_Texture *tface;
Uint8 r, g, b;
/* Get test face. */
tface = loadTestFace();
if (!tface) {
return 0;
}
/* See if supported. */
fail = 0;
ret = SDL_SetTextureColorMod(tface, 100, 100, 100);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_GetTextureColorMod(tface, &r, &g, &b);
if (!isSupported(ret)) {
fail = 1;
}
/* Clean up. */
SDL_DestroyTexture(tface);
if (fail) {
return 0;
} else if ((r != 100) || (g != 100) || (b != 100)) {
return 0;
}
return 1;
}
/**
* Test to see if we can vary the alpha of the texture. Helper function.
*
* \sa SDL_SetTextureAlphaMod
* \sa SDL_GetTextureAlphaMod
* \sa SDL_DestroyTexture
*/
static int
hasTexAlpha(void)
{
int fail;
int ret;
SDL_Texture *tface;
Uint8 a;
/* Get test face. */
tface = loadTestFace();
if (!tface) {
return 0;
}
/* See if supported. */
fail = 0;
ret = SDL_SetTextureAlphaMod(tface, 100);
if (!isSupported(ret)) {
fail = 1;
}
ret = SDL_GetTextureAlphaMod(tface, &a);
if (!isSupported(ret)) {
fail = 1;
}
/* Clean up. */
SDL_DestroyTexture(tface);
if (fail) {
return 0;
} else if (a != 100) {
return 0;
}
return 1;
}
/**
* Compares screen pixels with image pixels. Helper function.
*
@ -1438,42 +1081,31 @@ static const SDLTest_TestCaseReference renderTest2 = {
(SDLTest_TestCaseFp)render_testPrimitives, "render_testPrimitives", "Tests rendering primitives", TEST_ENABLED
};
/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
static const SDLTest_TestCaseReference renderTest3 = {
(SDLTest_TestCaseFp)render_testPrimitivesBlend, "render_testPrimitivesBlend", "Tests rendering primitives with blending", TEST_DISABLED
};
static const SDLTest_TestCaseReference renderTest4 = {
(SDLTest_TestCaseFp)render_testPrimitivesWithViewport, "render_testPrimitivesWithViewport", "Tests rendering primitives within a viewport", TEST_ENABLED
};
static const SDLTest_TestCaseReference renderTest5 = {
static const SDLTest_TestCaseReference renderTest4 = {
(SDLTest_TestCaseFp)render_testBlit, "render_testBlit", "Tests blitting", TEST_ENABLED
};
static const SDLTest_TestCaseReference renderTest6 = {
static const SDLTest_TestCaseReference renderTest5 = {
(SDLTest_TestCaseFp)render_testBlitColor, "render_testBlitColor", "Tests blitting with color", TEST_ENABLED
};
/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
static const SDLTest_TestCaseReference renderTest6 = {
(SDLTest_TestCaseFp)render_testBlendModes, "render_testBlendModes", "Tests rendering blend modes", TEST_ENABLED
};
static const SDLTest_TestCaseReference renderTest7 = {
(SDLTest_TestCaseFp)render_testBlitAlpha, "render_testBlitAlpha", "Tests blitting with alpha", TEST_DISABLED
};
/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
static const SDLTest_TestCaseReference renderTest8 = {
(SDLTest_TestCaseFp)render_testBlitBlend, "render_testBlitBlend", "Tests blitting with blending", TEST_DISABLED
};
static const SDLTest_TestCaseReference renderTest9 = {
(SDLTest_TestCaseFp)render_testViewport, "render_testViewport", "Tests viewport", TEST_ENABLED
};
static const SDLTest_TestCaseReference renderTest10 = {
static const SDLTest_TestCaseReference renderTest8 = {
(SDLTest_TestCaseFp)render_testClipRect, "render_testClipRect", "Tests clip rect", TEST_ENABLED
};
static const SDLTest_TestCaseReference renderTest11 = {
static const SDLTest_TestCaseReference renderTest9 = {
(SDLTest_TestCaseFp)render_testLogicalSize, "render_testLogicalSize", "Tests logical size", TEST_ENABLED
};
@ -1481,7 +1113,7 @@ static const SDLTest_TestCaseReference renderTest11 = {
static const SDLTest_TestCaseReference *renderTests[] = {
&renderTest1, &renderTest2, &renderTest3, &renderTest4,
&renderTest5, &renderTest6, &renderTest7, &renderTest8,
&renderTest9, &renderTest10, &renderTest11, NULL
&renderTest9, NULL
};
/* Render test suite (global) */

View File

@ -69,141 +69,201 @@ static void surfaceTearDown(void *arg)
}
/**
* Helper that clears the test surface
* Helper that blits in a specific blend mode, -1 for color mod, -2 for alpha mod
*/
static void clearTestSurface(void)
static void testBlitBlendModeWithFormats(int mode, SDL_PixelFormat src_format, SDL_PixelFormat dst_format)
{
/* Allow up to 1 delta from theoretical value to account for rounding error */
const int MAXIMUM_ERROR = 1;
int ret;
Uint32 color;
/* Clear surface. */
color = SDL_MapSurfaceRGBA(testSurface, 0, 0, 0, 0);
SDLTest_AssertPass("Call to SDL_MapSurfaceRGBA()");
ret = SDL_FillSurfaceRect(testSurface, NULL, color);
SDLTest_AssertPass("Call to SDL_FillSurfaceRect()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_FillSurfaceRect, expected: 0, got: %i", ret);
}
/**
* Helper that blits in a specific blend mode, -1 for basic blitting, -2 for color mod, -3 for alpha mod, -4 for mixed blend modes.
*/
static void testBlitBlendMode(int mode)
{
int ret;
int i, j, ni, nj;
SDL_Surface *face;
SDL_Rect rect;
int nmode;
SDL_BlendMode bmode;
SDL_Surface *src;
SDL_Surface *dst;
int checkFailCount1;
int checkFailCount2;
int checkFailCount3;
int checkFailCount4;
Uint32 color;
Uint8 srcR = 10, srcG = 128, srcB = 240, srcA = 100;
Uint8 dstR = 128, dstG = 128, dstB = 128, dstA = 128;
Uint8 expectedR, expectedG, expectedB, expectedA;
Uint8 actualR, actualG, actualB, actualA;
int deltaR, deltaG, deltaB, deltaA;
/* Check test surface */
SDLTest_AssertCheck(testSurface != NULL, "Verify testSurface is not NULL");
if (testSurface == NULL) {
/* Create dst surface */
dst = SDL_CreateSurface(1, 1, dst_format);
SDLTest_AssertCheck(dst != NULL, "Verify dst surface is not NULL");
if (dst == NULL) {
return;
}
/* Create sample surface */
face = SDLTest_ImageFace();
SDLTest_AssertCheck(face != NULL, "Verify face surface is not NULL");
if (face == NULL) {
/* Clear surface. */
color = SDL_MapSurfaceRGBA(dst, dstR, dstG, dstB, dstA);
SDLTest_AssertPass("Call to SDL_MapSurfaceRGBA()");
ret = SDL_FillSurfaceRect(dst, NULL, color);
SDLTest_AssertPass("Call to SDL_FillSurfaceRect()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_FillSurfaceRect, expected: 0, got: %i", ret);
SDL_GetRGBA(color, SDL_GetPixelFormatDetails(dst->format), NULL, &dstR, &dstG, &dstB, &dstA);
/* Create src surface */
src = SDL_CreateSurface(1, 1, src_format);
SDLTest_AssertCheck(src != NULL, "Verify src surface is not NULL");
if (src == NULL) {
return;
}
/* Reset alpha modulation */
ret = SDL_SetSurfaceAlphaMod(face, 255);
ret = SDL_SetSurfaceAlphaMod(src, 255);
SDLTest_AssertPass("Call to SDL_SetSurfaceAlphaMod()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceAlphaMod(), expected: 0, got: %i", ret);
/* Reset color modulation */
ret = SDL_SetSurfaceColorMod(face, 255, 255, 255);
ret = SDL_SetSurfaceColorMod(src, 255, 255, 255);
SDLTest_AssertPass("Call to SDL_SetSurfaceColorMod()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceColorMod(), expected: 0, got: %i", ret);
/* Reset color key */
ret = SDL_SetSurfaceColorKey(face, SDL_FALSE, 0);
ret = SDL_SetSurfaceColorKey(src, SDL_FALSE, 0);
SDLTest_AssertPass("Call to SDL_SetSurfaceColorKey()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceColorKey(), expected: 0, got: %i", ret);
/* Clear the test surface */
clearTestSurface();
/* Clear surface. */
color = SDL_MapSurfaceRGBA(src, srcR, srcG, srcB, srcA);
SDLTest_AssertPass("Call to SDL_MapSurfaceRGBA()");
ret = SDL_FillSurfaceRect(src, NULL, color);
SDLTest_AssertPass("Call to SDL_FillSurfaceRect()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_FillSurfaceRect, expected: 0, got: %i", ret);
SDL_GetRGBA(color, SDL_GetPixelFormatDetails(src->format), NULL, &srcR, &srcG, &srcB, &srcA);
/* Target rect size */
rect.w = face->w;
rect.h = face->h;
/* Steps to take */
ni = testSurface->w - face->w;
nj = testSurface->h - face->h;
/* Optionally set blend mode. */
/* Set blend mode. */
if (mode >= 0) {
ret = SDL_SetSurfaceBlendMode(face, (SDL_BlendMode)mode);
ret = SDL_SetSurfaceBlendMode(src, (SDL_BlendMode)mode);
SDLTest_AssertPass("Call to SDL_SetSurfaceBlendMode()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceBlendMode(..., %i), expected: 0, got: %i", mode, ret);
} else {
ret = SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND);
SDLTest_AssertPass("Call to SDL_SetSurfaceBlendMode()");
SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceBlendMode(..., %i), expected: 0, got: %i", mode, ret);
}
/* Test blend mode. */
#define FLOAT(X) ((float)X / 255.0f)
checkFailCount1 = 0;
checkFailCount2 = 0;
checkFailCount3 = 0;
checkFailCount4 = 0;
for (j = 0; j <= nj; j += 4) {
for (i = 0; i <= ni; i += 4) {
if (mode == -2) {
/* Set color mod. */
ret = SDL_SetSurfaceColorMod(face, (Uint8)((255 / nj) * j), (Uint8)((255 / ni) * i), (Uint8)((255 / nj) * j));
if (ret != 0) {
checkFailCount2++;
}
} else if (mode == -3) {
/* Set alpha mod. */
ret = SDL_SetSurfaceAlphaMod(face, (Uint8)((255 / ni) * i));
if (ret != 0) {
checkFailCount3++;
}
} else if (mode == -4) {
/* Crazy blending mode magic. */
nmode = (i / 4 * j / 4) % 4;
if (nmode == 0) {
bmode = SDL_BLENDMODE_NONE;
} else if (nmode == 1) {
bmode = SDL_BLENDMODE_BLEND;
} else if (nmode == 2) {
bmode = SDL_BLENDMODE_ADD;
} else if (nmode == 3) {
bmode = SDL_BLENDMODE_MOD;
} else {
/* Should be impossible, but some static checkers are too imprecise and will complain */
SDLTest_LogError("Invalid: nmode=%d", nmode);
return;
}
ret = SDL_SetSurfaceBlendMode(face, bmode);
if (ret != 0) {
checkFailCount4++;
}
}
/* Blitting. */
rect.x = i;
rect.y = j;
ret = SDL_BlitSurface(face, NULL, testSurface, &rect);
if (ret != 0) {
checkFailCount1++;
}
switch (mode) {
case -1:
/* Set color mod. */
ret = SDL_SetSurfaceColorMod(src, srcR, srcG, srcB);
if (ret != 0) {
checkFailCount2++;
}
expectedR = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcR) * FLOAT(srcR)) * FLOAT(srcA) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcG) * FLOAT(srcG)) * FLOAT(srcA) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcB) * FLOAT(srcB)) * FLOAT(srcA) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
break;
case -2:
/* Set alpha mod. */
ret = SDL_SetSurfaceAlphaMod(src, srcA);
if (ret != 0) {
checkFailCount3++;
}
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstR) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstG) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstB) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
expectedA = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstA) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
break;
case SDL_BLENDMODE_NONE:
expectedR = srcR;
expectedG = srcG;
expectedB = srcB;
expectedA = SDL_ISPIXELFORMAT_ALPHA(dst_format) ? srcA : 255;
break;
case SDL_BLENDMODE_BLEND:
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(srcA) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(srcA) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(srcA) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
break;
case SDL_BLENDMODE_BLEND_PREMULTIPLIED:
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
break;
case SDL_BLENDMODE_ADD:
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(srcA) + FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(srcA) + FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(srcA) + FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
expectedA = dstA;
break;
case SDL_BLENDMODE_ADD_PREMULTIPLIED:
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) + FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) + FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) + FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
expectedA = dstA;
break;
case SDL_BLENDMODE_MOD:
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
expectedA = dstA;
break;
case SDL_BLENDMODE_MUL:
expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(dstR) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(dstG) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(dstB) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
expectedA = dstA;
break;
default:
SDLTest_LogError("Invalid blending mode: %d", mode);
return;
}
/* Blitting. */
ret = SDL_BlitSurface(src, NULL, dst, NULL);
if (ret != 0) {
checkFailCount1++;
}
SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_BlitSurface, expected: 0, got: %i", checkFailCount1);
SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetSurfaceColorMod, expected: 0, got: %i", checkFailCount2);
SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_SetSurfaceAlphaMod, expected: 0, got: %i", checkFailCount3);
SDLTest_AssertCheck(checkFailCount4 == 0, "Validate results from calls to SDL_SetSurfaceBlendMode, expected: 0, got: %i", checkFailCount4);
SDL_ReadSurfacePixel(dst, 0, 0, &actualR, &actualG, &actualB, &actualA);
deltaR = SDL_abs((int)actualR - expectedR);
deltaG = SDL_abs((int)actualG - expectedG);
deltaB = SDL_abs((int)actualB - expectedB);
deltaA = SDL_abs((int)actualA - expectedA);
SDLTest_AssertCheck(
deltaR <= MAXIMUM_ERROR &&
deltaG <= MAXIMUM_ERROR &&
deltaB <= MAXIMUM_ERROR &&
deltaA <= MAXIMUM_ERROR,
"Checking %s -> %s blit results, expected %d,%d,%d,%d, got %d,%d,%d,%d",
SDL_GetPixelFormatName(src_format),
SDL_GetPixelFormatName(dst_format),
expectedR, expectedG, expectedB, expectedA, actualR, actualG, actualB, actualA);
/* Clean up */
SDL_DestroySurface(face);
face = NULL;
SDL_DestroySurface(src);
SDL_DestroySurface(dst);
}
static void testBlitBlendMode(int mode)
{
const SDL_PixelFormat src_formats[] = {
SDL_PIXELFORMAT_XRGB8888, SDL_PIXELFORMAT_ARGB8888
};
const SDL_PixelFormat dst_formats[] = {
SDL_PIXELFORMAT_XRGB8888, SDL_PIXELFORMAT_ARGB8888
};
int i, j;
for (i = 0; i < SDL_arraysize(src_formats); ++i) {
for (j = 0; j < SDL_arraysize(dst_formats); ++j) {
testBlitBlendModeWithFormats(mode, src_formats[i], dst_formats[j]);
}
}
}
/* Helper to check that a file exists */
@ -418,19 +478,8 @@ static int surface_testLoadFailure(void *arg)
*/
static int surface_testBlit(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Basic blitting */
testBlitBlendMode(-1);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlit();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
testBlitBlendMode(SDL_BLENDMODE_NONE);
return TEST_COMPLETED;
}
@ -440,19 +489,8 @@ static int surface_testBlit(void *arg)
*/
static int surface_testBlitColorMod(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Basic blitting with color mod */
testBlitBlendMode(-2);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitColor();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
testBlitBlendMode(-1);
return TEST_COMPLETED;
}
@ -462,41 +500,8 @@ static int surface_testBlitColorMod(void *arg)
*/
static int surface_testBlitAlphaMod(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Basic blitting with alpha mod */
testBlitBlendMode(-3);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitAlpha();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
return TEST_COMPLETED;
}
/**
* Tests some more blitting routines.
*/
static int surface_testBlitBlendNone(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Basic blitting */
testBlitBlendMode(SDL_BLENDMODE_NONE);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitBlendNone();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
testBlitBlendMode(-2);
return TEST_COMPLETED;
}
@ -506,20 +511,9 @@ static int surface_testBlitBlendNone(void *arg)
*/
static int surface_testBlitBlendBlend(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Blend blitting */
testBlitBlendMode(SDL_BLENDMODE_BLEND);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitBlend();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
return TEST_COMPLETED;
}
@ -528,20 +522,9 @@ static int surface_testBlitBlendBlend(void *arg)
*/
static int surface_testBlitBlendPremultiplied(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Blend premultiplied blitting */
testBlitBlendMode(SDL_BLENDMODE_BLEND_PREMULTIPLIED);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitBlendPremultiplied();
ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 );
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
return TEST_COMPLETED;
}
@ -550,20 +533,9 @@ static int surface_testBlitBlendPremultiplied(void *arg)
*/
static int surface_testBlitBlendAdd(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Add blitting */
testBlitBlendMode(SDL_BLENDMODE_ADD);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitBlendAdd();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
return TEST_COMPLETED;
}
@ -572,20 +544,9 @@ static int surface_testBlitBlendAdd(void *arg)
*/
static int surface_testBlitBlendAddPremultiplied(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Add blitting */
/* Add premultiplied blitting */
testBlitBlendMode(SDL_BLENDMODE_ADD_PREMULTIPLIED);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitBlendAddPremultiplied();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
return TEST_COMPLETED;
}
@ -594,42 +555,19 @@ static int surface_testBlitBlendAddPremultiplied(void *arg)
*/
static int surface_testBlitBlendMod(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* Mod blitting */
testBlitBlendMode(SDL_BLENDMODE_MOD);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitBlendMod();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
return TEST_COMPLETED;
}
/**
* Tests some more blitting routines with loop
* Tests some more blitting routines.
*/
static int surface_testBlitBlendLoop(void *arg)
static int surface_testBlitBlendMul(void *arg)
{
int ret;
SDL_Surface *compareSurface;
/* All blitting modes */
testBlitBlendMode(-4);
/* Verify result by comparing surfaces */
compareSurface = SDLTest_ImageBlitBlendAll();
ret = SDLTest_CompareSurfaces(testSurface, compareSurface, 0);
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
/* Clean up. */
SDL_DestroySurface(compareSurface);
/* Mod blitting */
testBlitBlendMode(SDL_BLENDMODE_MUL);
return TEST_COMPLETED;
}
@ -967,58 +905,49 @@ static const SDLTest_TestCaseReference surfaceTest2 = {
};
static const SDLTest_TestCaseReference surfaceTest3 = {
(SDLTest_TestCaseFp)surface_testBlitBlendNone, "surface_testBlitBlendNone", "Tests blitting routines with none blending mode.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTest4 = {
(SDLTest_TestCaseFp)surface_testLoadFailure, "surface_testLoadFailure", "Tests sprite loading. A failure case.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTest5 = {
static const SDLTest_TestCaseReference surfaceTest4 = {
(SDLTest_TestCaseFp)surface_testSurfaceConversion, "surface_testSurfaceConversion", "Tests surface conversion.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTest6 = {
static const SDLTest_TestCaseReference surfaceTest5 = {
(SDLTest_TestCaseFp)surface_testCompleteSurfaceConversion, "surface_testCompleteSurfaceConversion", "Tests surface conversion across all pixel formats", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTest7 = {
static const SDLTest_TestCaseReference surfaceTest6 = {
(SDLTest_TestCaseFp)surface_testBlitColorMod, "surface_testBlitColorMod", "Tests some blitting routines with color mod.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTest8 = {
static const SDLTest_TestCaseReference surfaceTest7 = {
(SDLTest_TestCaseFp)surface_testBlitAlphaMod, "surface_testBlitAlphaMod", "Tests some blitting routines with alpha mod.", TEST_ENABLED
};
/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
static const SDLTest_TestCaseReference surfaceTest8 = {
(SDLTest_TestCaseFp)surface_testBlitBlendBlend, "surface_testBlitBlendBlend", "Tests blitting routines with blend blending mode.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTest9 = {
(SDLTest_TestCaseFp)surface_testBlitBlendLoop, "surface_testBlitBlendLoop", "Test blitting routines with various blending modes", TEST_DISABLED
(SDLTest_TestCaseFp)surface_testBlitBlendPremultiplied, "surface_testBlitBlendPremultiplied", "Tests blitting routines with premultiplied blending mode.", TEST_ENABLED
};
/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
static const SDLTest_TestCaseReference surfaceTest10 = {
(SDLTest_TestCaseFp)surface_testBlitBlendBlend, "surface_testBlitBlendBlend", "Tests blitting routines with blend blending mode.", TEST_DISABLED
(SDLTest_TestCaseFp)surface_testBlitBlendAdd, "surface_testBlitBlendAdd", "Tests blitting routines with add blending mode.", TEST_ENABLED
};
/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
static const SDLTest_TestCaseReference surfaceTest11 = {
(SDLTest_TestCaseFp)surface_testBlitBlendPremultiplied, "surface_testBlitBlendPremultiplied", "Tests blitting routines with premultiplied blending mode.", TEST_DISABLED
(SDLTest_TestCaseFp)surface_testBlitBlendAddPremultiplied, "surface_testBlitBlendAddPremultiplied", "Tests blitting routines with premultiplied add blending mode.", TEST_ENABLED
};
/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
static const SDLTest_TestCaseReference surfaceTest12 = {
(SDLTest_TestCaseFp)surface_testBlitBlendAdd, "surface_testBlitBlendAdd", "Tests blitting routines with add blending mode.", TEST_DISABLED
};
/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
static const SDLTest_TestCaseReference surfaceTest13 = {
(SDLTest_TestCaseFp)surface_testBlitBlendAddPremultiplied, "surface_testBlitBlendAddPremultiplied", "Tests blitting routines with premultiplied add blending mode.", TEST_DISABLED
};
static const SDLTest_TestCaseReference surfaceTest14 = {
(SDLTest_TestCaseFp)surface_testBlitBlendMod, "surface_testBlitBlendMod", "Tests blitting routines with mod blending mode.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTest13 = {
(SDLTest_TestCaseFp)surface_testBlitBlendMul, "surface_testBlitBlendMul", "Tests blitting routines with mul blending mode.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTestOverflow = {
surface_testOverflow, "surface_testOverflow", "Test overflow detection.", TEST_ENABLED
};
@ -1035,7 +964,7 @@ static const SDLTest_TestCaseReference surfaceTestPalette = {
static const SDLTest_TestCaseReference *surfaceTests[] = {
&surfaceTest1, &surfaceTest2, &surfaceTest3, &surfaceTest4, &surfaceTest5,
&surfaceTest6, &surfaceTest7, &surfaceTest8, &surfaceTest9, &surfaceTest10,
&surfaceTest11, &surfaceTest12, &surfaceTest13, &surfaceTest14,
&surfaceTest11, &surfaceTest12, &surfaceTest13,
&surfaceTestOverflow, &surfaceTestFlip, &surfaceTestPalette, NULL
};