We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 4761

Summary: Alpha blended blitting behaves inconsistently with and without MMX
Product: SDL Reporter: Kichikuou <KichikuouChrome>
Component: videoAssignee: Sam Lantinga <slouken>
Status: NEW --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: 2.0.10   
Hardware: x86   
OS: All   

Description Kichikuou 2019-08-12 05:50:10 UTC
main.c:
----
#include <SDL.h>

int main(void) {
  SDL_Surface *src, *dst;
  src = SDL_CreateRGBSurfaceWithFormat(0, 16, 16, 32, SDL_PIXELFORMAT_RGBA32);
  dst = SDL_CreateRGBSurfaceWithFormat(0, 16, 16, 32, SDL_PIXELFORMAT_RGBA32);

  SDL_FillRect(src, NULL, SDL_MapRGBA(src->format, 255, 255, 0, 128));
  SDL_FillRect(dst, NULL, SDL_MapRGBA(dst->format, 255, 255, 255, 0));
  SDL_BlitSurface(src, NULL, dst, NULL);

  Uint8 r, g, b;
  SDL_GetRGB(*(Uint32*)dst->pixels, dst->format, &r, &g, &b);
  printf("(%d, %d, %d)\n", r, g, b);
}
----

This program prints (253, 253, 126) on my MacOS where BlitRGBtoRGBPixelAlphaMMX3DNOW() is used for blitting, but prints (255, 255, 127) on a Raspberry Pi where non-accelerated BlitRGBtoRGBPixelAlpha() is used.

In BlitRGBtoRGBPixelAlphaMMX3DNOW(), the resulting pixel value is calculated as:

 (s*a >> 8) + (d*(255-a) >> 8)

where s is the source's RGB component value, a is the source's alpha value, and d is the destination's RGB component value. In BlitRGBtoRGBPixelAlpha(), a different calculation is used:

 d + ((s-d)*a >> 8)

IMO BlitRGBtoRGBPixelAlpha's behavior is more desirable because it preserves the total signal level.