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 1016

Summary: SDL_BlitSurface - multithread SW to SW surface crashes
Product: SDL Reporter: Mervin <muckmeck>
Component: videoAssignee: Sam Lantinga <slouken>
Status: RESOLVED WONTFIX QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: 1.2.14   
Hardware: x86_64   
OS: Windows (XP)   

Description Mervin 2010-07-02 11:01:43 UTC
When blitting from a software surface to another software surface without the screen surface involved using multiple threads to increase the speed, something goes wrong and the program always crashes. The debugger trace only shows "??".
When blitting to the screen surface it always works (there seems to be some locking mechanism), but slows down with more threads.

After some tests I located the problem. In my code each thread has an own target surface, later combined on the screen surface, but the source surface is shared. There was no crash when I made a separate copy of the source surface for each thread to use. Creating copies of all source surfaces is a bad workaround, actually a waste of memory and speed.

Normally one would think: "No problem, the source surface is only read from". But actually it seems that SDL_BlitSurface modifies internal struct members of the source.


//following simplified thread code crashes

int nthreads = 4; //number of threads, I use a 4 core CPU
SDL_Surface *src; //source such as image data, loaded somewhere

//there are "nthreads" threads running this function the same time
int threadfunc(){

 SDL_Surface *dst = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h / nthreads, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);

 //loop maybe important, with only 1 blit the crash didn't trigger
 for(int i = 0; i < 1000; i++) {
   SDL_BlitSurface(src, NULL, dst, NULL);
 }

 //... //write dst to screen

 SDL_FreeSurface(dst);

 return 0;
}
Comment 1 Sam Lantinga 2011-12-29 01:22:20 UTC
This isn't a supported use case, sorry!