Fixed bug 4188 - Software renderer SDL_RenderCopyEx blits corrupt image under certain cases

Sylvain

Re-opening this issue.

It fixes the test-case, but it introduces a regression with another bug (bug #4313).

So here's a new patch that activate cropping of the source surface to solve the issue.
It also reverts the wrong changeset.
It prevents unneeded colorkey error message.
This commit is contained in:
Sam Lantinga 2018-10-30 07:00:03 -07:00
parent 950f39e23b
commit da56cefa8b
2 changed files with 21 additions and 11 deletions

View File

@ -657,6 +657,11 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
blitRequired = SDL_TRUE; blitRequired = SDL_TRUE;
} }
/* srcrect is not selecting the whole src surface, so cropping is needed */
if (!(srcrect->w == src->w && srcrect->h == src->h && srcrect->x == 0 && srcrect->y == 0)) {
blitRequired = SDL_TRUE;
}
/* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */ /* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */
if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) { if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) {
applyModulation = SDL_TRUE; applyModulation = SDL_TRUE;

View File

@ -83,7 +83,9 @@ static Uint32
_colorkey(SDL_Surface *src) _colorkey(SDL_Surface *src)
{ {
Uint32 key = 0; Uint32 key = 0;
if (SDL_HasColorKey(src)) {
SDL_GetColorKey(src, &key); SDL_GetColorKey(src, &key);
}
return key; return key;
} }
@ -150,17 +152,17 @@ SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle,
/* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */ /* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */
static void static void
computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy, computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy,
int *sincx, int *sincy, int *signx, int *signy, SDL_Surface *dst) int *sincx, int *sincy, int *signx, int *signy)
{ {
int pitch = flipy ? -src->pitch : src->pitch; int pitch = flipy ? -src->pitch : src->pitch;
if (flipx) { if (flipx) {
bpp = -bpp; bpp = -bpp;
} }
switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
case 0: *sincx = bpp; *sincy = pitch - dst->w * *sincx; *signx = *signy = 1; break; case 0: *sincx = bpp; *sincy = pitch - src->w * *sincx; *signx = *signy = 1; break;
case 1: *sincx = -pitch; *sincy = bpp - *sincx * dst->h; *signx = 1; *signy = -1; break; case 1: *sincx = -pitch; *sincy = bpp - *sincx * src->h; *signx = 1; *signy = -1; break;
case 2: *sincx = -bpp; *sincy = -dst->w * *sincx - pitch; *signx = *signy = -1; break; case 2: *sincx = -bpp; *sincy = -src->w * *sincx - pitch; *signx = *signy = -1; break;
case 3: default: *sincx = pitch; *sincy = -*sincx * dst->h - bpp; *signx = -1; *signy = 1; break; case 3: default: *sincx = pitch; *sincy = -*sincx * src->h - bpp; *signx = -1; *signy = 1; break;
} }
if (flipx) { if (flipx) {
*signx = -*signx; *signx = -*signx;
@ -175,9 +177,10 @@ computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int
int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy; \ int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy; \
Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de; \ Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de; \
\ \
computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy, dst); \ computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy); \
if (signx < 0) sp += (dst->w-1)*sizeof(pixelType); \ if (signx < 0) sp += (src->w-1)*sizeof(pixelType); \
if (signy < 0) sp += (dst->h-1)*src->pitch; \ if (signy < 0) sp += (src->h-1)*src->pitch; \
\
for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \ for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \
if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */ \ if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */ \
SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \ SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \
@ -423,9 +426,11 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
if (src == NULL) if (src == NULL)
return NULL; return NULL;
if (SDL_HasColorKey(src)) {
if (SDL_GetColorKey(src, &colorkey) == 0) { if (SDL_GetColorKey(src, &colorkey) == 0) {
colorKeyAvailable = SDL_TRUE; colorKeyAvailable = SDL_TRUE;
} }
}
/* This function requires a 32-bit surface or 8-bit surface with a colorkey */ /* This function requires a 32-bit surface or 8-bit surface with a colorkey */
is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable; is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable;