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 3619

Summary: SDL_RenderReadPixels result is unspecified and fails testautomation
Product: SDL Reporter: beuc
Component: videoAssignee: Ryan C. Gordon <icculus>
Status: ASSIGNED --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: 2.0.5   
Hardware: x86_64   
OS: Linux   
Attachments: testautomation output
Proof of concept

Description beuc 2017-03-27 11:42:33 UTC
Created attachment 2708 [details]
testautomation output

I went back to a SDL2 project of mine (GNU FreeDink) which I hadn't worked on since 9/2015, and saw new issues with my testsuite.
It seems that SDL_RenderReadPixels now returns a previous state of the screen.

This breaks the SDL2 test suite as well:
  $ ./testautomation --seed 69HAAANC9H8J3A22 --filter render_testBlit
  => tests fails
  => CompareSurfaces0001_TestOutput.bmp is black
That test passes with SDL 2.0.3 but fails with SDL 2.0.5 and SDL HG.

It is possible that something changed in the GNU/Linux graphics stack, as I get the same buggy behavior in my project testsuite + SDL 2.0.3 (even if SDL 2.0.3's own test suite passes - possibly the test case was improved since then).

I tested my project with:
- Debian GNU/Linux Stretch (testing) 64-bit: fails with software and OpenGL renderers
- Windows XP: fails with OpenGL renderer (may be related to #3044)
Comment 1 beuc 2017-03-27 13:54:26 UTC
Precisions:
- Windows XP with displayed window: OK
- Windows XP with *SDL_WINDOW_HIDDEN*: fails with OpenGL renderer
  the read pixels are sometimes current, sometimes from a previous state;
  also the image is *horizontally* (left/right) flipped
Comment 2 beuc 2017-03-29 10:19:44 UTC
The issue seems related to a missing glReadBuffer(GL_FRONT) call, to explicitely specify the front buffer.
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glReadBuffer.xml

Precisions:

- in my game's software mode, I use SDL_RenderReadPixels and the renderer selected by SDL2 is 'opengl'.  I couldn't find any use of glReadBuffer in SDL2's renderers.

- in my game's OpenGL mode, I actually use glReadPixels directly so any error there was mine.  I didn't specify glReadBuffer() either and that wasn't necessary last year, so I guess the default changed in either my new graphic card or my new Debian system -- which is probably why there's the same issue in SDL2's opengl renderer.
Comment 3 beuc 2017-03-29 21:19:36 UTC
Created attachment 2710 [details]
Proof of concept
Comment 4 beuc 2017-03-29 21:40:05 UTC
The attach patch / proof-of-concept makes (only) the 'opengl' renderer read pixels from the frontbuffer rather than the backbuffer.


What is SDL_RenderReadPixels supposed behavior? Front or back?


Points of discussion:

- The issue is undetected when backbuffer is copied to frontbuffer.
If backbuffer and frontbuffer are swapped instead, the issue appears.
E.g. I can check for that issue on my Intel desktop card but not my android.

- Reading from the backbuffer is the default for double buffered GL mode - hence SDL2's empirical default.
However the current SDL2 test suite expects to read from the frontbuffer since: 
https://hg.libsdl.org/SDL/rev/6c469ea796e4 (30 Nov 2014)

- Reading from the backbuffer means the result is unspecified after a SDL_RenderPresent.
Reading from the frontbuffer means one cannot read pixels until a SDL_RenderPresent.

- GLES2 doesn't have glReadBuffer. It's supposed to read from the frame buffer, which isn't clear.
https://www.khronos.org/registry/OpenGL-Refpages/es2.0/


Depending on what SDL_RenderReadPixels is supposed to do, I can adapt my testsuite and check in the matching buffer, but this needs to be documented.