flightlessmango / MangoHud

A Vulkan and OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more. Discord: https://discordapp.com/invite/Gj5YmBb
MIT License
6.25k stars 269 forks source link

MangoHud doesn't use the freedesktop portal to communicate with the gamemode daemon when running in flatpak #685

Open lunaneff opened 2 years ago

lunaneff commented 2 years ago

gamemode uses a freedesktop portal to communicate with the gamemode daemon in order to avoid requiring an additional permission. MangoHud can't use this portal however, and doesn't do anything when the option is enabled

Documentation for the portal is available here: https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.GameMode

This was added to gamemode in FeralInteractive/gamemode#146, maybe it can be used as reference when fixing this?

Workaround until this is fixed:

flatpak override --user --talk-name=com.feralinteractive.GameMode flatpak.app.id
gasinvein commented 2 years ago

Workaround until this is fixed:

flatpak override --user --talk-name=com.feralinteractive.GameMode flatpak.app.id

It won't work properly. gamemoded expects clients to send their PIDs, which are different inside flatpak sandbox. E.g. a flatpak app usually has PID 2 inside the sandbox, while on host, as seen by gamemoded, PID 2 will be usually some kernel or systemd process. You shouldn't talk to com.feralinteractive.GameMode directly from inside a PID namespace. The gamemode portal properly translates sandbox-to-host PIDs.

FLAGEL commented 7 months ago

Disclaimer: I am just a tinkerer, and not familiar with the inner workings of MangoHud, Flatpak, or DBus.

@gasinvein is correct regarding the permission override workaround above. gamemoderun uses the org.freedesktop.portal.GameMode interface to enable and disable GameMode from within a Flatpak (details: https://github.com/FeralInteractive/gamemode/pull/146#issuecomment-1874440852).

That said, @lunaneff seems to be correct. As it stands, MangoHud from within a Flatpak is unable to reliably detect if GameMode is enabled or not.

Examples: mangohud gamemoderun %command% works as intended, showing GameMode being active.

gamescope -o 5 -h 720 -H 1080 -F fsr -f -- bash -c "mangoapp & gamemoderun %command%; kill -s TERM \$(jobs -pr)" does not work as intended, showing GameMode being disabled even when it is in fact active.

The latter is likely due to MangoHud detecting MangoApp as the Exe, and not polling Dbus.

Edit: FlightlessMango, btw, a big thank you for contributing quality software to the FOSS community! :-)

Setup [1] com.valvesoftware.Steam 1.0.0.78, org.freedesktop.Platform.VulkanLayer.MangoHud 0.7.0 [2] Linux host 6.6.8-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 21 Dec 2023 19:01:01 +0000 x86_64 GNU/Linux [3] dbus 1.14.10-1, gamemode 1.8.1-1

flightlessmango commented 7 months ago

mangoapp is not aware of the games pid at this point, so it's not able to do any gamemode, vkbasalt detection or process memory etc. That should be regarded as a separate issue

FLAGEL commented 7 months ago

@flightlessmango, does mangohud not face the same limitations that gamemoderun does within the Flatpak sandbox?

It seems the way gamemoderun circumvents not knowing the (non-sandbox) game PID is by using the org.freedesktop.portal.GameMode interface to query the (non-sandbox) D-Bus session for the (non-sandbox) game PID, only to then register that same (non-sandbox) game PID to the (non-sandbox) gamemode daemon, again via D-Bus. Please see below extract via dbus-monitor --session.

Getting the (non-sandbox) game PID:

method call time=1704210321.074698 sender=:1.3277 -> destination=org.freedesktop.portal.Desktop serial=26 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.portal.GameMode; member=RegisterGameByPIDFd
   file descriptor
         inode: 2099
         type:    file descriptor
         inode: 2099
         type: method call time=1704210321.074737 sender=:1.44 -> destination=org.freedesktop.DBus serial=7943 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionUnixProcessID
   string ":1.3277"
method return time=1704210321.074746 sender=org.freedesktop.DBus -> destination=:1.44 serial=1739 reply_serial=7943
   uint32 562044

Registering the (non-sandbox) game PID to host gamemoded:

signal time=1704210321.109850 sender=:1.3018 -> destination=(null destination) serial=384 path=/com/feralinteractive/GameMode; interface=com.feralinteractive.GameMode; member=GameRegistered
   int32 565669
   object path "/com/feralinteractive/GameMode/Games/565669"
flightlessmango commented 7 months ago

afaik mangohud doesn't use the dbus portal at all, we're just checking if the library is loaded in the app

FLAGEL commented 7 months ago

I see. In that case a D-Bus query would be more of a feature request. Another simpler(?) way would to have mangohud also check child/parent processes for if the library is loaded.

Edit: Or maybe it is possible to use /proc/ to figure out if gamemoderun has activated gamemode or not.

Edit 2: One way that works below.

Screenshot_2024-01-03_03-11-57

Get the Parent PID of the current process as seen by MangoHud, i.e. "mangoapp" as shown above:

[📦 com.valvesoftware.Steam valve]$ ps -o ppid --no-header --pid 1939 # 1939 is the PID of "mangoapp"
   1937

Then grep said Parent PID against gamemodelist (official shell script part of GameMode):

[📦 com.valvesoftware.Steam valve]$ find /proc -maxdepth 2 -type f -user "${USER}" -readable -name maps -exec   awk -- '$0 ~ /libgamemodeauto\.so\.0/ {pid=FILENAME; gsub("[^0-9]", "", pid); print pid;nextfile}' {} +   | xargs | xargs -I{} -- ps -o pid,ppid,user,ni,psr,comm --pid '{}' | grep 1937
   1940    1937 user       0   2 reaper

If there is a match, I can see not reason why one could not conclude that GameMode is enabled.