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 3096

Summary: Unexpected behaviour SDL_BlitSurface when using overlapping source and destination
Product: SDL Reporter: Andreas Löf <andreas>
Component: videoAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: amit.jain83, icculus, kratz00, shadowm
Version: 2.0.3   
Hardware: x86_64   
OS: Linux   
Attachments: The current behavior
image rendered
program illustrating the bug
screenshot showing the correct behaviour
Updated program illustrating the bug
Proposed bugfix.

Description Andreas Löf 2015-08-15 10:12:15 UTC
Created attachment 2242 [details]
The current behavior

I'm using SDL_Blitsurface to move parts of my existing surface down so I can fill the top with new data.

Expected behaviour:
The data contained in the source is successfully blitted into the destination.

Actual behaviour:
The destination is filled with the difference between source and original.

This bug appears to only occur when both source and destination is the same SDL_Surface.

I am attaching a small program to illustrate the problem as well as a screenshot of the current behaviour.
Comment 1 Andreas Löf 2015-08-15 10:13:26 UTC
Created attachment 2243 [details]
image rendered
Comment 2 Andreas Löf 2015-08-15 10:13:53 UTC
Created attachment 2244 [details]
program illustrating the bug
Comment 3 Amit Jain 2015-11-09 08:42:25 UTC
Hello
What is your expected output for this test program ?

Thanks
Amit
Comment 4 Andreas Löf 2015-12-02 08:56:04 UTC
I've attached a modified version of the demo program that provide an #ifdef. If it's compiled with -DWORKING it'll provide the non-broken output and if it's omitted it'll provide the broken output.

The relevant change (I also fixed a bug that has no impact on the output):

#ifdef WORKING
   copy = SDL_ConvertSurface(SDL_GetWindowSurface(win),
			    SDL_GetWindowSurface(win)->format,
			    0);
  SDL_BlitSurface(copy, &src, SDL_GetWindowSurface(win), &dst);
#else
  int r = SDL_BlitSurface(SDL_GetWindowSurface(win), &src, SDL_GetWindowSurface(win), &dst);
  if (r) {
    printf("Blitting failed!\n");
  }
#endif

Blitting with the same source and destination surface causes the pixels to be repeated, whereas the expected output is to not have the same set of pixels repeated. I'll attach a new screenshot demonstrating the non-broken behaviour
Comment 5 Andreas Löf 2015-12-02 08:57:21 UTC
Created attachment 2318 [details]
screenshot showing the correct behaviour

Screenshot showing the expected result
Comment 6 Andreas Löf 2015-12-02 09:01:38 UTC
Created attachment 2319 [details]
Updated program illustrating the bug

For broken behaviour, compile with:
gcc main2.c -lSDL2 -lSDL2_image

For correct behaviour:
gcc main2.c -DWORKING -lSDL2 -lSDL2_image

The version that exhibits the correct version takes a copy of the source surface instead of using the same source and destination surfaces
Comment 7 Steffen Pankratz 2016-10-10 17:29:45 UTC
Created attachment 2581 [details]
Proposed bugfix.

This bug is still present in version 2.0.4.
This patch fixes the issue, at least it does for me :)
Comment 8 Ryan C. Gordon 2016-10-11 16:10:03 UTC
(In reply to Steffen Pankratz from comment #7)
> Created attachment 2581 [details]
> Proposed bugfix.
> 
> This bug is still present in version 2.0.4.
> This patch fixes the issue, at least it does for me :)

This patch is now https://hg.libsdl.org/SDL/rev/f548233b2813, thanks!

--ryan.