Fixed bug 4188 - Software renderer SDL_RenderCopyEx blits corrupt image under certain cases
authorSam Lantinga <slouken@libsdl.org>
Tue, 30 Oct 2018 07:00:03 -0700
changeset 12372bced4041fcc0
parent 12371 41b93d8303d6
child 12373 8feb5da6f2fb
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.
src/render/software/SDL_render_sw.c
src/render/software/SDL_rotate.c
     1.1 --- a/src/render/software/SDL_render_sw.c	Mon Oct 29 19:58:59 2018 -0700
     1.2 +++ b/src/render/software/SDL_render_sw.c	Tue Oct 30 07:00:03 2018 -0700
     1.3 @@ -657,6 +657,11 @@
     1.4          blitRequired = SDL_TRUE;
     1.5      }
     1.6  
     1.7 +    /* srcrect is not selecting the whole src surface, so cropping is needed */
     1.8 +    if (!(srcrect->w == src->w && srcrect->h == src->h && srcrect->x == 0 && srcrect->y == 0)) {
     1.9 +        blitRequired = SDL_TRUE;
    1.10 +    }
    1.11 +
    1.12      /* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */
    1.13      if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) {
    1.14          applyModulation = SDL_TRUE;
     2.1 --- a/src/render/software/SDL_rotate.c	Mon Oct 29 19:58:59 2018 -0700
     2.2 +++ b/src/render/software/SDL_rotate.c	Tue Oct 30 07:00:03 2018 -0700
     2.3 @@ -83,7 +83,9 @@
     2.4  _colorkey(SDL_Surface *src)
     2.5  {
     2.6      Uint32 key = 0;
     2.7 -    SDL_GetColorKey(src, &key);
     2.8 +    if (SDL_HasColorKey(src)) {
     2.9 +        SDL_GetColorKey(src, &key);
    2.10 +    }
    2.11      return key;
    2.12  }
    2.13  
    2.14 @@ -150,17 +152,17 @@
    2.15  /* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */
    2.16  static void
    2.17  computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy,
    2.18 -                          int *sincx, int *sincy, int *signx, int *signy, SDL_Surface *dst)
    2.19 +                          int *sincx, int *sincy, int *signx, int *signy)
    2.20  {
    2.21      int pitch = flipy ? -src->pitch : src->pitch;
    2.22      if (flipx) {
    2.23          bpp = -bpp;
    2.24      }
    2.25      switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
    2.26 -    case 0: *sincx = bpp; *sincy = pitch - dst->w * *sincx; *signx = *signy = 1; break;
    2.27 -    case 1: *sincx = -pitch; *sincy = bpp - *sincx * dst->h; *signx = 1; *signy = -1; break;
    2.28 -    case 2: *sincx = -bpp; *sincy = -dst->w * *sincx - pitch; *signx = *signy = -1; break;
    2.29 -    case 3: default: *sincx = pitch; *sincy = -*sincx * dst->h - bpp; *signx = -1; *signy = 1; break;
    2.30 +    case 0: *sincx = bpp; *sincy = pitch - src->w * *sincx; *signx = *signy = 1; break;
    2.31 +    case 1: *sincx = -pitch; *sincy = bpp - *sincx * src->h; *signx = 1; *signy = -1; break;
    2.32 +    case 2: *sincx = -bpp; *sincy = -src->w * *sincx - pitch; *signx = *signy = -1; break;
    2.33 +    case 3: default: *sincx = pitch; *sincy = -*sincx * src->h - bpp; *signx = -1; *signy = 1; break;
    2.34      }
    2.35      if (flipx) {
    2.36          *signx = -*signx;
    2.37 @@ -175,9 +177,10 @@
    2.38      int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy;                      \
    2.39      Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de;                                        \
    2.40                                                                                                              \
    2.41 -    computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy, dst); \
    2.42 -    if (signx < 0) sp += (dst->w-1)*sizeof(pixelType);                                                      \
    2.43 -    if (signy < 0) sp += (dst->h-1)*src->pitch;                                                             \
    2.44 +    computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy); \
    2.45 +    if (signx < 0) sp += (src->w-1)*sizeof(pixelType);                                                      \
    2.46 +    if (signy < 0) sp += (src->h-1)*src->pitch;                                                             \
    2.47 +                                                                                                            \
    2.48      for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) {                                             \
    2.49          if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */               \
    2.50              SDL_memcpy(dp, sp, dst->w*sizeof(pixelType));                                                   \
    2.51 @@ -423,8 +426,10 @@
    2.52      if (src == NULL)
    2.53          return NULL;
    2.54  
    2.55 -    if (SDL_GetColorKey(src, &colorkey) == 0) {
    2.56 -        colorKeyAvailable = SDL_TRUE;
    2.57 +    if (SDL_HasColorKey(src)) {
    2.58 +        if (SDL_GetColorKey(src, &colorkey) == 0) {
    2.59 +            colorKeyAvailable = SDL_TRUE;
    2.60 +        }
    2.61      }
    2.62  
    2.63      /* This function requires a 32-bit surface or 8-bit surface with a colorkey */