libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.71k stars 1.8k forks source link

Window freezed with testshape example #8624

Closed serpilliere closed 1 week ago

serpilliere commented 10 months ago

Hi! Due to #6654 I tried using the testshape example.

I have tested the example of the main branch, and it seems there is something weird:

On the SDL2 branch, the testshape.c is ok using the trollface_32alpha.bmp (given in the SDL2 branch) shape_sdl2

But with the main branch, it seems the code 'freezes' in the SDL_RenderPresent function. (using the same picture) shape_sdl3

I tested this on Ubuntu 20.04 LTS with x11 server Note that others examples seems to be ok, even the OpenGL examples and draw examples.

Am I missing something?

serpilliere commented 10 months ago

Here is a backtrace from gdb: The SDL_GL_SwapWindow_REAL calls the X11_GL_SwapWindow which seems to lock at certain point in X11_GetDisplayModes

What surprises me is that the example testgl also calls SDL_GL_SwapWindow but this function doesn't lock in this case.

#0  futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x55eaf292ae98)
    at ../sysdeps/nptl/futex-internal.h:183
#1  __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x55eaf292c220, cond=0x55eaf292ae70) at pthread_cond_wait.c:508
#2  __pthread_cond_wait (cond=0x55eaf292ae70, mutex=0x55eaf292c220) at pthread_cond_wait.c:647
#3  0x00007f323d628fc2 in _XReply () from /lib/x86_64-linux-gnu/libX11.so.6
#4  0x00007f323d34b75b in ?? () from /lib/x86_64-linux-gnu/libXrandr.so.2
#5  0x00007f323df5a505 in X11_GetDisplayModes () from /home/ubuntu/SDL-build/libSDL3.so.0
#6  0x00007f323debec2b in SDL_GetCurrentDisplayMode_REAL () from /home/ubuntu/SDL-build/libSDL3.so.0
#7  0x00007f323df6084b in X11_SafetyNetErrHandler () from /home/ubuntu/SDL-build/libSDL3.so.0
#8  0x00007f323d62b28b in _XError () from /lib/x86_64-linux-gnu/libX11.so.6
#9  0x00007f323d627ff7 in ?? () from /lib/x86_64-linux-gnu/libX11.so.6
#10 0x00007f323d628095 in ?? () from /lib/x86_64-linux-gnu/libX11.so.6
#11 0x00007f323d62901d in _XReply () from /lib/x86_64-linux-gnu/libX11.so.6
#12 0x00007f323d6247f1 in XSync () from /lib/x86_64-linux-gnu/libX11.so.6
#13 0x00007f323cb7e5f4 in ?? () from /lib/x86_64-linux-gnu/libGLX_mesa.so.0
#14 0x00007f323aec4858 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#15 0x00007f323b5b9017 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#16 0x00007f323aec4961 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#17 0x00007f323cb7d4b4 in ?? () from /lib/x86_64-linux-gnu/libGLX_mesa.so.0
#18 0x00007f323df5ecc9 in X11_GL_SwapWindow () from /home/ubuntu/SDL-build/libSDL3.so.0
#19 0x00007f323dec6860 in SDL_GL_SwapWindow_REAL () from /home/ubuntu/SDL-build/libSDL3.so.0
#20 0x00007f323ddfa05a in GL_RenderPresent () from /home/ubuntu/SDL-build/libSDL3.so.0
#21 0x00007f323ddf3634 in SDL_RenderPresent_REAL () from /home/ubuntu/SDL-build/libSDL3.so.0
#22 0x00007f323ddb6405 in SDL_RenderPresent () from /home/ubuntu/SDL-build/libSDL3.so.0
slouken commented 10 months ago

It seems odd that we'd call SDL_GetCurrentDisplayMode() from an error handler, @icculus, can you take a look?

serpilliere commented 10 months ago

Oh, maybe my explanation is bad: That's not an error handler, I attached gdb on the stalled processus (which is locked is sub functions of SDL_GL_SawpWindow) So this is the stack trace of the living (stalled) process. Not a stack trace from a segfault.

serpilliere commented 10 months ago

Hum, ok: you mean X11_SafetyNetErrHandler.

icculus commented 10 months ago

It seems odd that we'd call SDL_GetCurrentDisplayMode() from an error handler, @icculus, can you take a look?

We call it because we're trying to reset the display mode to the original desktop size if the system is going down in flames.

We could call less X11 stuff here (like, set a flag if we actually changed the mode, to know whether there's a mess to clean up in the first place), but honestly it's probably not safe to call into Xlib at all once we hit this code, so we should probably not try to do this at all now.

(Also, do we need this in an XRandR world? This might have been to protect against XVidMode. Maybe if we change the resolution with XRandR and crash, the system knows to restore the previous resolution?)

(Also, fwiw, I don't trigger an Xlib error on this test case, so this might be a driver/hardware thing with the new SDL3 transparency code.)

icculus commented 10 months ago

Also, do we need this in an XRandR world?

We do:

#include <SDL3/SDL.h>

int main(int argc, char **argv)
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow("Hello SDL", 1280, 720, SDL_WINDOW_FULLSCREEN);
    SDL_SetWindowFullscreenMode(window, SDL_GetClosestFullscreenDisplayMode(SDL_GetPrimaryDisplay(), 1280, 720, 0.0f, SDL_FALSE));
    SDL_Event e;
    while (1) { while (SDL_PollEvent(&e)) {} }
    SDL_Quit();
    return 0;
}

Let this run and kill -9 it, and the lower resolution sticks.

Maybe there's a window manager protocol or something to say "this resolution change is associated with this window, when it goes away, go back to normal size" in modern times?

WerWolv commented 1 month ago

Hey, is there any real solution for this yet? I'm trying to write an App with SDL3 and I'm running into a complete lockup whenever I'm calling SDL_GL_SwapWindow on X11. On Windows and macOS everything runs great.

icculus commented 1 week ago

Duplicate of #7975, we'll handle this over there.