Compare commits

..

No commits in common. 'master' and 'v0.7.1-rc2' have entirely different histories.

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: FlightlessMango
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: https://www.paypal.me/flightlessmango

@ -28,7 +28,7 @@ jobs:
cd pkgbuild
pkgver=$(git describe --tags | sed -r 's/^v//;s/([^-]*-g)/r\1/;s/-/./g')
sed -i "s/pkgver=.*/pkgver=$pkgver/g" PKGBUILD
sudo -u nobody -- sh -c "makepkg -fsCc --noconfirm"
sudo -u nobody -- sh -c "makepkg -fsiCc --noconfirm"
- name: Edit release and add files
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

@ -2,6 +2,11 @@ name: Build release package
on:
release:
types: [published]
# push:
# tags: ["v*"]
# branches:
# - main
workflow_dispatch:
jobs:
build:
@ -11,16 +16,9 @@ jobs:
- uses: actions/checkout@v3
- name: Install build tools
run: |
set -x
sudo dpkg --add-architecture i386
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages focal main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt -y install gcc-multilib g++-multilib ninja-build python3-setuptools \
python3-wheel mesa-common-dev libxnvctrl-dev libdbus-1-dev \
python3-numpy python3-matplotlib unzip hub libxkbcommon-dev libwayland-dev wget unzip \
libxkbcommon-dev:i386 libwayland-dev:i386 gh
sudo pip3 --no-input install 'meson>=0.60' mako
sudo apt install gcc-multilib g++-multilib ninja-build python3-setuptools python3-wheel mesa-common-dev libxnvctrl-dev libdbus-1-dev python3-numpy python3-matplotlib unzip hub
sudo pip3 install 'meson>=0.60' mako
wget https://github.com/KhronosGroup/glslang/releases/download/SDK-candidate-26-Jul-2020/glslang-master-linux-Release.zip
unzip glslang-master-linux-Release.zip bin/glslangValidator
sudo install -m755 bin/glslangValidator /usr/local/bin/
@ -37,25 +35,31 @@ jobs:
else
echo "##[set-output name=short-sha;]$(git rev-parse --short "$GITHUB_SHA")"
fi
echo "##[set-output name=artifact-metadata;]$ARTIFACT_NAME"
- name: Build and package
echo "##[set-output name=artifact-metadata;]${ARTIFACT_NAME}"
id: git-vars
- name: Build release package
run: |
./build-source.sh
./build.sh build -Dwerror=true package release
- name: Upload assets to release
if: github.event.action == 'published'
- name: Upload release
if: ${{ github.event_name == 'release' && github.event.action == 'published' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag_name="${GITHUB_REF##*/}"
for pkg in ./build/*.tar.*; do
gh release upload "$tag_name" "$pkg" --clobber
assets=()
for asset in ./MangoHud-*-Source*.tar.*; do
assets+=("-a" "$asset")
done
for asset in ./build/MangoHud-*.tar.*; do
assets+=("-a" "$asset")
done
tag_name="${GITHUB_REF##*/}"
hub release edit "${assets[@]}" -m "" "$tag_name"
#hub release create "${assets[@]}" -m "$tag_name" "$tag_name"
- name: Upload artifact
uses: actions/upload-artifact@v3
continue-on-error: true
with:
name: MangoHud-${{steps.git-vars.outputs.artifact-metadata}}
path: ${{runner.workspace}}/MangoHud/build/MangoHud-*tar.gz
retention-days: 30
retention-days: 30

@ -11,13 +11,11 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Run build-source.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -x
sudo apt update
sudo apt -y install gcc g++ ninja-build python3-pip python3-setuptools python3-wheel pkg-config mesa-common-dev libx11-dev libxnvctrl-dev libdbus-1-dev glslang-tools hub libxkbcommon-dev libwayland-dev wget unzip
sudo pip3 --no-input install 'meson>=0.60' mako
sudo apt install gcc g++ ninja-build python3-pip python3-setuptools python3-wheel pkg-config mesa-common-dev libx11-dev libxnvctrl-dev libdbus-1-dev glslang-tools
sudo pip3 install 'meson>=0.60' mako
./build-source.sh
assets=()
for asset in ./MangoHud-*-Source*.tar.*; do
@ -26,10 +24,6 @@ jobs:
tag_name="${GITHUB_REF##*/}"
hub release edit "${assets[@]}" -m "" "$tag_name"
#hub release create "${assets[@]}" -m "$tag_name" "$tag_name"
- name: Upload artifact
uses: actions/upload-artifact@v3
continue-on-error: true
with:
name: MangoHud-${{steps.git-vars.outputs.artifact-metadata}}
path: ${{runner.workspace}}/MangoHud/build/MangoHud-*tar.gz
retention-days: 30
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

@ -28,8 +28,7 @@ jobs:
libglew-dev \
libglfw3-dev \
libwayland-dev \
libxnvctrl-dev \
libxkbcommon-dev
libxnvctrl-dev
sudo pip3 install 'meson>=0.60'
- name: 'Install clang'
if: ${{ (matrix.compiler == 'clang') }}

@ -28,7 +28,7 @@ A Vulkan and OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and m
- [Keybindings](#keybindings)
- [Workarounds](#workarounds)
- [FPS logging](#fps-logging)
- [Online visualization: FlightlessMango.com](#online-visualization-flightlessmangocom)
- [Online viualization: FlightlessMango.com](#online-viualization-flightlessmangocom)
- [Local visualization: `mangoplot`](#local-visualization-mangoplot)
## Installation - Build From Source
@ -76,8 +76,6 @@ Install necessary development packages.
- X11 (libx11-dev)
- XNVCtrl (libxnvctrl-dev), optional, use `-Dwith_xnvctrl=disabled` option with `meson` to disable
- D-Bus (libdbus-1-dev), optional, use `-Dwith_dbus=disabled` option with `meson` to disable
- wayland-client
- xcbcommon
Python 3 libraries:
@ -413,7 +411,6 @@ Parameters that are enabled by default have to be explicitly disabled. These (cu
| `throttling_status` | Show if GPU is throttling based on Power, current, temp or "other" (Only shows if throttling is currently happening). Currently disabled by default for Nvidia as it causes lag on 3000 series |
| `throttling_status_graph` | Same as `throttling_status` but displays throttling in the frametime graph and only power and temp throttling |
| `time`<br>`time_format=%T` | Display local time. See [std::put_time](https://en.cppreference.com/w/cpp/io/manip/put_time) for formatting help. NOTE: Sometimes apps may set `TZ` (timezone) environment variable to UTC/GMT |
| `time_no_label` | Remove the label before time |
| `toggle_fps_limit` | Cycle between FPS limits (needs at least two values set with `fps_limit`). Defaults to `Shift_L+F1` |
| `toggle_preset` | Cycle between Presets. Defaults to `Shift_R+F10` |
| `toggle_hud=`<br>`toggle_logging=` | Modifiable toggle hotkeys. Default are `Shift_R+F12` and `Shift_L+F2`, respectively |
@ -429,8 +426,6 @@ Parameters that are enabled by default have to be explicitly disabled. These (cu
| `wine_color` | Change color of the wine/proton text |
| `wine` | Show current Wine or Proton version in use |
| `winesync` | Show wine sync method in use |
| `present_mode` | Shows current vulkan [present mode](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPresentModeKHR.html) or vsync status in opengl |
| `network` | Show network interfaces tx and rx kb/s. You can specify interface with `network=eth0` |
Example: `MANGOHUD_CONFIG=cpu_temp,gpu_temp,position=top-right,height=500,font_size=32`
Because comma is also used as option delimiter and needs to be escaped for values with a backslash, you can use `+` like `MANGOHUD_CONFIG=fps_limit=60+30+0` instead.
@ -481,7 +476,7 @@ When you toggle logging (default keybind is `Shift_L+F2`), a file is created wit
Log files can be visualized with two different tools: online and locally.
### Online visualization: FlightlessMango.com
### Online viualization: FlightlessMango.com
Log files can be (batch) uploaded to [FlightlessMango.com](https://flightlessmango.com/games/user_benchmarks), which will then take care of creating a frametime graph and a summary with 1% min / average framerate / 97th percentile in a table form and a horizontal bar chart form.
Notes:

@ -11,7 +11,7 @@ fi
# Add exe names newline separated to the string to disable LD_PRELOAD
DISABLE_LD_PRELOAD="cs2.sh
"
some_other_exe"
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_opengl.so"

@ -31,7 +31,7 @@ rm -r ${NAME}/subprojects/nlohmann_json-*
# remove some vulkan clutter
rm -r ${NAME}/subprojects/Vulkan-Headers-*/cmake ${NAME}/subprojects/Vulkan-Headers-*/BUILD.gn
# remove some dear imgui clutter
rm -rf ${NAME}/subprojects/imgui-*/examples
rm -rf ${NAME}/subprojects/imgui-*/examples ${NAME}/subprojects/imgui-*/misc
# compress new sources
tar -cJf ${DFSG_TAR_NAME} ${NAME}

@ -54,7 +54,7 @@ dependencies() {
for i in $DISTRO; do
echo "# Checking dependencies for \"$i\""
case $i in
*arch*|*manjaro*|*artix*|*SteamOS*)
*arch*|*manjaro*|*artix*)
MANAGER_QUERY="pacman -Q"
MANAGER_INSTALL="pacman -S"
DEPS="{${DEPS_ARCH}}"
@ -68,12 +68,12 @@ dependencies() {
dep_install
unset INSTALL
DEPS="{glibc-devel.i686,libstdc++-devel.i686,libX11-devel.i686,wayland-devel.i686,libxkbcommon-devel.i686}"
DEPS="{glibc-devel.i686,libstdc++-devel.i686,libX11-devel.i686}"
dep_install
break
;;
*debian*|*ubuntu*|*deepin*|*pop*)
*debian*|*ubuntu*|*deepin*)
MANAGER_QUERY="dpkg-query -s"
MANAGER_INSTALL="apt install"
DEPS="{${DEPS_DEBIAN}}"

@ -1,7 +1,7 @@
DEPS_ARCH="gcc,meson,pkgconf,python-mako,glslang,libglvnd,lib32-libglvnd,libxnvctrl,libdrm,python-numpy,python-matplotlib,libxkbcommon"
DEPS_FEDORA="meson,gcc,gcc-c++,libX11-devel,glslang,python3-mako,mesa-libGL-devel,libXNVCtrl-devel,dbus-devel,python3-numpy,python3-matplotlib,libstdc++-static,libstdc++-static.i686,libxkbcommon-devel,wayland-devel"
DEPS_DEBIAN="gcc,g++,gcc-multilib,g++-multilib,ninja-build,python3-pip,python3-setuptools,python3-wheel,pkg-config,mesa-common-dev,libx11-dev,libxnvctrl-dev,libdbus-1-dev,python3-numpy,python3-matplotlib,libxkbcommon-dev,libxkbcommon-dev:i386,libwayland-dev,libwayland-dev:i386"
DEPS_SOLUS="mesalib-32bit-devel,glslang,libstdc++-32bit,glibc-32bit-devel,mako,numpy,matplotlib,libxkbcommon-devel"
DEPS_ARCH="gcc,meson,pkgconf,python-mako,glslang,libglvnd,lib32-libglvnd,libxnvctrl,libdrm,python-numpy,python-matplotlib"
DEPS_FEDORA="meson,gcc,gcc-c++,libX11-devel,glslang,python3-mako,mesa-libGL-devel,libXNVCtrl-devel,dbus-devel,python3-numpy,python3-matplotlib,libstdc++-static,libstdc++-static.i686"
DEPS_DEBIAN="gcc,g++,gcc-multilib,g++-multilib,ninja-build,python3-pip,python3-setuptools,python3-wheel,pkg-config,mesa-common-dev,libx11-dev,libxnvctrl-dev,libdbus-1-dev,python3-numpy,python3-matplotlib"
DEPS_SOLUS="mesalib-32bit-devel,glslang,libstdc++-32bit,glibc-32bit-devel,mako,numpy,matplotlib"
DEPS_SUSE="gcc-c++,gcc-c++-32bit,libpkgconf-devel,ninja,python3-pip,python3-Mako,libX11-devel,glslang-devel,glibc-devel,glibc-devel-32bit,libstdc++-devel,libstdc++-devel-32bit,Mesa-libGL-devel,dbus-1-devel,python-numpy,python-matplotlib,libxkbcommon-devel"
DEPS_SUSE="gcc-c++,gcc-c++-32bit,libpkgconf-devel,ninja,python3-pip,python3-Mako,libX11-devel,glslang-devel,glibc-devel,glibc-devel-32bit,libstdc++-devel,libstdc++-devel-32bit,Mesa-libGL-devel,dbus-1-devel,python-numpy,python-matplotlib"
DEPS_SUSE_EXTRA="libXNVCtrl-devel"

@ -62,8 +62,6 @@
### Display the current system time
# time
## removes the time label
# time_no_label
### Time formatting examples
## %H:%M
@ -90,7 +88,7 @@ gpu_stats
## GPU fan in rpm on AMD, FAN in percent on NVIDIA
# gpu_fan
## gpu_voltage only works on AMD GPUs
# gpu_voltage
# gpu_voltage
### Display the current CPU information
cpu_stats
@ -212,14 +210,6 @@ frame_timing
## example: Track:;{title};By:;{artist};From:;{album}
# media_player_format=title,artist,album
### Network interface throughput
# network
## Network can take arguments but it's not required.
## without arguments it shows all interfaces
## arguments set which interfaces will be displayed
# network=eth0,wlo1
### Change the hud font size
# font_size=24
# font_scale=1.0

@ -1,6 +1,6 @@
project('MangoHud',
['c', 'cpp'],
version : 'v0.7.2',
version : 'v0.7.0',
license : 'MIT',
meson_version: '>=0.60.0',
default_options : ['buildtype=release', 'c_std=c99', 'cpp_std=c++14', 'warning_level=2']
@ -89,7 +89,6 @@ if is_unixy
dep_wayland_client = dependency('wayland-client',
required: get_option('with_wayland'), version : '>=1.11')
dbus_dep = dependency('dbus-1', required: get_option('with_dbus')).partial_dependency(compile_args : true, includes : true)
dep_xkb = dependency('xkbcommon', required: get_option('with_wayland'))
else
dep_x11 = null_dep
dep_wayland_client = null_dep
@ -103,7 +102,6 @@ endif
if dep_wayland_client.found()
vulkan_wsi_args += ['-DVK_USE_PLATFORM_WAYLAND_KHR']
vulkan_wsi_deps += dep_wayland_client
vulkan_wsi_deps += dep_xkb
endif
if is_unixy and not dep_x11.found() and not dep_wayland_client.found()
@ -166,18 +164,9 @@ else
dep_rt = null_dep
endif
# Commented code can be used if mangohud start using latest SDK Vulkan-Headers
# Allowing user to build mangohud using system Vulkan-Headers
#if not dependency('VulkanHeaders').found()
vkh_sp = subproject('vulkan-headers')
vk_api_xml = vkh_sp.get_variable('vulkan_api_xml')
dep_vulkan = vkh_sp.get_variable('vulkan_headers_dep')
#else
# dep_vulkan = dependency('VulkanHeaders', required: true)
# vk_api_xml = files('/usr/share/vulkan/registry/vk.xml')
#endif
vkh_sp = subproject('vulkan-headers')
vk_api_xml = vkh_sp.get_variable('vulkan_api_xml')
dep_vulkan = vkh_sp.get_variable('vulkan_headers_dep')
vk_enum_to_str = custom_target(
'vk_enum_to_str',
@ -222,36 +211,35 @@ if get_option('mangoapp')
'glfw=enabled',
]
endif
dearimgui_dep = dependency('imgui', fallback: ['imgui'], required: true, default_options: imgui_options)
dearimgui_sp = subproject('imgui', default_options: imgui_options)
dearimgui_dep = dearimgui_sp.get_variable('imgui_dep')
if is_unixy
implot_dep = dependency('implot', fallback: ['implot'], required: true, default_options: ['default_library=static'])
implot_sp = subproject('implot', default_options: ['default_library=static'])
implot_dep = implot_sp.get_variable('implot_dep')
else
implot_dep = null_dep
implot_lib = static_library('nulllib', [])
endif
spdlog_options = [
'default_library=static',
'compile_library=true',
'werror=false',
'tests=disabled',
'external_fmt=disabled',
'std_format=disabled'
]
spdlog_dep = dependency('spdlog', required: false)
if get_option('use_system_spdlog').disabled() or not spdlog_dep.found()
if get_option('use_system_spdlog').enabled()
warning('spdlog depedency not found follwing back to submodule')
endif
spdlog_sp = subproject('spdlog', default_options: spdlog_options)
spdlog_dep = spdlog_sp.get_variable('spdlog_dep')
spdlog_dep = cpp.find_library('spdlog', required: get_option('use_system_spdlog'))
if not spdlog_dep.found()
spdlog_sp = subproject('spdlog', default_options: [
'default_library=static',
'compile_library=true',
'werror=false',
'tests=false',
'external_fmt=disabled'
])
spdlog_dep = spdlog_sp.get_variable('spdlog_dep')
else
spdlog_dep = dependency('spdlog', required: true)
endif
if ['windows', 'mingw'].contains(host_machine.system())
minhook_dep = dependency('minhook', fallback: ['minhook', 'minhook_dep'], required: true)
minhook_sp = subproject('minhook')
minhook_dep = minhook_sp.get_variable('minhook_dep')
windows_deps = [
minhook_dep,
]
@ -284,10 +272,8 @@ if get_option('tests').enabled()
),
cpp_args: ['-DTEST_ONLY'],
dependencies: [
dep_vulkan,
cmocka_dep,
spdlog_dep,
implot_dep,
dearimgui_dep
],
include_directories: inc_common)

@ -5,7 +5,7 @@ option('include_doc', type : 'boolean', value : true, description: 'Include the
option('with_nvml', type : 'combo', value : 'enabled', choices: ['enabled', 'system', 'disabled'], description: 'Enable NVML support')
option('with_xnvctrl', type : 'feature', value : 'enabled', description: 'Enable XNVCtrl support')
option('with_x11', type : 'feature', value : 'enabled')
option('with_wayland', type : 'feature', value : 'enabled')
option('with_wayland', type : 'feature', value : 'disabled')
option('with_dbus', type : 'feature', value : 'enabled')
option('loglevel', type: 'combo', choices : ['trace', 'debug', 'info', 'warn', 'err', 'critical', 'off'], value : 'info', description: 'Max log level in non-debug build')
option('mangoapp', type: 'boolean', value : false)

@ -1,13 +1,12 @@
# Maintainer: Simon Hallsten <flightlessmangoyt@gmail.com>
pkgname=('mangohud' 'lib32-mangohud')
pkgver=0.7.2.rc3.r13.g5d744d3
pkgver=0.6.8.r140.g1b3f8b2
pkgrel=1
pkgdesc="Vulkan and OpenGL overlay to display performance information"
arch=('x86_64')
makedepends=('dbus' 'gcc' 'meson' 'python-mako' 'libx11' 'lib32-libx11' 'git' 'pkgconf' 'vulkan-headers')
depends=('glslang' 'libglvnd' 'lib32-libglvnd' 'glew' 'glfw-x11' 'python-numpy' 'python-matplotlib'
'libxrandr' 'libxkbcommon' 'lib32-libxkbcommon')
depends=('glslang' 'libglvnd' 'lib32-libglvnd' 'glew' 'glfw-x11' 'python-numpy' 'python-matplotlib')
replaces=('vulkan-mesa-layer-mango')
license=('MIT')
source=(
@ -15,8 +14,8 @@ source=(
"mangohud-minhook"::"git+https://github.com/flightlessmango/minhook.git"
"imgui-1.89.9.tar.gz::https://github.com/ocornut/imgui/archive/refs/tags/v1.89.9.tar.gz"
"imgui_1.89.9-1_patch.zip::https://wrapdb.mesonbuild.com/v2/imgui_1.89.9-1/get_patch"
"spdlog-1.14.1.tar.gz::https://github.com/gabime/spdlog/archive/refs/tags/v1.14.1.tar.gz"
"spdlog_1.14.1-1_patch.zip::https://wrapdb.mesonbuild.com/v2/spdlog_1.14.1-1/get_patch"
"spdlog-1.12.0.tar.gz::https://github.com/gabime/spdlog/archive/refs/tags/v1.12.0.tar.gz"
"spdlog_1.12.0-1_patch.zip::https://wrapdb.mesonbuild.com/v2/spdlog_1.12.0-1/get_patch"
"nlohmann_json-3.10.5.zip::https://github.com/nlohmann/json/releases/download/v3.10.5/include.zip"
"vulkan-headers-1.2.158.tar.gz::https://github.com/KhronosGroup/Vulkan-Headers/archive/v1.2.158.tar.gz"
"vulkan-headers-1.2.158-2-wrap.zip::https://wrapdb.mesonbuild.com/v2/vulkan-headers_1.2.158-2/get_patch"
@ -29,8 +28,8 @@ sha256sums=(
'SKIP'
'1acc27a778b71d859878121a3f7b287cd81c29d720893d2b2bf74455bf9d52d6'
'9b21290c597d76bf8d4eeb3f9ffa024b11d9ea6c61e91d648ccc90b42843d584'
'1586508029a7d0670dfcb2d97575dcdc242d3868a259742b69f100801ab4e16b'
'ae878e732330ea1048f90d7e117c40c0cd2a6fb8ae5492c7955818ce3aaade6c'
'4dccf2d10f410c1e2feaff89966bfc49a1abb29ef6f08246335b110e001e09a9'
'0515906db7324df0e439bdd018bf019a60304430f6af8f1725910652e30ebe69'
'b94997df68856753b72f0d7a3703b7d484d4745c567f3584ef97c96c25a5798e'
"53361271cfe274df8782e1e47bdc9e61b7af432ba30acbfe31723f9df2c257f3"
"860358cf5e73f458cd1e88f8c38116d123ab421d5ce2e4129ec38eaedd820e17"
@ -53,7 +52,7 @@ prepare() {
# meson subprojects
ln -sv "$srcdir/imgui-1.89.9" subprojects
ln -sv "$srcdir/spdlog-1.14.1" subprojects
ln -sv "$srcdir/spdlog-1.12.0" subprojects
mkdir subprojects/nlohmann_json-3.10.5
ln -sv "$srcdir/include" subprojects/nlohmann_json-3.10.5/
ln -sv "$srcdir/single_include" subprojects/nlohmann_json-3.10.5/

@ -162,63 +162,56 @@ static void msg_read_thread(){
while (1){
// make sure that the message recieved is compatible
// and that we're not trying to use variables that don't exist (yet)
size_t msg_size = msgrcv(msgid, (void *) raw_msg, sizeof(raw_msg), 1, 0);
if (msg_size != -1)
{
if (hdr->version == 1){
if (msg_size > offsetof(struct mangoapp_msg_v1, visible_frametime_ns)){
bool should_new_frame = false;
if (mangoapp_v1->visible_frametime_ns != ~(0lu) && (!params.no_display || logger->is_active())) {
update_hud_info_with_frametime(sw_stats, params, vendorID, mangoapp_v1->visible_frametime_ns);
should_new_frame = true;
}
size_t msg_size = msgrcv(msgid, (void *) raw_msg, sizeof(raw_msg), 1, 0) + sizeof(long);
if (hdr->version == 1){
if (msg_size > offsetof(struct mangoapp_msg_v1, visible_frametime_ns)){
bool should_new_frame = false;
if (mangoapp_v1->visible_frametime_ns != ~(0lu) && (!params.no_display || logger->is_active())) {
update_hud_info_with_frametime(sw_stats, params, vendorID, mangoapp_v1->visible_frametime_ns);
should_new_frame = true;
}
if (msg_size > offsetof(mangoapp_msg_v1, fsrUpscale)){
HUDElements.g_fsrUpscale = mangoapp_v1->fsrUpscale;
if (params.fsr_steam_sharpness < 0)
HUDElements.g_fsrSharpness = mangoapp_v1->fsrSharpness;
else
HUDElements.g_fsrSharpness = params.fsr_steam_sharpness - mangoapp_v1->fsrSharpness;
}
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_mangoapp_steam]){
steam_focused = get_prop("GAMESCOPE_FOCUSED_APP_GFX") == 769;
} else {
steam_focused = false;
}
// if (!steam_focused && mangoapp_v1->pid != previous_pid){
// string path = "/tmp/mangoapp/" + to_string(mangoapp_v1->pid) + ".json";
// ifstream i(path);
// if (i.fail()){
// sw_stats.engine = EngineTypes::GAMESCOPE;
// } else {
// json j;
// i >> j;
// sw_stats.engine = static_cast<EngineTypes> (j["engine"]);
// }
// previous_pid = mangoapp_v1->pid;
// }
if (msg_size > offsetof(mangoapp_msg_v1, latency_ns))
gamescope_frametime(mangoapp_v1->app_frametime_ns, mangoapp_v1->latency_ns);
if (should_new_frame)
if (msg_size > offsetof(mangoapp_msg_v1, fsrUpscale)){
HUDElements.g_fsrUpscale = mangoapp_v1->fsrUpscale;
if (params.fsr_steam_sharpness < 0)
HUDElements.g_fsrSharpness = mangoapp_v1->fsrSharpness;
else
HUDElements.g_fsrSharpness = params.fsr_steam_sharpness - mangoapp_v1->fsrSharpness;
}
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_mangoapp_steam]){
steam_focused = get_prop("GAMESCOPE_FOCUSED_APP_GFX") == 769;
} else {
steam_focused = false;
}
// if (!steam_focused && mangoapp_v1->pid != previous_pid){
// string path = "/tmp/mangoapp/" + to_string(mangoapp_v1->pid) + ".json";
// ifstream i(path);
// if (i.fail()){
// sw_stats.engine = EngineTypes::GAMESCOPE;
// } else {
// json j;
// i >> j;
// sw_stats.engine = static_cast<EngineTypes> (j["engine"]);
// }
// previous_pid = mangoapp_v1->pid;
// }
if (msg_size > offsetof(mangoapp_msg_v1, latency_ns))
gamescope_frametime(mangoapp_v1->app_frametime_ns, mangoapp_v1->latency_ns);
if (should_new_frame)
{
{
{
std::unique_lock<std::mutex> lk(mangoapp_m);
new_frame = true;
}
mangoapp_cv.notify_one();
screenWidth = mangoapp_v1->outputWidth;
screenHeight = mangoapp_v1->outputHeight;
std::unique_lock<std::mutex> lk(mangoapp_m);
new_frame = true;
}
mangoapp_cv.notify_one();
screenWidth = mangoapp_v1->outputWidth;
screenHeight = mangoapp_v1->outputHeight;
}
} else {
printf("Unsupported mangoapp struct version: %i\n", hdr->version);
exit(1);
}
}
else
{
printf("mangoapp: msgrcv returned -1 with error %d - %s\n", errno, strerror(errno));
} else {
printf("Unsupported mangoapp struct version: %i\n", hdr->version);
exit(1);
}
}
}
@ -347,10 +340,6 @@ int main(int, char**)
std::thread(msg_read_thread).detach();
std::thread(ctrl_thread).detach();
if(!logger) logger = std::make_unique<Logger>(HUDElements.params);
Atom noFocusAtom = XInternAtom(x11_display, "GAMESCOPE_NO_FOCUS", False);
uint32_t value = 1;
XChangeProperty(x11_display, x11_window, noFocusAtom, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&value, 1);
// Main loop
while (!glfwWindowShouldClose(window)){
if (!params.no_display){

@ -25,7 +25,6 @@ static std::vector<std::string> blacklist {
"EpicGamesLauncher.exe",
"IGOProxy.exe",
"IGOProxy64.exe",
"monado-service",
"Origin.exe",
"OriginThinSetupInternal.exe",
"steam",
@ -54,10 +53,6 @@ static std::vector<std::string> blacklist {
"wine-preloader",
"iexplore.exe",
"rundll32.exe",
"Launcher", //Paradox Interactive Launcher
"steamwebhelper.exe",
"EpicWebHelper.exe",
"UplayWebCore.exe"
};

@ -99,6 +99,8 @@ static void enumerate_config_files(std::vector<std::string>& paths) {
}
void parseConfigFile(overlay_params& params) {
HUDElements.options.clear();
params.options.clear();
std::vector<std::string> paths;
const char *cfg_file = getenv("MANGOHUD_CONFIGFILE");

@ -469,8 +469,7 @@ static bool find_input(const std::string& path, const char* input_prefix, std::s
if (uscore != std::string::npos) {
file.erase(uscore, std::string::npos);
input = path + "/" + file + "_input";
//9 characters should not overflow the 32-bit int
return std::stoi(read_line(input).substr(0, 9)) > 0;
return true;
}
}
return false;
@ -521,10 +520,8 @@ bool CPUStats::GetCpuFile() {
find_input(path, "temp", input, "temp1");
break;
} else if (starts_with(name, "nct")) {
// Only break if nct module has TSI0_TEMP node
if (find_input(path, "temp", input, "TSI0_TEMP"))
break;
find_input(path, "temp", input, "TSI0_TEMP");
break;
} else if (name == "asusec") {
find_input(path, "temp", input, "CPU");
break;

@ -56,7 +56,6 @@ enum {
};
struct CPUPowerData {
virtual ~CPUPowerData() = default;
int source;
};

@ -6,7 +6,6 @@
namespace fs = ghc::filesystem;
using namespace std;
std::mutex device_lock;
std::vector<device_batt> device_data;
std::vector<std::string> list;
bool device_found = false;
@ -19,7 +18,6 @@ int ds5_count = 0;
int switch_count = 0;
int bitdo_count = 0;
int logi_count = 0; //Logitech devices, mice & keyboards etc.
int shield_count = 0;
std::string xbox_paths [2]{"gip","xpadneo"};
@ -30,7 +28,6 @@ static bool operator<(const device_batt& a, const device_batt& b)
void device_update(const struct overlay_params& params){
std::unique_lock<std::mutex> l(device_lock);
fs::path path("/sys/class/power_supply");
list.clear();
xbox_count = 0;
@ -38,7 +35,6 @@ void device_update(const struct overlay_params& params){
ds5_count = 0;
switch_count = 0;
bitdo_count = 0;
shield_count = 0;
for (auto &p : fs::directory_iterator(path)) {
string fileName = p.path().filename();
//Gamepads
@ -75,14 +71,7 @@ void device_update(const struct overlay_params& params){
device_found = true;
bitdo_count += 1;
}
//CHECK NVIDIA SHIELD DEVICES
if (fileName.find("thunderstrike") != std::string::npos) {
list.push_back(p.path());
device_found = true;
shield_count += 1;
}
}
}
// Mice and Keyboards
//CHECK LOGITECH DEVICES
if (std::find(params.device_battery.begin(), params.device_battery.end(), "mouse") != params.device_battery.end()) {
@ -97,7 +86,6 @@ void device_update(const struct overlay_params& params){
void device_info () {
std::unique_lock<std::mutex> l(device_lock);
device_count = 0;
device_data.clear();
//gamepad counters
@ -106,7 +94,6 @@ void device_info () {
int ds5_counter = 0;
int switch_counter = 0;
int bitdo_counter = 0;
int shield_counter = 0;
for (auto &path : list ) {
//Set devices paths
@ -165,25 +152,14 @@ void device_info () {
device_data[device_count].name = "8BITDO PAD-" + to_string(bitdo_counter + 1);
bitdo_counter++;
}
//Shield devices
if (path.find("thunderstrike") != std::string::npos) {
if (shield_count == 1)
device_data[device_count].name = "SHIELD PAD";
else
device_data[device_count].name = "SHIELD PAD-" + to_string(shield_counter + 1);
shield_counter++;
}
}
// MICE AND KEYBOARDS
//Logitech Devices
if (check_mouse == true) {
if (path.find("hidpp_battery") != std::string::npos) {
// Find a good way truncate name or retreive device type before using this
// if (std::getline(device_name, line)) {
// device_data[device_count].name = line;
// }
device_data[device_count].name = "LOGI MOUSE/KB";
if (std::getline(device_name, line)) {
device_data[device_count].name = line;
}
}
}

@ -14,7 +14,6 @@ struct device_batt {
};
extern std::vector<device_batt> device_data;
extern std::mutex device_lock;
extern bool device_found;
extern int device_count;

@ -9,8 +9,6 @@
#include <algorithm>
#include <condition_variable>
#include <stdexcept>
#include <iomanip>
#include <spdlog/spdlog.h>
struct metric_t {
std::string name;
@ -27,7 +25,6 @@ class fpsMetrics {
bool run = false;
bool thread_init = false;
bool terminate = false;
bool resetting = false;
void calculate(){
thread_init = true;
@ -108,12 +105,7 @@ class fpsMetrics {
};
void update(uint64_t now, double fps){
if (resetting)
return;
if (fps > 0.0001)
fps_stats.push_back({now, fps});
fps_stats.push_back({now, fps});
uint64_t ten_minute_duration = 600000000000ULL; // 10 minutes in nanoseconds
// Check if the system's uptime is less than 10 minutes
@ -122,8 +114,8 @@ class fpsMetrics {
fps_stats.erase(
std::remove_if(
fps_stats.begin(),
fps_stats.end(),
fps_stats.begin(),
fps_stats.end(),
[ten_minutes_ago](const std::pair<uint64_t, float>& entry) {
return entry.first < ten_minutes_ago;
}
@ -134,9 +126,6 @@ class fpsMetrics {
}
void update_thread(){
if (resetting)
return;
{
std::lock_guard<std::mutex> lock(mtx);
run = true;
@ -144,13 +133,6 @@ class fpsMetrics {
cv.notify_one();
}
void reset_metrics(){
resetting = true;
while (run){}
fps_stats.clear();
resetting = false;
}
~fpsMetrics(){
terminate = true;
{

@ -20,7 +20,7 @@ static void* get_egl_proc_address(const char* name) {
void *func = nullptr;
static void *(*pfn_eglGetProcAddress)(const char*) = nullptr;
if (!pfn_eglGetProcAddress) {
void *handle = real_dlopen("libEGL.so.1", RTLD_LAZY);
void *handle = real_dlopen("libEGL.so.1", RTLD_LAZY|RTLD_LOCAL);
if (!handle) {
SPDLOG_ERROR("Failed to open " MANGOHUD_ARCH " libEGL.so.1: {}", dlerror());
} else {
@ -35,7 +35,7 @@ static void* get_egl_proc_address(const char* name) {
func = get_proc_address( name );
if (!func) {
SPDLOG_ERROR("Failed to get function '{}'", name);
SPDLOG_DEBUG("Failed to get function '{}'", name);
}
return func;

@ -19,7 +19,6 @@
#include <glad/glad.h>
#include "gl_hud.h"
#include "../config.h"
using namespace MangoHud::GL;

@ -46,7 +46,6 @@ void getNvidiaGpuInfo(const struct overlay_params& params){
gpu_info.CoreClock = nvidiaCoreClock;
gpu_info.MemClock = nvidiaMemClock;
gpu_info.powerUsage = nvidiaPowerUsage / 1000;
gpu_info.fan_rpm = false;
gpu_info.memoryTotal = nvidiaMemory.total / (1024.f * 1024.f * 1024.f);
gpu_info.fan_speed = nvidiaFanSpeed;
if (params.enabled[OVERLAY_PARAM_ENABLED_throttling_status]){
@ -56,10 +55,8 @@ void getNvidiaGpuInfo(const struct overlay_params& params){
}
#ifdef HAVE_XNVCTRL
static bool nvctrl_available = checkXNVCtrl();
if (nvctrl_available) {
gpu_info.fan_rpm = true;
if (nvctrl_available)
gpu_info.fan_speed = getNvctrlFanSpeed();
}
#endif
return;
@ -75,7 +72,6 @@ void getNvidiaGpuInfo(const struct overlay_params& params){
gpu_info.MemClock = nvctrl_info.MemClock;
gpu_info.powerUsage = 0;
gpu_info.memoryTotal = nvctrl_info.memoryTotal;
gpu_info.fan_rpm = true;
gpu_info.fan_speed = nvctrl_info.fan_speed;
return;
}
@ -126,9 +122,8 @@ void getAmdGpuInfo(){
if (fscanf(amdgpu.fan, "%" PRId64, &value) != 1)
value = 0;
gpu_info.fan_speed = value;
gpu_info.fan_rpm = true;
}
if (amdgpu.vram_total) {
rewind(amdgpu.vram_total);
fflush(amdgpu.vram_total);

@ -44,7 +44,6 @@ struct gpuInfo{
float gtt_used;
int fan_speed;
int voltage;
bool fan_rpm;
};
extern struct gpuInfo gpu_info;

@ -15,7 +15,6 @@ EXPORT_C_(void*) dlsym(void * handle, const char * name)
find_egl_ptr = reinterpret_cast<decltype(find_egl_ptr)> (real_dlsym(RTLD_NEXT, "mangohud_find_egl_ptr"));
void* func = nullptr;
bool is_angle = real_dlsym(handle, "eglStreamPostD3DTextureANGLE");
void* real_func = real_dlsym(handle, name);
if (find_glx_ptr && real_func) {
@ -26,7 +25,7 @@ EXPORT_C_(void*) dlsym(void * handle, const char * name)
}
}
if (find_egl_ptr && real_func && !is_angle) {
if (find_egl_ptr && real_func) {
func = find_egl_ptr(name);
if (func) {
//fprintf(stderr,"%s: local: %s\n", __func__ , name);

@ -98,7 +98,6 @@ void HudElements::convert_colors(const struct overlay_params& params)
HUDElements.colors.fps_value_med = convert(params.fps_color[1]);
HUDElements.colors.fps_value_high = convert(params.fps_color[2]);
HUDElements.colors.text_outline = convert(params.text_outline_color);
HUDElements.colors.network = convert(params.network_color);
ImGuiStyle& style = ImGui::GetStyle();
style.Colors[ImGuiCol_PlotLines] = convert(params.frametime_color);
@ -162,9 +161,7 @@ static void ImGuiTableSetColumnIndex(int column)
void HudElements::time(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_time]){
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_horizontal] &&
!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_hud_compact] &&
!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_time_no_label]){
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_horizontal] && !HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_hud_compact]){
ImguiNextColumnFirstItem();
HUDElements.TextColored(HUDElements.colors.text, "Time");
ImguiNextColumnOrNewRow();
@ -253,14 +250,16 @@ void HudElements::gpu_stats(){
ImguiNextColumnOrNewRow();
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.fan_speed);
ImGui::SameLine(0, 1.0f);
if (gpu_info.fan_rpm) {
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.text, "RPM");
} else {
// if Nvidia GPU
if (HUDElements.vendorID == 0x10de) {
HUDElements.TextColored(HUDElements.colors.text, "%%");
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::SameLine(0, 1.0f);
HUDElements.TextColored(HUDElements.colors.text, "FAN");
// if AMD GPU
} else if (HUDElements.vendorID == 0x1002) {
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.text, "RPM");
}
ImGui::PopFont();
}
@ -813,7 +812,7 @@ void HudElements::frame_timing(){
ImPlot::SetupAxes(nullptr, nullptr, ax_flags_x, ax_flags_y);
ImPlot::SetupAxisScale(ImAxis_Y1, TransformForward_Custom, TransformInverse_Custom);
ImPlot::SetupAxesLimits(0, 200, min_time, max_time);
ImPlot::SetNextLineStyle(HUDElements.colors.frametime, 1.5);
ImPlot::SetNextLineStyle(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), 1.5);
ImPlot::PlotLine("frametime line", frametime_data.data(), frametime_data.size());
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_throttling_status_graph] && throttling){
ImPlot::SetNextLineStyle(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), 1.5);
@ -941,9 +940,8 @@ void HudElements::_exec(){
ImGui::PushFont(HUDElements.sw_stats->font1);
ImguiNextColumnFirstItem();
for (auto& item : HUDElements.exec_list){
if (item.pos == HUDElements.place){
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", item.ret.c_str());
}
if (item.pos == HUDElements.place)
HUDElements.TextColored(HUDElements.colors.text, "%s", item.ret.c_str());
}
ImGui::PopFont();
}
@ -1085,24 +1083,25 @@ void HudElements::gamescope_frame_timing(){
static double min_time = 0.0f;
static double max_time = 50.0f;
if (HUDElements.gamescope_debug_app.size() > 0 && HUDElements.gamescope_debug_app.back() > -1){
ImguiNextColumnFirstItem();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.engine, "%s", "App");
ImGui::TableNextRow();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
auto min = std::min_element(HUDElements.gamescope_debug_app.begin(),
HUDElements.gamescope_debug_app.end());
auto max = std::max_element(HUDElements.gamescope_debug_app.begin(),
HUDElements.gamescope_debug_app.end());
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
HUDElements.TextColored(HUDElements.colors.engine, "%s", "App");
ImGui::TableSetColumnIndex(ImGui::TableGetColumnCount() - 1);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width * 1.3, "min: %.1fms, max: %.1fms", min[0], max[0]);
ImGui::Dummy(ImVec2(0.0f, real_font_size.y / 2));
ImguiNextColumnFirstItem();
ImGui::PopFont();
ImguiNextColumnFirstItem();
char hash[40];
snprintf(hash, sizeof(hash), "##%s", overlay_param_names[OVERLAY_PARAM_ENABLED_frame_timing]);
HUDElements.sw_stats->stat_selector = OVERLAY_PLOTS_frame_timing;
HUDElements.sw_stats->time_dividor = 1000000.0f; /* ns -> ms */
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
if (ImGui::BeginChild("gamescope_app_window", ImVec2(ImGui::GetWindowContentRegionWidth(), 50))) {
ImGui::PlotLines("", HUDElements.gamescope_debug_app.data(),
@ -1144,7 +1143,6 @@ void HudElements::gamescope_frame_timing(){
void HudElements::device_battery()
{
#ifdef __linux__
std::unique_lock<std::mutex> l(device_lock);
if (!HUDElements.params->device_battery.empty()) {
if (device_found) {
for (int i = 0; i < device_count; i++) {
@ -1359,6 +1357,7 @@ void HudElements::graphs(){
ImGui::PopFont();
ImGui::Dummy(ImVec2(0.0f,5.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
ImguiNextColumnOrNewRow();
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_histogram]){
ImGui::PlotLines("", arr.data(),
arr.size(), 0,
@ -1412,12 +1411,10 @@ void HudElements::hdr() {
void HudElements::refresh_rate() {
if (HUDElements.refresh > 0) {
ImGui::PushFont(HUDElements.sw_stats->font1);
ImguiNextColumnFirstItem();
HUDElements.TextColored(HUDElements.colors.engine, "%s", "Display Hz");
ImguiNextColumnOrNewRow();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", HUDElements.refresh);
ImGui::PopFont();
}
}
@ -1426,55 +1423,13 @@ void HudElements::winesync() {
HUDElements.winesync_ptr = std::make_unique<WineSync>();
if (HUDElements.winesync_ptr->valid()) {
ImGui::PushFont(HUDElements.sw_stats->font1);
ImguiNextColumnFirstItem();
HUDElements.TextColored(HUDElements.colors.engine, "%s", "WSYNC");
ImguiNextColumnOrNewRow();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", HUDElements.winesync_ptr->get_method().c_str());
ImGui::PopFont();
}
}
void HudElements::present_mode() {
ImguiNextColumnFirstItem();
ImGui::PushFont(HUDElements.sw_stats->font1);
if (HUDElements.is_vulkan)
HUDElements.TextColored(HUDElements.colors.engine, "%s", "Present Mode");
else
HUDElements.TextColored(HUDElements.colors.engine, "%s", "VSYNC");
ImguiNextColumnOrNewRow();
HUDElements.TextColored(HUDElements.colors.text, "%s\n", HUDElements.get_present_mode().c_str());
ImGui::PopFont();
}
void HudElements::network() {
#ifdef __linux__
if (HUDElements.net && HUDElements.net->should_reset)
HUDElements.net.reset(new Net);
if (!HUDElements.net)
HUDElements.net = std::make_unique<Net>();
for (auto& iface : HUDElements.net->interfaces){
ImGui::TableNextRow();
ImGui::TableNextColumn();
HUDElements.TextColored(HUDElements.colors.network, "%.8s", iface.name.c_str());
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.0f", iface.txBps / 1000.f);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.text, "KB/s %s", ICON_FK_ARROW_UP);
ImGui::PopFont();
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.0f", iface.rxBps / 1000.f);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.text, "KB/s %s", ICON_FK_ARROW_DOWN);
ImGui::PopFont();
}
#endif
}
void HudElements::sort_elements(const std::pair<std::string, std::string>& option) {
const auto& param = option.first;
const auto& value = option.second;
@ -1520,10 +1475,7 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
{"fps_metrics", {fps_metrics}},
{"hdr", {hdr}},
{"refresh_rate", {refresh_rate}},
{"winesync", {winesync}},
{"present_mode", {present_mode}},
{"network", {network}}
{"winesync", {winesync}}
};
auto check_param = display_params.find(param);
@ -1585,8 +1537,6 @@ void HudElements::legacy_elements(){
ordered_functions.push_back({vram, "vram", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_ram])
ordered_functions.push_back({ram, "ram", value});
if (!params->network.empty())
ordered_functions.push_back({network, "network", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_battery])
ordered_functions.push_back({battery, "battery", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_fan])
@ -1595,6 +1545,8 @@ void HudElements::legacy_elements(){
ordered_functions.push_back({gamescope_fsr, "gamescope_fsr", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_hdr])
ordered_functions.push_back({hdr, "hdr", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_refresh_rate])
ordered_functions.push_back({refresh_rate, "refresh_rate", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_throttling_status])
ordered_functions.push_back({throttling_status, "throttling_status", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_fps])
@ -1646,20 +1598,11 @@ void HudElements::legacy_elements(){
ordered_functions.push_back({duration, "duration", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_winesync])
ordered_functions.push_back({winesync, "winesync", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_present_mode])
ordered_functions.push_back({present_mode, "present_mode", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_refresh_rate])
ordered_functions.push_back({refresh_rate, "refresh_rate", value});
}
void HudElements::update_exec(){
#ifdef __linux__
if (!HUDElements.shell)
HUDElements.shell = std::make_unique<Shell>();
for(auto& item : exec_list)
item.ret = HUDElements.shell->exec(item.value + "\n");
#endif
item.ret = exec(item.value);
}
HudElements HUDElements;

@ -6,11 +6,6 @@
#include "timing.hpp"
#include <functional>
#include "winesync.h"
#include "vulkan/vulkan.h"
#include <array>
#include "net.h"
#include "overlay_params.h"
#include "shell.h"
struct Function {
std::function<void()> run; // Using std::function instead of a raw function pointer for more flexibility
@ -31,7 +26,7 @@ class HudElements{
float ralign_width;
float old_scale;
float res_width, res_height;
bool is_vulkan = true, gamemode_bol = false, vkbasalt_bol = false;
bool is_vulkan, gamemode_bol = false, vkbasalt_bol = false;
int place;
int text_column = 1;
int table_columns_count = 0;
@ -53,10 +48,6 @@ class HudElements{
int hdr_status = 0;
int refresh = 0;
std::unique_ptr<WineSync> winesync_ptr = nullptr;
std::unique_ptr<Net> net = nullptr;
#ifdef __linux__
std::unique_ptr<Shell> shell = nullptr;
#endif
void sort_elements(const std::pair<std::string, std::string>& option);
void legacy_elements();
@ -101,8 +92,6 @@ class HudElements{
static void hdr();
static void refresh_rate();
static void winesync();
static void present_mode();
static void network();
void convert_colors(const struct overlay_params& params);
void convert_colors(bool do_conv, const struct overlay_params& params);
@ -130,41 +119,10 @@ class HudElements{
fps_value_low,
fps_value_med,
fps_value_high,
text_outline,
network;
text_outline;
} colors {};
void TextColored(ImVec4 col, const char *fmt, ...);
std::array<VkPresentModeKHR, 6> presentModes = {
VK_PRESENT_MODE_FIFO_RELAXED_KHR,
VK_PRESENT_MODE_IMMEDIATE_KHR,
VK_PRESENT_MODE_MAILBOX_KHR,
VK_PRESENT_MODE_FIFO_KHR,
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR,
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR};
std::map<VkPresentModeKHR, std::string> presentModeMap = {
{VK_PRESENT_MODE_IMMEDIATE_KHR, "IMMEDIATE"},
{VK_PRESENT_MODE_MAILBOX_KHR, "MAILBOX"},
{VK_PRESENT_MODE_FIFO_KHR, "FIFO"},
{VK_PRESENT_MODE_FIFO_RELAXED_KHR, "FIFO Relaxed"},
{VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, "DEMAND"},
{VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, "CONTINUOUS"}
};
VkPresentModeKHR cur_present_mode;
std::string get_present_mode(){
if (is_vulkan)
return presentModeMap[cur_present_mode];
// TODO: the opengl side is probably not as solid.
// But it also might not be possible to figure out if vsync
// is on or off unless we specify it.
else
return params->gl_vsync == 0 ? "OFF" : "ON";
}
};
extern HudElements HUDElements;

@ -62,6 +62,8 @@ void Intel::intel_gpu_thread(){
if (exitcode == 1)
SPDLOG_INFO("Missing permissions for '{}'", "intel_gpu_top");
SPDLOG_INFO("Disabling gpu_stats");
HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_stats] = false;
}
}
@ -99,6 +101,7 @@ FILE* Intel::find_fd() {
if (found_driver){
if(strstr(line, "drm-engine-render")){
sscanf(line, "drm-engine-render: %" SCNu64 " ns", &val);
if (val > 0)
return file;
}
}

@ -32,7 +32,7 @@ class Intel {
runtime = true;
fdinfo = find_fd();
// thread = std::thread(&Intel::intel_gpu_thread, this);
thread = std::thread(&Intel::intel_gpu_thread, this);
}
void update() {
@ -42,10 +42,10 @@ class Intel {
gpu_info = gpu_info_intel;
}
// ~Intel(){
// stop = true;
// thread.join();
// }
~Intel(){
stop = true;
thread.join();
}
};
extern std::unique_ptr<Intel> intel;

@ -1,15 +1,8 @@
#include <cstdint>
#include <cstring>
#include <array>
#include <algorithm>
#include <unistd.h>
#include "overlay.h"
#include "timing.hpp"
#include "logging.h"
#include "keybinds.h"
#include "fps_metrics.h"
Clock::time_point last_f2_press, toggle_fps_limit_press, toggle_preset_press, last_f12_press, reload_cfg_press, last_upload_press;
void check_keybinds(struct overlay_params& params, uint32_t vendorID){
using namespace std::chrono_literals;
@ -26,7 +19,7 @@ void check_keybinds(struct overlay_params& params, uint32_t vendorID){
return;
last_check = now;
const auto keyPressDelay = 400ms;
auto keyPressDelay = 400ms;
if (elapsedF2 >= keyPressDelay &&
keys_are_pressed(params.toggle_logging)) {
@ -101,11 +94,4 @@ void check_keybinds(struct overlay_params& params, uint32_t vendorID){
next_hud_position(params);
last_f12_press = now;
}
if (elapsedF12 >= keyPressDelay &&
keys_are_pressed(params.reset_fps_metrics)) {
last_f12_press = now;
if (fpsmetrics)
fpsmetrics->reset_metrics();
}
}

@ -6,50 +6,37 @@
#include "shared_x11.h"
#include "loaders/loader_x11.h"
#endif
#ifdef HAVE_WAYLAND
#include "wayland_hook.h"
#endif
#ifndef KeySym
typedef unsigned long KeySym;
#endif
#if defined(HAVE_X11) || defined(HAVE_WAYLAND)
static inline bool keys_are_pressed(const std::vector<KeySym>& keys)
{
#if defined(HAVE_WAYLAND)
if(wl_display_ptr && wl_handle)
{
update_wl_queue();
Clock::time_point last_f2_press, toggle_fps_limit_press, toggle_preset_press, last_f12_press, reload_cfg_press, last_upload_press;
if(wl_pressed_keys.size() == keys.size() && wl_pressed_keys == keys)
return true;
}
#endif
#if defined(HAVE_X11)
static inline bool keys_are_pressed(const std::vector<KeySym>& keys) {
#if defined(HAVE_X11)
if (init_x11())
{
char keys_return[32];
size_t pressed = 0;
if (!init_x11())
return false;
auto libx11 = get_libx11();
libx11->XQueryKeymap(get_xdisplay(), keys_return);
char keys_return[32];
size_t pressed = 0;
for (KeySym ks : keys) {
KeyCode kc2 = libx11->XKeysymToKeycode(get_xdisplay(), ks);
auto libx11 = get_libx11();
libx11->XQueryKeymap(get_xdisplay(), keys_return);
bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
for (KeySym ks : keys) {
KeyCode kc2 = libx11->XKeysymToKeycode(get_xdisplay(), ks);
if (isPressed)
pressed++;
}
bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
if (pressed > 0 && pressed == keys.size()) {
return true;
}
if (isPressed)
pressed++;
}
if (pressed > 0 && pressed == keys.size()) {
return true;
}
#endif
return false;
}
@ -69,6 +56,10 @@ static inline bool keys_are_pressed(const std::vector<KeySym>& keys) {
return false;
}
#else // XXX: Add wayland support
static inline bool keys_are_pressed(const std::vector<KeySym>& keys) {
return false;
}
#endif
#endif //MANGOHUD_KEYBINDS_H

@ -36,7 +36,7 @@ bool libnvctrl_loader::Load(const std::string& library_name) {
#if defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN)
library_ = dlopen(library_name.c_str(), RTLD_LAZY);
if (!library_) {
SPDLOG_DEBUG("Failed to open " MANGOHUD_ARCH " {}: {}", library_name, dlerror());
SPDLOG_ERROR("Failed to open " MANGOHUD_ARCH " {}: {}", library_name, dlerror());
return false;
}

@ -1,7 +1,6 @@
#include <sstream>
#include <iomanip>
#include <array>
#include <algorithm>
#include <spdlog/spdlog.h>
#include "logging.h"
#include "overlay.h"
@ -27,8 +26,7 @@ string exec(string command) {
#endif
std::array<char, 128> buffer;
std::string result;
auto deleter = [](FILE* ptr){ pclose(ptr); };
std::unique_ptr<FILE, decltype(deleter)> pipe(popen(command.c_str(), "r"), deleter);
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(command.c_str(), "r"), pclose);
if (!pipe) {
return "popen failed!";
}
@ -72,24 +70,12 @@ static void writeSummary(string filename){
SPDLOG_DEBUG("Writing summary log file [{}]", filename);
std::ofstream out(filename, ios::out | ios::app);
if (out){
out << "0.1% Min FPS," << "1% Min FPS," << "97% Percentile FPS," << "Average FPS," << "GPU Load," << "CPU Load," << "Average Frame Time," << "Average GPU Temp," << "Average CPU Temp," << "Average VRAM Used," << "Average RAM Used," << "Average Swap Used," << "Peak GPU Load," << "Peak CPU Load," << "Peak GPU Temp," << "Peak CPU Temp," << "Peak VRAM Used," << "Peak RAM Used," << "Peak Swap Used" << "\n";
out << "0.1% Min FPS," << "1% Min FPS," << "97% Percentile FPS," << "Average FPS," << "GPU Load," << "CPU Load" << "\n";
std::vector<logData> sorted = logArray;
std::sort(sorted.begin(), sorted.end(), compareByFps);
float total = 0.0f;
float total_gpu = 0.0f;
float total_cpu = 0.0f;
int total_gpu_temp = 0.0f;
int total_cpu_temp = 0.0f;
float total_vram = 0.0f;
float total_ram = 0.0f;
float total_swap = 0.0f;
int peak_gpu = 0.0f;
float peak_cpu = 0.0f;
int peak_gpu_temp = 0.0f;
int peak_cpu_temp = 0.0f;
float peak_vram = 0.0f;
float peak_ram = 0.0f;
float peak_swap = 0.0f;
float total_gpu = 0.0f;
float result;
float percents[2] = {0.001, 0.01};
for (auto percent : percents){
@ -104,66 +90,21 @@ static void writeSummary(string filename){
// 97th percentile
result = sorted.empty() ? 0.0f : 1000 / sorted[floor(0.97 * (sorted.size() - 1))].frametime;
out << fixed << setprecision(1) << result << ",";
// avg + peak
// avg
total = 0;
for (auto input : sorted){
total = total + input.frametime;
total_gpu = total_gpu + input.gpu_load;
total_cpu = total_cpu + input.cpu_load;
total_gpu_temp = total_gpu_temp + input.gpu_temp;
total_cpu_temp = total_cpu_temp + input.cpu_temp;
total_vram = total_vram + input.gpu_vram_used;
total_ram = total_ram + input.ram_used;
total_swap = total_swap + input.swap_used;
peak_gpu = std::max(peak_gpu, input.gpu_load);
peak_cpu = std::max(peak_cpu, input.cpu_load);
peak_gpu_temp = std::max(peak_gpu_temp, input.gpu_temp);
peak_cpu_temp = std::max(peak_cpu_temp, input.cpu_temp);
peak_vram = std::max(peak_vram, input.gpu_vram_used);
peak_ram = std::max(peak_ram, input.ram_used);
peak_swap = std::max(peak_swap, input.swap_used);
total_gpu = total_gpu + input.gpu_load;
}
// Average FPS
result = 1000 / (total / sorted.size());
out << fixed << setprecision(1) << result << ",";
// GPU Load (Average)
// GPU
result = total_gpu / sorted.size();
out << result << ",";
// CPU Load (Average)
// CPU
result = total_cpu / sorted.size();
out << result << ",";
// Average Frame Time
result = total / sorted.size();
out << result << ",";
// Average GPU Temp
result = total_gpu_temp / sorted.size();
out << result << ",";
// Average CPU Temp
result = total_cpu_temp / sorted.size();
out << result << ",";
// Average VRAM Used
result = total_vram / sorted.size();
out << result << ",";
// Average RAM Used
result = total_ram / sorted.size();
out << result << ",";
// Average Swap Used
result = total_swap / sorted.size();
out << result << ",";
// Peak GPU Load
out << peak_gpu << ",";
// Peak CPU Load
out << peak_cpu << ",";
// Peak GPU Temp
out << peak_gpu_temp << ",";
// Peak CPU Temp
out << peak_cpu_temp << ",";
// Peak VRAM Used
out << peak_vram << ",";
// Peak RAM Used
out << peak_ram << ",";
// Peak Swap Used
out << peak_swap;
out << result;
} else {
SPDLOG_ERROR("Failed to write log file");
}
@ -364,9 +305,6 @@ void Logger::calculate_benchmark_data(){
string label;
float mins[2] = {0.01f, 0.001f};
for (auto percent : mins){
if (sorted.empty())
continue;
size_t percentile_pos = sorted.size() * percent;
percentile_pos = std::min(percentile_pos, sorted.size() - 1);
float result = 1000 / sorted[percentile_pos];

@ -8,7 +8,5 @@
dlsym;
mangohud_find_glx_ptr;
mangohud_find_egl_ptr;
wl_display_connect;
wl_display_connect_to_fd;
local: *;
};

@ -59,7 +59,7 @@ vklayer_files = files(
'config.cpp',
'gpu.cpp',
'blacklist.cpp',
'file_utils.cpp'
'file_utils.cpp',
)
opengl_files = []
@ -91,9 +91,7 @@ if is_unixy
'device.cpp',
'amdgpu.cpp',
'intel.cpp',
'msm.cpp',
'net.cpp',
'shell.cpp'
'msm.cpp'
)
opengl_files = files(
@ -145,20 +143,11 @@ if is_unixy
'loaders/loader_x11.cpp',
'shared_x11.cpp',
)
endif
opengl_files += files(
'loaders/loader_glx.cpp',
'gl/inject_glx.cpp',
)
if get_option('with_wayland').enabled()
pre_args += '-DHAVE_WAYLAND'
vklayer_files += files(
'wayland_hook.cpp',
'wayland_keybinds.cpp'
)
endif
if dbus_dep.found() and get_option('with_dbus').enabled()
@ -278,9 +267,6 @@ if is_unixy
endif
if get_option('mangoapp')
if not get_option('with_x11').enabled()
error('mangoapp also needs \'with_x11\'')
endif
pre_args += '-DIMGUI_IMPL_OPENGL_LOADER_GLEW'
pre_args += '-DMANGOAPP'
mangoapp = executable(
@ -300,11 +286,9 @@ if get_option('mangoapp')
dependencies : [
dearimgui_dep,
dep_dl,
dep_vulkan,
spdlog_dep,
dbus_dep,
dep_x11,
dep_wayland_client,
glfw3_dep,
json_dep,
glew_dep,

@ -1,58 +0,0 @@
#include "net.h"
#include "hud_elements.h"
Net::Net() {
should_reset = false;
fs::path net_dir(NETDIR);
if (fs::exists(net_dir) && fs::is_directory(net_dir)) {
for (const auto& entry : fs::directory_iterator(net_dir)) {
if (fs::is_directory(entry.status())) {
auto val = entry.path().filename().string();
if (val == "lo")
continue;
if (!HUDElements.params->network.empty() && HUDElements.params->network.front() == "1") {
interfaces.push_back({entry.path().filename().string(), 0, 0});
} else if (!HUDElements.params->network.empty()){
auto it = std::find(HUDElements.params->network.begin(), HUDElements.params->network.end(), val);
if (it != HUDElements.params->network.end())
interfaces.push_back({entry.path().filename().string(), 0, 0});
}
}
}
}
if (interfaces.empty())
SPDLOG_ERROR("Network: couldn't find any interfaces");
}
void Net::update() {
if (!interfaces.empty()) {
for (auto& iface : interfaces) {
// path to tx_bytes and rx_bytes
std::string txfile = (NETDIR + iface.name + TXFILE);
std::string rxfile = (NETDIR + iface.name + RXFILE);
// amount of bytes at previous update
uint64_t prevTx = iface.txBytes;
uint64_t prevRx = iface.rxBytes;
// current amount of bytes
iface.txBytes = std::stoll(read_line(txfile));
iface.rxBytes = std::stoll(read_line(rxfile));
auto now = std::chrono::steady_clock::now();
// calculate the bytes per second since last update
iface.txBps = calculateThroughput(iface.txBytes, prevTx, iface.previousTime, now);
iface.rxBps = calculateThroughput(iface.rxBytes, prevRx, iface.previousTime, now);
iface.previousTime = now;
}
}
}
uint64_t Net::calculateThroughput(long long currentBytes, long long previousBytes,
std::chrono::steady_clock::time_point previousTime,
std::chrono::steady_clock::time_point currentTime) {
std::chrono::duration<double> elapsed = (currentTime - previousTime);
return static_cast<long long>((currentBytes - previousBytes) / elapsed.count());
}

@ -1,46 +0,0 @@
#pragma once
#include <vector>
#include <string>
#include <stdint.h>
#include "filesystem.h"
#include "file_utils.h"
#include <spdlog/spdlog.h>
#include <iostream>
namespace fs = ghc::filesystem;
#ifndef NETDIR
#define NETDIR "/sys/class/net/"
#endif
#ifndef TXFILE
#define TXFILE "/statistics/tx_bytes"
#endif
#ifndef RXFILE
#define RXFILE "/statistics/rx_bytes"
#endif
class Net {
public:
bool should_reset = false;
struct networkInterface {
std::string name;
uint64_t txBytes;
uint64_t rxBytes;
uint64_t txBps;
uint64_t rxBps;
std::chrono::steady_clock::time_point previousTime;
};
Net();
void update();
std::vector<networkInterface> interfaces = {};
private:
uint64_t calculateThroughput(long long currentBytes, long long previousBytes,
std::chrono::steady_clock::time_point previousTime,
std::chrono::steady_clock::time_point currentTime);
};
extern std::unique_ptr<Net> net;

@ -45,7 +45,7 @@ bool checkXNVCtrl()
auto& nvctrl = get_libnvctrl_loader();
if (!nvctrl.IsLoaded()) {
SPDLOG_DEBUG("XNVCtrl loader failed to load");
SPDLOG_ERROR("XNVCtrl loader failed to load");
return false;
}

@ -5,7 +5,6 @@
#include "overlay.h"
#include "overlay_params.h"
#include "nvctrl.h"
#include "logging.h"
nvmlReturn_t result;
nvmlDevice_t nvidiaDevice;
@ -53,22 +52,16 @@ bool getNVMLInfo(const struct overlay_params& params){
nvmlReturn_t response;
auto& nvml = get_libnvml_loader();
response = nvml.nvmlDeviceGetUtilizationRates(nvidiaDevice, &nvidiaUtilization);
if (params.enabled[OVERLAY_PARAM_ENABLED_gpu_temp] || logger->is_active())
nvml.nvmlDeviceGetTemperature(nvidiaDevice, NVML_TEMPERATURE_GPU, &nvidiaTemp);
if (params.enabled[OVERLAY_PARAM_ENABLED_vram] || logger->is_active())
nvml.nvmlDeviceGetMemoryInfo(nvidiaDevice, &nvidiaMemory);
if (params.enabled[OVERLAY_PARAM_ENABLED_gpu_core_clock] || logger->is_active())
nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_GRAPHICS, &nvidiaCoreClock);
if (params.enabled[OVERLAY_PARAM_ENABLED_gpu_mem_clock] || logger->is_active())
nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_MEM, &nvidiaMemClock);
if (params.enabled[OVERLAY_PARAM_ENABLED_gpu_power] || logger->is_active())
nvml.nvmlDeviceGetPowerUsage(nvidiaDevice, &nvidiaPowerUsage);
nvml.nvmlDeviceGetTemperature(nvidiaDevice, NVML_TEMPERATURE_GPU, &nvidiaTemp);
nvml.nvmlDeviceGetMemoryInfo(nvidiaDevice, &nvidiaMemory);
nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_GRAPHICS, &nvidiaCoreClock);
nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_MEM, &nvidiaMemClock);
nvml.nvmlDeviceGetPowerUsage(nvidiaDevice, &nvidiaPowerUsage);
deviceID = nvidiaPciInfo.pciDeviceId >> 16;
if (params.enabled[OVERLAY_PARAM_ENABLED_throttling_status])
nvml.nvmlDeviceGetCurrentClocksThrottleReasons(nvidiaDevice, &nvml_throttle_reasons);
if (params.enabled[OVERLAY_PARAM_ENABLED_gpu_fan] || logger->is_active())
nvml.nvmlDeviceGetFanSpeed(nvidiaDevice, &nvidiaFanSpeed);
nvml.nvmlDeviceGetFanSpeed(nvidiaDevice, &nvidiaFanSpeed);
if (response == NVML_ERROR_NOT_SUPPORTED) {
if (nvmlSuccess)

@ -26,7 +26,6 @@
#include "fps_metrics.h"
#include "intel.h"
#include "msm.h"
#include "net.h"
#ifdef __linux__
#include <libgen.h>
@ -269,9 +268,6 @@ void update_hud_info_with_frametime(struct swapchain_stats& sw_stats, const stru
hw_update_thread->update(&params, vendorID);
if (fpsmetrics) fpsmetrics->update_thread();
#ifdef __linux__
if (HUDElements.net) HUDElements.net->update();
#endif
sw_stats.fps = 1000000000.0 * sw_stats.n_frames_since_update / elapsed;
@ -666,10 +662,6 @@ void horizontal_separator(struct overlay_params& params) {
void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, bool is_vulkan)
{
{
std::unique_lock<std::mutex> lock(config_mtx);
config_cv.wait(lock, []{ return config_ready; });
}
// data.engine = EngineTypes::GAMESCOPE;
HUDElements.sw_stats = &data; HUDElements.params = &params;
HUDElements.is_vulkan = is_vulkan;
@ -909,7 +901,6 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para
const std::string device_path = path + "/device";
const std::string gpu_metrics_path = device_path + "/gpu_metrics";
if (amdgpu_verify_metrics(gpu_metrics_path)) {
gpu_info.fan_rpm = true;
gpu_metrics_exists = true;
metrics_path = gpu_metrics_path;
throttling = std::make_unique<Throttling>();

@ -41,9 +41,6 @@
#include "fps_metrics.h"
std::unique_ptr<fpsMetrics> fpsmetrics;
std::mutex config_mtx;
std::condition_variable config_cv;
bool config_ready = false;
#if __cplusplus >= 201703L
@ -111,8 +108,8 @@ parse_control(const char *str)
int ret = os_socket_listen_abstract(path.c_str(), 1);
if (ret < 0) {
SPDLOG_DEBUG("Couldn't create socket pipe at '{}'", path);
SPDLOG_DEBUG("ERROR: '{}'", strerror(errno));
SPDLOG_ERROR("Couldn't create socket pipe at '{}'", path);
SPDLOG_ERROR("ERROR: '{}'", strerror(errno));
return ret;
}
@ -159,7 +156,6 @@ parse_string_to_keysym_vec(const char *str)
#define parse_upload_logs parse_string_to_keysym_vec
#define parse_toggle_fps_limit parse_string_to_keysym_vec
#define parse_toggle_preset parse_string_to_keysym_vec
#define parse_reset_fps_metrics parse_string_to_keysym_vec
#else
#define parse_toggle_hud(x) {}
@ -170,7 +166,6 @@ parse_string_to_keysym_vec(const char *str)
#define parse_upload_logs(x) {}
#define parse_toggle_fps_limit(x) {}
#define parse_toggle_preset(x) {}
#define parse_reset_fps_metrics(x) {}
#endif
// NOTE: This is NOT defined as an OVERLAY_PARAM and will be called manually
@ -486,7 +481,6 @@ parse_fps_metrics(const char *str){
#define parse_text_color(s) parse_color(s)
#define parse_media_player_color(s) parse_color(s)
#define parse_wine_color(s) parse_color(s)
#define parse_network_color(s) parse_color(s)
#define parse_gpu_load_color(s) parse_load_color(s)
#define parse_cpu_load_color(s) parse_load_color(s)
#define parse_gpu_load_value(s) parse_load_value(s)
@ -502,7 +496,6 @@ parse_fps_metrics(const char *str){
#define parse_text_outline_color(s) parse_color(s)
#define parse_text_outline_thickness(s) parse_float(s)
#define parse_device_battery(s) parse_str_tokenize(s)
#define parse_network(s) parse_str_tokenize(s)
static bool
parse_help(const char *str)
@ -576,116 +569,61 @@ const char *overlay_param_names[] = {
#undef OVERLAY_PARAM_CUSTOM
};
static void
initialize_preset(struct overlay_params *params)
{
if (params->options.find("preset") != params->options.end()) {
auto presets = parse_preset(params->options.find("preset")->second.c_str());
if (!presets.empty())
params->preset = presets;
}
current_preset = params->preset[0];
}
static void
set_parameters_from_options(struct overlay_params *params)
{
bool read_cfg = false;
if (params->options.find("read_cfg") != params->options.end() && params->options.find("read_cfg")->second != "0")
read_cfg = true;
if (params->options.find("full") != params->options.end() && params->options.find("full")->second != "0") {
#define OVERLAY_PARAM_BOOL(name) \
params->enabled[OVERLAY_PARAM_ENABLED_##name] = 1;
#define OVERLAY_PARAM_CUSTOM(name)
OVERLAY_PARAMS
#undef OVERLAY_PARAM_BOOL
#undef OVERLAY_PARAM_CUSTOM
params->enabled[OVERLAY_PARAM_ENABLED_histogram] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_fps_only] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_battery_icon] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_mangoapp_steam] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_hide_fsr_sharpness] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_throttling_status] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_fcat] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_horizontal] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_hud_no_margin] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_log_versioning] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_hud_compact] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_exec_name] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_trilinear] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_bicubic] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_retro] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_debug] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_engine_short_names] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_dynamic_frame_timing] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_temp_fahrenheit] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_duration] = false;
params->enabled[OVERLAY_PARAM_ENABLED_core_bars] = false;
params->enabled[OVERLAY_PARAM_ENABLED_read_cfg] = read_cfg;
params->enabled[OVERLAY_PARAM_ENABLED_time_no_label] = false;
params->options.erase("full");
}
for (auto& it : params->options) {
#define OVERLAY_PARAM_BOOL(name) \
if (it.first == #name) { \
params->enabled[OVERLAY_PARAM_ENABLED_##name] = \
strtol(it.second.c_str(), NULL, 0); \
continue; \
}
#define OVERLAY_PARAM_CUSTOM(name) \
if (it.first == #name) { \
params->name = parse_##name(it.second.c_str()); \
continue; \
}
OVERLAY_PARAMS
#undef OVERLAY_PARAM_BOOL
#undef OVERLAY_PARAM_CUSTOM
if (it.first == "preset") {
continue; // Handled above
}
SPDLOG_ERROR("Unknown option '{}'", it.first.c_str());
}
}
static void
parse_overlay_env(struct overlay_params *params,
const char *env, bool use_existing_preset)
const char *env)
{
const char *env_start = env;
uint32_t num;
char key[256], value[256];
while ((num = parse_string(env, key, value)) != 0) {
trim_char(key);
trim_char(value);
env += num;
if (!strcmp("preset", key)) {
if (!use_existing_preset) {
add_to_options(params, key, value);
initialize_preset(params);
}
break;
}
}
presets(current_preset, params);
env = env_start;
while ((num = parse_string(env, key, value)) != 0) {
trim_char(key);
trim_char(value);
env += num;
if (!strcmp("preset", key)) {
continue; // Avoid 'Unknown option' error
if (!strcmp("full", key)) {
bool read_cfg = params->enabled[OVERLAY_PARAM_ENABLED_read_cfg];
#define OVERLAY_PARAM_BOOL(name) \
params->enabled[OVERLAY_PARAM_ENABLED_##name] = 1;
#define OVERLAY_PARAM_CUSTOM(name)
OVERLAY_PARAMS
#undef OVERLAY_PARAM_BOOL
#undef OVERLAY_PARAM_CUSTOM
params->enabled[OVERLAY_PARAM_ENABLED_histogram] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_gpu_load_change] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_cpu_load_change] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_fps_only] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_fps_color_change] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_core_load_change] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_battery_icon] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_mangoapp_steam] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_hide_fsr_sharpness] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_throttling_status] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_read_cfg] = read_cfg;
params->enabled[OVERLAY_PARAM_ENABLED_fcat] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_horizontal] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_horizontal_stretch] = 1;
params->enabled[OVERLAY_PARAM_ENABLED_hud_no_margin] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_log_versioning] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_hud_compact] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_exec_name] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_trilinear] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_bicubic] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_retro] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_debug] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_engine_short_names] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_dynamic_frame_timing] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_temp_fahrenheit] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_core_bars] = false;
}
#define OVERLAY_PARAM_BOOL(name) \
if (!strcmp(#name, key)) { \
params->enabled[OVERLAY_PARAM_ENABLED_##name] = \
strtol(value, NULL, 0); \
add_to_options(params, key, value); \
continue; \
}
#define OVERLAY_PARAM_CUSTOM(name) \
if (!strcmp(#name, key)) { \
params->name = parse_##name(value); \
add_to_options(params, key, value); \
continue; \
}
@ -694,7 +632,6 @@ parse_overlay_env(struct overlay_params *params,
#undef OVERLAY_PARAM_CUSTOM
SPDLOG_ERROR("Unknown option '{}'", key);
}
set_parameters_from_options(params);
}
static void set_param_defaults(struct overlay_params *params){
@ -758,7 +695,6 @@ static void set_param_defaults(struct overlay_params *params){
params->background_color = 0x020202;
params->text_color = 0xffffff;
params->media_player_color = 0xffffff;
params->network_color = 0xe07b85;
params->media_player_name = "";
params->font_scale = 1.0f;
params->wine_color = 0xeb5b5b;
@ -794,15 +730,11 @@ parse_overlay_config(struct overlay_params *params,
.preset = use_existing_preset ? params->preset : default_preset
};
set_param_defaults(params);
if (!use_existing_preset) {
current_preset = params->preset[0];
}
#ifdef HAVE_X11
params->toggle_hud = { XK_Shift_R, XK_F12 };
params->toggle_hud_position = { XK_Shift_R, XK_F11 };
params->toggle_preset = { XK_Shift_R, XK_F10 };
params->reset_fps_metrics = { XK_Shift_R, XK_F9};
params->toggle_fps_limit = { XK_Shift_L, XK_F1 };
params->toggle_logging = { XK_Shift_L, XK_F2 };
params->reload_cfg = { XK_Shift_L, XK_F4 };
@ -813,7 +745,6 @@ parse_overlay_config(struct overlay_params *params,
#ifdef _WIN32
params->toggle_hud = { VK_F12 };
params->toggle_preset = { VK_F10 };
params->reset_fps_metrics = { VK_F9};
params->toggle_fps_limit = { VK_F3 };
params->toggle_logging = { VK_F2 };
params->reload_cfg = { VK_F4 };
@ -833,31 +764,77 @@ parse_overlay_config(struct overlay_params *params,
HUDElements.ordered_functions.clear();
HUDElements.exec_list.clear();
params->options.clear();
HUDElements.options.clear();
// first pass with env var
if (env)
parse_overlay_env(params, env, use_existing_preset);
parse_overlay_env(params, env);
bool read_cfg = params->enabled[OVERLAY_PARAM_ENABLED_read_cfg];
bool env_contains_preset = params->options.find("preset") != params->options.end();
if (!env || read_cfg) {
// Get config options
parseConfigFile(*params);
if (!use_existing_preset && !env_contains_preset) {
initialize_preset(params);
if (!use_existing_preset) {
if (params->options.find("preset") != params->options.end()) {
auto presets = parse_preset(params->options.find("preset")->second.c_str());
if (!presets.empty())
params->preset = presets;
}
current_preset = params->preset[0];
}
// clear options since we don't want config options to appear first
params->options.clear();
HUDElements.options.clear();
// add preset options
presets(current_preset, params);
// potentially override preset options with config options
parseConfigFile(*params);
set_parameters_from_options(params);
if (params->options.find("full") != params->options.end() && params->options.find("full")->second != "0") {
#define OVERLAY_PARAM_BOOL(name) \
params->enabled[OVERLAY_PARAM_ENABLED_##name] = 1;
#define OVERLAY_PARAM_CUSTOM(name)
OVERLAY_PARAMS
#undef OVERLAY_PARAM_BOOL
#undef OVERLAY_PARAM_CUSTOM
params->enabled[OVERLAY_PARAM_ENABLED_histogram] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_fps_only] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_battery_icon] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_mangoapp_steam] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_hide_fsr_sharpness] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_throttling_status] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_fcat] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_horizontal] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_hud_no_margin] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_log_versioning] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_hud_compact] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_exec_name] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_trilinear] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_bicubic] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_retro] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_debug] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_engine_short_names] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_dynamic_frame_timing] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_temp_fahrenheit] = 0;
params->enabled[OVERLAY_PARAM_ENABLED_duration] = false;
params->enabled[OVERLAY_PARAM_ENABLED_core_bars] = false;
params->options.erase("full");
}
for (auto& it : params->options) {
#define OVERLAY_PARAM_BOOL(name) \
if (it.first == #name) { \
params->enabled[OVERLAY_PARAM_ENABLED_##name] = \
strtol(it.second.c_str(), NULL, 0); \
continue; \
}
#define OVERLAY_PARAM_CUSTOM(name) \
if (it.first == #name) { \
params->name = parse_##name(it.second.c_str()); \
continue; \
}
OVERLAY_PARAMS
#undef OVERLAY_PARAM_BOOL
#undef OVERLAY_PARAM_CUSTOM
if (it.first == "preset") {
continue;
}
SPDLOG_ERROR("Unknown option '{}'", it.first.c_str());
}
}
// TODO decide what to do for legacy_layout=0
@ -865,7 +842,7 @@ parse_overlay_config(struct overlay_params *params,
if (params->enabled[OVERLAY_PARAM_ENABLED_legacy_layout] && env && read_cfg) {
// If passing legacy_layout=0 to MANGOHUD_CONFIG anyway then clear first pass' results
HUDElements.ordered_functions.clear();
parse_overlay_env(params, env, true);
parse_overlay_env(params, env);
}
// If fps_only param is enabled disable legacy_layout
@ -879,7 +856,7 @@ parse_overlay_config(struct overlay_params *params,
params->font_scale_media_player = 0.55f;
// Convert from 0xRRGGBB to ImGui's format
std::array<unsigned *, 23> colors = {
std::array<unsigned *, 22> colors = {
&params->cpu_color,
&params->gpu_color,
&params->vram_color,
@ -902,7 +879,6 @@ parse_overlay_config(struct overlay_params *params,
&params->fps_color[1],
&params->fps_color[2],
&params->text_outline_color,
&params->network_color,
};
for (auto color : colors){
@ -979,7 +955,6 @@ parse_overlay_config(struct overlay_params *params,
if (params->enabled[OVERLAY_PARAM_ENABLED_legacy_layout]) {
HUDElements.legacy_elements();
} else {
HUDElements.ordered_functions.clear();
for (auto& option : HUDElements.options) {
HUDElements.sort_elements(option);
}
@ -1007,14 +982,6 @@ parse_overlay_config(struct overlay_params *params,
mangoapp_cv.notify_one();
g_fsrSharpness = params->fsr_steam_sharpness;
#endif
if (HUDElements.net)
HUDElements.net->should_reset = true;
{
std::lock_guard<std::mutex> lock(config_mtx);
config_ready = true;
config_cv.notify_one();
}
}
bool parse_preset_config(int preset, struct overlay_params *params){
@ -1029,7 +996,7 @@ bool parse_preset_config(int preset, struct overlay_params *params){
stream.imbue(std::locale::classic());
if (!stream.good()) {
SPDLOG_DEBUG("Failed to read presets file: '{}'. Falling back to default presets", preset_path);
SPDLOG_ERROR("Failed to read presets file: '{}'", preset_path);
return false;
}
@ -1147,11 +1114,6 @@ void presets(int preset, struct overlay_params *params, bool inherit) {
add_to_options(params, "debug", "1");
add_to_options(params, "version", "0");
add_to_options(params, "frame_timing_detailed", "1");
add_to_options(params, "network", "1");
add_to_options(params, "present_mode", "0");
if ( deviceID == 0x1435 || deviceID == 0x163f )
add_to_options(params, "gpu_fan", "0");
break;
}

@ -6,8 +6,6 @@
#include <vector>
#include <unordered_map>
#include <cstdint>
#include <condition_variable>
#include <mutex>
#ifdef __cplusplus
extern "C" {
@ -112,8 +110,6 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_BOOL(refresh_rate) \
OVERLAY_PARAM_BOOL(frame_timing_detailed) \
OVERLAY_PARAM_BOOL(winesync) \
OVERLAY_PARAM_BOOL(present_mode) \
OVERLAY_PARAM_BOOL(time_no_label) \
OVERLAY_PARAM_CUSTOM(fps_sampling_period) \
OVERLAY_PARAM_CUSTOM(output_folder) \
OVERLAY_PARAM_CUSTOM(output_file) \
@ -142,7 +138,6 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(toggle_preset) \
OVERLAY_PARAM_CUSTOM(toggle_fps_limit) \
OVERLAY_PARAM_CUSTOM(toggle_logging) \
OVERLAY_PARAM_CUSTOM(reset_fps_metrics) \
OVERLAY_PARAM_CUSTOM(reload_cfg) \
OVERLAY_PARAM_CUSTOM(upload_log) \
OVERLAY_PARAM_CUSTOM(upload_logs) \
@ -163,7 +158,6 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(text_color) \
OVERLAY_PARAM_CUSTOM(wine_color) \
OVERLAY_PARAM_CUSTOM(battery_color) \
OVERLAY_PARAM_CUSTOM(network_color) \
OVERLAY_PARAM_CUSTOM(alpha) \
OVERLAY_PARAM_CUSTOM(log_duration) \
OVERLAY_PARAM_CUSTOM(pci_dev) \
@ -197,7 +191,6 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(fps_text) \
OVERLAY_PARAM_CUSTOM(device_battery) \
OVERLAY_PARAM_CUSTOM(fps_metrics) \
OVERLAY_PARAM_CUSTOM(network) \
enum overlay_param_position {
LAYER_POSITION_TOP_LEFT,
@ -270,9 +263,7 @@ struct overlay_params {
enum gl_size_query gl_size_query {GL_SIZE_DRAWABLE};
bool gl_dont_flip {false};
int64_t log_duration, log_interval;
unsigned cpu_color, gpu_color, vram_color, ram_color,
engine_color, io_color, frametime_color, background_color,
text_color, wine_color, battery_color, network_color;
unsigned cpu_color, gpu_color, vram_color, ram_color, engine_color, io_color, frametime_color, background_color, text_color, wine_color, battery_color;
std::vector<unsigned> gpu_load_color;
std::vector<unsigned> cpu_load_color;
std::vector<unsigned> gpu_load_value;
@ -295,7 +286,6 @@ struct overlay_params {
std::vector<KeySym> upload_log;
std::vector<KeySym> upload_logs;
std::vector<KeySym> toggle_hud_position;
std::vector<KeySym> reset_fps_metrics;
std::string time_format, output_folder, output_file;
std::string pci_dev;
std::string media_player_name;
@ -322,7 +312,6 @@ struct overlay_params {
float text_outline_thickness;
std::vector<std::string> device_battery;
std::vector<std::string> fps_metrics;
std::vector<std::string> network;
};
const extern char *overlay_param_names[];
@ -332,11 +321,9 @@ void parse_overlay_config(struct overlay_params *params,
void presets(int preset, struct overlay_params *params, bool inherit=false);
bool parse_preset_config(int preset, struct overlay_params *params);
void add_to_options(struct overlay_params *params, std::string option, std::string value);
#ifdef __cplusplus
}
#endif
extern std::mutex config_mtx;
extern std::condition_variable config_cv;
extern bool config_ready;
#endif /* MANGOHUD_OVERLAY_PARAMS_H */

@ -35,11 +35,8 @@ bool init_x11() {
}
failed = !display;
if (failed && displayid)
if (failed)
SPDLOG_ERROR("XOpenDisplay failed to open display '{}'", displayid);
if (!displayid)
SPDLOG_DEBUG("DISPLAY env is not set");
return !!display;
}

@ -1,92 +0,0 @@
#include "shell.h"
#include <thread>
#include <iostream>
#include <sys/wait.h>
#include <spdlog/spdlog.h>
#include "string_utils.h"
#include <array>
std::string Shell::readOutput() {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
std::array<char, 128> buffer;
std::string result;
ssize_t count;
while ((count = ::read(from_shell[0], buffer.data(), buffer.size())) > 0) {
result.append(buffer.data(), count);
}
// Split the result into lines and return the last line
std::istringstream stream(result);
std::string line;
std::string last_line;
while (std::getline(stream, line)) {
last_line = line;
}
SPDLOG_DEBUG("Shell: recieved output: {}", last_line);
return last_line;
}
Shell::Shell() {
static bool failed;
if (pipe(to_shell) == -1) {
SPDLOG_ERROR("Failed to create to_shell pipe: {}", strerror(errno));
failed = true;
}
if (pipe(from_shell) == -1) {
SPDLOG_ERROR("Failed to create from_shell pipe: {}", strerror(errno));
failed = true;
}
// if either pipe fails, there's no point in continuing.
if (failed){
SPDLOG_ERROR("Shell has failed, will not be able to use exec");
return;
}
shell_pid = fork();
if (shell_pid == 0) { // Child process
close(to_shell[1]);
close(from_shell[0]);
dup2(to_shell[0], STDIN_FILENO);
dup2(from_shell[1], STDOUT_FILENO);
dup2(from_shell[1], STDERR_FILENO);
execl("/bin/sh", "sh", nullptr);
exit(1); // Exit if execl fails
} else {
close(to_shell[0]);
close(from_shell[1]);
// Set the read end of the from_shell pipe to non-blocking
setNonBlocking(from_shell[0]);
}
success = true;
}
std::string Shell::exec(std::string cmd) {
if (!success)
return "";
writeCommand(cmd);
return readOutput();
}
void Shell::writeCommand(std::string command) {
if (write(to_shell[1], command.c_str(), command.length()) == -1)
SPDLOG_ERROR("Failed to write to shell");
trim(command);
SPDLOG_DEBUG("Shell: wrote command: {}", command);
}
Shell::~Shell() {
if (write(to_shell[1], "exit\n", 5) == -1)
SPDLOG_ERROR("Failed exit shell");
close(to_shell[1]);
close(from_shell[0]);
waitpid(shell_pid, nullptr, 0);
}

@ -1,35 +0,0 @@
#pragma once
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#ifdef __linux__
#include <sys/wait.h>
#endif
#include <string>
#include <memory>
class Shell {
private:
int to_shell[2];
int from_shell[2];
pid_t shell_pid;
bool success;
#ifdef __linux__
void setNonBlocking(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
#endif
void writeCommand(std::string command);
std::string readOutput();
public:
Shell();
~Shell();
std::string exec(std::string cmd);
};
extern std::unique_ptr<Shell> shell;

@ -50,13 +50,8 @@
#include "notify.h"
#include "blacklist.h"
#include "pci_ids.h"
#if defined(HAVE_WAYLAND)
#include "wayland_hook.h"
#endif
#include "real_dlsym.h"
#include "file_utils.h"
#ifdef __linux__
#include <dlfcn.h>
#include "implot.h"
#endif
@ -1502,14 +1497,6 @@ static struct overlay_draw *before_present(struct swapchain_data *swapchain_data
return draw;
}
static bool IsPresentModeSupported(VkPresentModeKHR targetPresentMode, const std::vector<VkPresentModeKHR>& supportedPresentModes) {
for (const auto& mode : supportedPresentModes)
if (mode == targetPresentMode)
return true;
return false; // Not found
}
static VkResult overlay_CreateSwapchainKHR(
VkDevice device,
const VkSwapchainCreateInfoKHR* pCreateInfo,
@ -1521,35 +1508,12 @@ static VkResult overlay_CreateSwapchainKHR(
createInfo.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
struct device_data *device_data = FIND(struct device_data, device);
auto params = device_data->instance->params;
if (device_data->instance->params.vsync < 4) {
HUDElements.cur_present_mode = HUDElements.presentModes[params.vsync];
createInfo.presentMode = HUDElements.cur_present_mode;
} else {
HUDElements.cur_present_mode = createInfo.presentMode;
}
struct instance_data *instance_data =
FIND(struct instance_data, device_data->physical_device);
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR =
(PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) instance_data->vtable.GetInstanceProcAddr(instance_data->instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
if (fpGetPhysicalDeviceSurfacePresentModesKHR != NULL) {
uint32_t presentModeCount;
std::vector<VkPresentModeKHR> presentModes(6);
VkResult result = fpGetPhysicalDeviceSurfacePresentModesKHR(device_data->physical_device, pCreateInfo->surface, &presentModeCount, presentModes.data());
if (result == VK_SUCCESS) {
if (IsPresentModeSupported(HUDElements.cur_present_mode, presentModes))
SPDLOG_DEBUG("Present mode: {}", HUDElements.presentModeMap[HUDElements.cur_present_mode]);
else {
SPDLOG_DEBUG("Present mode is not supported: {}", HUDElements.presentModeMap[HUDElements.cur_present_mode]);
HUDElements.cur_present_mode = VK_PRESENT_MODE_FIFO_KHR;
}
}
}
array<VkPresentModeKHR, 4> modes = {VK_PRESENT_MODE_FIFO_RELAXED_KHR,
VK_PRESENT_MODE_IMMEDIATE_KHR,
VK_PRESENT_MODE_MAILBOX_KHR,
VK_PRESENT_MODE_FIFO_KHR};
if (device_data->instance->params.vsync < 4)
createInfo.presentMode = modes[device_data->instance->params.vsync];
VkResult result = device_data->vtable.CreateSwapchainKHR(device, &createInfo, pAllocator, pSwapchain);
if (result != VK_SUCCESS) return result;
@ -1805,7 +1769,6 @@ static VkResult overlay_CreateDevice(
pCreateInfo->enabledExtensionCount);
uint32_t extension_count;
instance_data->vtable.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extension_count, nullptr);
std::vector<VkExtensionProperties> available_extensions(extension_count);
@ -2033,23 +1996,6 @@ static void overlay_DestroyInstance(
destroy_instance_data(instance_data);
}
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
static VkResult overlay_CreateWaylandSurfaceKHR(
VkInstance instance,
const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface
)
{
struct instance_data *instance_data = FIND(struct instance_data, instance);
if (!wl_handle)
wl_handle = real_dlopen("libwayland-client.so", RTLD_LAZY);
wl_display_ptr = pCreateInfo->display;
init_wayland_data();
return instance_data->vtable.CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
}
#endif
extern "C" VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL overlay_GetDeviceProcAddr(VkDevice dev,
const char *funcName);
extern "C" VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL overlay_GetInstanceProcAddr(VkInstance instance,
@ -2070,9 +2016,6 @@ static const struct {
ADD_HOOK(EndCommandBuffer),
ADD_HOOK(CmdExecuteCommands),
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
ADD_HOOK(CreateWaylandSurfaceKHR),
#endif
ADD_HOOK(CreateSwapchainKHR),
ADD_HOOK(QueuePresentKHR),
ADD_HOOK(DestroySwapchainKHR),

@ -1,63 +0,0 @@
#include <cstdint>
#include <array>
#include <dlfcn.h>
#include <cstdio>
#include "real_dlsym.h"
#include "wayland_hook.h"
EXPORT_C_(struct wl_display*) wl_display_connect(const char *name);
EXPORT_C_(struct wl_display*) wl_display_connect_to_fd(int fd);
typedef struct wl_display* (*pwl_display_connect)(const char *name);
typedef struct wl_display* (*pwl_display_connect_to_fd)(int fd);
pwl_display_connect wl_display_connect_ptr = nullptr;
pwl_display_connect_to_fd wl_display_connect_to_fd_ptr = nullptr;
void* wl_handle = nullptr;
struct wl_display* wl_display_ptr = nullptr;
EXPORT_C_(struct wl_display*) wl_display_connect(const char *name)
{
struct wl_display *ret = nullptr;
if (!wl_handle) {
wl_handle = real_dlopen("libwayland-client.so", RTLD_LAZY);
}
if (wl_handle) {
wl_display_connect_ptr = (pwl_display_connect)real_dlsym(wl_handle, "wl_display_connect");
wl_display_connect_to_fd_ptr = (pwl_display_connect_to_fd)real_dlsym(wl_handle, "wl_display_connect_to_fd");
ret = wl_display_connect_ptr(name);
if (!wl_display_ptr) {
wl_display_ptr = ret;
init_wayland_data();
}
}
return ret;
}
EXPORT_C_(struct wl_display*) wl_display_connect_to_fd(int fd)
{
struct wl_display *ret = nullptr;
if (!wl_handle) {
wl_handle = real_dlopen("libwayland-client.so", RTLD_LAZY);
}
if (wl_handle) {
wl_display_connect_to_fd_ptr = (pwl_display_connect_to_fd)real_dlsym(wl_handle, "wl_display_connect_to_fd");
wl_display_connect_ptr = (pwl_display_connect)real_dlsym(wl_handle, "wl_display_connect");
ret = wl_display_connect_to_fd_ptr(fd);
if (!wl_display_ptr) {
wl_display_ptr = ret;
init_wayland_data();
}
}
return ret;
}

@ -1,13 +0,0 @@
#include <wayland-client.h>
#include <vector>
#ifndef KeySym
typedef unsigned long KeySym;
#endif
extern void* wl_handle;
extern struct wl_display* wl_display_ptr;
extern std::vector<KeySym> wl_pressed_keys;
void init_wayland_data();
void update_wl_queue();

@ -1,118 +0,0 @@
#include <cstdint>
#include <cstring>
#include <array>
#include <algorithm>
#include <unistd.h>
#include <vector>
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
#include <sys/mman.h>
#include "wayland_hook.h"
#include "timing.hpp"
#include "keybinds.h"
struct wl_seat* seat = nullptr;
struct wl_keyboard* keyboard = nullptr;
struct xkb_context *context_xkb = nullptr;
struct xkb_keymap *keymap_xkb = nullptr;
struct xkb_state *state_xkb = nullptr;
struct wl_event_queue* queue = nullptr;
std::vector<KeySym> wl_pressed_keys {};
static void registry_handle_global(void *data, struct wl_registry* registry, uint32_t name, const char *interface, uint32_t version)
{
if(strcmp(interface, wl_seat_interface.name) == 0)
{
seat = (struct wl_seat*)wl_registry_bind(registry, name, &wl_seat_interface, 7);
}
}
static void registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name){}
static void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size)
{
char* map_shm = (char*)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
if(!context_xkb)
context_xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if(keymap_xkb && state_xkb)
{
xkb_keymap_unref(keymap_xkb);
xkb_state_unref(state_xkb);
}
keymap_xkb = xkb_keymap_new_from_string(
context_xkb, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1,
XKB_KEYMAP_COMPILE_NO_FLAGS);
state_xkb = xkb_state_new(keymap_xkb);
munmap((void*)map_shm, size);
close(fd);
}
static void wl_keyboard_enter(void *user_data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys){}
static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface)
{
wl_pressed_keys.clear();
}
static void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
{
xkb_keycode_t keycode = key + 8;
xkb_keysym_t keysym = xkb_state_key_get_one_sym(state_xkb, keycode);
if(state)
{
wl_pressed_keys.push_back(keysym);
}
else
{
auto it = std::find(wl_pressed_keys.begin(), wl_pressed_keys.end(), keysym);
if(it != wl_pressed_keys.end())
wl_pressed_keys.erase(it);
}
}
static void wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group){}
static void wl_keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay){}
struct wl_registry_listener registry_listener {
.global = registry_handle_global,
.global_remove = registry_handle_global_remove
};
struct wl_keyboard_listener keyboard_listener {
.keymap = wl_keyboard_keymap,
.enter = wl_keyboard_enter,
.leave = wl_keyboard_leave,
.key = wl_keyboard_key,
.modifiers = wl_keyboard_modifiers,
.repeat_info = wl_keyboard_repeat_info
};
void update_wl_queue()
{
wl_display_roundtrip_queue(wl_display_ptr, queue);
}
void init_wayland_data()
{
if (!wl_display_ptr)
return;
struct wl_display *display_wrapped = (struct wl_display*)wl_proxy_create_wrapper(wl_display_ptr);
queue = wl_display_create_queue(wl_display_ptr);
wl_proxy_set_queue((struct wl_proxy*)display_wrapped, queue);
wl_registry *registry = wl_display_get_registry(display_wrapped);
wl_proxy_wrapper_destroy(display_wrapped);
wl_registry_add_listener(registry, &registry_listener, NULL);
update_wl_queue();
update_wl_queue();
keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL);
update_wl_queue();
}

@ -47,8 +47,7 @@ class WineSync {
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
path = paths[i];
for (auto& p : fs::directory_iterator(path)) {
auto filepath = p.path().string();
const char* filename = filepath.c_str();
auto filename = p.path().string().c_str();
auto sym = read_symlink(filename);
if (sym.find("winesync") != std::string::npos)
method = syncMethods::NTSYNC;

@ -1,13 +1,13 @@
[wrap-file]
directory = spdlog-1.14.1
source_url = https://github.com/gabime/spdlog/archive/refs/tags/v1.14.1.tar.gz
source_filename = spdlog-1.14.1.tar.gz
source_hash = 1586508029a7d0670dfcb2d97575dcdc242d3868a259742b69f100801ab4e16b
patch_filename = spdlog_1.14.1-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.14.1-1/get_patch
patch_hash = ae878e732330ea1048f90d7e117c40c0cd2a6fb8ae5492c7955818ce3aaade6c
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/spdlog_1.14.1-1/spdlog-1.14.1.tar.gz
wrapdb_version = 1.14.1-1
directory = spdlog-1.12.0
source_url = https://github.com/gabime/spdlog/archive/refs/tags/v1.12.0.tar.gz
source_filename = spdlog-1.12.0.tar.gz
source_hash = 4dccf2d10f410c1e2feaff89966bfc49a1abb29ef6f08246335b110e001e09a9
patch_filename = spdlog_1.12.0-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.12.0-1/get_patch
patch_hash = 0515906db7324df0e439bdd018bf019a60304430f6af8f1725910652e30ebe69
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/spdlog_1.12.0-1/spdlog-1.12.0.tar.gz
wrapdb_version = 1.12.0-1
[provide]
spdlog = spdlog_dep

Loading…
Cancel
Save