| Summary: | SDL_BlitSurface on Mac has rendering problems | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Ryan Bannon <mrbannon> |
| Component: | video | Assignee: | Ryan C. Gordon <icculus> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | ||
| Version: | 1.2.11 | ||
| Hardware: | PowerPC | ||
| OS: | Mac OS X 10.3 (PPC) | ||
The bug is in Blit32to32SurfaceAlphaAltivec() in src/video/SDL_blit_A.c ... it uses a different, correct blitter when the alpha is set to zero (which is why it jumps at the end of the fade for one frame). If I have SDL report there's no Altivec unit, it falls into a very slow but correct alpha-blending blitter and the problem goes away...but this leaves tons of performance on the table. The problem is that we didn't handle data alignment correctly, pushing everything over by a few pixels. Fixed in svn revision #2955 for the 1.2 branch, and #2956 for the 1.3 branch. Thanks for the bug report! --ryan. |
The following code causes two renderings of backgrounds and shifts one 4-5 pixels to the right if alpha blending. #include <SDL/SDL.h> #include <SDL_image/SDL_image.h> int main(int argc, char*argv[]) { // Initialize SDL with the given driverName. SDL_Init(SDL_INIT_VIDEO); SDL_putenv("SDL_VIDEODRIVER=Quartz"); // Create surfaces. SDL_Surface* pSurfaceOne = IMG_Load("/1.jpg"); SDL_Surface *pSurfaceTwo = IMG_Load("/2.jpg"); // Convert surfaces. SDL_Surface* pConversionSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 1, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); SDL_Surface* pSurfaceOneConverted = SDL_ConvertSurface(pSurfaceOne, pConversionSurface->format, SDL_SWSURFACE); SDL_Surface* pSurfaceTwoConverted = SDL_ConvertSurface(pSurfaceTwo, pConversionSurface->format, SDL_SWSURFACE); // Create window and display surface. SDL_Surface* pDisplaySurface = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE); // Display int alpha = 0; while(true) { // Set alpha. alpha += 10; if(alpha > 255) { alpha = 0; SDL_Surface* temp = pSurfaceOneConverted; pSurfaceOneConverted = pSurfaceTwoConverted; pSurfaceTwoConverted = temp; } // Apply to surfaces and blit. pSurfaceOneConverted->format->Amask = 0; pSurfaceTwoConverted->format->Amask = 0; SDL_SetAlpha(pSurfaceTwoConverted, SDL_SRCALPHA, 255 - alpha); SDL_BlitSurface(pSurfaceTwoConverted, NULL, pDisplaySurface, NULL); SDL_SetAlpha(pSurfaceOneConverted, SDL_SRCALPHA, alpha); SDL_BlitSurface(pSurfaceOneConverted, NULL, pDisplaySurface, NULL); // Update the surface. SDL_Flip(pDisplaySurface); } return 0; } The assets are 800x600 jpegs. The problem happens with the surface conversion code.