sdl2_frt/src
Sam Lantinga e589cdba2f Fixed bug 3023 - setting a white and then non-white texture color mod breaks the texture with software renderer
Adam M.

Okay, here is the problem, I think.

During the first blit, RLEAlphaSurface is called to do RLE conversion of the RGBA source into a format allowing it "to be quickly alpha-blittable onto dest". Since the destination is the screen, it has no alpha channel. RLEAlphaSurface calls copy_opaque(dst, src + runstart, len, sf, df) (where copy_opaque is copy_32), which has this code:

SDL_RLEaccel.c:984:
  RGBA_FROM_8888(*src, sfmt, r, g, b, a);
  PIXEL_FROM_RGBA(*d, dfmt, r, g, b, a);

On the first line, it reads the source pixel 0xFFFFFFFF. The second line drops the alpha value (because dfmt for the screen has no alpha channel) and writes 0x00FFFFFF. Later, when the RLE conversion is being undone, uncopy_32 is called, which has the following code:

SDL_RLEaccel.c:1001:
  Uint32 pixel = *s++;
  RGB_FROM_PIXEL(pixel, sfmt, r, g, b);
  a = pixel >> 24;
  PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a);

However, the the alpha channel has already been dropped by copy_opaque (= copy_32), so pixel = 0x00FFFFFF and 'a' becomes 0. Thus, all opaque pixels lose their alpha channel when being unRLE'd. (I don't know what happens to pixels with alpha from 1-254, but they should be checked too.)

So, that seems to be the problem, but I'm not sure what the solution should be. Since opaque pixels have alpha == 255, I'm thinking to create another uncopy function for opaque pixels that simply uses 255 for alpha.

However, there may be other problems here. For translucent pixels, uncopy_32 assumes the alpha channel is stored in the upper 8 bits, but copy_32 doesn't store it there. Instead, it stores it in whatever location is appropriate for the destination surface. Isn't one of their behaviors incorrect, given the other? I'm not sure which to change, however.

For translucent pixels, it seems that the blit function uses do_blend, which is the BLIT_TRANSL_888 macro, which also assumes alpha is in top 8 bits. It has the comment "we have made sure the alpha is stored in the top 8 bits...", but it seems that's not true (copy_32 doesn't make sure the alpha goes there).

Perhaps the correct fix is to make copy_32 put the alpha there, but then that seems to require that RLE conversion be limited to destination surfaces that don't use the upper 8 bits. However, looking further, it seems that has already been done: if (masksum != 0x00ffffff) return -1; /* requires unused high byte */
2015-06-19 23:12:13 -07:00
..
atomic Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
audio AIX: Fixed nearly impossible file descriptor leak. 2015-06-04 17:52:51 +02:00
core Make some string literals "const char *", not "char *" (thanks, Martin!). 2015-06-12 11:58:31 -04:00
cpuinfo Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
dynapi Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
events Fixed crash if allocation for touch device failed. 2015-06-12 21:10:31 +02:00
file Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
filesystem Windows SDL_GetBasePath: free string on failure. 2015-05-28 15:36:27 -04:00
haptic Haptic/Linux: Keep track of device numbers properly to track duplicates. 2015-06-16 00:57:45 -04:00
joystick Fixed bug 2948 - [Android] Arrow keys from external keyboard are not received 2015-06-17 00:00:53 -07:00
libm Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
loadso Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
main Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
power Linux: Implemented sysfs-based version of SDL_GetPowerInfo(). 2015-06-03 13:11:28 -07:00
render [mq]: 3027_rleperf.diff 2015-06-19 22:12:47 -07:00
stdlib Let's assume that if VS2005 and VS2010 do it, VS2008 probably does, too. 2015-06-07 20:00:20 -04:00
test Some setups need _GNU_SOURCE to make LLONG_MAX available (thanks, Ozkan!). 2015-05-26 16:31:11 -04:00
thread Android: Fixed two warnings. 2015-06-17 21:05:25 +02:00
timer Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
video Fixed bug 3023 - setting a white and then non-white texture color mod breaks the texture with software renderer 2015-06-19 23:12:13 -07:00
SDL_assert_c.h Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
SDL_assert.c Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
SDL_error_c.h Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
SDL_error.c Fixed bug 2210 - Initializing Video produces unnecessary errors 2015-05-28 12:31:25 -07:00
SDL_hints.c Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
SDL_internal.h Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
SDL_log.c Updated the copyright year to 2015 2015-05-26 06:27:46 -07:00
SDL.c Stack hint should look for 0, not -1, and not care about environment variables. 2015-05-26 21:19:23 -04:00