joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.79k stars 382 forks source link

Screen flicker #3183

Open nickysn opened 2 years ago

nickysn commented 2 years ago

Code of Conduct & Contributing Guidelines

Have you checked that no other similar bug report(s) already exists?

What operating system(s) this bug have occurred on?

Fedora Linux 35

What version(s) of DOSBox-X have this bug?

0.83.20 SDL2

Describe the bug

After going fullscreen on a widescreen monitor, the screen area that is outside the dos screen (on the left and right) sometimes flickers, showing random garbage video data.

Expected behavior

The unused area of the screen should remain black. Screencast from 12-28-2021 02:17:07 PM.webm.zip

Steps to reproduce the behaviour

  1. Start DOSBox-X, compiled for SDL2
  2. Enable Video->Fit to aspect ratio
  3. Select Video->Output->OpenGL
  4. Go fullscreen
  5. Type something and observe the undesired screen flicker. Note that it doesn't always happen, but happens quite often. A workaround I use is to try to switch back to windowed mode, then back to fullscreen several times, until there's no flicker.

Used configuration

I use Fedora Linux 35 for x86_64 with GNOME3 and Wayland. My graphics card is AMD Radeon RX 5700 XT. I use the open source graphics driver that come with Fedora. Extract from glxinfo:

OpenGL vendor string: AMD
OpenGL renderer string: AMD Radeon RX 5700 XT (NAVI10, DRM 3.42.0, 5.15.11-200.fc35.x86_64, LLVM 13.0.0)
OpenGL core profile version string: 4.6 (Core Profile) Mesa 21.3.2
OpenGL core profile shading language version string: 4.60
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile

I can provide more info, if needed.

Emulator log

No response

Additional context

No response

rderooy commented 2 years ago

Please see https://github.com/joncampbell123/dosbox-x/issues/1959

grapeli commented 2 years ago

This has nothing to do with the dosbox-x code. I run dosbox-x under linux every day in various configurations. I have not observed anything of the sort.

Possible cause is: graphics driver, mesa, SDL2, system configuration, WM configuration. You must find the cause of your problems yourself.

https://user-images.githubusercontent.com/452325/147583688-ddb39e10-d9e7-4c74-a263-d07a4d09b3c5.mp4

https://user-images.githubusercontent.com/452325/147583718-8645c2a2-b6db-4edc-bcf2-430204e10726.mp4

edit: You can try to run like this: SDL_RENDER_VSYNC=1 dosbox-x and see if it changes anything. If he did not look for changes in the settings of the graphics driver. I would use an Intel driver (if possible). I would check under another WM, etc.

nickysn commented 2 years ago

Ok, some more testing: 1) SDL_RENDER_VSYNC=1 dosbox-x <--- doesn't fix the issue :( 2) using Intel driver - tried this on different hardware - the problem doesn't appear there, so it does look like the driver matters. Unfortunately, using the Intel driver is not an option on hardware with an AMD CPU and GPU. 3) using Gnome Classic - problem disappears, so apparently, the desktop environment also matters. 4) using Gnome on X11 (no Wayland) - problem still exists. 5) I created this patch to workaround the issue:

diff -Naur orig/dosbox-x-dosbox-x-v0.83.20/src/output/output_opengl.cpp new/dosbox-x-dosbox-x-v0.83.20/src/output/output_opengl.cpp --- orig/dosbox-x-dosbox-x-v0.83.20/src/output/output_opengl.cpp<------>2021-12-01 08:24:49.000000000 +0200 +++ new/dosbox-x-dosbox-x-v0.83.20/src/output/output_opengl.cpp>2021-12-28 20:10:12.549997109 +0200 @@ -925,21 +925,21 @@ { if (!(sdl.must_redraw_all && changedLines == NULL)). {

It forces the entire screen to be redrawn (including the black border area and the menus) each frame, so in theory it does make things slower. In practice, I didn't notice any difference in performance, and it removed the annoying flicker, so I'll be using this patch from now on. But I wonder if there's a more elegant solution?

Is this an OpenGL driver bug or is dosbox-x relying on undefined behavior?

nickysn commented 2 years ago

The patch got mangled, so I'm attaching it as a file. opengl_flicker_glitch_workaround.patch.txt

joncampbell123 commented 2 years ago

When I added the code, it was based on the assumption that OpenGL provided a front and back buffer (as it usually does), so clearing the whole background only two frames would take care of any issues.

grapeli commented 2 years ago

See if it works properly with the software-based opengl rendering. LIBGL_ALWAYS_SOFTWARE=1 dosbox-x

nickysn commented 2 years ago

yes, it works properly with LIBGL_ALWAYS_SOFTWARE=1 dosbox-x

grapeli commented 2 years ago

and try vblank_mode with values 1,2,3,4 (with hardware rendering) vblank_mode=3 dosbox-x

nickysn commented 2 years ago

tried vblank_mode with values 1,2,3,4 - the problem appears with all of them

grapeli commented 2 years ago

I would definitely check the behavior under another wm. Different from GNOME/mutter. Under wayland - Sway or KDE (possibly Weston). Under x11. Anything. Even a banally simple i3.

nickysn commented 2 years ago

Tried KDE Plasma Wayland and KDE Plasma X11 - both work without flicker.

grapeli commented 2 years ago

Maybe you'd better report it here. https://gitlab.gnome.org/GNOME/mutter/-/issues

Alternatively, if you have some experience building software, check with another older version of SDL2 (there is sometimes regression here). First, build SDL2 statically (though that's not necessary). Dirty recipe.

curl -JOL https://www.libsdl.org/release/SDL2-2.0.14.tar.gz
tar xf SDL2-2.0.14.tar.gz &&  cd SDL2-2.0.14
CFLAGS="-O2 -pipe -march=native" ./configure --prefix=/tmp/sdl2 --disable-shared --enable-static --disable-jack --disable-arts --disable-nas --dis able-sndio && make install

cd dosbox-x
PATH="/tmp/sdl2/bin:$PATH" PKG_CONFIG_PATH=/tmp/sdl2/lib/pkgconfig ./configure --prefix=/usr --disable-sdl --enable-sdl2 --with-sdl2-prefix=/tmp/sdl2 ... CFLAGS=...  CXXFLAGS=... LDFLAGS=...

edit: Even simpler waraint - see how dosbox-x works with SDL1.

nickysn commented 2 years ago

Tried SDL1 - the one that comes with the DOSBox-x sources. Fullscreen is buggy as hell (probably because SDL1's fullscreen mode is not compliant with the freedesktop.org standards, namely _NET_WM_STATE_FULLSCREEN, defined in https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html) and keyboard doesn't work while fullscreen, alt-tab also doesn't work, and you need to kill dosbox-x from a virtual console in order to close it. The glitch didn't appear, but it may be due to luck. However, I tried resizing in windowed mode and could manage to get the glitch to appear, although it looks differently, it doesn't flicker, the garbage image just stays there, until the menus are updated. See the attached screencast. Note that the glitch appears more rarely this way, but still appears.

Anyhow, SDL1 is obsolete, and I don't care about it. Regarding SDL2, there are 15 SDL2 versions so far. Which ones should I try? Screencast from 12-29-2021 11:43:31 AM.webm.zip

grapeli commented 2 years ago

Try with sdl2-2.0.14. With others, it will no longer make sense.

nickysn commented 2 years ago

Ok, tried SDL 2.0.14, flicker still appears (same as SDL 2.0.18).

grapeli commented 2 years ago

For me, it's GNOME/Mutter's fault. It's best to report it to them.

Maybe try to run like this. CLUTTER_VBLANK=none dosbox-x

I have no other ideas. Change the gnome to something else.

nickysn commented 2 years ago

Tried this "CLUTTER_VBLANK=none dosbox-x" and it doesn't fix the problem.

I have no reason to switch away from GNOME, because I'm used to it and there are workarounds that work (e.g. with my patch or with "LIBGL_ALWAYS_SOFTWARE=1 dosbox-x").

I will report this to GNOME/Mutter if @joncampbell123 (who wrote this code) agrees that it's indeed a bug in the window manager. I have done some graphics programming, including with OpenGL, but I'm not an expert and I don't know whether OpenGL guarantees that the back buffer pixels would stay the same from the previous frame, if you don't redraw them for the current frame. It might as well be undefined behavior. I tried reading the OpenGL spec, but couldn't find the relevant info.

grapeli commented 2 years ago

In my opinion, this is a matter of compositing manager (mutter). Not WM.

If you are not experiencing the same faults under KWin. This is the more for ordinary WM (x11) that does not use OpenGL, the more you will not experience them. You mentioned that Gnome Classic is OK.

Disable any desktop effects (if possible) in Gnome/Mutter.

nickysn commented 2 years ago

Reported bug for GNOME/Mutter, as you advised:

https://gitlab.gnome.org/GNOME/mutter/-/issues/2069

grapeli commented 2 years ago

You did very well to report this case. They know a lot better there (they deal with similar cases more often).

I am not a developer. I'm the most ordinary dosbox-x user. I just suggested where it is best to report it. The reason could be elsewhere - in MESA, the graphics driver, and maybe ultimately in dosbox-x (it is not obvious to me).

nickysn commented 2 years ago

Michel Dänzer says that indeed this is a problem with dosbox-x code, since it is relying on undefined behavior.

Quote:

"By default, the contents of the back buffer become undefined after SwapBuffers."

They actually rely on them not changing, [...]

"The best way to achieve that is to make use of the GLX_EXT_buffer_age/EGL_EXT_buffer_age extension. Each buffer still needs to be fully initialized explicitly the first time it's used though. Another possibility is to use the GLX_OML_swap_method extension (anything other than GLX_SWAP_UNDEFINED_OML) or set EGL_SWAP_BEHAVIOR to EGL_BUFFER_PRESERVED, but this will be less efficient. Note that glClear is very cheap with modern GPUs, so neither of the above may be justified to avoid just that."

grapeli commented 2 years ago

@nickysn However, this only manifests itself in Gnome/mutter.

Although these developers really know what it is all about. They participate in active development of the basic components of the graphics stack under Linux.

You mentioned that this doesn't always occur even in Gnome/mutter. You tried to invoke dosbox-x with different settings.

dosbox-x -set startbanner=false -set fastbioslogo=true -set aspect=true -set glshader=sharp -set fullscreen=true
dosbox-x -set aspect=true -set glshader=sharp -set fullscreen=true
dosbox-x -set aspect=true -set glshader=none -set fullscreen=true
dosbox-x -set startbanner=true -set fastbioslogo=true -set aspect=true -set fullscreen=false
...
nickysn commented 2 years ago

It is probably undefined behavior, triggered by incorrect dosbox-x code. It is essentially similar to an use-after-free bug or using uninitialized variables something like that, except it doesn't cause security issues, only visual artifacts. It might work correctly with certain drivers and memory allocation schemes and patterns, due to luck, but it is still wrong code. The fact that OpenGL extensions such as these (GLX_EXT_buffer_age, GLX_OML_swap_method, etc.) exist, confirms it. They are supported by the AMD driver, see the glxinfo:

glxinfo.txt

So, dosbox-x should use them, if they are available, and if they are not available, it should always redraw the entire frame, including the black parts and the menu.

grapeli commented 2 years ago

@nickysn I tested your proposed workaround.

In the case of my archaic hardware, I am noting a slight decrease in the case of windowed mode.

pcpbench ~3.15% quake 800x600 demo2 ~2.7%. Each test was performed five times. In the case of full screen, I do not notice the difference.

For me, your patch is fully acceptable at the beginning.

grapeli commented 2 years ago

Your patch also fixes a fairly rare case of an unexpectedly disappearing menu.

https://user-images.githubusercontent.com/452325/148309324-6dfee51b-7366-4084-bb16-6b97f2d91c37.mp4

It appears on startup and disappears when dhry1nd is started. Extremely difficult to reproduce. Does not occur with startbanner=false. It's hard to catch. It took about five tries to record this. For me it only happens by running dhry1nd only on video output opengl, only with WM - i3 and notion (both work under Xorg). This is not the case under sway, kde, gnome with x11 or wayland and xwayland.

I also know which change to dosbox-x is responsible for this (with 100% certainty). I wasted half a day checking it out. improve code page compatibility for text in UI shortcuts too

nickysn commented 2 years ago

Yeah, my patch causes a small slowdown in windowed mode, because it causes the menu to be drawn every frame. By using the proposed OpenGL extensions, we can probably achieve the original performance, without any of the glitches in certain drivers and compositors, but it makes the patch more complicated and I've no experience with these OpenGL extensions.

grapeli commented 2 years ago

With the menu switched off, the difference disappears (inaccurate tests). dosbox-x -set showmenu=false or F12-esc So if someone wants to maximize performance (for example, for a benchmark), he should always turn off the menu. This also applied before.

In the margin. There has been a sudden silence from the new year (not in this thread). Wengier makes no sign. I don't know if it's just a temporary breakup (I'm afraid not). Probably more seriously involved with dosbox-staging. I'm afraid that the activity here will drop significantly. And it will even be boring.

joncampbell123 commented 2 years ago

@grapeli I've been busy more with my professional work, so I don't have as much time to work on this project as I'd like. I can't speak for Wengier but perhaps he has a similar situation. This project may go dormant from time to time but it's not dead.