I'm getting wayland x11 jams ChatGPT sanoi: Wayland + X11 jams—sounds like you're experiencing performance or rendering stalls when running an X11 app under Wayland, maybe through XWayland? Could you give me some more details about the problem? What exactly do you mean by "jams"? (e.g. frame freezes, input lag, tearing, crashes) Which application or stack are you running? (SDL, OpenGL, Vulkan, a game engine, custom software?) What GPU and driver are you using? Do the jams happen only under Wayland or also under native X11 sessions? What compositor are you running under Wayland? (e.g. GNOME Mutter, Sway, KDE KWin) Common causes for jams or stalls with XWayland include: Syncing issues with vsync and buffer swaps Input event delays or grab issues Driver or compositor bugs related to XWayland Overloading CPU or GPU with high workload + inefficient buffer swapping Some quick troubleshooting tips: Try running your app directly on native Wayland if possible (no XWayland) to isolate the problem. Check if disabling or enabling vsync helps. For OpenGL apps, environment variables like __GL_SYNC_TO_VBLANK or compositor vsync settings matter. Try switching to a different compositor or running a barebones one (e.g. Weston) to see if compositor interaction causes jams. Monitor system load (top or htop) while jams happen to see if CPU or GPU max out. Run with debug or verbose logs for your app, driver, or compositor. If you want, I can help you craft environment variables or debug steps to dig deeper. What does your current environment look like? Sinä sanoit: it's using sdl2 with opengl_es hint in sdl2. ChatGPT sanoi: Got it — SDL2 with the OpenGL ES hint, running under Wayland with XWayland fallback (or maybe native Wayland)? SDL2 + OpenGL ES + Wayland can be tricky sometimes. Here’s a checklist and some tips tailored for your setup: 1. Confirm SDL2 Video Driver and Backend Make sure SDL2 is actually using the Wayland backend if you want native Wayland, or X11 if using XWayland. You can force it with environment variables: For native Wayland: bash Kopioi Muokkaa SDL_VIDEODRIVER=wayland For X11: bash Kopioi Muokkaa SDL_VIDEODRIVER=x11 You can check SDL2 video backend at runtime with: c Kopioi Muokkaa printf("SDL Video Driver: %s\n", SDL_GetVideoDriver(0)); 2. Set the OpenGL ES Hint Properly SDL2 requires the hint to be set before creating the window/context: c Kopioi Muokkaa SDL_SetHint(SDL_HINT_OPENGL_ES_DRIVER, "1"); Also consider: c Kopioi Muokkaa SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2"); Or explicitly request the GLES context with: c Kopioi Muokkaa SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); 3. Disable or Enable VSync — Test Both Try toggling vsync to see if it affects the jams: c Kopioi Muokkaa SDL_GL_SetSwapInterval(1); // Enable vsync // or SDL_GL_SetSwapInterval(0); // Disable vsync 4. Wayland Compositor vsync Wayland compositors usually handle vsync themselves, and XWayland may cause double buffering sync issues. Some compositors like GNOME Mutter or KDE KWin are known to handle this well. Try testing on a simpler compositor like Weston or Sway. 5. Use SDL Event Loop Properly Ensure your event loop calls SDL_PollEvent regularly, even during waiting/delays. Avoid blocking calls without event polling — this can cause input or redraw stalls. 6. Debugging Run with WAYLAND_DEBUG=1 environment variable to see Wayland protocol logs. Run with SDL_VIDEODRIVER=wayland and WAYLAND_DEBUG=1 to check for protocol errors. 7. Check Driver and GPU Confirm you’re using a modern, stable Mesa or proprietary driver supporting GLES and Wayland properly. Some older drivers have bugs causing stalls in buffer swaps. Summary: Make sure SDL2 is using the intended video backend. Set GLES hints before window creation. Test with vsync on/off. Poll events constantly. Try different compositors or native Wayland to isolate problem. If you want, share your minimal SDL2 init code snippet and I can review it for best practice with GLES + Wayland. Also, what GPU and Linux distro + driver version are you using? That helps narrow down driver bugs. Sinä sanoit: what's the text string of SDL_HINT_RENDER_DRIVER ChatGPT sanoi: The SDL hint string for setting the render driver is: nginx Kopioi Muokkaa SDL_HINT_RENDER_DRIVER You use it like this in code: c Kopioi Muokkaa SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2"); // to request the OpenGL ES 2.0 renderer Or any of these typical values: "opengl" — for OpenGL "opengles2" — for OpenGL ES 2 "software" — for software renderer "direct3d" — for Direct3D (Windows) "metal" — for Metal (macOS) If you want SDL2 to use the OpenGL ES renderer, "opengles2" is the usual string to try. If you want, I can help with a snippet setting it properly before window/context creation. Sinä sanoit: I mean what string is behind the label? ChatGPT sanoi: Ah, you want the actual string literal value behind the macro SDL_HINT_RENDER_DRIVER in SDL2. The string behind SDL_HINT_RENDER_DRIVER is: arduino Kopioi Muokkaa "SDL_RENDER_DRIVER" So the macro: c Kopioi Muokkaa #define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER" If you look inside SDL2’s SDL_hints.h (or related headers), SDL_HINT_RENDER_DRIVER is defined exactly as "SDL_RENDER_DRIVER". You can confirm this by printing: c Kopioi Muokkaa printf("%s\n", SDL_HINT_RENDER_DRIVER); which will output: nginx Kopioi Muokkaa SDL_RENDER_DRIVER If you want me to check or explain any other SDL hint strings, just ask! Sinä sanoit: what other hint strings are available? ChatGPT sanoi: SDL2 has quite a few predefined hint strings to tweak its behavior. Here are some common ones you might find useful, with their literal string values: Macro Name String Value Description SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER" Preferred render driver (e.g., "opengl", "opengles2") SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR" Controls compositor bypass on X11 (0 or 1) SDL_HINT_VIDEO_ALLOW_SCREENSAVER "SDL_VIDEO_ALLOW_SCREENSAVER" Allow the screensaver while SDL app is running SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" Minimize window when focus is lost (1 = yes) SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK" Treat accelerometer input as joystick input SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" Grab keyboard input exclusively SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" Which D3D shader compiler to use on Windows SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP" Use mouse warp instead of hardware relative mode SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" Enable or disable vsync in render driver SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY" Set texture filtering mode ("0"=nearest, "1"=linear, "2"=anisotropic) SDL_HINT_VIDEO_WIN_DPI_AWARENESS "SDL_VIDEO_WIN_DPI_AWARENESS" DPI awareness level for Windows (e.g. "system") SDL_HINT_VIDEO_ALLOW_RENDER_DRIVER "SDL_VIDEO_ALLOW_RENDER_DRIVER" Allow/disallow specific render drivers SDL_HINT_AUDIO_RESAMPLING_MODE "SDL_AUDIO_RESAMPLING_MODE" Quality level for audio resampling How to find more hints? The full list is in the SDL2 source header SDL_hints.h. Also in the SDL wiki hints page. You can print all hints in your environment by looking at SDL source or manually tracking. If you want, I can list more or explain any specific hint! Sinä sanoit: why is it always jamming after moving focus to another window? ChatGPT sanoi: Jams or freezes after losing or switching window focus in an SDL2 + OpenGL ES app under Wayland (or XWayland) can stem from several common issues: Possible causes: Event loop blocking / missing event polling If your main loop stops polling events (SDL_PollEvent) when the window loses focus or is backgrounded, the compositor or SDL might not receive necessary messages, causing the app to stall. Incorrect handling of SDL_WINDOWEVENT_FOCUS_LOST / FOCUS_GAINED Some apps pause rendering or processing on focus loss but don’t resume properly on focus gain. Swap interval (vsync) issues Vsync-related stalls often surface after focus change if the driver or compositor doesn’t reset vsync sync properly. SDL_GL context issues after focus switch Sometimes the OpenGL context can get into an invalid or lost state if the app doesn’t handle context loss properly. Wayland compositor interaction quirks Under Wayland, compositor policy can pause or throttle background apps’ rendering to save resources, and some compositors handle XWayland differently, leading to stalls. Driver or Mesa bugs GPU drivers (especially with XWayland + GLES) sometimes have bugs causing hangs when window focus changes. What to check and try: Always poll SDL events continuously, even if app is minimized or unfocused. Handle these events explicitly and carefully: c Kopioi Muokkaa case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { // Optionally pause updates but keep polling events } else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { // Resume updates or redraw } break; Avoid blocking calls like sleep or wait loops when unfocused, or make sure event polling continues. Try toggling vsync on/off with SDL_GL_SetSwapInterval() to see if it affects the issue. Test the app on native Wayland (SDL_VIDEODRIVER=wayland) vs X11 (SDL_VIDEODRIVER=x11) to isolate if it’s an XWayland problem. Run with compositor debug logs (WAYLAND_DEBUG=1) or check system logs for GPU errors. Make sure your OpenGL context is valid and no GL errors appear after focus changes. Try a minimal test app with just an event loop and simple GL clear+swap to see if focus jams happen there. If you want, share your main event loop and SDL_GL context setup snippet — I can look for potential problems in handling focus or events. Also GPU model, driver version, and compositor used could help nail down the issue. Sinä sanoit: what numbers are behind labels SDL_WINDOWEVENT_FOCUS_LOST and SDL_WINDOWEVENT_FOCUS_GAINED ChatGPT sanoi: The numeric values behind the SDL window event labels are: SDL_WINDOWEVENT_FOCUS_GAINED = 7 SDL_WINDOWEVENT_FOCUS_LOST = 8 These constants are defined in SDL_events.h inside the SDL2 source code as enum values, for example: c Kopioi Muokkaa typedef enum { SDL_WINDOWEVENT_NONE, SDL_WINDOWEVENT_SHOWN, SDL_WINDOWEVENT_HIDDEN, SDL_WINDOWEVENT_EXPOSED, SDL_WINDOWEVENT_MOVED, SDL_WINDOWEVENT_RESIZED, SDL_WINDOWEVENT_SIZE_CHANGED, SDL_WINDOWEVENT_MINIMIZED, SDL_WINDOWEVENT_MAXIMIZED, SDL_WINDOWEVENT_RESTORED, SDL_WINDOWEVENT_ENTER, SDL_WINDOWEVENT_LEAVE, SDL_WINDOWEVENT_FOCUS_GAINED = 7, SDL_WINDOWEVENT_FOCUS_LOST = 8, ... } SDL_WindowEventID; (Actually, in the SDL source, FOCUS_GAINED and FOCUS_LOST are 7 and 8, respectively.) So when you check the event.window.event value in the SDL event loop: c Kopioi Muokkaa if (event.window.event == 7) { /* Focus gained */ } if (event.window.event == 8) { /* Focus lost */ } But it's best to use the named constants for clarity. If you want, I can help you write a snippet that handles these events explicitly! Sinä sanoit: I'm getting jam at #0 __syscall_cancel_arch () at ../sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S:56 #1 0x00007ffff5a9eae3 in __internal_syscall_cancel (a1=a1@entry=93824997743616, a2=, a3=a3@entry=32, a4=a4@entry=0, a5=a5@entry=0, a6=a6@entry=4294967295, nr=202) at ./nptl/cancellation.c:49 #2 0x00007ffff5a9f237 in __futex_abstimed_wait_common64 (private=0, futex_word=0x555555a95c00, expected=32, op=393, abstime=0x0, cancel=true) at ./nptl/futex-internal.c:57 #3 __futex_abstimed_wait_common (futex_word=0x555555a95c00, expected=32, clockid=0, abstime=0x0, private=0, cancel=true) at ./nptl/futex-internal.c:87 #4 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x555555a95c00, expected=expected@entry=7352, clockid=clockid@entry=0, abstime=abstime@entry=0x0, private=private@entry=0) at ./nptl/futex-internal.c:139 #5 0x00007ffff5aa1b17 in __pthread_cond_wait_common (cond=, mutex=0x555555a95bb0, clockid=0, abstime=0x0) at ./nptl/pthread_cond_wait.c:426 #6 ___pthread_cond_wait (cond=, mutex=0x555555a95bb0) at ./nptl/pthread_cond_wait.c:458 #7 0x00007ffff6d3284b in task_implementation::join_id (this=0x7ffff7e2f440 , id=3011) at GameApi_dep_env.cc:278 --Type for more, q to quit, c to continue without paging-- #8 0x00007ffff6d31e62 in tasks_join (id=3011) at GameApi_dep_env.cc:95 #9 0x00007ffff6e2c836 in SpriteTexture::GenTexture (this=0x7fffffffc350, num=0) at Graph.cc:1136 #10 0x00007ffff6d5dedd in ArrayRender::UpdateTexture (this=0x55555b40f920, tex=..., num=0) at GameApi_dep_arr_render.cc:243 #11 0x00007ffff6e2ca1f in TexturePrepare (s=..., rend=..., progress=true) at Graph.cc:1191 #12 0x00007ffff6f34a56 in GameApi::SpriteApi::create_vertex_array (this=0x7fffffffd290, bm=..., progress=true) at GameApi_sp.cc:721 #13 0x00007ffff6f33a5b in RenderVertexArray4::execute (this=0x55556dddddf0, e=...) at GameApi_sp.cc:550 #14 0x00007ffff6f316c9 in TurnTo2d::execute (this=0x55555b028d90, e=...) at GameApi_sp.cc:253 #15 0x00007ffff6deebaf in GameApi::MainLoopApi::execute_ml (this=0x7fffffffd260, ev=..., ml=..., color=..., texture=..., texture_2d=..., array_texture=..., in_MV=..., in_T=..., in_N=..., screen_size_x=800, screen_size_y=600) at GameApi_main.cc:2148 #16 0x00007ffff6d6de54 in MLGuiWidget::render (this=0x55555ea62d40) at GameApi_gui.cc:1286 #17 0x00007ffff6d67926 in GuiWidgetForward::render (this=0x55556d84cc90) at /home/terop/cvs/GameApi/GameApi/GameApi_gui.hh:197 #18 0x00007ffff6d67926 in GuiWidgetForward::render (this=0x55556d84c980) at /home/terop/cvs/GameApi/GameApi/GameApi_gui.hh:197 --Type for more, q to quit, c to continue without paging-- #19 0x00007ffff6d67926 in GuiWidgetForward::render (this=0x55555b27f290) at /home/terop/cvs/GameApi/GameApi/GameApi_gui.hh:197 #20 0x00007ffff6d73b8b in ArrayYWidget::render (this=0x55555b27f290) at GameApi_gui.cc:2203 #21 0x00007ffff6d67926 in GuiWidgetForward::render (this=0x55555b27f380) at /home/terop/cvs/GameApi/GameApi/GameApi_gui.hh:197 #22 0x00007ffff6d93ba4 in GameApi::GuiApi::render (this=0x5555562b2978, w=...) at GameApi_gui.cc:5643 #23 0x0000555555566bf2 in render_cb (env=env@entry=0x555555a99160) at test.cpp:3569 #24 0x000055555556e756 in MainIter::render (this=0x5555562c2730, arg=0x555555a99160) at test.cpp:731 #25 MainIter::render (this=0x5555562c2730, arg=0x555555a99160) at test.cpp:717 #26 0x0000555555567576 in IterAlgo (ee=..., vec=std::vector of length 2, capacity 2 = {...}, args=std::vector of length 2, capacity 2 = {...}, ev=ev@entry=0x7fffffffd260) at test.cpp:3193 #27 0x00005555555651c2 in main (argc=3, argv=) at test.cpp:3923 ChatGPT sanoi: This stack trace indicates your program is hanging (jammed) inside a pthread condition variable wait (pthread_cond_wait) called from your task_implementation::join_id() function, which is waiting on a thread or task to finish. What this means: The thread is stuck waiting on a condition variable futex (__futex_abstimed_wait_common64) in the system pthread library. The function task_implementation::join_id() is blocking on a task or thread join. This is often a deadlock or missed wakeup scenario — the thread it waits for never signals the condition variable or never finishes. How to debug and fix: Check your task/thread lifecycle: Ensure every thread/task you join has been started and is able to finish. Make sure the thread you join calls pthread_cond_signal() or pthread_cond_broadcast() after it finishes work, so the waiter can proceed. Verify no circular waits or deadlocks in task dependencies. Timeout or cancellation: If your join_id supports timeouts, consider using a timeout to avoid indefinite blocking. Check if your thread/task can be cancelled or interrupted cleanly. Look at the code around GameApi_dep_env.cc:278 (join_id implementation): See how the condition variable wait is done. Check what signals or state changes are expected to unblock the wait. Add logging before and after wait calls to identify where it hangs. Thread safety and mutex usage: Verify the mutex associated with the condition variable is locked/unlocked properly. Confirm no race conditions or lost wakeups. Check your tasks or jobs that spawn GPU/OpenGL work: Sometimes GPU driver stalls or waits for sync objects can cause worker threads to hang indirectly. Minimal reproduction: Try to isolate the problem with a minimal test case that just starts and joins a thread or task. Quick checklist: Are all threads you join actually running and finishing? Is the condition variable always signaled after the condition is met? Do you lock the mutex before waiting and signal properly? Any chance of deadlock due to multiple threads waiting on each other? Check for infinite loops or blocking calls in the worker thread. If you share the relevant code snippet around task_implementation::join_id() and the task/thread creation logic, I can help identify the deadlock or missing signal. Sinä sanoit: how to create a timeout for pthread_cond_wait? ChatGPT sanoi: To create a timeout for pthread_cond_wait, you use the timed version called pthread_cond_timedwait. It works like pthread_cond_wait but takes an absolute timeout (a struct timespec) to specify the maximum time to wait. Basic usage of pthread_cond_timedwait c Kopioi Muokkaa #include #include #include int wait_with_timeout(pthread_cond_t *cond, pthread_mutex_t *mutex, int timeout_ms) { struct timespec ts; int ret; // Get current time clock_gettime(CLOCK_REALTIME, &ts); // Add timeout_ms milliseconds to current time for absolute timeout ts.tv_sec += timeout_ms / 1000; ts.tv_nsec += (timeout_ms % 1000) * 1000000; // Normalize nanoseconds if > 1 second if (ts.tv_nsec >= 1000000000) { ts.tv_sec += 1; ts.tv_nsec -= 1000000000; } // Wait on the condition variable with timeout ret = pthread_cond_timedwait(cond, mutex, &ts); if (ret == 0) { // Condition was signaled before timeout return 0; } else if (ret == ETIMEDOUT) { // Timeout expired return 1; } else { // Some other error occurred return -1; } } Notes The timeout parameter is an absolute time, not a relative interval. Use CLOCK_REALTIME or CLOCK_MONOTONIC with clock_gettime, but be consistent with what your system expects. Always hold the mutex locked before calling pthread_cond_timedwait. After the function returns, check the return code: 0 means the condition was signaled. ETIMEDOUT means the timeout expired. Other errors may occur, handle accordingly. If you want, I can help you modify your task_implementation::join_id function to add a timeout based on this. ChatGPT voi tehdä virheitä. Suosittelemme tarkastamaan tärkeät tiedot. Katso evästeasetukset.