libsdl-org / sdl12-compat

An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes.
Other
197 stars 40 forks source link

Awesomenauts (Steam, free-to-play): black window, no titlebar or borders #168

Closed smcv closed 2 years ago

smcv commented 2 years ago

Expected result: normal gameplay

Actual result: a black window with no titlebar or borders (but the game is running and sounds still play)

slouken commented 2 years ago

Ryan, can you take a look at this?

icculus commented 2 years ago

Checking now, but I assume it's going to be a framebuffer object issue, and disabling OpenGL scaling will fix it. One moment.

smcv commented 2 years ago

I should have mentioned that I'm testing under GNOME in X11 mode, in case it matters.

Setting the Steam launch options to SDL12COMPAT_OPENGL_SCALING=0 %command% changes the result to: instead of a black window, I get a window whose contents are a snapshot of what was underneath the window at the time it was launched (in my case, that's the Steam UI). I can only tell where it is because GNOME draws a drop-shadow around it. I can move it around with Windows key + left-click + drag, like any other non-fullscreen window in GNOME.

icculus commented 2 years ago

So the titlebar/border issue is that Awesomenauts is calling SDL_SetVideoMode(width of desktop, height of desktop, 32, SDL_NOFRAME)...what we might call "borderless fullscreen" (or whatever) in some games, but lots of X11 desktop environments will likely clamp this window (on my Ubuntu 21.10 system, Gnome is refusing to hide the Dock on the left hand side of the screen in this case with sdl12-compat).

Should we detect this and create the SDL2 window with SDL_WINDOW_FULLSCREEN_DESKTOP...? It seems like an obvious thing to do that likely has some non-obvious corner cases.

Still checking into the black screen issue.

slouken commented 2 years ago

Should we detect this and create the SDL2 window with SDL_WINDOW_FULLSCREEN_DESKTOP...? It seems like an obvious thing to do that likely has some non-obvious corner cases.

That seems like the intent of the application and a reasonable thing to do...

icculus commented 2 years ago

Adding that (and a switch to turn it off, if it makes something misbehave, like we do for GL scaling).

smcv commented 2 years ago

I'm using vanilla GNOME on this particular test system (no dock, just a vaguely Mac-like top bar), and games that go into "borderless fullscreen" are usually genuinely full-screen here (they end up "in front of" the top bar). My screen is 1920x1080.

I had Awesomenauts set to 1024x768 borderless fullscreen (sorry, I don't remember whether that was the default or something I did deliberately). With sdl12-compat, the result was a 1024x768 borderless window. With "real" SDL 1.2, the result was fullscreen, but the game's graphics were only drawn into the top left 1024x768 region, with the rest of the screen black.

I tried reconfiguring Awesomenauts to be 1920x1080 borderless fullscreen while using "real" SDL 1.2, and that worked correctly when restarted. On swapping back to sdl12-compat, the result was that it fills almost the whole screen (everything except the top bar), but with the same broken window contents that I had before: plain black with no special workarounds, or a snapshot of the previous screen contents with SDL12COMPAT_OPENGL_SCALING=0.

icculus commented 2 years ago

Side note: the game appears to be statically linked to libGLEW and makes glX calls directly (specifically: glxGetProcAddress) which will fail on Wayland if SDL doesn't use its x11 backend to talk to XWayland.

Eventually we might want to have some sort of basic detection of specific games (if the binary is called "dynamitejack-bin", turn off GL scaling by default, if it's called "Awesomenauts.bin.x86," force SDL_VIDEODRIVER to "x11", etc).

icculus commented 2 years ago

@smcv the commit I just pushed fixes the "borderless fullscreen windowed" thing to just give the game access to the whole display, but I'm still working on the rendering issue.

sulix commented 2 years ago

The bug here seems to be that the game is calling SDL_GL_SwapBuffers() from a different thread, where the GL context isn't current. (Indeed, Awesomenauts seems to directly call glXMakeCurrent() a lot, though exactly how I'm not sure.

Hackily adding in a call to SDL_GL_EnableContext_Thread() fixes it here, though due to Cg being a pain in the rear, OpenGL scaling does need to be disabled.

I'm not 100% sure why this works on SDL 1.2, to be honest, but it does seem to.

icculus commented 2 years ago

Good catch, this was driving me nuts. :)

I have no idea why this would work for classic 1.2, but I'll figure that out today and resolve this bug.

smcv commented 2 years ago

Since Awesomenauts seems to need multiple quirks (force X11; disable OpenGL scaling; OpenGL vs. threads), it might make a good example use-case for a quirks mechanism, either in sdl12-compat itself or in Steam or both.

sulix commented 2 years ago

I experimented a little bit with a quirks mechanism here: https://github.com/sulix/sdl12-compat/commit/51005a8497f26dd66ae4d0c7e09f7f6f0c8bb039

The actual code is super-ugly, but serves as a proof-of-concept at least. And Awesomenauts does appear to work with it, despite the fix being hacky.

Thoughts?

slouken commented 2 years ago

I'm actually totally okay with this. :)

It seems reasonable to put the hacks directly into sdl12-compat since that guarantees they'll work wherever the library is deployed. I don't think we need executable hash, etc., since presumably we're talking about old applications that will never be updated.

Feel free to clean this up (and remove the #warning) and submit a PR.

DanielGibson commented 2 years ago

since presumably we're talking about old applications that will never be updated.

and if they are, they'll hopefully finally port to SDL2 ;)

icculus commented 2 years ago

It's going to drive me nuts as to why the background thread gets a valid GL context in 1.2 but not sdl12-compat, though.

For completeness, this appears to be the calls to glXMakeCurrent:

SDL_SetVideoMode ends
Resolution of actual screen:  1920  1080
unbindGLFromCallingThread starts, threadID:  4121836800

Thread 1 "Awesomenauts.bi" hit Breakpoint 1, 0xf7f7b660 in glXMakeCurrent () from /home/icculus/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so
#0  0xf7f7b660 in glXMakeCurrent () from /home/icculus/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so
#1  0x08443731 in ?? ()
[...]

Outside of SDL_SetVideoMode() (and the idTech 4 extension functions), 1.2 never sets a context current anywhere, so it's not clear to me why this works on 1.2 but not 12-compat.

It's worth noting that glXMakeCurrent is hooked by the Steam overlay, too, but I can't see how it would be interfering here, at least in the case of 1.2 vs 12-compat.

ThecaTTony commented 2 years ago

Thanks for working in this problem, until fixed, I will preload libSDL-1.2 to play:

LD_PRELOAD="$HOME/.local/share/Steam/ubuntu12_32/steam-runtime/usr/lib/i386-linux-gnu/libSDL-1.2.so.0" %command%

Edit: Testing the latest commit (r568.9403529-1) compiled from AUR, the game works as expected, even the steam overlay (this was broken using LD_PRELOAD). The only side effect I see its the compositor (kwin) being disabled when the game start, but remains enabled if restarted manually.

icculus commented 2 years ago

This can be closed; we fixed the issue, even though the mystery of how this worked in classic 1.2 remains unsolved...but it's not that important that we understand that, I think.

icculus commented 2 years ago

Reopening this because it's still broken on my desktop machine. Going to research this more.

icculus commented 2 years ago

Okay, it's broken on the laptop I originally verified this fixed on, too, using the revision that fixed it. :/

The debug info dumped to stdio has this:

OpenGL GL_VENDOR  
OpenGL GL_RENDERER  
OpenGL GL_VERSION  
OpenGL GL_EXTENSIONS  

Which, with classic SDL 1.2, lists the contents of these glGetString calls, so I'm assuming we don't have a current GL context when this call is made in sdl12-compat, which causes several other things to break, too.

Is it possible something changed in the Steam overlay that we didn't realize we were relying on? I'll keep researching.

icculus commented 2 years ago

Okay, so here's where we are:

So with sdl12-compat, it's creating a GL context in SDL_SetVideoMode, as usual, and then the game itself calls glXMakeCurrent() from the main thread to make no context current. (the (void *) 0x0 printouts are me asking gdb to print ((void **) $esp)[1] and ((void **) $esp)[2] when hitting the breakpoint, which would be the two arguments to the function).

unbindGLFromCallingThread starts, threadID:  4130539840

Thread 1 "Awesomenauts.bi" hit Breakpoint 1, 0xf7f15380 in glXMakeCurrent () from /lib/i386-linux-gnu/libGL.so.1
$26 = (void *) 0x0
$27 = (void *) 0x0

Then it switches to thread 11 and tries to make it current...

bindGLToCallingThread starts, threadID:  3591371456
[Switching to Thread 0xd60ffac0 (LWP 1599040)]

Thread 11 "Awesomenauts.bi" hit Breakpoint 1, 0xf7f78660 in glXMakeCurrent () from /home/icculus/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so
$30 = (void *) 0x0
$31 = (void *) 0x0

...but it's still NULL.

Notably, here's classic SDL 1.2:

unbindGLFromCallingThread starts, threadID:  4123503872

Thread 1 "Awesomenauts.bi" hit Breakpoint 1, 0xf7f78660 in glXMakeCurrent () from /home/icculus/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so
$14 = (void *) 0x9c15b00
$15 = (void *) 0x0

It has a drawable when unbinding in the main thread, sdl12-compat did not.

And it has a context and drawable when the background thread rebinds it:

bindGLToCallingThread starts, threadID:  3590322880

Thread 10 "Awesomenauts.bi" hit Breakpoint 1, 0xf7f78660 in glXMakeCurrent () from /home/icculus/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so
$20 = (void *) 0x9c15b00
$21 = (void *) 0x4c00015

Which makes me guess that it failed to query the drawable with sdl12-compat, which caused it to fail to query the context, and everything went pear-shaped at that point. Still not sure what changed to cause this.

icculus commented 2 years ago

Our original assertion is incorrect that Awesomenauts tries to swapbuffers without a current context; while it does move between threads at startup for init, loading, and rendering, it does have a current context whenever it uses OpenGL with SDL 1.2, which is why would could never figure out how this was able to work...it wasn't doing what we thought it was.

(with sdl12-compat, it's doing this, but that's because it's failing to discover the context for whatever reason.)

We can probably dump the SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT quirk from Awesomenauts, and remove the ForceGLSwapBufferContext code generally.

icculus commented 2 years ago

Okay, so here's this problem:

tl;dr: another victim of the version scheme change. :/

Once I forced the version to 2.0.14, it worked (and then I still needed the quirk, so that goes back to being a mystery, I guess). Pushing a fix to sdl12-compat in a moment.

icculus commented 2 years ago

This also needs fe3810fda122599b6227fb18002627326f6da69b, or the quirks won't be applied unless debug logging is enabled, due to a piece of code being in the wrong scope.

smcv commented 2 years ago

The SDL2 in the Steam Runtime doesn't have this patch yet: https://github.com/libsdl-org/SDL/commit/412ceb84d4b8daf05c020feafc3a391a46814854#diff-4d617e5c2011238b8ec8564c68b8a4bf491d9500c1cfc2d2660ceaa39d56c4f7

A future version of the scout Steam Runtime will get that change when it updates to 2.24.0.

Workaround: Use the "Steam Linux Runtime" compat tool, together with the Steam Linux Runtime - soldier public beta.

Other workaround: If you're on a rolling-release OS that has SDL 2.24 installed system-wide, make sure you have the version corresponding to the game's word size, and don't use the "Steam Linux Runtime" compat tool.

smcv commented 2 years ago

The SDL2 in the Steam Runtime doesn't have this patch yet

Before 2.23.0 that change would have been unnecessary (because the version number was 2.0.x), and after 2.24.0 it's included. Does this mean you're using a version of sdl12-compat that was compiled against SDL2 >= 2.23, and then running that against the older SDL2 in the Steam Runtime? In general that sort of downgrade can't be guaranteed to work.

icculus commented 2 years ago

Yes, sdl12-compat was built with my system-installed SDL2 headers (built from sources by me from git, not a package), then when running against Awesomenauts, it used the Steam Runtime's SDL2.

It's a corner case but I think the workaround I committed should deal with it for everyone acceptably, and eventually it goes away as SDL2 builds (Steam runtime or otherwise) get upgraded.

(This was a bunch of work to track down, but I think the reason this was revisited at all was people seeing a black screen on Awesomenauts again...and that was probably more about the quirks fix I applied, as they likely aren't in my particular corner case.)

AngryPhantom commented 1 year ago

I confirm strange screen resolution behavior with OpenArena. My config is:

seta r_customwidth "1680"
seta r_customheight "1050"
seta r_fullscreen "1"
seta r_mode "-1"

And it appears not fullscreen and a bit laggy or something.

P.S. Oh, sorry it's closed already. A bit different issue. Seems I've posted in the wrong place. Should I open a new bug report?

sezero commented 1 year ago

P.S. Oh, sorry it's closed already. A bit different issue. Seems I've posted in the wrong place. Should I open a new bug report?

Yes please