Compare commits
No commits in common. 'master' and 'v0.4.0' 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: # Replace with a single Patreon username
|
||||
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
|
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: "[Bug report] - Issue"
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**List relevant hardware/software information**
|
||||
- Linux Distribution
|
||||
- MangoHud version
|
||||
- GPU
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
@ -1,6 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
@ -1,42 +0,0 @@
|
||||
name: arch package
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-arch-pkg:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: archlinux:latest
|
||||
steps:
|
||||
- name: set git global safe directory
|
||||
run: |
|
||||
pacman -Syu git --noconfirm
|
||||
git config --global --add safe.directory $(realpath .)
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install prerequisites
|
||||
run: |
|
||||
echo "ParallelDownloads = 10" >> /etc/pacman.conf
|
||||
echo "\n" && echo "[multilib]" >> /etc/pacman.conf
|
||||
echo "Include = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
|
||||
pacman -Syu base-devel sudo meson python-mako glslang hub python-numpy python-matplotlib --noconfirm
|
||||
- name: makepkg
|
||||
run: |
|
||||
echo "nobody ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
chown nobody:nobody pkgbuild
|
||||
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"
|
||||
- name: Edit release and add files
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -x
|
||||
assets=()
|
||||
for pkg in ./pkgbuild/*mangohud*.tar.zst;
|
||||
do echo $pkg;
|
||||
assets+=("-a" "$pkg")
|
||||
done;
|
||||
tag_name="${GITHUB_REF##*/}"
|
||||
hub release edit "${assets[@]}" -m "" "$tag_name"
|
@ -1,59 +0,0 @@
|
||||
name: Build release package
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- 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
|
||||
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/
|
||||
- name: Prepare Artifact Git Info
|
||||
shell: bash
|
||||
run: |
|
||||
echo "##[set-output name=branch;]${GITHUB_REF#refs/heads/}"
|
||||
ARTIFACT_NAME="commit-$(git rev-parse --short "$GITHUB_SHA")"
|
||||
if [ ${{ github.event_name == 'pull_request' }} ]; then
|
||||
echo "##[set-output name=short-sha;]$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")"
|
||||
if [ ! -z "${{ github.event.pull_request.number }}" ]; then
|
||||
ARTIFACT_NAME="pr-${{ github.event.pull_request.number }}-commit-$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")"
|
||||
fi
|
||||
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
|
||||
run: |
|
||||
./build-source.sh
|
||||
./build.sh build -Dwerror=true package release
|
||||
- name: Upload assets to release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
tag_name="${GITHUB_REF##*/}"
|
||||
for pkg in ./build/*.tar.*; do
|
||||
gh release upload "$tag_name" "$pkg" --clobber
|
||||
done
|
||||
|
||||
- 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
|
@ -1,33 +0,0 @@
|
||||
name: Build source tars
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
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
|
||||
./build-source.sh
|
||||
assets=()
|
||||
for asset in ./MangoHud-*-Source*.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
|
@ -1,17 +0,0 @@
|
||||
name: Mingw build testing
|
||||
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
build-mingw:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: archlinux:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install prerequisites
|
||||
run: |
|
||||
pacman -Syu mingw-w64-gcc meson python-mako glslang mingw-w64-headers git --noconfirm
|
||||
- name: configure
|
||||
run: meson setup --cross-file mingw64.txt build64
|
||||
- name: build
|
||||
run: ninja -C build64
|
@ -1,23 +0,0 @@
|
||||
name: param check
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'src/overlay_params.h'
|
||||
- 'README.md'
|
||||
- 'data/MangoHud.conf'
|
||||
|
||||
jobs:
|
||||
param-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11.2' # Replace with the version of Python you want to use
|
||||
- name: Run Python script
|
||||
run: |
|
||||
cd tests
|
||||
python params.py
|
@ -1,60 +0,0 @@
|
||||
name: Ubuntu build testing
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build-test:
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: [clang, gcc]
|
||||
os: [ubuntu-22.04, ubuntu-20.04]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: actions/checkout@v3
|
||||
- name: 'Install prerequisites'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
appstream \
|
||||
glslang-tools \
|
||||
ninja-build \
|
||||
python3-mako \
|
||||
python3-setuptools \
|
||||
python3-wheel \
|
||||
mesa-common-dev \
|
||||
libcmocka-dev \
|
||||
libdbus-1-dev \
|
||||
libglew-dev \
|
||||
libglfw3-dev \
|
||||
libwayland-dev \
|
||||
libxnvctrl-dev \
|
||||
libxkbcommon-dev
|
||||
sudo pip3 install 'meson>=0.60'
|
||||
- name: 'Install clang'
|
||||
if: ${{ (matrix.compiler == 'clang') }}
|
||||
run: |
|
||||
sudo apt-get install -y clang
|
||||
echo "CC=clang" >> "$GITHUB_ENV"
|
||||
echo "CXX=clang++" >> "$GITHUB_ENV"
|
||||
- name: 'Install gcc'
|
||||
if: ${{ (matrix.compiler == 'gcc') }}
|
||||
run: |
|
||||
sudo apt-get install -y gcc g++
|
||||
echo "CC=gcc" >> "$GITHUB_ENV"
|
||||
echo "CXX=g++" >> "$GITHUB_ENV"
|
||||
- name: 'Configure'
|
||||
run: meson setup ./builddir --prefix=/usr
|
||||
-D include_doc=true
|
||||
-D with_xnvctrl=enabled
|
||||
-D with_x11=enabled
|
||||
-D with_wayland=enabled
|
||||
-D with_dbus=enabled
|
||||
-D mangoapp=true
|
||||
-D mangohudctl=true
|
||||
-D mangoapp_layer=true
|
||||
-D tests=enabled
|
||||
- name: 'Build'
|
||||
run: meson compile -C ./builddir || ninja -C ./builddir
|
||||
- name: 'Install'
|
||||
run: sudo meson install -C ./builddir
|
@ -1,70 +0,0 @@
|
||||
name: Update Meson Version and Recreate Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
update-version:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: sudo apt-get install -y gh
|
||||
|
||||
- name: Extract version from release
|
||||
id: extract_version
|
||||
run: echo "version=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Fetch release description
|
||||
id: fetch_description
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG_NAME=${{ env.version }}
|
||||
DESCRIPTION=$(gh release view $TAG_NAME --json body -q .body)
|
||||
echo "description=$DESCRIPTION" >> $GITHUB_ENV
|
||||
|
||||
- name: Update meson.build
|
||||
run: |
|
||||
VERSION=${{ env.version }}
|
||||
sed -i "s/^\(\s*version\s*:\s*'\)[^']*'/\1${VERSION}'/" meson.build
|
||||
|
||||
- name: Commit changes
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add meson.build
|
||||
git commit -m "Update version to ${{ env.version }}"
|
||||
git push origin HEAD:refs/heads/master
|
||||
|
||||
- name: Force-update tag
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG_NAME=${{ env.version }}
|
||||
git tag -fa $TAG_NAME -m "Update tag to include version update"
|
||||
git push origin --force $TAG_NAME
|
||||
|
||||
- name: Recreate release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG_NAME=${{ env.version }}
|
||||
DESCRIPTION=${{ env.description }}
|
||||
gh release delete $TAG_NAME --yes
|
||||
gh release create $TAG_NAME --target $(git rev-parse HEAD) --title "$TAG_NAME" --notes "$DESCRIPTION"
|
||||
|
||||
- name: Trigger other workflows
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG_NAME=${{ env.version }}
|
||||
gh workflow run .github/workflows/build-source.yml --ref $TAG_NAME
|
||||
gh workflow run .github/workflows/build-package.yml --ref $TAG_NAME
|
@ -1,3 +1,3 @@
|
||||
[submodule "modules/minhook"]
|
||||
path = modules/minhook
|
||||
url = https://github.com/flightlessmango/minhook
|
||||
[submodule "modules/ImGui/src"]
|
||||
path = modules/ImGui/src
|
||||
url = https://github.com/flightlessmango/imgui.git
|
||||
|
@ -0,0 +1,36 @@
|
||||
pkgname=('mangohud' 'lib32-mangohud')
|
||||
pkgver=r24.b67a2aa
|
||||
pkgrel=1
|
||||
pkgdesc="Vulkan overlay layer to display information about the application"
|
||||
arch=('x86_64')
|
||||
makedepends=('gcc' 'meson' 'python-mako' 'libx11' 'lib32-libx11' 'git')
|
||||
depends=('glslang' 'libglvnd' 'lib32-libglvnd' 'vulkan-headers')
|
||||
replaces=('vulkan-mesa-layer-mango' 'lib32-vulkan-mesa-layer-mango')
|
||||
url="https://github.com/flightlessmango/MangoHud"
|
||||
|
||||
pkgver() {
|
||||
cd $startdir
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
git submodule update --init --depth 50
|
||||
}
|
||||
|
||||
build() {
|
||||
cd $startdir
|
||||
# ./build.sh clean
|
||||
./build.sh build
|
||||
}
|
||||
|
||||
package_mangohud() {
|
||||
provides=("mangohud=${pkgver}")
|
||||
cd $startdir
|
||||
install -Dm664 "build/release/usr/lib64/libMangoHud.so" "${pkgdir}/usr/lib/libMangoHud.so"
|
||||
install -Dm664 "build/release/usr/share/vulkan/implicit_layer.d/mangohud.json" "${pkgdir}/usr/share/vulkan/implicit_layer.d/mangohud.json"
|
||||
}
|
||||
package_lib32-mangohud() {
|
||||
provides=("lib32-mangohud=${pkgver}")
|
||||
cd $startdir
|
||||
install -Dm664 "build/release/usr/lib32/libMangoHud.so" "${pkgdir}/usr/lib32/libMangoHud.so"
|
||||
}
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 56 KiB |
@ -0,0 +1,117 @@
|
||||
### MangoHud configuration file
|
||||
### Uncomment any options you wish to enable. Default options are left uncommented
|
||||
### Use some_parameter=0 to disable a parameter (only works with on/off parameters)
|
||||
### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead
|
||||
|
||||
################ PERFORMANCE #################
|
||||
|
||||
### Limit the application FPS
|
||||
# fps_limit=
|
||||
|
||||
### VSYNC [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on
|
||||
# vsync=
|
||||
|
||||
### OpenGL VSYNC [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a fps limiter (fps = display refresh rate / N)
|
||||
# gl_vsync=
|
||||
|
||||
################### VISUAL ###################
|
||||
|
||||
### Display the current CPU information
|
||||
cpu_stats
|
||||
# cpu_temp
|
||||
|
||||
### Display the current GPU information
|
||||
gpu_stats
|
||||
# gpu_temp
|
||||
# gpu_core_clock
|
||||
# gpu_mem_clock
|
||||
|
||||
### Display loaded MangoHud architecture
|
||||
# arch
|
||||
|
||||
### Display the frametime line graph
|
||||
frame_timing
|
||||
#histogram
|
||||
|
||||
### Display the current system time
|
||||
# time
|
||||
|
||||
### Time formatting examples
|
||||
# time_format = %H:%M
|
||||
# time_format = [ %T %F ]
|
||||
# time_format = %X # locally formatted time, because of limited glyph range, missing characters may show as '?' (e.g. japanese)
|
||||
|
||||
### Change the hud font size (default is 24)
|
||||
font_size=24
|
||||
# font_scale_media_player = 0.55
|
||||
|
||||
### Change the hud position (default is top-left)
|
||||
position=top-left
|
||||
|
||||
### Display the current CPU load & frequency for each core
|
||||
# core_load
|
||||
|
||||
### IO read and write for the app (not system)
|
||||
# io_read
|
||||
# io_write
|
||||
|
||||
### Display system ram / vram usage
|
||||
# ram
|
||||
# vram
|
||||
|
||||
### Disable / hide the hud by deafult
|
||||
# no_display
|
||||
|
||||
### Hud position offset
|
||||
# offset_x=
|
||||
# offset_y=
|
||||
|
||||
### Hud dimensions
|
||||
# width=
|
||||
# height=
|
||||
|
||||
### Hud transparency / alpha
|
||||
background_alpha=0.5
|
||||
# alpha=
|
||||
|
||||
### Color customization
|
||||
# text_color=FFFFFF
|
||||
# gpu_color=2E9762
|
||||
# cpu_color=2E97CB
|
||||
# vram_color=AD64C1
|
||||
# ram_color=C26693
|
||||
# engine_color=EB5B5B
|
||||
# io_color=A491D3
|
||||
# frametime_color=00FF00
|
||||
# background_color=020202
|
||||
# media_player_color=FFFFFF
|
||||
|
||||
### Change default font (set location to .TTF/.OTF file )
|
||||
# font_file
|
||||
|
||||
### Crosshair overlay (default size is 30)
|
||||
# crosshair
|
||||
# crosshair_size=
|
||||
# crosshair_color=RRGGBB
|
||||
|
||||
### Show media player metadata
|
||||
# media_player
|
||||
# media_player_name = spotify
|
||||
|
||||
### Specify gpu with pci bus id for amdgpu and NVML stats.
|
||||
### Set to 'domain:bus:slot.function'
|
||||
# pci_dev = 0:0a:0.0
|
||||
|
||||
################## INTERACTION #################
|
||||
|
||||
### Change toggle keybinds for the hud & logging
|
||||
#toggle_hud=Shift_R+F12
|
||||
#toggle_logging=F2
|
||||
#reload_cfg=Shift_L+F4
|
||||
|
||||
################## LOG #################
|
||||
|
||||
### Set amount of time in second that the logging will run for
|
||||
# log_duration
|
||||
### Define name and location of the output file (Required for logging)
|
||||
# output_file
|
@ -1,58 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
programname=$(basename "$0")
|
||||
echo "ERROR: No program supplied"
|
||||
echo
|
||||
echo "Usage: $programname <program>"
|
||||
exit 1
|
||||
MANGOHUD_LIB_NAME="libMangoHud.so"
|
||||
if [ "$MANGOHUD_DLSYM" = "1" ]; then
|
||||
MANGOHUD_LIB_NAME="libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}"
|
||||
fi
|
||||
|
||||
|
||||
# Add exe names newline separated to the string to disable LD_PRELOAD
|
||||
DISABLE_LD_PRELOAD="cs2.sh
|
||||
"
|
||||
|
||||
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_opengl.so"
|
||||
|
||||
if [ "$1" = "--dlsym" ]; then
|
||||
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}"
|
||||
shift # shift will only be executed if $1 is "--dlsym"
|
||||
elif [ "$MANGOHUD_DLSYM" = "1" ]; then
|
||||
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}"
|
||||
fi
|
||||
|
||||
if [ "$1" = "--version" ]; then
|
||||
echo @version@
|
||||
exit 0
|
||||
if [ "$#" -eq 0 ]; then
|
||||
programname=`basename "$0"`
|
||||
echo "ERROR: No program supplied"
|
||||
echo
|
||||
echo "Usage: $programname <program>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# grab all arguments from command_line
|
||||
command_line="$*"
|
||||
# flag for disable_preload
|
||||
disable_preload=false
|
||||
# Execute the program under a clean environment
|
||||
# pass through the overriden LD_PRELOAD environment variables
|
||||
LD_PRELOAD="${LD_PRELOAD}:${MANGOHUD_LIB_NAME}"
|
||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:@libdir_mangohud@"
|
||||
|
||||
# Check if the script name or any of the executables in DISABLE_LD_PRELOAD are in the command line
|
||||
for exe in $DISABLE_LD_PRELOAD; do
|
||||
if echo "$command_line" | grep -q "$exe"; then
|
||||
disable_preload=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$disable_preload" = true ]; then
|
||||
exec env MANGOHUD=1 "$@"
|
||||
if hash @mangohud_sh@ 2>/dev/null; then
|
||||
exec env MANGOHUD=1 LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" LD_PRELOAD="${LD_PRELOAD}" @mangohud_sh@ "$@"
|
||||
else
|
||||
# Make sure we don't append mangohud lib multiple times
|
||||
# otherwise, this could cause issues with the steam runtime
|
||||
case ":${LD_PRELOAD-}:" in
|
||||
(*:$MANGOHUD_LIB_NAME:*)
|
||||
;;
|
||||
(*)
|
||||
# Preload using the plain filenames of the libs, the dynamic linker will
|
||||
# figure out whether the 32 or 64 bit version should be used
|
||||
LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}${MANGOHUD_LIB_NAME}"
|
||||
esac
|
||||
|
||||
exec env MANGOHUD=1 LD_PRELOAD="${LD_PRELOAD}" "$@"
|
||||
exec env MANGOHUD=1 LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" LD_PRELOAD="${LD_PRELOAD}" "$@"
|
||||
fi
|
||||
|
@ -1,447 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
r"""
|
||||
Script to plot all the MangoHud benchmarks contained in a given folder.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import csv
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.widgets import Cursor
|
||||
from matplotlib.colors import LinearSegmentedColormap
|
||||
from matplotlib.ticker import EngFormatter
|
||||
|
||||
plt.rcParams['font.family'] = "Lato,serif"
|
||||
plt.rcParams['font.weight'] = "600"
|
||||
|
||||
background_color = "#1A1C1D"
|
||||
legend_facecolor = "#585f63"
|
||||
legend_textcolor = "#cccbc9"
|
||||
text_color = "#e8e6e3"
|
||||
mango_color = "#BB770A"
|
||||
graphbox_linewidth = 1.5
|
||||
|
||||
mango_cmap = LinearSegmentedColormap.from_list("mango_heat", [background_color, mango_color])
|
||||
|
||||
def identity(val):
|
||||
r"""
|
||||
returns the value as-is
|
||||
"""
|
||||
return val
|
||||
|
||||
|
||||
def get_integer(val: str) -> int:
|
||||
r"""
|
||||
interprets the str 'val' as an integer and returns it
|
||||
"""
|
||||
if is_integer(val):
|
||||
return int(val)
|
||||
else:
|
||||
raise ValueError("Casting a non integer value: ", val)
|
||||
|
||||
|
||||
def is_integer(s: str) -> bool:
|
||||
r"""
|
||||
tests if 's' is an integer and returns a bool
|
||||
"""
|
||||
try:
|
||||
int(s)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
def get_float(val):
|
||||
r"""
|
||||
interprets the str 'val' as a float and returns it
|
||||
"""
|
||||
if is_float(val):
|
||||
return float(val)
|
||||
else:
|
||||
return float("nan")
|
||||
|
||||
|
||||
def is_float(s: str) -> bool:
|
||||
r"""
|
||||
tests if 's' is an float and returns a bool
|
||||
"""
|
||||
try:
|
||||
float(s)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
class Database:
|
||||
r"""
|
||||
A class that contains all the csv files within
|
||||
the folder that it is instanced with
|
||||
"""
|
||||
def __init__(self,
|
||||
data_folder_path=None,
|
||||
csv_separator=" ",
|
||||
filename_var_separator="|"):
|
||||
|
||||
self.datafiles = []
|
||||
self.result_names_col = None
|
||||
self.result_values_col = None
|
||||
self.sim_settings_names_col = None
|
||||
self.sim_settings_values_col = None
|
||||
|
||||
if data_folder_path:
|
||||
self.load_from_folder(
|
||||
data_folder_path,
|
||||
csv_separator,
|
||||
filename_var_separator)
|
||||
|
||||
def load_from_folder(self,
|
||||
data_folder_path,
|
||||
csv_separator=" ",
|
||||
filename_var_separator="|"):
|
||||
r"""
|
||||
Load all CSV files form the given folder
|
||||
"""
|
||||
filepaths = list(Path(data_folder_path).rglob("*.csv"))
|
||||
|
||||
self.datafiles = []
|
||||
N = len(filepaths)
|
||||
|
||||
print(f"Loading {N} benchmark files")
|
||||
for filepath in filepaths:
|
||||
try:
|
||||
datafile = BenchmarkFile(
|
||||
str(filepath),
|
||||
csv_separator=csv_separator,
|
||||
filename_var_separator=filename_var_separator)
|
||||
self.datafiles.append(datafile)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self.datafiles.sort()
|
||||
|
||||
|
||||
class BenchmarkFile:
|
||||
r"""
|
||||
A class that represents a single CSV file, can load CSV files
|
||||
with arbitrary separators. It can return separately any column
|
||||
of the file and any mathematical combinations of its columns.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
filepath="",
|
||||
filename_var_separator="|",
|
||||
csv_separator=" "):
|
||||
self.csv_separator = csv_separator
|
||||
self.filepath = Path(filepath)
|
||||
self.filename = self.filepath.name
|
||||
self.filename_var_separator = filename_var_separator
|
||||
self.variables = dict()
|
||||
|
||||
self.skip_lines = None
|
||||
|
||||
self.columns = []
|
||||
self.column_name_to_index = dict()
|
||||
|
||||
self._is_data_loaded = False
|
||||
|
||||
if not self.filepath.is_file():
|
||||
raise Exception("CSV file does not exist")
|
||||
|
||||
self._read_column_names()
|
||||
|
||||
def __lt__(self, other):
|
||||
stem = self.filename[:-4] # remove the trailing ".csv"
|
||||
other_stem = other.filename[:-4]
|
||||
if stem.startswith(other_stem):
|
||||
return False
|
||||
elif stem.startswith(other_stem):
|
||||
return True
|
||||
else:
|
||||
return stem < other_stem
|
||||
|
||||
def set_variable(self, name, value):
|
||||
r"""
|
||||
Saves a variable within the datafile instance
|
||||
Note: it will not be saved to disk, it's just a helper method to
|
||||
attach variables to a given data file.
|
||||
"""
|
||||
self.variables[name] = value
|
||||
|
||||
def get_variable(self, name):
|
||||
r"""
|
||||
Retrieves a saved variable in the instance
|
||||
"""
|
||||
return self.variables[name]
|
||||
|
||||
def _read_column_names(self):
|
||||
r"""
|
||||
Read the first few lines of the benchmark file
|
||||
to look for the row taht contains the benchmark's
|
||||
column names i.e. "fps", "frametime", "cpu_load"... etc
|
||||
and save the columns names and their index
|
||||
|
||||
Note: we decide that we found the right row by looking if it
|
||||
contains "fps"
|
||||
not the best approach, but it works TM
|
||||
"""
|
||||
|
||||
with open(self.filepath) as open_file:
|
||||
reader = csv.reader(open_file, delimiter=self.csv_separator)
|
||||
|
||||
found_fps_column = False
|
||||
for row_number, row_content in enumerate(reader):
|
||||
if row_number > 4:
|
||||
# if we're past the 4th row, break the loop
|
||||
break
|
||||
|
||||
if "fps" in row_content:
|
||||
self.skip_lines = row_number + 1
|
||||
found_fps_column = True
|
||||
|
||||
for col, col_name in enumerate(row_content):
|
||||
if col_name in self.column_name_to_index:
|
||||
raise Exception("Two columns have the same name")
|
||||
self.column_name_to_index[col_name] = col
|
||||
|
||||
if not found_fps_column:
|
||||
raise Exception("Not a benchmark file")
|
||||
|
||||
def _load_data(self):
|
||||
r"""
|
||||
Load the benchmark data into memory.
|
||||
"""
|
||||
|
||||
def extend_columns(new_column_num):
|
||||
current_row_num = 0
|
||||
if self.columns:
|
||||
current_row_num = len(self.columns[0])
|
||||
assert (all([len(column) == current_row_num for column in self.columns]))
|
||||
|
||||
current_column_num = len(self.columns)
|
||||
if new_column_num >= current_column_num:
|
||||
self.columns += [["" for j in range(current_row_num)] for i in range(new_column_num - current_column_num)]
|
||||
|
||||
# no need to load data if it's already loaded
|
||||
if self._is_data_loaded:
|
||||
return
|
||||
|
||||
with open(self.filepath) as open_file:
|
||||
reader = csv.reader(open_file, delimiter=self.csv_separator)
|
||||
self._is_data_loaded = True
|
||||
|
||||
for row_number, row_content in enumerate(reader):
|
||||
if row_number <= self.skip_lines:
|
||||
continue
|
||||
|
||||
extend_columns(len(row_content))
|
||||
for col, val in enumerate(row_content):
|
||||
self.columns[col].append(val)
|
||||
|
||||
# Delete any eventual empty column
|
||||
if all([val == "" for val in self.columns[-1]]):
|
||||
del self.columns[-1]
|
||||
|
||||
def get_column_names(self) -> List[str]:
|
||||
r"""
|
||||
Returns the list of columns names of the csv file.
|
||||
"""
|
||||
|
||||
return list(self.column_name_to_index.keys())
|
||||
|
||||
def get(self, col: str, data_type: str = "float") \
|
||||
-> Union[List[float], List[str], List[int], List[complex]]:
|
||||
r"""
|
||||
Returns the column `col`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
col : str
|
||||
The desired column name to retrieve, or its index
|
||||
|
||||
data_type : str
|
||||
"string", "integer" or "float", the type to cast
|
||||
the data to before returning it.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
A list of `data_type` containing the column `col`
|
||||
|
||||
"""
|
||||
|
||||
if not self._is_data_loaded:
|
||||
self._load_data()
|
||||
|
||||
if len(self.columns) == 0:
|
||||
raise ValueError("Datafile empty, can't return any data")
|
||||
|
||||
data_caster_dict = {
|
||||
"string": identity,
|
||||
"float": get_float,
|
||||
"integer": get_integer
|
||||
}
|
||||
|
||||
if data_type not in data_caster_dict:
|
||||
raise ValueError("the given `data_type' doesn't match any "
|
||||
"known types. Which are `string', `integer', "
|
||||
"`float' or `complex'")
|
||||
|
||||
if is_integer(col):
|
||||
# the column's index is given
|
||||
return [data_caster_dict[data_type](val) for val in self.columns[col]]
|
||||
|
||||
if col in self.column_name_to_index:
|
||||
# a column name has been given
|
||||
return [data_caster_dict[data_type](val)
|
||||
for val in self.columns[self.column_name_to_index[col]]]
|
||||
|
||||
raise Exception("Column {} does not exist".format(col))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Plot all the MangoHud benchmarks contained in a given folder.')
|
||||
|
||||
parser.add_argument('folder', metavar='folder', nargs=1,
|
||||
help='path the a MangoHud benchmark folder')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
bench_folder_path = Path(args.folder[0])
|
||||
|
||||
if not bench_folder_path.is_dir():
|
||||
print(f"The path '{bench_folder_path.absolute()}' "
|
||||
"does not point to an existing folder")
|
||||
exit(1)
|
||||
|
||||
fps_subdivs = 1.0 # one division every fps_subdivs FPS
|
||||
|
||||
y_labels = [] # bench files
|
||||
x_labels = [] # FPS subidivions
|
||||
|
||||
database = Database(bench_folder_path, csv_separator=',')
|
||||
distributions = []
|
||||
|
||||
if len(database.datafiles) == 0:
|
||||
print(f"The folder \n {bench_folder_path.absolute()} \n"
|
||||
"contains no CSV file "
|
||||
"(make sure they have the .csv extension)")
|
||||
exit(1)
|
||||
|
||||
for datafile in database.datafiles:
|
||||
bar_distribution = []
|
||||
|
||||
# sort array to get percentiles
|
||||
fps_array = np.sort(datafile.get("fps"))
|
||||
|
||||
# save percentiles
|
||||
if len(fps_array) < 10000:
|
||||
print(f"'{datafile.filename}' simulation "
|
||||
"isn't long enough for precise statistics")
|
||||
datafile.set_variable("selected", False)
|
||||
continue
|
||||
|
||||
# Save label only if this file has long enough simulation
|
||||
y_labels.append(datafile.filename[:-4])
|
||||
datafile.set_variable("selected", True)
|
||||
|
||||
# Save percentiles
|
||||
datafile.set_variable("0.1%", fps_array[int(float(len(fps_array))*0.001)])
|
||||
datafile.set_variable("1%", fps_array[int(float(len(fps_array))*0.01)])
|
||||
datafile.set_variable("50%", fps_array[int(float(len(fps_array))*0.5)])
|
||||
|
||||
datafile.set_variable("average fps", np.average(fps_array))
|
||||
|
||||
for frame_num, fps in enumerate(fps_array):
|
||||
if fps > 1000:
|
||||
print("FPS value above 1000, omitting outlier.")
|
||||
continue
|
||||
index = int(fps/fps_subdivs)
|
||||
for i in range(len(bar_distribution), index+1):
|
||||
bar_distribution.append(0)
|
||||
bar_distribution[index] += 1
|
||||
distributions.append(bar_distribution)
|
||||
|
||||
if not distributions:
|
||||
print("Nothing to plot, exiting.")
|
||||
exit(1)
|
||||
|
||||
num_benchs = len(distributions)
|
||||
max_size = 0
|
||||
for distrib in distributions:
|
||||
max_size = max(max_size, len(distrib))
|
||||
for distrib in distributions:
|
||||
for i in range(len(distrib), max_size):
|
||||
distrib.append(0)
|
||||
|
||||
for i in range(max_size):
|
||||
x_labels.append(str(fps_subdivs * i))
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
|
||||
# change color of the graph box to the same color as the text
|
||||
for spine in ['left', 'right', 'bottom', 'top']:
|
||||
ax.spines[spine].set_color(text_color)
|
||||
ax.spines[spine].set_linewidth(graphbox_linewidth)
|
||||
|
||||
im = ax.imshow(distributions,
|
||||
aspect="auto",
|
||||
extent=[0, max_size*fps_subdivs, 0, num_benchs],
|
||||
cmap=mango_cmap)
|
||||
|
||||
# draw thick line that separates each benchmark
|
||||
for i in range(len(y_labels)+1):
|
||||
ax.axhline(float(i), color=text_color, lw=graphbox_linewidth)
|
||||
|
||||
i = 0
|
||||
for datafile in database.datafiles:
|
||||
if datafile.get_variable("selected"):
|
||||
kwargs = dict(ymin=(num_benchs-i-1+0.15)/num_benchs,
|
||||
ymax=(num_benchs-i-0.15)/num_benchs,
|
||||
lw=3)
|
||||
|
||||
ax.axvline(datafile.get_variable("0.1%"),
|
||||
color='#35260f',
|
||||
label=("0.1%" if i == 0 else None), **kwargs)
|
||||
|
||||
ax.axvline(datafile.get_variable("1%"),
|
||||
color='#6E4503',
|
||||
label=("1%" if i == 0 else None), **kwargs)
|
||||
|
||||
ax.axvline(datafile.get_variable("50%"),
|
||||
color='#0967BA',
|
||||
label=("50%" if i == 0 else None), **kwargs)
|
||||
|
||||
ax.axvline(datafile.get_variable("average fps"),
|
||||
color='#003A6E',
|
||||
label=("Average" if i == 0 else None), **kwargs)
|
||||
i += 1
|
||||
|
||||
ax.tick_params(axis='y', colors=text_color)
|
||||
ax.tick_params(axis='x', colors=text_color)
|
||||
ax.set_yticks(np.arange(len(y_labels)-0.5, 0, -1), labels=y_labels)
|
||||
ax.grid(False)
|
||||
|
||||
fig.set_facecolor(background_color)
|
||||
|
||||
ax.ticklabel_format(axis='x', style='plain')
|
||||
|
||||
formatter0 = EngFormatter(unit='FPS')
|
||||
ax.xaxis.set_major_formatter(formatter0)
|
||||
|
||||
plt.tight_layout()
|
||||
plt.legend(facecolor=legend_facecolor, labelcolor=legend_textcolor)
|
||||
|
||||
cursor = Cursor(ax,
|
||||
horizOn=False,
|
||||
color='#6c49abff',
|
||||
linewidth=4,
|
||||
useblit=True)
|
||||
|
||||
plt.show()
|
@ -1,7 +0,0 @@
|
||||
# runtime dependencies for `mangoplot`: matplotlib and a GUI backed like PyQt5
|
||||
install_data(
|
||||
'mangoplot.py',
|
||||
install_dir: get_option('bindir'),
|
||||
rename: 'mangoplot',
|
||||
install_mode: 'rwxr-xr-x'
|
||||
)
|
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
MANGOHUD_LIB_NAME="libMangoHud.so"
|
||||
if [ "$MANGOHUD_NODLSYM" = "1" ]; then
|
||||
MANGOHUD_LIB_NAME="libMangoHud_nodlsym.so"
|
||||
fi
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
programname=`basename "$0"`
|
||||
echo "ERROR: No program supplied"
|
||||
echo
|
||||
echo "Usage: $programname <program>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute the program under a clean environment
|
||||
# pass through the overriden LD_PRELOAD environment variables
|
||||
LD_PRELOAD="${LD_PRELOAD}:${MANGOHUD_LIB_NAME}"
|
||||
|
||||
exec env MANGOHUD=1 LD_PRELOAD="${LD_PRELOAD}" "$@"
|
@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
MANGOHUD_LIB_NAME="libMangoHud.so:libMangoHud32.so"
|
||||
if [ "$MANGOHUD_NODLSYM" = "1" ]; then
|
||||
MANGOHUD_LIB_NAME="libMangoHud_nodlsym.so:libMangoHud_nodlsym32.so"
|
||||
fi
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
programname=`basename "$0"`
|
||||
echo "ERROR: No program supplied"
|
||||
echo
|
||||
echo "Usage: $programname <program>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute the program under a clean environment
|
||||
# pass through the overriden LD_PRELOAD environment variables
|
||||
LD_PRELOAD="${LD_PRELOAD}:${MANGOHUD_LIB_NAME}"
|
||||
LD_LIBRARY_PATH="${XDG_DATA_HOME}/MangoHud"
|
||||
|
||||
echo $LD_LIBRARY_PATH
|
||||
exec env MANGOHUD=1 LD_LIBRARY_PATH="$LD_LIBRARY_PATH" LD_PRELOAD="${LD_PRELOAD}" "$@"
|
@ -1,40 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
VERSION=$(git describe --tags --dirty)
|
||||
NAME=MangoHud-${VERSION}
|
||||
TAR_NAME=${NAME}-Source.tar.xz
|
||||
DFSG_TAR_NAME=${NAME}-Source-DFSG.tar.xz
|
||||
VERSION=$(git describe --tags --dirty=+)
|
||||
|
||||
# remove existing files
|
||||
rm -rf sourcedir
|
||||
rm -rf ${NAME}
|
||||
rm -f ${TAR_NAME}
|
||||
rm -f ${DFSG_TAR_NAME}
|
||||
FILE_PATTERN="--exclude-vcs --exclude-vcs-ignores ."
|
||||
|
||||
# create tarball with meson
|
||||
meson setup sourcedir
|
||||
meson dist --formats=xztar --include-subprojects --no-tests -C sourcedir
|
||||
mv sourcedir/meson-dist/*.tar.xz ${TAR_NAME}
|
||||
|
||||
# create DFSG compliant version
|
||||
# unpack since tarball is compressed
|
||||
mkdir ${NAME}
|
||||
tar -xf ${TAR_NAME} --strip 1 -C ${NAME}
|
||||
# nvml.h is not DFSG compliant
|
||||
rm ${NAME}/include/nvml.h
|
||||
# minhook not needed
|
||||
rm -r ${NAME}/modules/minhook
|
||||
# spdlog from system
|
||||
rm -r ${NAME}/subprojects/spdlog-*
|
||||
# nlohmann_json from system
|
||||
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
|
||||
# compress new sources
|
||||
tar -cJf ${DFSG_TAR_NAME} ${NAME}
|
||||
|
||||
# cleanup
|
||||
rm -r sourcedir
|
||||
rm -r ${NAME}
|
||||
# default version
|
||||
tar -czf MangoHud-$VERSION-Source.tar.gz $FILE_PATTERN
|
||||
# DFSG compliant version, excludes NVML
|
||||
tar -czf MangoHud-$VERSION-Source-DFSG.tar.gz --exclude=include/nvml.h $FILE_PATTERN
|
||||
|
@ -1,161 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Specialized build script for Steam Runtime SDK docker
|
||||
set -e
|
||||
|
||||
IFS=" " read -ra debian_chroot < /etc/debian_chroot
|
||||
LOCAL_CC=${CC:-gcc-5}
|
||||
LOCAL_CXX=${CXX:-g++-5}
|
||||
RUNTIME=${RUNTIME:-${debian_chroot[1]}}
|
||||
SRT_VERSION=${SRT_VERSION:-${debian_chroot[2]}}
|
||||
VERSION=$(git describe --long --tags --always | sed 's/\([^-]*-g\)/r\1/;s/-/./g;s/^v//')
|
||||
|
||||
dependencies() {
|
||||
|
||||
if [[ ! -f build-srt/release/usr/lib/libMangoHud.so ]]; then
|
||||
install() {
|
||||
set +e
|
||||
for i in ${DEPS[@]}; do
|
||||
dpkg-query -s "$i" &> /dev/null
|
||||
if [[ $? == 1 ]]; then
|
||||
INSTALL="$INSTALL""$i "
|
||||
fi
|
||||
done
|
||||
if [[ ! -z "$INSTALL" ]]; then
|
||||
apt-get update
|
||||
apt-get -y install $INSTALL
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
echo "# Checking Dependencies"
|
||||
DEPS=(${LOCAL_CC}-multilib ${LOCAL_CXX}-multilib unzip)
|
||||
install
|
||||
|
||||
|
||||
# use py3.5 with scout, otherwise hope python is new enough
|
||||
set +e
|
||||
which python3.5 >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# py3.2 is weird
|
||||
ln -sf python3.5 /usr/bin/python3
|
||||
fi
|
||||
set -e
|
||||
|
||||
if [[ ! -f ./bin/get-pip.py ]]; then
|
||||
curl https://bootstrap.pypa.io/pip/3.5/get-pip.py -o bin/get-pip.py
|
||||
python3 ./bin/get-pip.py
|
||||
fi
|
||||
pip3 install 'meson>=0.54' mako
|
||||
|
||||
if [[ ! -f /usr/include/NVCtrl/NVCtrl.h ]]; then
|
||||
curl -LO http://mirrors.kernel.org/ubuntu/pool/main/n/nvidia-settings/libxnvctrl0_440.64-0ubuntu1_amd64.deb
|
||||
curl -LO http://mirrors.kernel.org/ubuntu/pool/main/n/nvidia-settings/libxnvctrl-dev_440.64-0ubuntu1_amd64.deb
|
||||
dpkg -i libxnvctrl0_440.64-0ubuntu1_amd64.deb libxnvctrl-dev_440.64-0ubuntu1_amd64.deb
|
||||
fi
|
||||
|
||||
# preinstalled 7.10.xxxx
|
||||
#if [[ ! -f /usr/local/bin/glslangValidator ]]; then
|
||||
# curl -LO https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-linux-Release.zip
|
||||
# unzip glslang-master-linux-Release.zip bin/glslangValidator
|
||||
# /usr/bin/install -m755 bin/glslangValidator /usr/local/bin/
|
||||
# rm bin/glslangValidator glslang-master-linux-Release.zip
|
||||
#fi
|
||||
fi
|
||||
}
|
||||
|
||||
configure() {
|
||||
dependencies
|
||||
git submodule update --init
|
||||
if [[ ! -f "build-srt/meson64/build.ninja" ]]; then
|
||||
export CC="${LOCAL_CC}"
|
||||
export CXX="${LOCAL_CXX}"
|
||||
meson build-srt/meson64 --libdir lib/mangohud/lib --prefix /usr -Dappend_libdir_mangohud=false $@ ${CONFIGURE_OPTS}
|
||||
fi
|
||||
if [[ ! -f "build-srt/meson32/build.ninja" ]]; then
|
||||
export CC="${LOCAL_CC} -m32"
|
||||
export CXX="${LOCAL_CXX} -m32"
|
||||
export PKG_CONFIG_PATH="/usr/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib/pkgconfig:${PKG_CONFIG_PATH_32}"
|
||||
meson build-srt/meson32 --libdir lib/mangohud/lib32 --prefix /usr -Dappend_libdir_mangohud=false $@ ${CONFIGURE_OPTS}
|
||||
fi
|
||||
}
|
||||
|
||||
build() {
|
||||
if [[ ! -f "build-srt/meson64/build.ninja" || ! -f "build-srt/meson32/build.ninja" ]]; then
|
||||
configure $@
|
||||
fi
|
||||
DESTDIR="$PWD/build-srt/release" ninja -C build-srt/meson32 install
|
||||
DESTDIR="$PWD/build-srt/release" ninja -C build-srt/meson64 install
|
||||
}
|
||||
|
||||
package() {
|
||||
LIB="build-srt/release/usr/lib/mangohud/lib/libMangoHud.so"
|
||||
LIB32="build-srt/release/usr/lib/mangohud/lib32/libMangoHud.so"
|
||||
if [[ ! -f "$LIB" || "$LIB" -ot "build-srt/meson64/src/libMangoHud.so" ]]; then
|
||||
build
|
||||
fi
|
||||
tar --numeric-owner --owner=0 --group=0 \
|
||||
-C build-srt/release -cvf "build-srt/MangoHud-package.tar" .
|
||||
}
|
||||
|
||||
release() {
|
||||
rm build-srt/MangoHud-package.tar
|
||||
mkdir -p build-srt/MangoHud
|
||||
package
|
||||
cp --preserve=mode bin/mangohud-setup.sh build-srt/MangoHud/mangohud-setup.sh
|
||||
cp build-srt/MangoHud-package.tar build-srt/MangoHud/MangoHud-package.tar
|
||||
tar --numeric-owner --owner=0 --group=0 \
|
||||
-C build-srt -czvf build-srt/MangoHud-${VERSION}_${RUNTIME}-${SRT_VERSION}.tar.gz MangoHud
|
||||
}
|
||||
|
||||
clean() {
|
||||
rm -rf "build-srt/"
|
||||
}
|
||||
|
||||
usage() {
|
||||
if test -z $1; then
|
||||
echo "Unrecognized command argument: $a"
|
||||
else
|
||||
echo "$0 requires one argument"
|
||||
fi
|
||||
echo -e "\nUsage: $0 <command>\n"
|
||||
echo "Available commands:"
|
||||
echo -e "\tpull\t\tPull latest commits (code) from Git"
|
||||
echo -e "\tconfigure\tEnsures that dependencies are installed, updates git submodules, and generates files needed for building MangoHud. This is automatically run by the build command"
|
||||
echo -e "\tbuild\t\tIf needed runs configure and then builds (compiles) MangoHud"
|
||||
echo -e "\tpackage\t\tRuns build if needed and then builds a tar package from MangoHud"
|
||||
echo -e "\tclean\t\tRemoves build directory"
|
||||
echo -e "\trelease\t\tBuilds a MangoHud release tar package"
|
||||
}
|
||||
|
||||
if [[ -z $@ ]]; then
|
||||
usage no-args
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
OPTS=()
|
||||
arg="$1"
|
||||
shift
|
||||
|
||||
while [ $# -gt 0 ] ; do
|
||||
case $1 in
|
||||
-*)
|
||||
OPTS+=("$1")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac;
|
||||
done
|
||||
|
||||
echo -e "\e[1mCommand:\e[92m" $arg "\e[94m"${OPTS[@]}"\e[39m\e[0m"
|
||||
case $arg in
|
||||
"configure") configure ${OPTS[@]};;
|
||||
"build") build ${OPTS[@]};;
|
||||
"package") package;;
|
||||
"clean") clean;;
|
||||
"release") release;;
|
||||
*)
|
||||
usage
|
||||
esac
|
||||
done
|
@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Usage example: $0 master soldier 0.20210618.0
|
||||
set -u
|
||||
|
||||
if [ $# -eq 2 ]; then
|
||||
echo Specify runtime version too
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SRCDIR=$PWD
|
||||
BRANCH="${1:-master}"
|
||||
# soldier 0.20210618.0 or newer
|
||||
# scout 0.20210630.0 or newer
|
||||
RUNTIME="${2:-soldier}"
|
||||
VERSION="${3:-0.20210618.0}"
|
||||
IMAGE="steamrt_${RUNTIME}_${VERSION}_amd64:mango-${RUNTIME}"
|
||||
BASEURL="https://repo.steampowered.com/steamrt-images-${RUNTIME}/snapshots/${VERSION}"
|
||||
CACHEDIR="./cache/steamrt-images-${RUNTIME}/snapshots/${VERSION}"
|
||||
|
||||
mkdir -p "${CACHEDIR}"
|
||||
|
||||
echo -e "\e[1mBuilding branch \e[92m${BRANCH}\e[39m using \e[92m${RUNTIME}:${VERSION}\e[39m runtime\e[0m"
|
||||
|
||||
if ! docker inspect --type=image ${IMAGE} 2>&1 >/dev/null ; then
|
||||
rm -fr ./cache/empty
|
||||
set -e
|
||||
mkdir -p ./cache/empty
|
||||
sed "s/%RUNTIME%/${RUNTIME}/g" steamrt.Dockerfile.in > ./cache/steamrt.Dockerfile
|
||||
|
||||
wget -P "${CACHEDIR}" -c ${BASEURL}/com.valvesoftware.SteamRuntime.Sdk-amd64,i386-${RUNTIME}-sysroot.tar.gz
|
||||
cp --reflink=always "${CACHEDIR}/com.valvesoftware.SteamRuntime.Sdk-amd64,i386-${RUNTIME}-sysroot.tar.gz" ./cache/empty/
|
||||
docker build -f ./cache/steamrt.Dockerfile -t ${IMAGE} ./cache/empty
|
||||
fi
|
||||
|
||||
docker run --entrypoint=/bin/sh --rm -i -v "${SRCDIR}/srt-output:/output" ${IMAGE} << EOF
|
||||
export RUNTIME=${RUNTIME}
|
||||
export SRT_VERSION=${VERSION}
|
||||
git clone git://github.com/flightlessmango/MangoHud.git . --branch ${BRANCH} --recurse-submodules --progress
|
||||
./build-srt.sh clean build package release
|
||||
cp -v build-srt/MangoHud*tar.gz /output/
|
||||
EOF
|
@ -1,7 +0,0 @@
|
||||
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_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_EXTRA="libXNVCtrl-devel"
|
@ -1,27 +0,0 @@
|
||||
[metadata]
|
||||
name = mangohud_control
|
||||
version = 0.0.1
|
||||
author = Simon Hallsten
|
||||
author_email = flightlessmangoyt@gmail.com
|
||||
description = control interface for mangohud
|
||||
classifiers =
|
||||
Programming Language :: Python :: 3
|
||||
License :: OSI Approved :: MIT License
|
||||
Operating System :: Linux
|
||||
|
||||
[options]
|
||||
package_dir =
|
||||
= src
|
||||
|
||||
packages = find:
|
||||
python_requires = >=3.6
|
||||
|
||||
[options.packages.find]
|
||||
where = src
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
mangohud-control = control:main
|
||||
|
||||
[pycodestyle]
|
||||
max-line-length = 160
|
@ -1,9 +0,0 @@
|
||||
import site
|
||||
import sys
|
||||
from setuptools import setup
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
|
||||
# See https://github.com/pypa/pip/issues/7953
|
||||
site.ENABLE_USER_SITE = "--user" in sys.argv[1:]
|
@ -1,223 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import select
|
||||
from select import EPOLLIN, EPOLLPRI, EPOLLERR
|
||||
import time
|
||||
from collections import namedtuple
|
||||
import argparse
|
||||
|
||||
TIMEOUT = 1.0 # seconds
|
||||
|
||||
VERSION_HEADER = bytearray('MangoHudControlVersion', 'utf-8')
|
||||
DEVICE_NAME_HEADER = bytearray('DeviceName', 'utf-8')
|
||||
MANGOHUD_VERSION_HEADER = bytearray('MangoHudVersion', 'utf-8')
|
||||
|
||||
DEFAULT_SERVER_ADDRESS = "\0mangohud"
|
||||
|
||||
class Connection:
|
||||
def __init__(self, path):
|
||||
# Create a Unix Domain socket and connect
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
try:
|
||||
sock.connect(path)
|
||||
except socket.error as msg:
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
|
||||
self.sock = sock
|
||||
|
||||
# initialize poll interface and register socket
|
||||
epoll = select.epoll()
|
||||
epoll.register(sock, EPOLLIN | EPOLLPRI | EPOLLERR)
|
||||
self.epoll = epoll
|
||||
|
||||
def recv(self, timeout):
|
||||
'''
|
||||
timeout as float in seconds
|
||||
returns:
|
||||
- None on error or disconnection
|
||||
- bytes() (empty) on timeout
|
||||
'''
|
||||
|
||||
events = self.epoll.poll(timeout)
|
||||
for ev in events:
|
||||
(fd, event) = ev
|
||||
if fd != self.sock.fileno():
|
||||
continue
|
||||
|
||||
# check for socket error
|
||||
if event & EPOLLERR:
|
||||
return None
|
||||
|
||||
# EPOLLIN or EPOLLPRI, just read the message
|
||||
msg = self.sock.recv(4096)
|
||||
|
||||
# socket disconnected
|
||||
if len(msg) == 0:
|
||||
return None
|
||||
|
||||
return msg
|
||||
|
||||
return bytes()
|
||||
|
||||
def send(self, msg):
|
||||
self.sock.send(msg)
|
||||
|
||||
class MsgParser:
|
||||
MSGBEGIN = bytes(':', 'utf-8')[0]
|
||||
MSGEND = bytes(';', 'utf-8')[0]
|
||||
MSGSEP = bytes('=', 'utf-8')[0]
|
||||
|
||||
def __init__(self, conn):
|
||||
self.cmdpos = 0
|
||||
self.parampos = 0
|
||||
self.bufferpos = 0
|
||||
self.reading_cmd = False
|
||||
self.reading_param = False
|
||||
self.buffer = None
|
||||
self.cmd = bytearray(4096)
|
||||
self.param = bytearray(4096)
|
||||
|
||||
self.conn = conn
|
||||
|
||||
def readCmd(self, ncmds, timeout=TIMEOUT):
|
||||
'''
|
||||
returns:
|
||||
- None on error or disconnection
|
||||
- bytes() (empty) on timeout
|
||||
'''
|
||||
|
||||
parsed = []
|
||||
|
||||
remaining = timeout
|
||||
|
||||
while remaining > 0 and ncmds > 0:
|
||||
now = time.monotonic()
|
||||
|
||||
if self.buffer == None:
|
||||
self.buffer = self.conn.recv(remaining)
|
||||
self.bufferpos = 0
|
||||
|
||||
# disconnected or error
|
||||
if self.buffer == None:
|
||||
return None
|
||||
|
||||
for i in range(self.bufferpos, len(self.buffer)):
|
||||
c = self.buffer[i]
|
||||
self.bufferpos += 1
|
||||
if c == self.MSGBEGIN:
|
||||
self.cmdpos = 0
|
||||
self.parampos = 0
|
||||
self.reading_cmd = True
|
||||
self.reading_param = False
|
||||
elif c == self.MSGEND:
|
||||
if not self.reading_cmd:
|
||||
continue
|
||||
self.reading_cmd = False
|
||||
self.reading_param = False
|
||||
|
||||
cmd = self.cmd[0:self.cmdpos]
|
||||
param = self.param[0:self.parampos]
|
||||
self.reading_cmd = False
|
||||
self.reading_param = False
|
||||
|
||||
parsed.append((cmd, param))
|
||||
ncmds -= 1
|
||||
if ncmds == 0:
|
||||
break
|
||||
elif c == self.MSGSEP:
|
||||
if self.reading_cmd:
|
||||
self.reading_param = True
|
||||
else:
|
||||
if self.reading_param:
|
||||
self.param[self.parampos] = c
|
||||
self.parampos += 1
|
||||
elif self.reading_cmd:
|
||||
self.cmd[self.cmdpos] = c
|
||||
self.cmdpos += 1
|
||||
|
||||
# if we read the entire buffer and didn't finish the command,
|
||||
# throw it away
|
||||
self.buffer = None
|
||||
|
||||
# check if we have time for another iteration
|
||||
elapsed = time.monotonic() - now
|
||||
remaining = max(0, remaining - elapsed)
|
||||
|
||||
# timeout
|
||||
return parsed
|
||||
|
||||
def control(args):
|
||||
if args.socket:
|
||||
address = '\0' + args.socket
|
||||
else:
|
||||
address = DEFAULT_SERVER_ADDRESS
|
||||
|
||||
conn = Connection(address)
|
||||
msgparser = MsgParser(conn)
|
||||
|
||||
version = None
|
||||
name = None
|
||||
mangohud_version = None
|
||||
|
||||
msgs = msgparser.readCmd(3)
|
||||
|
||||
for m in msgs:
|
||||
cmd, param = m
|
||||
if cmd == VERSION_HEADER:
|
||||
version = int(param)
|
||||
elif cmd == DEVICE_NAME_HEADER:
|
||||
name = param.decode('utf-8')
|
||||
elif cmd == MANGOHUD_VERSION_HEADER:
|
||||
mangohud_version = param.decode('utf-8')
|
||||
|
||||
if args.info:
|
||||
info = "Protocol Version: {}\n"
|
||||
info += "Device Name: {}\n"
|
||||
info += "MangoHud Version: {}"
|
||||
print(info.format(version, name, mangohud_version))
|
||||
|
||||
|
||||
if args.cmd == 'toggle-logging':
|
||||
conn.send(bytearray(':logging;', 'utf-8'))
|
||||
elif args.cmd == 'start-logging':
|
||||
conn.send(bytearray(':logging=1;', 'utf-8'))
|
||||
|
||||
elif args.cmd == 'stop-logging':
|
||||
conn.send(bytearray(':logging=0;', 'utf-8'))
|
||||
now = time.monotonic()
|
||||
while True:
|
||||
msg = str(conn.recv(3))
|
||||
if "LoggingFinished" in msg:
|
||||
print("Logging has stopped")
|
||||
exit(0)
|
||||
elapsed = time.monotonic() - now
|
||||
if elapsed > 3:
|
||||
print("Stop logging timed out")
|
||||
exit(1)
|
||||
|
||||
elif args.cmd == 'toggle-hud':
|
||||
conn.send(bytearray(':hud;', 'utf-8'))
|
||||
elif args.cmd == 'toggle-fcat':
|
||||
conn.send(bytearray(':fcat;', 'utf-8'))
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='MangoHud control client')
|
||||
parser.add_argument('--info', action='store_true', help='Print info from socket')
|
||||
parser.add_argument('--socket', '-s', type=str, help='Path to socket')
|
||||
|
||||
commands = parser.add_subparsers(help='commands to run', dest='cmd')
|
||||
commands.add_parser('toggle-hud')
|
||||
commands.add_parser('toggle-logging')
|
||||
commands.add_parser('start-logging')
|
||||
commands.add_parser('stop-logging')
|
||||
commands.add_parser('toggle-fcat')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
control(args)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,359 +0,0 @@
|
||||
### MangoHud configuration file
|
||||
### Uncomment any options you wish to enable. Default options are left uncommented
|
||||
### Use some_parameter=0 to disable a parameter (only works with on/off parameters)
|
||||
### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead
|
||||
|
||||
################ INFORMATIONAL #################
|
||||
## prints possible options on stdout
|
||||
# help
|
||||
|
||||
################ PERFORMANCE #################
|
||||
|
||||
### Limit the application FPS. Comma-separated list of one or more FPS values (e.g. 0,30,60). 0 means unlimited (unless VSynced)
|
||||
# fps_limit=0
|
||||
|
||||
### early = wait before present, late = wait after present
|
||||
# fps_limit_method=
|
||||
|
||||
### VSync [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on
|
||||
# vsync=-1
|
||||
|
||||
### OpenGL VSync [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a FPS limiter (FPS = display refresh rate / N)
|
||||
# gl_vsync=-2
|
||||
|
||||
### Mip-map LoD bias. Negative values will increase texture sharpness (and aliasing)
|
||||
## Positive values will increase texture blurriness (-16 to 16)
|
||||
# picmip=-17
|
||||
|
||||
### Anisotropic filtering level. Improves sharpness of textures viewed at an angle (0 to 16)
|
||||
# af=-1
|
||||
|
||||
### Force bicubic filtering
|
||||
# bicubic
|
||||
|
||||
### Force trilinear filtering
|
||||
# trilinear
|
||||
|
||||
### Disable linear texture filtering. Makes textures look blocky
|
||||
# retro
|
||||
|
||||
################### VISUAL ###################
|
||||
|
||||
### Legacy layout
|
||||
# legacy_layout=0
|
||||
|
||||
### pre defined presets
|
||||
# -1 = default
|
||||
# 0 = no display
|
||||
# 1 = fps only
|
||||
# 2 = horizontal view
|
||||
# 3 = extended
|
||||
# 4 = high detailed information
|
||||
# preset=-1
|
||||
|
||||
### Enable most of the toggleable parameters (currently excludes `histogram`)
|
||||
# full
|
||||
|
||||
### Show FPS only. ***Not meant to be used with other display params***
|
||||
# fps_only
|
||||
|
||||
### Display custom centered text, useful for a header
|
||||
# custom_text_center=
|
||||
|
||||
### Display the current system time
|
||||
# time
|
||||
## removes the time label
|
||||
# time_no_label
|
||||
|
||||
### Time formatting examples
|
||||
## %H:%M
|
||||
## [ %T %F ]
|
||||
## %X # locally formatted time, because of limited glyph range, missing characters may show as '?' (e.g. Japanese)
|
||||
# time_format="%T"
|
||||
|
||||
### Display MangoHud version
|
||||
# version
|
||||
|
||||
### Display the current GPU information
|
||||
## Note: gpu_mem_clock and gpu_mem_temp also need "vram" to be enabled
|
||||
gpu_stats
|
||||
# gpu_temp
|
||||
# gpu_junction_temp
|
||||
# gpu_core_clock
|
||||
# gpu_mem_temp
|
||||
# gpu_mem_clock
|
||||
# gpu_power
|
||||
# gpu_text=
|
||||
# gpu_load_change
|
||||
# gpu_load_value=60,90
|
||||
# gpu_load_color=39F900,FDFD09,B22222
|
||||
## GPU fan in rpm on AMD, FAN in percent on NVIDIA
|
||||
# gpu_fan
|
||||
## gpu_voltage only works on AMD GPUs
|
||||
# gpu_voltage
|
||||
|
||||
### Display the current CPU information
|
||||
cpu_stats
|
||||
# cpu_temp
|
||||
# cpu_power
|
||||
# cpu_text=
|
||||
# cpu_mhz
|
||||
# cpu_load_change
|
||||
# cpu_load_value=60,90
|
||||
# cpu_load_color=39F900,FDFD09,B22222
|
||||
|
||||
### Display the current CPU load & frequency for each core
|
||||
# core_load
|
||||
# core_load_change
|
||||
|
||||
### Display IO read and write for the app (not system)
|
||||
# io_read
|
||||
# io_write
|
||||
|
||||
### Display system vram / ram / swap space usage
|
||||
# vram
|
||||
# ram
|
||||
# swap
|
||||
|
||||
### Display per process memory usage
|
||||
## Show resident memory and other types, if enabled
|
||||
# procmem
|
||||
# procmem_shared
|
||||
# procmem_virt
|
||||
|
||||
### Display battery information
|
||||
# battery
|
||||
# battery_icon
|
||||
# device_battery=gamepad,mouse
|
||||
# device_battery_icon
|
||||
# battery_watt
|
||||
# battery_time
|
||||
|
||||
### Display FPS and frametime
|
||||
fps
|
||||
# fps_sampling_period=500
|
||||
# fps_color_change
|
||||
# fps_value=30,60
|
||||
# fps_color=B22222,FDFD09,39F900
|
||||
frametime
|
||||
# frame_count
|
||||
## fps_metrics takes a list of decimal values or the value avg
|
||||
# fps_metrics=avg,0.01
|
||||
|
||||
### Display GPU throttling status based on Power, current, temp or "other"
|
||||
## Only shows if throttling is currently happening
|
||||
throttling_status
|
||||
## Same as throttling_status but displays throttling on the frametime graph
|
||||
#throttling_status_graph
|
||||
|
||||
### Display miscellaneous information
|
||||
# engine_version
|
||||
# engine_short_names
|
||||
# gpu_name
|
||||
# vulkan_driver
|
||||
# wine
|
||||
# exec_name
|
||||
# winesync
|
||||
|
||||
### Display loaded MangoHud architecture
|
||||
# arch
|
||||
|
||||
### Display the frametime line graph
|
||||
frame_timing
|
||||
# histogram
|
||||
|
||||
### Display GameMode / vkBasalt running status
|
||||
# gamemode
|
||||
# vkbasalt
|
||||
|
||||
### Gamescope related options
|
||||
## Display the status of FSR (only works in gamescope)
|
||||
# fsr
|
||||
## Hides the sharpness info for the `fsr` option (only available in gamescope)
|
||||
# hide_fsr_sharpness
|
||||
## Shows the graph of gamescope app frametimes and latency (only on gamescope obviously)
|
||||
# debug
|
||||
## Display the status of HDR (only works in gamescope)
|
||||
# hdr
|
||||
## Display the current refresh rate (only works in gamescope)
|
||||
# refresh_rate
|
||||
|
||||
|
||||
### graphs displays one or more graphs that you chose
|
||||
## seperated by ",", available graphs are
|
||||
## gpu_load,cpu_load,gpu_core_clock,gpu_mem_clock,vram,ram,cpu_temp,gpu_temp
|
||||
# graphs=
|
||||
|
||||
### mangoapp related options
|
||||
## Enables mangoapp to be displayed above the Steam UI
|
||||
# mangoapp_steam
|
||||
|
||||
### Steam Deck options
|
||||
## Shows the Steam Deck fan rpm
|
||||
# fan
|
||||
|
||||
### Display current FPS limit
|
||||
# show_fps_limit
|
||||
|
||||
### Display the current resolution
|
||||
# resolution
|
||||
|
||||
### Display custom text
|
||||
# custom_text=
|
||||
### Display output of Bash command in next column
|
||||
# exec=
|
||||
|
||||
### Display media player metadata
|
||||
# media_player
|
||||
## for example spotify
|
||||
# media_player_name=
|
||||
## Format metadata, lines are delimited by ; (wip)
|
||||
## example: {title};{artist};{album}
|
||||
## 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
|
||||
# font_size_text=24
|
||||
# font_scale_media_player=0.55
|
||||
# no_small_font
|
||||
|
||||
### Change default font (set location to TTF/OTF file)
|
||||
## Set font for the whole hud
|
||||
# font_file=
|
||||
|
||||
## Set font only for text like media player metadata
|
||||
# font_file_text=
|
||||
|
||||
## Set font glyph ranges. Defaults to Latin-only. Don't forget to set font_file/font_file_text to font that supports these
|
||||
## Probably don't enable all at once because of memory usage and hardware limits concerns
|
||||
## If you experience crashes or text is just squares, reduce glyph range or reduce font size
|
||||
# font_glyph_ranges=korean,chinese,chinese_simplified,japanese,cyrillic,thai,vietnamese,latin_ext_a,latin_ext_b
|
||||
|
||||
### Outline text
|
||||
text_outline
|
||||
# text_outline_color = 000000
|
||||
# text_outline_thickness = 1.5
|
||||
|
||||
### Change the hud position
|
||||
# position=top-left
|
||||
|
||||
### Change the corner roundness
|
||||
# round_corners=0
|
||||
|
||||
### Remove margins around MangoHud
|
||||
# hud_no_margin
|
||||
|
||||
### Display compact version of MangoHud
|
||||
# hud_compact
|
||||
|
||||
### Display MangoHud in a horizontal position
|
||||
# horizontal
|
||||
# horizontal_stretch
|
||||
|
||||
### Disable / hide the hud by default
|
||||
# no_display
|
||||
|
||||
### Hud position offset
|
||||
# offset_x=0
|
||||
# offset_y=0
|
||||
|
||||
### Hud dimensions
|
||||
# width=0
|
||||
# height=140
|
||||
# table_columns=3
|
||||
# cellpadding_y=-0.085
|
||||
|
||||
### Hud transparency / alpha
|
||||
# background_alpha=0.5
|
||||
# alpha=1.0
|
||||
|
||||
### FCAT overlay
|
||||
### This enables an FCAT overlay to perform frametime analysis on the final image stream.
|
||||
### Enable the overlay
|
||||
# fcat
|
||||
### Set the width of the FCAT overlay.
|
||||
### 24 is a performance optimization on AMD GPUs that should not have adverse effects on nVidia GPUs.
|
||||
### A minimum of 20 pixels is recommended by nVidia.
|
||||
# fcat_overlay_width=24
|
||||
### Set the screen edge, this can be useful for special displays that don't update from top edge to bottom. This goes from 0 (left side) to 3 (top edge), counter-clockwise.
|
||||
# fcat_screen_edge=0
|
||||
|
||||
### Color customization
|
||||
# text_color=FFFFFF
|
||||
# gpu_color=2E9762
|
||||
# cpu_color=2E97CB
|
||||
# vram_color=AD64C1
|
||||
# ram_color=C26693
|
||||
# engine_color=EB5B5B
|
||||
# io_color=A491D3
|
||||
# frametime_color=00FF00
|
||||
# background_color=020202
|
||||
# media_player_color=FFFFFF
|
||||
# wine_color=EB5B5B
|
||||
# battery_color=FF9078
|
||||
|
||||
### Specify GPU with PCI bus ID for AMDGPU and NVML stats
|
||||
### Set to 'domain:bus:slot.function'
|
||||
# pci_dev=0:0a:0.0
|
||||
|
||||
### Blacklist
|
||||
# blacklist=
|
||||
|
||||
### Control over socket
|
||||
### Enable and set socket name, '%p' is replaced with process id
|
||||
## example: mangohud
|
||||
## example: mangohud-%p
|
||||
# control = -1
|
||||
|
||||
################ WORKAROUNDS #################
|
||||
### Options starting with "gl_*" are for OpenGL
|
||||
### Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable
|
||||
# gl_size_query=viewport
|
||||
|
||||
### (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III
|
||||
# gl_bind_framebuffer=0
|
||||
|
||||
### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx
|
||||
# gl_dont_flip=1
|
||||
|
||||
################ INTERACTION #################
|
||||
|
||||
### Change toggle keybinds for the hud & logging
|
||||
# toggle_hud=Shift_R+F12
|
||||
# toggle_hud_position=Shift_R+F11
|
||||
# toggle_preset=Shift_R+F10
|
||||
# toggle_fps_limit=Shift_L+F1
|
||||
# toggle_logging=Shift_L+F2
|
||||
# reload_cfg=Shift_L+F4
|
||||
# upload_log=Shift_L+F3
|
||||
|
||||
#################### LOG #####################
|
||||
### Automatically start the log after X seconds
|
||||
# autostart_log=
|
||||
### Set amount of time in seconds that the logging will run for
|
||||
# log_duration=
|
||||
### Change the default log interval, 0 is default
|
||||
# log_interval=0
|
||||
### Set location of the output files (required for logging)
|
||||
# output_folder=/home/<USERNAME>/mangologs
|
||||
### Permit uploading logs directly to FlightlessMango.com
|
||||
## set to 1 to enable
|
||||
# permit_upload=0
|
||||
### Define a '+'-separated list of percentiles shown in the benchmark results
|
||||
### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1
|
||||
## example: ['97', 'AVG', '1', '0.1']
|
||||
# benchmark_percentiles=97,AVG
|
||||
## Adds more headers and information such as versioning to the log. This format is not supported on flightlessmango.com (yet)
|
||||
# log_versioning
|
||||
## Enable automatic uploads of logs to flightlessmango.com
|
||||
# upload_logs
|
@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="generic">
|
||||
<id>io.github.flightlessmango.mangohud</id>
|
||||
|
||||
<name>MangoHud</name>
|
||||
<summary>Vulkan/OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more</summary>
|
||||
<developer_name>FlightlessMango</developer_name>
|
||||
<icon type="stock">io.github.flightlessmango.mangohud</icon>
|
||||
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>MIT</project_license>
|
||||
|
||||
<description>
|
||||
<p>A modification of the Mesa Vulkan overlay, including GUI improvements with HUD configuration, temperature reporting, and logging capabilities. Includes a script (mangohud) to start it on any OpenGL or Vulkan application.</p>
|
||||
</description>
|
||||
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Example</caption>
|
||||
<image>https://raw.githubusercontent.com/flightlessmango/MangoHud/master/assets/overlay_example.gif</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Log uploading walkthrough</caption>
|
||||
<image>https://raw.githubusercontent.com/flightlessmango/MangoHud/master/assets/log_upload_example.gif</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<url type="homepage">https://github.com/flightlessmango/MangoHud</url>
|
||||
<url type="bugtracker">https://github.com/flightlessmango/MangoHud/issues</url>
|
||||
<url type="donation">https://www.paypal.me/flightlessmango</url>
|
||||
|
||||
<provides>
|
||||
<binary>mangohud</binary>
|
||||
</provides>
|
||||
|
||||
<categories>
|
||||
<category>Utility</category>
|
||||
<category>Game</category>
|
||||
</categories>
|
||||
|
||||
<content_rating type="oars-1.1" />
|
||||
</component>
|
@ -1,383 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="86.038002mm"
|
||||
height="86.038002mm"
|
||||
viewBox="-6.468 0 86.038221 86.038221"
|
||||
version="1.1"
|
||||
id="svg3290"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
sodipodi:docname="io.github.flightlessmango.mangohud.svg">
|
||||
<title
|
||||
id="title5515">FlightlessMango Icon</title>
|
||||
<defs
|
||||
id="defs3284">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath2486">
|
||||
<rect
|
||||
style="opacity:1;stroke-width:0.75"
|
||||
id="rect2488"
|
||||
width="207.21774"
|
||||
height="243.88824"
|
||||
x="893.77185"
|
||||
y="-713.32947"
|
||||
transform="scale(1,-1)" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath2344">
|
||||
<path
|
||||
d="M 0,2000 H 2000 V 0 H 0 Z"
|
||||
id="path2342" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.2547806"
|
||||
inkscape:cx="98.679223"
|
||||
inkscape:cy="162.32178"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="mm"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1010"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="393"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata3287">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>FlightlessMango Icon</dc:title>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by/4.0/" />
|
||||
<dc:date>2020-11-14</dc:date>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>FlightlessMango</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by/4.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.06554034,-0.07012108)">
|
||||
<rect
|
||||
style="display:inline;fill:#fffae3;fill-opacity:1;stroke-width:0.265336"
|
||||
id="rect235"
|
||||
width="86.038216"
|
||||
height="86.038216"
|
||||
x="-6.4024596"
|
||||
y="0.07012108" />
|
||||
<g
|
||||
id="g2338"
|
||||
clip-path="url(#clipPath2486)"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,-315.2373,251.7169)">
|
||||
<g
|
||||
id="g2340"
|
||||
clip-path="url(#clipPath2344)">
|
||||
<g
|
||||
id="g2346"
|
||||
transform="translate(683.6049,1312.4586)">
|
||||
<path
|
||||
d="M 0,0 V -4.41 H -11.995 V -14.829 H 0 v -4.41 H -11.995 V -34.09 h -4.411 V 0 Z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2348" />
|
||||
</g>
|
||||
<path
|
||||
d="m 715.713,1278.369 h -4.432 v 34.111 h 4.432 z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2350" />
|
||||
<path
|
||||
d="m 748.695,1278.369 h -4.41 v 21.924 h 4.41 z m -0.022,30.042 c 0.611,-0.597 0.916,-1.328 0.916,-2.195 0,-0.867 -0.305,-1.598 -0.916,-2.195 -0.611,-0.596 -1.342,-0.894 -2.194,-0.894 -0.839,0 -1.563,0.298 -2.173,0.894 -0.611,0.597 -0.916,1.328 -0.916,2.195 0,0.867 0.305,1.598 0.916,2.195 0.61,0.596 1.334,0.895 2.173,0.895 0.852,0 1.583,-0.299 2.194,-0.895"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2352" />
|
||||
<g
|
||||
id="g2354"
|
||||
transform="translate(796.2708,1291.6427)">
|
||||
<path
|
||||
d="m 0,0 c -0.27,1.349 -0.951,2.571 -2.045,3.665 -1.478,1.491 -3.267,2.237 -5.369,2.237 -2.103,0 -3.896,-0.746 -5.38,-2.237 -1.485,-1.492 -2.227,-3.281 -2.227,-5.37 0,-2.102 0.742,-3.895 2.227,-5.379 1.484,-1.485 3.277,-2.227 5.38,-2.227 2.102,0 3.891,0.739 5.369,2.216 1.094,1.094 1.775,2.301 2.045,3.622 z M 0.022,7.137 V 8.65 H 4.453 V -7.649 c 0,-4.261 -1.158,-7.549 -3.473,-9.864 -2.372,-2.089 -5.234,-3.133 -8.586,-3.133 -3.352,0 -6.215,1.044 -8.587,3.133 -0.483,0.483 -1.256,1.463 -2.322,2.94 l 4.389,1.576 c 0.568,-0.681 0.952,-1.121 1.15,-1.321 1.492,-1.477 3.282,-2.215 5.37,-2.215 3.508,0 5.937,2.301 7.287,6.903 -1.378,-2.671 -3.743,-4.006 -7.095,-4.006 -3.353,0 -6.211,1.151 -8.576,3.452 -2.365,2.301 -3.547,5.127 -3.547,8.479 0,3.353 1.182,6.211 3.547,8.576 2.365,2.365 5.223,3.548 8.576,3.548 2.826,0 5.305,-1.094 7.436,-3.282"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2356" />
|
||||
</g>
|
||||
<g
|
||||
id="g2358"
|
||||
transform="translate(829.0182,1312.4586)">
|
||||
<path
|
||||
d="m 0,0 h 4.432 v -14.531 c 1.235,2.372 3.025,3.558 5.369,3.558 2.344,0 4.215,-0.841 5.614,-2.524 1.399,-1.683 2.12,-3.796 2.163,-6.339 V -34.09 h -4.411 v 14.084 c 0,1.264 -0.358,2.347 -1.076,3.249 -0.717,0.902 -1.85,1.353 -3.398,1.353 -1.832,0 -3.253,-0.98 -4.261,-2.94 V -34.09 H 0 Z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2360" />
|
||||
</g>
|
||||
<g
|
||||
id="g2362"
|
||||
transform="translate(877.4686,1300.2928)">
|
||||
<path
|
||||
d="M 0,0 V 8.224 H 4.41 V 0 H 8.352 V -4.41 H 4.41 V -21.924 H 0 V -4.41 H -3.942 V 0 Z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2364" />
|
||||
</g>
|
||||
<path
|
||||
d="m 917.204,1278.369 h -4.432 v 34.111 h 4.432 z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2366" />
|
||||
<g
|
||||
id="g2368"
|
||||
transform="translate(959.6033,1296.9692)">
|
||||
<path
|
||||
d="m 0,0 c -0.497,0.384 -1.613,0.575 -3.345,0.575 -2.088,0 -3.875,-0.742 -5.359,-2.226 -1.484,-1.485 -2.226,-3.278 -2.226,-5.38 0,-1.719 0.191,-2.834 0.575,-3.345 z m -7.372,-13.636 c 0.738,-0.654 2.08,-0.98 4.027,-0.98 2.102,0 3.899,0.739 5.39,2.216 0.185,0.199 0.561,0.639 1.129,1.321 l 4.411,-1.577 c -1.08,-1.491 -1.861,-2.479 -2.344,-2.961 -2.372,-2.373 -5.234,-3.558 -8.586,-3.558 -3.338,0 -6.193,1.185 -8.565,3.558 -2.373,2.372 -3.558,5.234 -3.558,8.586 0,3.352 1.185,6.214 3.558,8.587 2.372,2.371 5.227,3.557 8.565,3.557 2.869,0 5.383,-0.866 7.542,-2.599 C 4.552,2.216 4.9,1.896 5.241,1.556 5.383,1.413 5.787,0.966 6.456,0.213 L 4.24,-2.024 Z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2370" />
|
||||
</g>
|
||||
<g
|
||||
id="g2372"
|
||||
transform="translate(998.5509,1283.0776)">
|
||||
<path
|
||||
d="M 0,0 C 0.525,-0.511 1.151,-0.767 1.875,-0.767 2.6,-0.767 3.221,-0.511 3.74,0 4.258,0.512 4.517,1.143 4.517,1.896 4.517,2.621 4.261,3.239 3.75,3.75 3.395,4.105 2.635,4.652 1.47,5.39 c -1.591,0.867 -2.72,1.634 -3.388,2.301 -1.165,1.165 -1.746,2.564 -1.746,4.198 0,1.647 0.581,3.057 1.746,4.229 1.165,1.172 2.571,1.758 4.219,1.758 1.647,0 3.019,-0.554 4.113,-1.662 0.78,-0.781 1.278,-1.655 1.49,-2.621 L 3.622,12.358 c -0.1,0.354 -0.199,0.589 -0.298,0.703 -0.256,0.255 -0.597,0.383 -1.023,0.383 -0.426,0 -0.792,-0.152 -1.097,-0.458 -0.306,-0.305 -0.458,-0.671 -0.458,-1.097 0,-0.426 0.149,-0.788 0.447,-1.087 C 1.463,10.547 2.074,10.113 3.026,9.503 4.787,8.536 6.065,7.656 6.861,6.86 8.238,5.468 8.928,3.814 8.928,1.896 c 0,-1.96 -0.686,-3.632 -2.057,-5.017 -1.37,-1.385 -3.036,-2.078 -4.996,-2.078 -1.946,0 -3.608,0.696 -4.985,2.088 -0.953,0.952 -1.577,2.138 -1.876,3.559 l 4.39,0.937 C -0.468,0.732 -0.27,0.27 0,0"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2374" />
|
||||
</g>
|
||||
<g
|
||||
id="g2376"
|
||||
transform="translate(1039.1595,1283.0776)">
|
||||
<path
|
||||
d="m 0,0 c 0.525,-0.511 1.151,-0.767 1.875,-0.767 0.724,0 1.346,0.256 1.865,0.767 0.518,0.512 0.777,1.143 0.777,1.896 0,0.725 -0.256,1.343 -0.767,1.854 -0.355,0.355 -1.116,0.902 -2.28,1.64 -1.591,0.867 -2.72,1.634 -3.388,2.301 -1.165,1.165 -1.746,2.564 -1.746,4.198 0,1.647 0.581,3.057 1.746,4.229 1.165,1.172 2.571,1.758 4.219,1.758 1.647,0 3.019,-0.554 4.113,-1.662 0.78,-0.781 1.278,-1.655 1.49,-2.621 L 3.622,12.358 c -0.1,0.354 -0.199,0.589 -0.298,0.703 -0.256,0.255 -0.597,0.383 -1.023,0.383 -0.426,0 -0.792,-0.152 -1.097,-0.458 -0.306,-0.305 -0.458,-0.671 -0.458,-1.097 0,-0.426 0.149,-0.788 0.447,-1.087 C 1.463,10.547 2.074,10.113 3.026,9.503 4.787,8.536 6.065,7.656 6.861,6.86 8.238,5.468 8.928,3.814 8.928,1.896 c 0,-1.96 -0.686,-3.632 -2.057,-5.017 -1.37,-1.385 -3.036,-2.078 -4.996,-2.078 -1.946,0 -3.608,0.696 -4.985,2.088 -0.953,0.952 -1.577,2.138 -1.876,3.559 l 4.39,0.937 C -0.468,0.732 -0.27,0.27 0,0"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2378" />
|
||||
</g>
|
||||
<g
|
||||
id="g2380"
|
||||
transform="translate(1080.4086,1312.4586)">
|
||||
<path
|
||||
d="M 0,0 11.058,-19.111 22.072,0 H 26.1 V -34.09 H 21.69 V -9.46 L 11.058,-27.868 0.384,-9.46 V -34.09 H -4.027 V 0 Z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2382" />
|
||||
</g>
|
||||
<g
|
||||
id="g2384"
|
||||
transform="translate(1154.7667,1288.2979)">
|
||||
<path
|
||||
d="m 0,0 v 3.239 c -0.256,1.377 -0.938,2.627 -2.046,3.749 -1.491,1.477 -3.281,2.216 -5.369,2.216 -2.102,0 -3.896,-0.739 -5.379,-2.216 -1.485,-1.477 -2.227,-3.267 -2.227,-5.369 0,-2.088 0.742,-3.874 2.227,-5.358 1.483,-1.485 3.277,-2.227 5.379,-2.227 2.088,0 3.878,0.738 5.369,2.216 1.108,1.122 1.79,2.372 2.046,3.75 m 0,10.461 v 1.534 H 4.432 V -9.95 H 0 v 2.748 c -2.131,-2.201 -4.603,-3.302 -7.415,-3.302 -3.352,0 -6.21,1.183 -8.576,3.547 -2.365,2.365 -3.547,5.224 -3.547,8.576 0,3.352 1.182,6.211 3.547,8.576 2.366,2.365 5.224,3.547 8.576,3.547 2.812,0 5.284,-1.094 7.415,-3.281"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2386" />
|
||||
</g>
|
||||
<g
|
||||
id="g2388"
|
||||
transform="translate(1191.8602,1294.4125)">
|
||||
<path
|
||||
d="M 0,0 V -16.043 H -4.432 V 5.88 H 0 V 3.324 c 0.923,2.499 2.777,3.749 5.561,3.749 2.372,0 4.257,-0.841 5.657,-2.524 1.399,-1.683 2.12,-3.796 2.162,-6.339 V -16.043 H 8.97 V -1.96 C 8.97,-0.696 8.508,0.387 7.585,1.289 6.661,2.191 5.561,2.642 4.282,2.642 3.018,2.642 1.925,2.202 1.001,1.321 0.49,0.796 0.156,0.355 0,0"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2390" />
|
||||
</g>
|
||||
<g
|
||||
id="g2392"
|
||||
transform="translate(1252.5187,1291.6427)">
|
||||
<path
|
||||
d="m 0,0 c -0.271,1.349 -0.952,2.571 -2.046,3.665 -1.477,1.491 -3.267,2.237 -5.369,2.237 -2.102,0 -3.896,-0.746 -5.379,-2.237 -1.485,-1.492 -2.227,-3.281 -2.227,-5.37 0,-2.102 0.742,-3.895 2.227,-5.379 1.483,-1.485 3.277,-2.227 5.379,-2.227 2.102,0 3.892,0.739 5.369,2.216 1.094,1.094 1.775,2.301 2.046,3.622 z M 0.021,7.137 V 8.65 H 4.453 V -7.649 c 0,-4.261 -1.158,-7.549 -3.473,-9.864 -2.372,-2.089 -5.235,-3.133 -8.586,-3.133 -3.353,0 -6.215,1.044 -8.587,3.133 -0.483,0.483 -1.257,1.463 -2.322,2.94 l 4.388,1.576 c 0.569,-0.681 0.952,-1.121 1.152,-1.321 1.491,-1.477 3.28,-2.215 5.369,-2.215 3.507,0 5.937,2.301 7.286,6.903 -1.378,-2.671 -3.743,-4.006 -7.095,-4.006 -3.352,0 -6.21,1.151 -8.576,3.452 -2.365,2.301 -3.547,5.127 -3.547,8.479 0,3.353 1.182,6.211 3.547,8.576 2.366,2.365 5.224,3.548 8.576,3.548 2.827,0 5.305,-1.094 7.436,-3.282"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2394" />
|
||||
</g>
|
||||
<g
|
||||
id="g2396"
|
||||
transform="translate(1290.7312,1295.3074)">
|
||||
<path
|
||||
d="m 0,0 c -1.484,-1.492 -2.226,-3.281 -2.226,-5.369 0,-2.102 0.742,-3.892 2.226,-5.369 1.484,-1.477 3.278,-2.216 5.38,-2.216 2.102,0 3.895,0.739 5.38,2.216 1.484,1.477 2.226,3.267 2.226,5.369 0,2.088 -0.742,3.877 -2.226,5.369 C 9.275,1.492 7.482,2.237 5.38,2.237 3.278,2.237 1.484,1.492 0,0 m 5.38,6.775 c 3.352,0 6.211,-1.186 8.575,-3.558 2.365,-2.372 3.548,-5.234 3.548,-8.586 0,-3.353 -1.183,-6.214 -3.548,-8.587 -2.364,-2.372 -5.223,-3.557 -8.575,-3.557 -3.338,0 -6.193,1.185 -8.565,3.557 -2.372,2.373 -3.558,5.234 -3.558,8.587 0,3.352 1.186,6.214 3.558,8.586 2.372,2.372 5.227,3.558 8.565,3.558"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2398" />
|
||||
</g>
|
||||
<path
|
||||
d="M 2000,0 H 5 v 983 h 1995 z"
|
||||
style="fill:#fffae3;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2400" />
|
||||
<g
|
||||
id="g2402"
|
||||
transform="translate(757.9102,452.8965)">
|
||||
<path
|
||||
d="m 0,0 v -7.977 h 6.042 v -3.947 H 0 V -24.251 H -4.271 V 3.947 H 7.533 V 0 Z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2404" />
|
||||
</g>
|
||||
<g
|
||||
id="g2406"
|
||||
transform="translate(797.7944,432.6738)">
|
||||
<path
|
||||
d="M 0,0 V -4.028 H -11.4 V 24.17 h 4.27 L -7.13,0 Z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2408" />
|
||||
</g>
|
||||
<path
|
||||
d="m 818.666,456.844 h 4.27 v -28.198 h -4.27 z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2410" />
|
||||
<g
|
||||
id="g2412"
|
||||
transform="translate(858.5898,450.4785)">
|
||||
<path
|
||||
d="m 0,0 v -1.934 l -4.109,-0.201 v 1.693 c 0,2.255 -0.846,3.262 -2.497,3.262 -1.652,0 -2.498,-1.007 -2.498,-2.86 v -15.388 c 0,-1.853 0.806,-2.86 2.458,-2.86 1.651,0 2.457,1.007 2.457,3.263 v 4.834 h -2.417 v 3.948 H 0 v -9.226 c 0,-4.269 -2.457,-6.767 -6.728,-6.767 -4.229,0 -6.646,2.498 -6.646,6.767 V 0 c 0,4.271 2.417,6.768 6.646,6.768 C -2.457,6.768 0,4.271 0,0"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2414" />
|
||||
</g>
|
||||
<g
|
||||
id="g2416"
|
||||
transform="translate(890.0957,428.6455)">
|
||||
<path
|
||||
d="M 0,0 V 12.286 H -5.075 V 0 h -4.271 v 28.198 h 4.271 V 16.314 H 0 V 28.198 H 4.271 V 0 Z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2418" />
|
||||
</g>
|
||||
<g
|
||||
id="g2420"
|
||||
transform="translate(924.0195,452.8154)">
|
||||
<path
|
||||
d="M 0,0 V -24.17 H -4.271 V 0 H -8.822 V 4.028 H 4.552 V 0 Z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2422" />
|
||||
</g>
|
||||
<g
|
||||
id="g2424"
|
||||
transform="translate(960.8022,432.6738)">
|
||||
<path
|
||||
d="M 0,0 V -4.028 H -11.4 V 24.17 h 4.27 L -7.13,0 Z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2426" />
|
||||
</g>
|
||||
<g
|
||||
id="g2428"
|
||||
transform="translate(985.9434,452.8965)">
|
||||
<path
|
||||
d="m 0,0 v -7.977 h 6.244 v -3.947 H 0 v -8.379 h 7.734 v -3.948 H -4.27 V 3.947 H 7.734 V 0 Z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2430" />
|
||||
</g>
|
||||
<g
|
||||
id="g2432"
|
||||
transform="translate(1026.7549,450.9219)">
|
||||
<path
|
||||
d="m 0,0 v -0.725 l -4.109,-0.403 v 1.048 c 0,1.611 -0.766,2.457 -2.175,2.457 -1.41,0 -2.176,-0.846 -2.176,-2.457 v -0.363 c 0,-1.652 0.726,-3.061 3.585,-5.479 3.908,-3.303 5.358,-5.639 5.358,-9.023 v -1.409 c 0,-4.029 -2.377,-6.326 -6.606,-6.326 -4.231,0 -6.606,2.297 -6.606,6.326 v 1.893 l 4.108,0.402 v -2.013 c 0,-1.774 0.806,-2.659 2.417,-2.659 1.611,0 2.417,0.885 2.417,2.659 v 0.926 c 0,1.772 -0.846,3.182 -3.706,5.599 -3.907,3.303 -5.236,5.64 -5.236,8.943 V 0 c 0,4.028 2.295,6.324 6.364,6.324 C -2.297,6.324 0,4.028 0,0"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2434" />
|
||||
</g>
|
||||
<g
|
||||
id="g2436"
|
||||
transform="translate(1059.3076,450.9219)">
|
||||
<path
|
||||
d="m 0,0 v -0.725 l -4.109,-0.403 v 1.048 c 0,1.611 -0.766,2.457 -2.175,2.457 -1.41,0 -2.176,-0.846 -2.176,-2.457 v -0.363 c 0,-1.652 0.726,-3.061 3.585,-5.479 3.908,-3.303 5.358,-5.639 5.358,-9.023 v -1.409 c 0,-4.029 -2.377,-6.326 -6.606,-6.326 -4.231,0 -6.606,2.297 -6.606,6.326 v 1.893 l 4.108,0.402 v -2.013 c 0,-1.774 0.806,-2.659 2.417,-2.659 1.611,0 2.417,0.885 2.417,2.659 v 0.926 c 0,1.772 -0.846,3.182 -3.706,5.599 -3.907,3.303 -5.236,5.64 -5.236,8.943 V 0 c 0,4.028 2.295,6.324 6.364,6.324 C -2.297,6.324 0,4.028 0,0"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2438" />
|
||||
</g>
|
||||
<g
|
||||
id="g2440"
|
||||
transform="translate(1094.3184,428.6455)">
|
||||
<path
|
||||
d="M 0,0 V 19.577 H -0.081 L -3.626,4.028 H -6.163 L -9.708,19.577 H -9.789 V 0 h -4.028 v 28.198 h 5.599 l 3.344,-15.146 h 0.08 L -1.49,28.198 H 4.271 V 0 Z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2442" />
|
||||
</g>
|
||||
<g
|
||||
id="g2444"
|
||||
transform="translate(1125.542,438.918)">
|
||||
<path
|
||||
d="M 0,0 H 3.586 L 1.854,11.883 H 1.732 Z m 5.076,-10.272 -0.927,6.405 h -4.712 l -0.927,-6.405 h -4.27 l 4.874,28.198 h 5.439 l 4.874,-28.198 z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2446" />
|
||||
</g>
|
||||
<g
|
||||
id="g2448"
|
||||
transform="translate(1165.8701,428.6455)">
|
||||
<path
|
||||
d="M 0,0 -5.599,18.691 H -5.68 V 0 h -4.028 v 28.198 h 4.754 L 0.081,11.4 H 0.162 V 28.198 H 4.189 V 0 Z"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2450" />
|
||||
</g>
|
||||
<g
|
||||
id="g2452"
|
||||
transform="translate(1205.7158,450.4785)">
|
||||
<path
|
||||
d="m 0,0 v -1.934 l -4.108,-0.201 v 1.693 c 0,2.255 -0.846,3.262 -2.497,3.262 -1.653,0 -2.499,-1.007 -2.499,-2.86 v -15.388 c 0,-1.853 0.806,-2.86 2.458,-2.86 1.652,0 2.457,1.007 2.457,3.263 v 4.834 h -2.416 v 3.948 H 0 v -9.226 c 0,-4.269 -2.457,-6.767 -6.727,-6.767 -4.23,0 -6.646,2.498 -6.646,6.767 V 0 c 0,4.271 2.416,6.768 6.646,6.768 C -2.457,6.768 0,4.271 0,0"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2454" />
|
||||
</g>
|
||||
<g
|
||||
id="g2456"
|
||||
transform="translate(1231.7031,450.0762)">
|
||||
<path
|
||||
d="m 0,0 v -14.663 c 0,-2.095 0.927,-3.223 2.618,-3.223 1.693,0 2.619,1.128 2.619,3.223 V 0 C 5.237,2.095 4.311,3.223 2.618,3.223 0.927,3.223 0,2.095 0,0 m 9.507,0.04 v -14.743 c 0,-4.432 -2.618,-7.131 -6.889,-7.131 -4.269,0 -6.889,2.699 -6.889,7.131 V 0.04 c 0,4.432 2.62,7.13 6.889,7.13 4.271,0 6.889,-2.698 6.889,-7.13"
|
||||
style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2458" />
|
||||
</g>
|
||||
<g
|
||||
id="g2460"
|
||||
transform="translate(1100.9401,661.5807)">
|
||||
<path
|
||||
d="m 0,0 c 0,0 -31.4,46.786 -77.244,51.496 0,0 -86.911,9.978 -106.761,-96.712 -3.373,-18.131 -3.024,-34.734 0.124,-49.549 9.467,-10.111 23.255,-20.105 40.687,-27.366 19.155,-7.978 26.834,-21.155 29.838,-31.678 18.644,26.846 1.258,68.715 1.258,68.715 19.468,-6.28 27.318,-35.796 27.318,-35.796 10.362,11.304 19.154,43.332 -0.314,67.196 -14.232,17.446 -13.816,42.076 -11.618,51.496 3.172,13.595 15.085,25.277 29.045,25.277 13.96,0 25.277,-11.317 25.277,-25.277 0,-8.236 -7.629,-15.162 -12.234,-21.266 -21.443,-28.425 6.896,-39.65 8.78,-69.48 4.359,-69.014 -50.868,-64.057 -50.868,-64.057 -1.587,-5.818 -8.659,-12.973 -10.85,-15.085 0.003,0 0.007,-10e-4 0.011,-0.002 0.065,0.043 0.103,0.066 0.103,0.066 l 5.242,-0.849 c 26.536,-3 53.043,7.333 68.922,34.083 C 7.536,-70.022 -91.06,-52.124 0,0"
|
||||
style="fill:#f7941e;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2462" />
|
||||
</g>
|
||||
<g
|
||||
id="g2464"
|
||||
transform="translate(1038.7678,651.5327)">
|
||||
<path
|
||||
d="m 0,0 c 5.116,0 9.263,4.147 9.263,9.263 0,1.321 -0.281,2.575 -0.779,3.712 C 7.875,12.379 7.042,12.01 6.123,12.01 c -1.864,0 -3.375,1.512 -3.375,3.376 0,0.919 0.368,1.752 0.964,2.361 C 2.575,18.245 1.321,18.526 0,18.526 -5.116,18.526 -9.263,14.379 -9.263,9.263 -9.263,4.147 -5.116,0 0,0"
|
||||
style="fill:#f7941e;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2466" />
|
||||
</g>
|
||||
<g
|
||||
id="g2468"
|
||||
transform="translate(993.389,489.493)">
|
||||
<path
|
||||
d="m 0,0 c -0.013,-0.008 -0.028,-0.019 -0.043,-0.029 -0.151,-0.1 -0.411,-0.281 -0.75,-0.549 -1.987,-1.572 -6.576,-6.075 -6.361,-14.016 0.273,-10.12 8.456,-4.177 7.895,1.106 -0.561,5.282 5.368,12.581 5.368,12.581 L 5.346,-0.783 0.103,0.066 C 0.103,0.066 0.065,0.043 0,0"
|
||||
style="fill:#74a643;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2470" />
|
||||
</g>
|
||||
<g
|
||||
id="g2472"
|
||||
transform="translate(987.5845,507.7722)">
|
||||
<path
|
||||
d="m 0,0 c -3.004,10.522 -10.684,23.7 -29.839,31.678 -17.432,7.26 -31.219,17.254 -40.686,27.365 -9.959,10.637 -15.137,21.403 -14.738,29.25 0,0 -26.008,-65.675 13.438,-101.405 34.576,-31.319 71.326,-7.651 71.326,-7.651 0,0 -45.521,6.117 -65.664,49.919 0,0 24.448,-30.526 52.688,-41.624 4.976,-1.956 10.07,-3.313 15.169,-3.789 0,0 0.912,7.13 -1.694,16.257"
|
||||
style="fill:#74a643;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path2474" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 22 KiB |
@ -1,39 +0,0 @@
|
||||
.\" Manpage for mangoapp.
|
||||
.TH mangoapp 1 "" "" "mangoapp"
|
||||
|
||||
.SH NAME
|
||||
mangoapp \- transparent background application with a built in mangohud
|
||||
|
||||
.SH SYNOPSIS
|
||||
\fBmangoapp\fR
|
||||
|
||||
.SH DESCRIPTION
|
||||
MangoHud is a Vulkan/OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more.
|
||||
.PP
|
||||
Mangoapp is a transparent background opengl application with a built in MangoHud. It's designed to be run inside a
|
||||
gamescope instance which will display mangoapp ontop of gamescopes output. It also takes frame information from
|
||||
gamescope. The purpose of this is to "easily" make MangoHud compatible with any application, or at least any
|
||||
application that gamescope can run. This solves issues with some OpenGL games and certain ports that have stdc++ issues
|
||||
as it's no longer directly injected into the game.
|
||||
|
||||
.SH USAGE
|
||||
Create a script (e.g. \fBrun.sh\fR) containing the app you want to run (e.g. \fBvkcube\fR) and \fBmangoapp\fR like so:
|
||||
.PP
|
||||
.RS 4
|
||||
.EX
|
||||
#!/bin/sh
|
||||
|
||||
vkcube&
|
||||
mangoapp
|
||||
.EE
|
||||
.RE
|
||||
.PP
|
||||
And then run it with \fBgamescope ./run.sh\fR.
|
||||
|
||||
.SH SEE ALSO
|
||||
mangohud(1)
|
||||
|
||||
.SH ABOUT
|
||||
MangoHud development takes place at \fIhttps://github.com/flightlessmango/MangoHud\fR.
|
||||
.br
|
||||
Benchmarks created with MangoHud can be uploaded to \fIhttps://flightlessmango.com\fR.
|
@ -1,53 +0,0 @@
|
||||
.\" Manpage for mangohud.
|
||||
.TH mangohud 1 "" "" "mangohud"
|
||||
|
||||
.SH NAME
|
||||
mangohud \- enable MangoHud on any application
|
||||
|
||||
.SH SYNOPSIS
|
||||
\fBmangohud\fR [--dlsym] COMMAND
|
||||
|
||||
.SH DESCRIPTION
|
||||
MangoHud is a Vulkan/OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more.
|
||||
|
||||
.SH USAGE
|
||||
MangoHud can be enabled for Vulkan applications by setting \fBMANGOHUD=1\fR as environment variable.
|
||||
.br
|
||||
To load MangoHud for any application, including OpenGL applications, the \fBmangohud\fR executable can be used. It preloads a library via ld into the application.
|
||||
.br
|
||||
Note: some OpenGL applications may also need dlsym hooking. This can be done by passing option \fB--dlsym\fR or by setting \fBMANGOHUD_DLSYM=1\fR as envrionment variable.
|
||||
|
||||
.SH CONFIG
|
||||
MangoHud comes with a config file which can be used to set configuration options globally or per application. The priorities of different config files are:
|
||||
.LP
|
||||
.RS 4
|
||||
/path/to/application/MangoHud.conf
|
||||
.br
|
||||
$XDG_CONFIG_HOME/MangoHud/{application_name}.conf
|
||||
.br
|
||||
$XDG_CONFIG_HOME/MangoHud/MangoHud.conf
|
||||
.RS -4
|
||||
.LP
|
||||
An example config file is located in /usr/share/doc/mangohud/MangoHud.conf, containing all available options.
|
||||
.LP
|
||||
A custom config file location can also be specified with the \fBMANGOHUD_CONFIGFILE\fR environment variable.
|
||||
.br
|
||||
Config options can also be set with the \fBMANGOHUD_CONFIG\fR environment variable. This takes priority over any config file.
|
||||
|
||||
.SH EXAMPLES
|
||||
OpenGL: \fBmangohud glxgears\fR
|
||||
.br
|
||||
Vulkan: \fBMANGOHUD=1 vkcube\fR
|
||||
.br
|
||||
Steam: set your launch option to \fBmangohud %command%\fR
|
||||
.br
|
||||
Lutris: add \fBmangohud\fR to the Command prefix setting
|
||||
.br
|
||||
OpenGL with dlsym: \fBmangohud --dlsym glxgears\fR
|
||||
.br
|
||||
Custom config options: \fBMANGOHUD_CONFIG="gpu_stats=0,font_size=12" mangohud glxgears\fR
|
||||
|
||||
.SH ABOUT
|
||||
MangoHud development takes place at \fIhttps://github.com/flightlessmango/MangoHud\fR.
|
||||
.br
|
||||
Benchmarks created with MangoHud can be uploaded to \fIhttps://flightlessmango.com\fR.
|
@ -1,56 +0,0 @@
|
||||
man1dir = join_paths(get_option('mandir'), 'man1')
|
||||
datadir = get_option('datadir')
|
||||
metainfo_file = files('io.github.flightlessmango.mangohud.metainfo.xml')
|
||||
icon_file = files('io.github.flightlessmango.mangohud.svg')
|
||||
|
||||
# Validate metainfo file
|
||||
ascli_exe = find_program('appstreamcli', required: get_option('tests'))
|
||||
if ascli_exe.found()
|
||||
test('validate metainfo file',
|
||||
ascli_exe,
|
||||
args: ['validate',
|
||||
'--no-net',
|
||||
'--pedantic',
|
||||
metainfo_file]
|
||||
)
|
||||
endif
|
||||
|
||||
# Install metainfo file
|
||||
install_data(
|
||||
metainfo_file,
|
||||
install_dir: join_paths(datadir, 'metainfo'),
|
||||
install_tag : 'doc',
|
||||
)
|
||||
|
||||
# Install icon for metainfo
|
||||
install_data(
|
||||
icon_file,
|
||||
install_dir: join_paths(datadir, 'icons', 'hicolor', 'scalable', 'apps'),
|
||||
install_tag : 'doc',
|
||||
)
|
||||
|
||||
# Install man pages
|
||||
install_man(
|
||||
files('mangohud.1'),
|
||||
install_dir: man1dir,
|
||||
)
|
||||
if get_option('mangoapp')
|
||||
install_man(
|
||||
files('mangoapp.1'),
|
||||
install_dir: man1dir,
|
||||
)
|
||||
endif
|
||||
|
||||
install_data(
|
||||
files('MangoHud.conf'),
|
||||
install_dir : join_paths(get_option('datadir'), 'doc', 'mangohud'),
|
||||
rename : ['MangoHud.conf.example'],
|
||||
install_tag : 'doc',
|
||||
)
|
||||
|
||||
install_data(
|
||||
files('presets.conf'),
|
||||
install_dir : join_paths(get_option('datadir'), 'doc', 'mangohud'),
|
||||
rename : ['presets.conf.example'],
|
||||
install_tag : 'doc',
|
||||
)
|
@ -1,10 +0,0 @@
|
||||
[preset 1]
|
||||
no_display
|
||||
|
||||
[preset 2]
|
||||
legacy_layout=0
|
||||
cpu_stats=0
|
||||
gpu_stats=0
|
||||
fps
|
||||
fps_only=1
|
||||
frametime=0
|
@ -1,805 +0,0 @@
|
||||
// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py for languages C and C++
|
||||
// from https://raw.githubusercontent.com/ForkAwesome/Fork-Awesome/master/src/icons/icons.yml
|
||||
// for use with https://github.com/ForkAwesome/Fork-Awesome/blob/master/fonts/forkawesome-webfont.ttf
|
||||
#pragma once
|
||||
|
||||
#define FONT_ICON_FILE_NAME_FK "forkawesome-webfont.ttf"
|
||||
|
||||
#define ICON_MIN_FK 0xf000
|
||||
#define ICON_MAX_FK 0xf35f
|
||||
#define ICON_FK_GLASS "\xef\x80\x80" // U+f000
|
||||
#define ICON_FK_MUSIC "\xef\x80\x81" // U+f001
|
||||
#define ICON_FK_SEARCH "\xef\x80\x82" // U+f002
|
||||
#define ICON_FK_ENVELOPE_O "\xef\x80\x83" // U+f003
|
||||
#define ICON_FK_HEART "\xef\x80\x84" // U+f004
|
||||
#define ICON_FK_STAR "\xef\x80\x85" // U+f005
|
||||
#define ICON_FK_STAR_O "\xef\x80\x86" // U+f006
|
||||
#define ICON_FK_USER "\xef\x80\x87" // U+f007
|
||||
#define ICON_FK_FILM "\xef\x80\x88" // U+f008
|
||||
#define ICON_FK_TH_LARGE "\xef\x80\x89" // U+f009
|
||||
#define ICON_FK_TH "\xef\x80\x8a" // U+f00a
|
||||
#define ICON_FK_TH_LIST "\xef\x80\x8b" // U+f00b
|
||||
#define ICON_FK_CHECK "\xef\x80\x8c" // U+f00c
|
||||
#define ICON_FK_TIMES "\xef\x80\x8d" // U+f00d
|
||||
#define ICON_FK_SEARCH_PLUS "\xef\x80\x8e" // U+f00e
|
||||
#define ICON_FK_SEARCH_MINUS "\xef\x80\x90" // U+f010
|
||||
#define ICON_FK_POWER_OFF "\xef\x80\x91" // U+f011
|
||||
#define ICON_FK_SIGNAL "\xef\x80\x92" // U+f012
|
||||
#define ICON_FK_COG "\xef\x80\x93" // U+f013
|
||||
#define ICON_FK_TRASH_O "\xef\x80\x94" // U+f014
|
||||
#define ICON_FK_HOME "\xef\x80\x95" // U+f015
|
||||
#define ICON_FK_FILE_O "\xef\x80\x96" // U+f016
|
||||
#define ICON_FK_CLOCK_O "\xef\x80\x97" // U+f017
|
||||
#define ICON_FK_ROAD "\xef\x80\x98" // U+f018
|
||||
#define ICON_FK_DOWNLOAD "\xef\x80\x99" // U+f019
|
||||
#define ICON_FK_ARROW_CIRCLE_O_DOWN "\xef\x80\x9a" // U+f01a
|
||||
#define ICON_FK_ARROW_CIRCLE_O_UP "\xef\x80\x9b" // U+f01b
|
||||
#define ICON_FK_INBOX "\xef\x80\x9c" // U+f01c
|
||||
#define ICON_FK_PLAY_CIRCLE_O "\xef\x80\x9d" // U+f01d
|
||||
#define ICON_FK_REPEAT "\xef\x80\x9e" // U+f01e
|
||||
#define ICON_FK_REFRESH "\xef\x80\xa1" // U+f021
|
||||
#define ICON_FK_LIST_ALT "\xef\x80\xa2" // U+f022
|
||||
#define ICON_FK_LOCK "\xef\x80\xa3" // U+f023
|
||||
#define ICON_FK_FLAG "\xef\x80\xa4" // U+f024
|
||||
#define ICON_FK_HEADPHONES "\xef\x80\xa5" // U+f025
|
||||
#define ICON_FK_VOLUME_OFF "\xef\x80\xa6" // U+f026
|
||||
#define ICON_FK_VOLUME_DOWN "\xef\x80\xa7" // U+f027
|
||||
#define ICON_FK_VOLUME_UP "\xef\x80\xa8" // U+f028
|
||||
#define ICON_FK_QRCODE "\xef\x80\xa9" // U+f029
|
||||
#define ICON_FK_BARCODE "\xef\x80\xaa" // U+f02a
|
||||
#define ICON_FK_TAG "\xef\x80\xab" // U+f02b
|
||||
#define ICON_FK_TAGS "\xef\x80\xac" // U+f02c
|
||||
#define ICON_FK_BOOK "\xef\x80\xad" // U+f02d
|
||||
#define ICON_FK_BOOKMARK "\xef\x80\xae" // U+f02e
|
||||
#define ICON_FK_PRINT "\xef\x80\xaf" // U+f02f
|
||||
#define ICON_FK_CAMERA "\xef\x80\xb0" // U+f030
|
||||
#define ICON_FK_FONT "\xef\x80\xb1" // U+f031
|
||||
#define ICON_FK_BOLD "\xef\x80\xb2" // U+f032
|
||||
#define ICON_FK_ITALIC "\xef\x80\xb3" // U+f033
|
||||
#define ICON_FK_TEXT_HEIGHT "\xef\x80\xb4" // U+f034
|
||||
#define ICON_FK_TEXT_WIDTH "\xef\x80\xb5" // U+f035
|
||||
#define ICON_FK_ALIGN_LEFT "\xef\x80\xb6" // U+f036
|
||||
#define ICON_FK_ALIGN_CENTER "\xef\x80\xb7" // U+f037
|
||||
#define ICON_FK_ALIGN_RIGHT "\xef\x80\xb8" // U+f038
|
||||
#define ICON_FK_ALIGN_JUSTIFY "\xef\x80\xb9" // U+f039
|
||||
#define ICON_FK_LIST "\xef\x80\xba" // U+f03a
|
||||
#define ICON_FK_OUTDENT "\xef\x80\xbb" // U+f03b
|
||||
#define ICON_FK_INDENT "\xef\x80\xbc" // U+f03c
|
||||
#define ICON_FK_VIDEO_CAMERA "\xef\x80\xbd" // U+f03d
|
||||
#define ICON_FK_PICTURE_O "\xef\x80\xbe" // U+f03e
|
||||
#define ICON_FK_PENCIL "\xef\x81\x80" // U+f040
|
||||
#define ICON_FK_MAP_MARKER "\xef\x81\x81" // U+f041
|
||||
#define ICON_FK_ADJUST "\xef\x81\x82" // U+f042
|
||||
#define ICON_FK_TINT "\xef\x81\x83" // U+f043
|
||||
#define ICON_FK_PENCIL_SQUARE_O "\xef\x81\x84" // U+f044
|
||||
#define ICON_FK_SHARE_SQUARE_O "\xef\x81\x85" // U+f045
|
||||
#define ICON_FK_CHECK_SQUARE_O "\xef\x81\x86" // U+f046
|
||||
#define ICON_FK_ARROWS "\xef\x81\x87" // U+f047
|
||||
#define ICON_FK_STEP_BACKWARD "\xef\x81\x88" // U+f048
|
||||
#define ICON_FK_FAST_BACKWARD "\xef\x81\x89" // U+f049
|
||||
#define ICON_FK_BACKWARD "\xef\x81\x8a" // U+f04a
|
||||
#define ICON_FK_PLAY "\xef\x81\x8b" // U+f04b
|
||||
#define ICON_FK_PAUSE "\xef\x81\x8c" // U+f04c
|
||||
#define ICON_FK_STOP "\xef\x81\x8d" // U+f04d
|
||||
#define ICON_FK_FORWARD "\xef\x81\x8e" // U+f04e
|
||||
#define ICON_FK_FAST_FORWARD "\xef\x81\x90" // U+f050
|
||||
#define ICON_FK_STEP_FORWARD "\xef\x81\x91" // U+f051
|
||||
#define ICON_FK_EJECT "\xef\x81\x92" // U+f052
|
||||
#define ICON_FK_CHEVRON_LEFT "\xef\x81\x93" // U+f053
|
||||
#define ICON_FK_CHEVRON_RIGHT "\xef\x81\x94" // U+f054
|
||||
#define ICON_FK_PLUS_CIRCLE "\xef\x81\x95" // U+f055
|
||||
#define ICON_FK_MINUS_CIRCLE "\xef\x81\x96" // U+f056
|
||||
#define ICON_FK_TIMES_CIRCLE "\xef\x81\x97" // U+f057
|
||||
#define ICON_FK_CHECK_CIRCLE "\xef\x81\x98" // U+f058
|
||||
#define ICON_FK_QUESTION_CIRCLE "\xef\x81\x99" // U+f059
|
||||
#define ICON_FK_INFO_CIRCLE "\xef\x81\x9a" // U+f05a
|
||||
#define ICON_FK_CROSSHAIRS "\xef\x81\x9b" // U+f05b
|
||||
#define ICON_FK_TIMES_CIRCLE_O "\xef\x81\x9c" // U+f05c
|
||||
#define ICON_FK_CHECK_CIRCLE_O "\xef\x81\x9d" // U+f05d
|
||||
#define ICON_FK_BAN "\xef\x81\x9e" // U+f05e
|
||||
#define ICON_FK_ARROW_LEFT "\xef\x81\xa0" // U+f060
|
||||
#define ICON_FK_ARROW_RIGHT "\xef\x81\xa1" // U+f061
|
||||
#define ICON_FK_ARROW_UP "\xef\x81\xa2" // U+f062
|
||||
#define ICON_FK_ARROW_DOWN "\xef\x81\xa3" // U+f063
|
||||
#define ICON_FK_SHARE "\xef\x81\xa4" // U+f064
|
||||
#define ICON_FK_EXPAND "\xef\x81\xa5" // U+f065
|
||||
#define ICON_FK_COMPRESS "\xef\x81\xa6" // U+f066
|
||||
#define ICON_FK_PLUS "\xef\x81\xa7" // U+f067
|
||||
#define ICON_FK_MINUS "\xef\x81\xa8" // U+f068
|
||||
#define ICON_FK_ASTERISK "\xef\x81\xa9" // U+f069
|
||||
#define ICON_FK_EXCLAMATION_CIRCLE "\xef\x81\xaa" // U+f06a
|
||||
#define ICON_FK_GIFT "\xef\x81\xab" // U+f06b
|
||||
#define ICON_FK_LEAF "\xef\x81\xac" // U+f06c
|
||||
#define ICON_FK_FIRE "\xef\x81\xad" // U+f06d
|
||||
#define ICON_FK_EYE "\xef\x81\xae" // U+f06e
|
||||
#define ICON_FK_EYE_SLASH "\xef\x81\xb0" // U+f070
|
||||
#define ICON_FK_EXCLAMATION_TRIANGLE "\xef\x81\xb1" // U+f071
|
||||
#define ICON_FK_PLANE "\xef\x81\xb2" // U+f072
|
||||
#define ICON_FK_CALENDAR "\xef\x81\xb3" // U+f073
|
||||
#define ICON_FK_RANDOM "\xef\x81\xb4" // U+f074
|
||||
#define ICON_FK_COMMENT "\xef\x81\xb5" // U+f075
|
||||
#define ICON_FK_MAGNET "\xef\x81\xb6" // U+f076
|
||||
#define ICON_FK_CHEVRON_UP "\xef\x81\xb7" // U+f077
|
||||
#define ICON_FK_CHEVRON_DOWN "\xef\x81\xb8" // U+f078
|
||||
#define ICON_FK_RETWEET "\xef\x81\xb9" // U+f079
|
||||
#define ICON_FK_SHOPPING_CART "\xef\x81\xba" // U+f07a
|
||||
#define ICON_FK_FOLDER "\xef\x81\xbb" // U+f07b
|
||||
#define ICON_FK_FOLDER_OPEN "\xef\x81\xbc" // U+f07c
|
||||
#define ICON_FK_ARROWS_V "\xef\x81\xbd" // U+f07d
|
||||
#define ICON_FK_ARROWS_H "\xef\x81\xbe" // U+f07e
|
||||
#define ICON_FK_BAR_CHART "\xef\x82\x80" // U+f080
|
||||
#define ICON_FK_TWITTER_SQUARE "\xef\x82\x81" // U+f081
|
||||
#define ICON_FK_FACEBOOK_SQUARE "\xef\x82\x82" // U+f082
|
||||
#define ICON_FK_CAMERA_RETRO "\xef\x82\x83" // U+f083
|
||||
#define ICON_FK_KEY "\xef\x82\x84" // U+f084
|
||||
#define ICON_FK_COGS "\xef\x82\x85" // U+f085
|
||||
#define ICON_FK_COMMENTS "\xef\x82\x86" // U+f086
|
||||
#define ICON_FK_THUMBS_O_UP "\xef\x82\x87" // U+f087
|
||||
#define ICON_FK_THUMBS_O_DOWN "\xef\x82\x88" // U+f088
|
||||
#define ICON_FK_STAR_HALF "\xef\x82\x89" // U+f089
|
||||
#define ICON_FK_HEART_O "\xef\x82\x8a" // U+f08a
|
||||
#define ICON_FK_SIGN_OUT "\xef\x82\x8b" // U+f08b
|
||||
#define ICON_FK_LINKEDIN_SQUARE "\xef\x82\x8c" // U+f08c
|
||||
#define ICON_FK_THUMB_TACK "\xef\x82\x8d" // U+f08d
|
||||
#define ICON_FK_EXTERNAL_LINK "\xef\x82\x8e" // U+f08e
|
||||
#define ICON_FK_SIGN_IN "\xef\x82\x90" // U+f090
|
||||
#define ICON_FK_TROPHY "\xef\x82\x91" // U+f091
|
||||
#define ICON_FK_GITHUB_SQUARE "\xef\x82\x92" // U+f092
|
||||
#define ICON_FK_UPLOAD "\xef\x82\x93" // U+f093
|
||||
#define ICON_FK_LEMON_O "\xef\x82\x94" // U+f094
|
||||
#define ICON_FK_PHONE "\xef\x82\x95" // U+f095
|
||||
#define ICON_FK_SQUARE_O "\xef\x82\x96" // U+f096
|
||||
#define ICON_FK_BOOKMARK_O "\xef\x82\x97" // U+f097
|
||||
#define ICON_FK_PHONE_SQUARE "\xef\x82\x98" // U+f098
|
||||
#define ICON_FK_TWITTER "\xef\x82\x99" // U+f099
|
||||
#define ICON_FK_FACEBOOK "\xef\x82\x9a" // U+f09a
|
||||
#define ICON_FK_GITHUB "\xef\x82\x9b" // U+f09b
|
||||
#define ICON_FK_UNLOCK "\xef\x82\x9c" // U+f09c
|
||||
#define ICON_FK_CREDIT_CARD "\xef\x82\x9d" // U+f09d
|
||||
#define ICON_FK_RSS "\xef\x82\x9e" // U+f09e
|
||||
#define ICON_FK_HDD_O "\xef\x82\xa0" // U+f0a0
|
||||
#define ICON_FK_BULLHORN "\xef\x82\xa1" // U+f0a1
|
||||
#define ICON_FK_BELL_O "\xef\x83\xb3" // U+f0f3
|
||||
#define ICON_FK_CERTIFICATE "\xef\x82\xa3" // U+f0a3
|
||||
#define ICON_FK_HAND_O_RIGHT "\xef\x82\xa4" // U+f0a4
|
||||
#define ICON_FK_HAND_O_LEFT "\xef\x82\xa5" // U+f0a5
|
||||
#define ICON_FK_HAND_O_UP "\xef\x82\xa6" // U+f0a6
|
||||
#define ICON_FK_HAND_O_DOWN "\xef\x82\xa7" // U+f0a7
|
||||
#define ICON_FK_ARROW_CIRCLE_LEFT "\xef\x82\xa8" // U+f0a8
|
||||
#define ICON_FK_ARROW_CIRCLE_RIGHT "\xef\x82\xa9" // U+f0a9
|
||||
#define ICON_FK_ARROW_CIRCLE_UP "\xef\x82\xaa" // U+f0aa
|
||||
#define ICON_FK_ARROW_CIRCLE_DOWN "\xef\x82\xab" // U+f0ab
|
||||
#define ICON_FK_GLOBE "\xef\x82\xac" // U+f0ac
|
||||
#define ICON_FK_GLOBE_E "\xef\x8c\x84" // U+f304
|
||||
#define ICON_FK_GLOBE_W "\xef\x8c\x85" // U+f305
|
||||
#define ICON_FK_WRENCH "\xef\x82\xad" // U+f0ad
|
||||
#define ICON_FK_TASKS "\xef\x82\xae" // U+f0ae
|
||||
#define ICON_FK_FILTER "\xef\x82\xb0" // U+f0b0
|
||||
#define ICON_FK_BRIEFCASE "\xef\x82\xb1" // U+f0b1
|
||||
#define ICON_FK_ARROWS_ALT "\xef\x82\xb2" // U+f0b2
|
||||
#define ICON_FK_USERS "\xef\x83\x80" // U+f0c0
|
||||
#define ICON_FK_LINK "\xef\x83\x81" // U+f0c1
|
||||
#define ICON_FK_CLOUD "\xef\x83\x82" // U+f0c2
|
||||
#define ICON_FK_FLASK "\xef\x83\x83" // U+f0c3
|
||||
#define ICON_FK_SCISSORS "\xef\x83\x84" // U+f0c4
|
||||
#define ICON_FK_FILES_O "\xef\x83\x85" // U+f0c5
|
||||
#define ICON_FK_PAPERCLIP "\xef\x83\x86" // U+f0c6
|
||||
#define ICON_FK_FLOPPY_O "\xef\x83\x87" // U+f0c7
|
||||
#define ICON_FK_SQUARE "\xef\x83\x88" // U+f0c8
|
||||
#define ICON_FK_BARS "\xef\x83\x89" // U+f0c9
|
||||
#define ICON_FK_LIST_UL "\xef\x83\x8a" // U+f0ca
|
||||
#define ICON_FK_LIST_OL "\xef\x83\x8b" // U+f0cb
|
||||
#define ICON_FK_STRIKETHROUGH "\xef\x83\x8c" // U+f0cc
|
||||
#define ICON_FK_UNDERLINE "\xef\x83\x8d" // U+f0cd
|
||||
#define ICON_FK_TABLE "\xef\x83\x8e" // U+f0ce
|
||||
#define ICON_FK_MAGIC "\xef\x83\x90" // U+f0d0
|
||||
#define ICON_FK_TRUCK "\xef\x83\x91" // U+f0d1
|
||||
#define ICON_FK_PINTEREST "\xef\x83\x92" // U+f0d2
|
||||
#define ICON_FK_PINTEREST_SQUARE "\xef\x83\x93" // U+f0d3
|
||||
#define ICON_FK_GOOGLE_PLUS_SQUARE "\xef\x83\x94" // U+f0d4
|
||||
#define ICON_FK_GOOGLE_PLUS "\xef\x83\x95" // U+f0d5
|
||||
#define ICON_FK_MONEY "\xef\x83\x96" // U+f0d6
|
||||
#define ICON_FK_CARET_DOWN "\xef\x83\x97" // U+f0d7
|
||||
#define ICON_FK_CARET_UP "\xef\x83\x98" // U+f0d8
|
||||
#define ICON_FK_CARET_LEFT "\xef\x83\x99" // U+f0d9
|
||||
#define ICON_FK_CARET_RIGHT "\xef\x83\x9a" // U+f0da
|
||||
#define ICON_FK_COLUMNS "\xef\x83\x9b" // U+f0db
|
||||
#define ICON_FK_SORT "\xef\x83\x9c" // U+f0dc
|
||||
#define ICON_FK_SORT_DESC "\xef\x83\x9d" // U+f0dd
|
||||
#define ICON_FK_SORT_ASC "\xef\x83\x9e" // U+f0de
|
||||
#define ICON_FK_ENVELOPE "\xef\x83\xa0" // U+f0e0
|
||||
#define ICON_FK_LINKEDIN "\xef\x83\xa1" // U+f0e1
|
||||
#define ICON_FK_UNDO "\xef\x83\xa2" // U+f0e2
|
||||
#define ICON_FK_GAVEL "\xef\x83\xa3" // U+f0e3
|
||||
#define ICON_FK_TACHOMETER "\xef\x83\xa4" // U+f0e4
|
||||
#define ICON_FK_COMMENT_O "\xef\x83\xa5" // U+f0e5
|
||||
#define ICON_FK_COMMENTS_O "\xef\x83\xa6" // U+f0e6
|
||||
#define ICON_FK_BOLT "\xef\x83\xa7" // U+f0e7
|
||||
#define ICON_FK_SITEMAP "\xef\x83\xa8" // U+f0e8
|
||||
#define ICON_FK_UMBRELLA "\xef\x83\xa9" // U+f0e9
|
||||
#define ICON_FK_CLIPBOARD "\xef\x83\xaa" // U+f0ea
|
||||
#define ICON_FK_LIGHTBULB_O "\xef\x83\xab" // U+f0eb
|
||||
#define ICON_FK_EXCHANGE "\xef\x83\xac" // U+f0ec
|
||||
#define ICON_FK_CLOUD_DOWNLOAD "\xef\x83\xad" // U+f0ed
|
||||
#define ICON_FK_CLOUD_UPLOAD "\xef\x83\xae" // U+f0ee
|
||||
#define ICON_FK_USER_MD "\xef\x83\xb0" // U+f0f0
|
||||
#define ICON_FK_STETHOSCOPE "\xef\x83\xb1" // U+f0f1
|
||||
#define ICON_FK_SUITCASE "\xef\x83\xb2" // U+f0f2
|
||||
#define ICON_FK_BELL "\xef\x82\xa2" // U+f0a2
|
||||
#define ICON_FK_COFFEE "\xef\x83\xb4" // U+f0f4
|
||||
#define ICON_FK_CUTLERY "\xef\x83\xb5" // U+f0f5
|
||||
#define ICON_FK_FILE_TEXT_O "\xef\x83\xb6" // U+f0f6
|
||||
#define ICON_FK_BUILDING_O "\xef\x83\xb7" // U+f0f7
|
||||
#define ICON_FK_HOSPITAL_O "\xef\x83\xb8" // U+f0f8
|
||||
#define ICON_FK_AMBULANCE "\xef\x83\xb9" // U+f0f9
|
||||
#define ICON_FK_MEDKIT "\xef\x83\xba" // U+f0fa
|
||||
#define ICON_FK_FIGHTER_JET "\xef\x83\xbb" // U+f0fb
|
||||
#define ICON_FK_BEER "\xef\x83\xbc" // U+f0fc
|
||||
#define ICON_FK_H_SQUARE "\xef\x83\xbd" // U+f0fd
|
||||
#define ICON_FK_PLUS_SQUARE "\xef\x83\xbe" // U+f0fe
|
||||
#define ICON_FK_ANGLE_DOUBLE_LEFT "\xef\x84\x80" // U+f100
|
||||
#define ICON_FK_ANGLE_DOUBLE_RIGHT "\xef\x84\x81" // U+f101
|
||||
#define ICON_FK_ANGLE_DOUBLE_UP "\xef\x84\x82" // U+f102
|
||||
#define ICON_FK_ANGLE_DOUBLE_DOWN "\xef\x84\x83" // U+f103
|
||||
#define ICON_FK_ANGLE_LEFT "\xef\x84\x84" // U+f104
|
||||
#define ICON_FK_ANGLE_RIGHT "\xef\x84\x85" // U+f105
|
||||
#define ICON_FK_ANGLE_UP "\xef\x84\x86" // U+f106
|
||||
#define ICON_FK_ANGLE_DOWN "\xef\x84\x87" // U+f107
|
||||
#define ICON_FK_DESKTOP "\xef\x84\x88" // U+f108
|
||||
#define ICON_FK_LAPTOP "\xef\x84\x89" // U+f109
|
||||
#define ICON_FK_TABLET "\xef\x84\x8a" // U+f10a
|
||||
#define ICON_FK_MOBILE "\xef\x84\x8b" // U+f10b
|
||||
#define ICON_FK_CIRCLE_O "\xef\x84\x8c" // U+f10c
|
||||
#define ICON_FK_QUOTE_LEFT "\xef\x84\x8d" // U+f10d
|
||||
#define ICON_FK_QUOTE_RIGHT "\xef\x84\x8e" // U+f10e
|
||||
#define ICON_FK_SPINNER "\xef\x84\x90" // U+f110
|
||||
#define ICON_FK_CIRCLE "\xef\x84\x91" // U+f111
|
||||
#define ICON_FK_REPLY "\xef\x84\x92" // U+f112
|
||||
#define ICON_FK_GITHUB_ALT "\xef\x84\x93" // U+f113
|
||||
#define ICON_FK_FOLDER_O "\xef\x84\x94" // U+f114
|
||||
#define ICON_FK_FOLDER_OPEN_O "\xef\x84\x95" // U+f115
|
||||
#define ICON_FK_SMILE_O "\xef\x84\x98" // U+f118
|
||||
#define ICON_FK_FROWN_O "\xef\x84\x99" // U+f119
|
||||
#define ICON_FK_MEH_O "\xef\x84\x9a" // U+f11a
|
||||
#define ICON_FK_GAMEPAD "\xef\x84\x9b" // U+f11b
|
||||
#define ICON_FK_KEYBOARD_O "\xef\x84\x9c" // U+f11c
|
||||
#define ICON_FK_FLAG_O "\xef\x84\x9d" // U+f11d
|
||||
#define ICON_FK_FLAG_CHECKERED "\xef\x84\x9e" // U+f11e
|
||||
#define ICON_FK_TERMINAL "\xef\x84\xa0" // U+f120
|
||||
#define ICON_FK_CODE "\xef\x84\xa1" // U+f121
|
||||
#define ICON_FK_REPLY_ALL "\xef\x84\xa2" // U+f122
|
||||
#define ICON_FK_STAR_HALF_O "\xef\x84\xa3" // U+f123
|
||||
#define ICON_FK_LOCATION_ARROW "\xef\x84\xa4" // U+f124
|
||||
#define ICON_FK_CROP "\xef\x84\xa5" // U+f125
|
||||
#define ICON_FK_CODE_FORK "\xef\x84\xa6" // U+f126
|
||||
#define ICON_FK_CHAIN_BROKEN "\xef\x84\xa7" // U+f127
|
||||
#define ICON_FK_QUESTION "\xef\x84\xa8" // U+f128
|
||||
#define ICON_FK_INFO "\xef\x84\xa9" // U+f129
|
||||
#define ICON_FK_EXCLAMATION "\xef\x84\xaa" // U+f12a
|
||||
#define ICON_FK_SUPERSCRIPT "\xef\x84\xab" // U+f12b
|
||||
#define ICON_FK_SUBSCRIPT "\xef\x84\xac" // U+f12c
|
||||
#define ICON_FK_ERASER "\xef\x84\xad" // U+f12d
|
||||
#define ICON_FK_PUZZLE_PIECE "\xef\x84\xae" // U+f12e
|
||||
#define ICON_FK_MICROPHONE "\xef\x84\xb0" // U+f130
|
||||
#define ICON_FK_MICROPHONE_SLASH "\xef\x84\xb1" // U+f131
|
||||
#define ICON_FK_SHIELD "\xef\x84\xb2" // U+f132
|
||||
#define ICON_FK_CALENDAR_O "\xef\x84\xb3" // U+f133
|
||||
#define ICON_FK_FIRE_EXTINGUISHER "\xef\x84\xb4" // U+f134
|
||||
#define ICON_FK_ROCKET "\xef\x84\xb5" // U+f135
|
||||
#define ICON_FK_MAXCDN "\xef\x84\xb6" // U+f136
|
||||
#define ICON_FK_CHEVRON_CIRCLE_LEFT "\xef\x84\xb7" // U+f137
|
||||
#define ICON_FK_CHEVRON_CIRCLE_RIGHT "\xef\x84\xb8" // U+f138
|
||||
#define ICON_FK_CHEVRON_CIRCLE_UP "\xef\x84\xb9" // U+f139
|
||||
#define ICON_FK_CHEVRON_CIRCLE_DOWN "\xef\x84\xba" // U+f13a
|
||||
#define ICON_FK_HTML5 "\xef\x84\xbb" // U+f13b
|
||||
#define ICON_FK_CSS3 "\xef\x84\xbc" // U+f13c
|
||||
#define ICON_FK_ANCHOR "\xef\x84\xbd" // U+f13d
|
||||
#define ICON_FK_UNLOCK_ALT "\xef\x84\xbe" // U+f13e
|
||||
#define ICON_FK_BULLSEYE "\xef\x85\x80" // U+f140
|
||||
#define ICON_FK_ELLIPSIS_H "\xef\x85\x81" // U+f141
|
||||
#define ICON_FK_ELLIPSIS_V "\xef\x85\x82" // U+f142
|
||||
#define ICON_FK_RSS_SQUARE "\xef\x85\x83" // U+f143
|
||||
#define ICON_FK_PLAY_CIRCLE "\xef\x85\x84" // U+f144
|
||||
#define ICON_FK_TICKET "\xef\x85\x85" // U+f145
|
||||
#define ICON_FK_MINUS_SQUARE "\xef\x85\x86" // U+f146
|
||||
#define ICON_FK_MINUS_SQUARE_O "\xef\x85\x87" // U+f147
|
||||
#define ICON_FK_LEVEL_UP "\xef\x85\x88" // U+f148
|
||||
#define ICON_FK_LEVEL_DOWN "\xef\x85\x89" // U+f149
|
||||
#define ICON_FK_CHECK_SQUARE "\xef\x85\x8a" // U+f14a
|
||||
#define ICON_FK_PENCIL_SQUARE "\xef\x85\x8b" // U+f14b
|
||||
#define ICON_FK_EXTERNAL_LINK_SQUARE "\xef\x85\x8c" // U+f14c
|
||||
#define ICON_FK_SHARE_SQUARE "\xef\x85\x8d" // U+f14d
|
||||
#define ICON_FK_COMPASS "\xef\x85\x8e" // U+f14e
|
||||
#define ICON_FK_CARET_SQUARE_O_DOWN "\xef\x85\x90" // U+f150
|
||||
#define ICON_FK_CARET_SQUARE_O_UP "\xef\x85\x91" // U+f151
|
||||
#define ICON_FK_CARET_SQUARE_O_RIGHT "\xef\x85\x92" // U+f152
|
||||
#define ICON_FK_EUR "\xef\x85\x93" // U+f153
|
||||
#define ICON_FK_GBP "\xef\x85\x94" // U+f154
|
||||
#define ICON_FK_USD "\xef\x85\x95" // U+f155
|
||||
#define ICON_FK_INR "\xef\x85\x96" // U+f156
|
||||
#define ICON_FK_JPY "\xef\x85\x97" // U+f157
|
||||
#define ICON_FK_RUB "\xef\x85\x98" // U+f158
|
||||
#define ICON_FK_KRW "\xef\x85\x99" // U+f159
|
||||
#define ICON_FK_BTC "\xef\x85\x9a" // U+f15a
|
||||
#define ICON_FK_FILE "\xef\x85\x9b" // U+f15b
|
||||
#define ICON_FK_FILE_TEXT "\xef\x85\x9c" // U+f15c
|
||||
#define ICON_FK_SORT_ALPHA_ASC "\xef\x85\x9d" // U+f15d
|
||||
#define ICON_FK_SORT_ALPHA_DESC "\xef\x85\x9e" // U+f15e
|
||||
#define ICON_FK_SORT_AMOUNT_ASC "\xef\x85\xa0" // U+f160
|
||||
#define ICON_FK_SORT_AMOUNT_DESC "\xef\x85\xa1" // U+f161
|
||||
#define ICON_FK_SORT_NUMERIC_ASC "\xef\x85\xa2" // U+f162
|
||||
#define ICON_FK_SORT_NUMERIC_DESC "\xef\x85\xa3" // U+f163
|
||||
#define ICON_FK_THUMBS_UP "\xef\x85\xa4" // U+f164
|
||||
#define ICON_FK_THUMBS_DOWN "\xef\x85\xa5" // U+f165
|
||||
#define ICON_FK_YOUTUBE_SQUARE "\xef\x85\xa6" // U+f166
|
||||
#define ICON_FK_YOUTUBE "\xef\x85\xa7" // U+f167
|
||||
#define ICON_FK_XING "\xef\x85\xa8" // U+f168
|
||||
#define ICON_FK_XING_SQUARE "\xef\x85\xa9" // U+f169
|
||||
#define ICON_FK_YOUTUBE_PLAY "\xef\x85\xaa" // U+f16a
|
||||
#define ICON_FK_DROPBOX "\xef\x85\xab" // U+f16b
|
||||
#define ICON_FK_STACK_OVERFLOW "\xef\x85\xac" // U+f16c
|
||||
#define ICON_FK_INSTAGRAM "\xef\x85\xad" // U+f16d
|
||||
#define ICON_FK_FLICKR "\xef\x85\xae" // U+f16e
|
||||
#define ICON_FK_ADN "\xef\x85\xb0" // U+f170
|
||||
#define ICON_FK_BITBUCKET "\xef\x85\xb1" // U+f171
|
||||
#define ICON_FK_BITBUCKET_SQUARE "\xef\x85\xb2" // U+f172
|
||||
#define ICON_FK_TUMBLR "\xef\x85\xb3" // U+f173
|
||||
#define ICON_FK_TUMBLR_SQUARE "\xef\x85\xb4" // U+f174
|
||||
#define ICON_FK_LONG_ARROW_DOWN "\xef\x85\xb5" // U+f175
|
||||
#define ICON_FK_LONG_ARROW_UP "\xef\x85\xb6" // U+f176
|
||||
#define ICON_FK_LONG_ARROW_LEFT "\xef\x85\xb7" // U+f177
|
||||
#define ICON_FK_LONG_ARROW_RIGHT "\xef\x85\xb8" // U+f178
|
||||
#define ICON_FK_APPLE "\xef\x85\xb9" // U+f179
|
||||
#define ICON_FK_WINDOWS "\xef\x85\xba" // U+f17a
|
||||
#define ICON_FK_ANDROID "\xef\x85\xbb" // U+f17b
|
||||
#define ICON_FK_LINUX "\xef\x85\xbc" // U+f17c
|
||||
#define ICON_FK_DRIBBBLE "\xef\x85\xbd" // U+f17d
|
||||
#define ICON_FK_SKYPE "\xef\x85\xbe" // U+f17e
|
||||
#define ICON_FK_FOURSQUARE "\xef\x86\x80" // U+f180
|
||||
#define ICON_FK_TRELLO "\xef\x86\x81" // U+f181
|
||||
#define ICON_FK_FEMALE "\xef\x86\x82" // U+f182
|
||||
#define ICON_FK_MALE "\xef\x86\x83" // U+f183
|
||||
#define ICON_FK_GRATIPAY "\xef\x86\x84" // U+f184
|
||||
#define ICON_FK_SUN_O "\xef\x86\x85" // U+f185
|
||||
#define ICON_FK_MOON_O "\xef\x86\x86" // U+f186
|
||||
#define ICON_FK_ARCHIVE "\xef\x86\x87" // U+f187
|
||||
#define ICON_FK_BUG "\xef\x86\x88" // U+f188
|
||||
#define ICON_FK_VK "\xef\x86\x89" // U+f189
|
||||
#define ICON_FK_WEIBO "\xef\x86\x8a" // U+f18a
|
||||
#define ICON_FK_RENREN "\xef\x86\x8b" // U+f18b
|
||||
#define ICON_FK_PAGELINES "\xef\x86\x8c" // U+f18c
|
||||
#define ICON_FK_STACK_EXCHANGE "\xef\x86\x8d" // U+f18d
|
||||
#define ICON_FK_ARROW_CIRCLE_O_RIGHT "\xef\x86\x8e" // U+f18e
|
||||
#define ICON_FK_ARROW_CIRCLE_O_LEFT "\xef\x86\x90" // U+f190
|
||||
#define ICON_FK_CARET_SQUARE_O_LEFT "\xef\x86\x91" // U+f191
|
||||
#define ICON_FK_DOT_CIRCLE_O "\xef\x86\x92" // U+f192
|
||||
#define ICON_FK_WHEELCHAIR "\xef\x86\x93" // U+f193
|
||||
#define ICON_FK_VIMEO_SQUARE "\xef\x86\x94" // U+f194
|
||||
#define ICON_FK_TRY "\xef\x86\x95" // U+f195
|
||||
#define ICON_FK_PLUS_SQUARE_O "\xef\x86\x96" // U+f196
|
||||
#define ICON_FK_SPACE_SHUTTLE "\xef\x86\x97" // U+f197
|
||||
#define ICON_FK_SLACK "\xef\x86\x98" // U+f198
|
||||
#define ICON_FK_ENVELOPE_SQUARE "\xef\x86\x99" // U+f199
|
||||
#define ICON_FK_WORDPRESS "\xef\x86\x9a" // U+f19a
|
||||
#define ICON_FK_OPENID "\xef\x86\x9b" // U+f19b
|
||||
#define ICON_FK_UNIVERSITY "\xef\x86\x9c" // U+f19c
|
||||
#define ICON_FK_GRADUATION_CAP "\xef\x86\x9d" // U+f19d
|
||||
#define ICON_FK_YAHOO "\xef\x86\x9e" // U+f19e
|
||||
#define ICON_FK_GOOGLE "\xef\x86\xa0" // U+f1a0
|
||||
#define ICON_FK_REDDIT "\xef\x86\xa1" // U+f1a1
|
||||
#define ICON_FK_REDDIT_SQUARE "\xef\x86\xa2" // U+f1a2
|
||||
#define ICON_FK_STUMBLEUPON_CIRCLE "\xef\x86\xa3" // U+f1a3
|
||||
#define ICON_FK_STUMBLEUPON "\xef\x86\xa4" // U+f1a4
|
||||
#define ICON_FK_DELICIOUS "\xef\x86\xa5" // U+f1a5
|
||||
#define ICON_FK_DIGG "\xef\x86\xa6" // U+f1a6
|
||||
#define ICON_FK_DRUPAL "\xef\x86\xa9" // U+f1a9
|
||||
#define ICON_FK_JOOMLA "\xef\x86\xaa" // U+f1aa
|
||||
#define ICON_FK_LANGUAGE "\xef\x86\xab" // U+f1ab
|
||||
#define ICON_FK_FAX "\xef\x86\xac" // U+f1ac
|
||||
#define ICON_FK_BUILDING "\xef\x86\xad" // U+f1ad
|
||||
#define ICON_FK_CHILD "\xef\x86\xae" // U+f1ae
|
||||
#define ICON_FK_PAW "\xef\x86\xb0" // U+f1b0
|
||||
#define ICON_FK_SPOON "\xef\x86\xb1" // U+f1b1
|
||||
#define ICON_FK_CUBE "\xef\x86\xb2" // U+f1b2
|
||||
#define ICON_FK_CUBES "\xef\x86\xb3" // U+f1b3
|
||||
#define ICON_FK_BEHANCE "\xef\x86\xb4" // U+f1b4
|
||||
#define ICON_FK_BEHANCE_SQUARE "\xef\x86\xb5" // U+f1b5
|
||||
#define ICON_FK_STEAM "\xef\x86\xb6" // U+f1b6
|
||||
#define ICON_FK_STEAM_SQUARE "\xef\x86\xb7" // U+f1b7
|
||||
#define ICON_FK_RECYCLE "\xef\x86\xb8" // U+f1b8
|
||||
#define ICON_FK_CAR "\xef\x86\xb9" // U+f1b9
|
||||
#define ICON_FK_TAXI "\xef\x86\xba" // U+f1ba
|
||||
#define ICON_FK_TREE "\xef\x86\xbb" // U+f1bb
|
||||
#define ICON_FK_SPOTIFY "\xef\x86\xbc" // U+f1bc
|
||||
#define ICON_FK_DEVIANTART "\xef\x86\xbd" // U+f1bd
|
||||
#define ICON_FK_SOUNDCLOUD "\xef\x86\xbe" // U+f1be
|
||||
#define ICON_FK_DATABASE "\xef\x87\x80" // U+f1c0
|
||||
#define ICON_FK_FILE_PDF_O "\xef\x87\x81" // U+f1c1
|
||||
#define ICON_FK_FILE_WORD_O "\xef\x87\x82" // U+f1c2
|
||||
#define ICON_FK_FILE_EXCEL_O "\xef\x87\x83" // U+f1c3
|
||||
#define ICON_FK_FILE_POWERPOINT_O "\xef\x87\x84" // U+f1c4
|
||||
#define ICON_FK_FILE_IMAGE_O "\xef\x87\x85" // U+f1c5
|
||||
#define ICON_FK_FILE_ARCHIVE_O "\xef\x87\x86" // U+f1c6
|
||||
#define ICON_FK_FILE_AUDIO_O "\xef\x87\x87" // U+f1c7
|
||||
#define ICON_FK_FILE_VIDEO_O "\xef\x87\x88" // U+f1c8
|
||||
#define ICON_FK_FILE_CODE_O "\xef\x87\x89" // U+f1c9
|
||||
#define ICON_FK_VINE "\xef\x87\x8a" // U+f1ca
|
||||
#define ICON_FK_CODEPEN "\xef\x87\x8b" // U+f1cb
|
||||
#define ICON_FK_JSFIDDLE "\xef\x87\x8c" // U+f1cc
|
||||
#define ICON_FK_LIFE_RING "\xef\x87\x8d" // U+f1cd
|
||||
#define ICON_FK_CIRCLE_O_NOTCH "\xef\x87\x8e" // U+f1ce
|
||||
#define ICON_FK_REBEL "\xef\x87\x90" // U+f1d0
|
||||
#define ICON_FK_EMPIRE "\xef\x87\x91" // U+f1d1
|
||||
#define ICON_FK_GIT_SQUARE "\xef\x87\x92" // U+f1d2
|
||||
#define ICON_FK_GIT "\xef\x87\x93" // U+f1d3
|
||||
#define ICON_FK_HACKER_NEWS "\xef\x87\x94" // U+f1d4
|
||||
#define ICON_FK_TENCENT_WEIBO "\xef\x87\x95" // U+f1d5
|
||||
#define ICON_FK_QQ "\xef\x87\x96" // U+f1d6
|
||||
#define ICON_FK_WEIXIN "\xef\x87\x97" // U+f1d7
|
||||
#define ICON_FK_PAPER_PLANE "\xef\x87\x98" // U+f1d8
|
||||
#define ICON_FK_PAPER_PLANE_O "\xef\x87\x99" // U+f1d9
|
||||
#define ICON_FK_HISTORY "\xef\x87\x9a" // U+f1da
|
||||
#define ICON_FK_CIRCLE_THIN "\xef\x87\x9b" // U+f1db
|
||||
#define ICON_FK_HEADER "\xef\x87\x9c" // U+f1dc
|
||||
#define ICON_FK_PARAGRAPH "\xef\x87\x9d" // U+f1dd
|
||||
#define ICON_FK_SLIDERS "\xef\x87\x9e" // U+f1de
|
||||
#define ICON_FK_SHARE_ALT "\xef\x87\xa0" // U+f1e0
|
||||
#define ICON_FK_SHARE_ALT_SQUARE "\xef\x87\xa1" // U+f1e1
|
||||
#define ICON_FK_BOMB "\xef\x87\xa2" // U+f1e2
|
||||
#define ICON_FK_FUTBOL_O "\xef\x87\xa3" // U+f1e3
|
||||
#define ICON_FK_TTY "\xef\x87\xa4" // U+f1e4
|
||||
#define ICON_FK_BINOCULARS "\xef\x87\xa5" // U+f1e5
|
||||
#define ICON_FK_PLUG "\xef\x87\xa6" // U+f1e6
|
||||
#define ICON_FK_SLIDESHARE "\xef\x87\xa7" // U+f1e7
|
||||
#define ICON_FK_TWITCH "\xef\x87\xa8" // U+f1e8
|
||||
#define ICON_FK_YELP "\xef\x87\xa9" // U+f1e9
|
||||
#define ICON_FK_NEWSPAPER_O "\xef\x87\xaa" // U+f1ea
|
||||
#define ICON_FK_WIFI "\xef\x87\xab" // U+f1eb
|
||||
#define ICON_FK_CALCULATOR "\xef\x87\xac" // U+f1ec
|
||||
#define ICON_FK_PAYPAL "\xef\x87\xad" // U+f1ed
|
||||
#define ICON_FK_GOOGLE_WALLET "\xef\x87\xae" // U+f1ee
|
||||
#define ICON_FK_CC_VISA "\xef\x87\xb0" // U+f1f0
|
||||
#define ICON_FK_CC_MASTERCARD "\xef\x87\xb1" // U+f1f1
|
||||
#define ICON_FK_CC_DISCOVER "\xef\x87\xb2" // U+f1f2
|
||||
#define ICON_FK_CC_AMEX "\xef\x87\xb3" // U+f1f3
|
||||
#define ICON_FK_CC_PAYPAL "\xef\x87\xb4" // U+f1f4
|
||||
#define ICON_FK_CC_STRIPE "\xef\x87\xb5" // U+f1f5
|
||||
#define ICON_FK_BELL_SLASH "\xef\x87\xb6" // U+f1f6
|
||||
#define ICON_FK_BELL_SLASH_O "\xef\x87\xb7" // U+f1f7
|
||||
#define ICON_FK_TRASH "\xef\x87\xb8" // U+f1f8
|
||||
#define ICON_FK_COPYRIGHT "\xef\x87\xb9" // U+f1f9
|
||||
#define ICON_FK_AT "\xef\x87\xba" // U+f1fa
|
||||
#define ICON_FK_EYEDROPPER "\xef\x87\xbb" // U+f1fb
|
||||
#define ICON_FK_PAINT_BRUSH "\xef\x87\xbc" // U+f1fc
|
||||
#define ICON_FK_BIRTHDAY_CAKE "\xef\x87\xbd" // U+f1fd
|
||||
#define ICON_FK_AREA_CHART "\xef\x87\xbe" // U+f1fe
|
||||
#define ICON_FK_PIE_CHART "\xef\x88\x80" // U+f200
|
||||
#define ICON_FK_LINE_CHART "\xef\x88\x81" // U+f201
|
||||
#define ICON_FK_LASTFM "\xef\x88\x82" // U+f202
|
||||
#define ICON_FK_LASTFM_SQUARE "\xef\x88\x83" // U+f203
|
||||
#define ICON_FK_TOGGLE_OFF "\xef\x88\x84" // U+f204
|
||||
#define ICON_FK_TOGGLE_ON "\xef\x88\x85" // U+f205
|
||||
#define ICON_FK_BICYCLE "\xef\x88\x86" // U+f206
|
||||
#define ICON_FK_BUS "\xef\x88\x87" // U+f207
|
||||
#define ICON_FK_IOXHOST "\xef\x88\x88" // U+f208
|
||||
#define ICON_FK_ANGELLIST "\xef\x88\x89" // U+f209
|
||||
#define ICON_FK_CC "\xef\x88\x8a" // U+f20a
|
||||
#define ICON_FK_ILS "\xef\x88\x8b" // U+f20b
|
||||
#define ICON_FK_MEANPATH "\xef\x88\x8c" // U+f20c
|
||||
#define ICON_FK_BUYSELLADS "\xef\x88\x8d" // U+f20d
|
||||
#define ICON_FK_CONNECTDEVELOP "\xef\x88\x8e" // U+f20e
|
||||
#define ICON_FK_DASHCUBE "\xef\x88\x90" // U+f210
|
||||
#define ICON_FK_FORUMBEE "\xef\x88\x91" // U+f211
|
||||
#define ICON_FK_LEANPUB "\xef\x88\x92" // U+f212
|
||||
#define ICON_FK_SELLSY "\xef\x88\x93" // U+f213
|
||||
#define ICON_FK_SHIRTSINBULK "\xef\x88\x94" // U+f214
|
||||
#define ICON_FK_SIMPLYBUILT "\xef\x88\x95" // U+f215
|
||||
#define ICON_FK_SKYATLAS "\xef\x88\x96" // U+f216
|
||||
#define ICON_FK_CART_PLUS "\xef\x88\x97" // U+f217
|
||||
#define ICON_FK_CART_ARROW_DOWN "\xef\x88\x98" // U+f218
|
||||
#define ICON_FK_DIAMOND "\xef\x88\x99" // U+f219
|
||||
#define ICON_FK_SHIP "\xef\x88\x9a" // U+f21a
|
||||
#define ICON_FK_USER_SECRET "\xef\x88\x9b" // U+f21b
|
||||
#define ICON_FK_MOTORCYCLE "\xef\x88\x9c" // U+f21c
|
||||
#define ICON_FK_STREET_VIEW "\xef\x88\x9d" // U+f21d
|
||||
#define ICON_FK_HEARTBEAT "\xef\x88\x9e" // U+f21e
|
||||
#define ICON_FK_VENUS "\xef\x88\xa1" // U+f221
|
||||
#define ICON_FK_MARS "\xef\x88\xa2" // U+f222
|
||||
#define ICON_FK_MERCURY "\xef\x88\xa3" // U+f223
|
||||
#define ICON_FK_TRANSGENDER "\xef\x88\xa4" // U+f224
|
||||
#define ICON_FK_TRANSGENDER_ALT "\xef\x88\xa5" // U+f225
|
||||
#define ICON_FK_VENUS_DOUBLE "\xef\x88\xa6" // U+f226
|
||||
#define ICON_FK_MARS_DOUBLE "\xef\x88\xa7" // U+f227
|
||||
#define ICON_FK_VENUS_MARS "\xef\x88\xa8" // U+f228
|
||||
#define ICON_FK_MARS_STROKE "\xef\x88\xa9" // U+f229
|
||||
#define ICON_FK_MARS_STROKE_V "\xef\x88\xaa" // U+f22a
|
||||
#define ICON_FK_MARS_STROKE_H "\xef\x88\xab" // U+f22b
|
||||
#define ICON_FK_NEUTER "\xef\x88\xac" // U+f22c
|
||||
#define ICON_FK_GENDERLESS "\xef\x88\xad" // U+f22d
|
||||
#define ICON_FK_FACEBOOK_OFFICIAL "\xef\x88\xb0" // U+f230
|
||||
#define ICON_FK_PINTEREST_P "\xef\x88\xb1" // U+f231
|
||||
#define ICON_FK_WHATSAPP "\xef\x88\xb2" // U+f232
|
||||
#define ICON_FK_SERVER "\xef\x88\xb3" // U+f233
|
||||
#define ICON_FK_USER_PLUS "\xef\x88\xb4" // U+f234
|
||||
#define ICON_FK_USER_TIMES "\xef\x88\xb5" // U+f235
|
||||
#define ICON_FK_BED "\xef\x88\xb6" // U+f236
|
||||
#define ICON_FK_VIACOIN "\xef\x88\xb7" // U+f237
|
||||
#define ICON_FK_TRAIN "\xef\x88\xb8" // U+f238
|
||||
#define ICON_FK_SUBWAY "\xef\x88\xb9" // U+f239
|
||||
#define ICON_FK_MEDIUM "\xef\x88\xba" // U+f23a
|
||||
#define ICON_FK_MEDIUM_SQUARE "\xef\x8b\xb8" // U+f2f8
|
||||
#define ICON_FK_Y_COMBINATOR "\xef\x88\xbb" // U+f23b
|
||||
#define ICON_FK_OPTIN_MONSTER "\xef\x88\xbc" // U+f23c
|
||||
#define ICON_FK_OPENCART "\xef\x88\xbd" // U+f23d
|
||||
#define ICON_FK_EXPEDITEDSSL "\xef\x88\xbe" // U+f23e
|
||||
#define ICON_FK_BATTERY_FULL "\xef\x89\x80" // U+f240
|
||||
#define ICON_FK_BATTERY_THREE_QUARTERS "\xef\x89\x81" // U+f241
|
||||
#define ICON_FK_BATTERY_HALF "\xef\x89\x82" // U+f242
|
||||
#define ICON_FK_BATTERY_QUARTER "\xef\x89\x83" // U+f243
|
||||
#define ICON_FK_BATTERY_EMPTY "\xef\x89\x84" // U+f244
|
||||
#define ICON_FK_MOUSE_POINTER "\xef\x89\x85" // U+f245
|
||||
#define ICON_FK_I_CURSOR "\xef\x89\x86" // U+f246
|
||||
#define ICON_FK_OBJECT_GROUP "\xef\x89\x87" // U+f247
|
||||
#define ICON_FK_OBJECT_UNGROUP "\xef\x89\x88" // U+f248
|
||||
#define ICON_FK_STICKY_NOTE "\xef\x89\x89" // U+f249
|
||||
#define ICON_FK_STICKY_NOTE_O "\xef\x89\x8a" // U+f24a
|
||||
#define ICON_FK_CC_JCB "\xef\x89\x8b" // U+f24b
|
||||
#define ICON_FK_CC_DINERS_CLUB "\xef\x89\x8c" // U+f24c
|
||||
#define ICON_FK_CLONE "\xef\x89\x8d" // U+f24d
|
||||
#define ICON_FK_BALANCE_SCALE "\xef\x89\x8e" // U+f24e
|
||||
#define ICON_FK_HOURGLASS_O "\xef\x89\x90" // U+f250
|
||||
#define ICON_FK_HOURGLASS_START "\xef\x89\x91" // U+f251
|
||||
#define ICON_FK_HOURGLASS_HALF "\xef\x89\x92" // U+f252
|
||||
#define ICON_FK_HOURGLASS_END "\xef\x89\x93" // U+f253
|
||||
#define ICON_FK_HOURGLASS "\xef\x89\x94" // U+f254
|
||||
#define ICON_FK_HAND_ROCK_O "\xef\x89\x95" // U+f255
|
||||
#define ICON_FK_HAND_PAPER_O "\xef\x89\x96" // U+f256
|
||||
#define ICON_FK_HAND_SCISSORS_O "\xef\x89\x97" // U+f257
|
||||
#define ICON_FK_HAND_LIZARD_O "\xef\x89\x98" // U+f258
|
||||
#define ICON_FK_HAND_SPOCK_O "\xef\x89\x99" // U+f259
|
||||
#define ICON_FK_HAND_POINTER_O "\xef\x89\x9a" // U+f25a
|
||||
#define ICON_FK_HAND_PEACE_O "\xef\x89\x9b" // U+f25b
|
||||
#define ICON_FK_TRADEMARK "\xef\x89\x9c" // U+f25c
|
||||
#define ICON_FK_REGISTERED "\xef\x89\x9d" // U+f25d
|
||||
#define ICON_FK_CREATIVE_COMMONS "\xef\x89\x9e" // U+f25e
|
||||
#define ICON_FK_GG "\xef\x89\xa0" // U+f260
|
||||
#define ICON_FK_GG_CIRCLE "\xef\x89\xa1" // U+f261
|
||||
#define ICON_FK_TRIPADVISOR "\xef\x89\xa2" // U+f262
|
||||
#define ICON_FK_ODNOKLASSNIKI "\xef\x89\xa3" // U+f263
|
||||
#define ICON_FK_ODNOKLASSNIKI_SQUARE "\xef\x89\xa4" // U+f264
|
||||
#define ICON_FK_GET_POCKET "\xef\x89\xa5" // U+f265
|
||||
#define ICON_FK_WIKIPEDIA_W "\xef\x89\xa6" // U+f266
|
||||
#define ICON_FK_SAFARI "\xef\x89\xa7" // U+f267
|
||||
#define ICON_FK_CHROME "\xef\x89\xa8" // U+f268
|
||||
#define ICON_FK_FIREFOX "\xef\x89\xa9" // U+f269
|
||||
#define ICON_FK_OPERA "\xef\x89\xaa" // U+f26a
|
||||
#define ICON_FK_INTERNET_EXPLORER "\xef\x89\xab" // U+f26b
|
||||
#define ICON_FK_TELEVISION "\xef\x89\xac" // U+f26c
|
||||
#define ICON_FK_CONTAO "\xef\x89\xad" // U+f26d
|
||||
#define ICON_FK_500PX "\xef\x89\xae" // U+f26e
|
||||
#define ICON_FK_AMAZON "\xef\x89\xb0" // U+f270
|
||||
#define ICON_FK_CALENDAR_PLUS_O "\xef\x89\xb1" // U+f271
|
||||
#define ICON_FK_CALENDAR_MINUS_O "\xef\x89\xb2" // U+f272
|
||||
#define ICON_FK_CALENDAR_TIMES_O "\xef\x89\xb3" // U+f273
|
||||
#define ICON_FK_CALENDAR_CHECK_O "\xef\x89\xb4" // U+f274
|
||||
#define ICON_FK_INDUSTRY "\xef\x89\xb5" // U+f275
|
||||
#define ICON_FK_MAP_PIN "\xef\x89\xb6" // U+f276
|
||||
#define ICON_FK_MAP_SIGNS "\xef\x89\xb7" // U+f277
|
||||
#define ICON_FK_MAP_O "\xef\x89\xb8" // U+f278
|
||||
#define ICON_FK_MAP "\xef\x89\xb9" // U+f279
|
||||
#define ICON_FK_COMMENTING "\xef\x89\xba" // U+f27a
|
||||
#define ICON_FK_COMMENTING_O "\xef\x89\xbb" // U+f27b
|
||||
#define ICON_FK_HOUZZ "\xef\x89\xbc" // U+f27c
|
||||
#define ICON_FK_VIMEO "\xef\x89\xbd" // U+f27d
|
||||
#define ICON_FK_BLACK_TIE "\xef\x89\xbe" // U+f27e
|
||||
#define ICON_FK_FONTICONS "\xef\x8a\x80" // U+f280
|
||||
#define ICON_FK_REDDIT_ALIEN "\xef\x8a\x81" // U+f281
|
||||
#define ICON_FK_EDGE "\xef\x8a\x82" // U+f282
|
||||
#define ICON_FK_CREDIT_CARD_ALT "\xef\x8a\x83" // U+f283
|
||||
#define ICON_FK_CODIEPIE "\xef\x8a\x84" // U+f284
|
||||
#define ICON_FK_MODX "\xef\x8a\x85" // U+f285
|
||||
#define ICON_FK_FORT_AWESOME "\xef\x8a\x86" // U+f286
|
||||
#define ICON_FK_USB "\xef\x8a\x87" // U+f287
|
||||
#define ICON_FK_PRODUCT_HUNT "\xef\x8a\x88" // U+f288
|
||||
#define ICON_FK_MIXCLOUD "\xef\x8a\x89" // U+f289
|
||||
#define ICON_FK_SCRIBD "\xef\x8a\x8a" // U+f28a
|
||||
#define ICON_FK_PAUSE_CIRCLE "\xef\x8a\x8b" // U+f28b
|
||||
#define ICON_FK_PAUSE_CIRCLE_O "\xef\x8a\x8c" // U+f28c
|
||||
#define ICON_FK_STOP_CIRCLE "\xef\x8a\x8d" // U+f28d
|
||||
#define ICON_FK_STOP_CIRCLE_O "\xef\x8a\x8e" // U+f28e
|
||||
#define ICON_FK_SHOPPING_BAG "\xef\x8a\x90" // U+f290
|
||||
#define ICON_FK_SHOPPING_BASKET "\xef\x8a\x91" // U+f291
|
||||
#define ICON_FK_HASHTAG "\xef\x8a\x92" // U+f292
|
||||
#define ICON_FK_BLUETOOTH "\xef\x8a\x93" // U+f293
|
||||
#define ICON_FK_BLUETOOTH_B "\xef\x8a\x94" // U+f294
|
||||
#define ICON_FK_PERCENT "\xef\x8a\x95" // U+f295
|
||||
#define ICON_FK_GITLAB "\xef\x8a\x96" // U+f296
|
||||
#define ICON_FK_WPBEGINNER "\xef\x8a\x97" // U+f297
|
||||
#define ICON_FK_WPFORMS "\xef\x8a\x98" // U+f298
|
||||
#define ICON_FK_ENVIRA "\xef\x8a\x99" // U+f299
|
||||
#define ICON_FK_UNIVERSAL_ACCESS "\xef\x8a\x9a" // U+f29a
|
||||
#define ICON_FK_WHEELCHAIR_ALT "\xef\x8a\x9b" // U+f29b
|
||||
#define ICON_FK_QUESTION_CIRCLE_O "\xef\x8a\x9c" // U+f29c
|
||||
#define ICON_FK_BLIND "\xef\x8a\x9d" // U+f29d
|
||||
#define ICON_FK_AUDIO_DESCRIPTION "\xef\x8a\x9e" // U+f29e
|
||||
#define ICON_FK_VOLUME_CONTROL_PHONE "\xef\x8a\xa0" // U+f2a0
|
||||
#define ICON_FK_BRAILLE "\xef\x8a\xa1" // U+f2a1
|
||||
#define ICON_FK_ASSISTIVE_LISTENING_SYSTEMS "\xef\x8a\xa2" // U+f2a2
|
||||
#define ICON_FK_AMERICAN_SIGN_LANGUAGE_INTERPRETING "\xef\x8a\xa3" // U+f2a3
|
||||
#define ICON_FK_DEAF "\xef\x8a\xa4" // U+f2a4
|
||||
#define ICON_FK_GLIDE "\xef\x8a\xa5" // U+f2a5
|
||||
#define ICON_FK_GLIDE_G "\xef\x8a\xa6" // U+f2a6
|
||||
#define ICON_FK_SIGN_LANGUAGE "\xef\x8a\xa7" // U+f2a7
|
||||
#define ICON_FK_LOW_VISION "\xef\x8a\xa8" // U+f2a8
|
||||
#define ICON_FK_VIADEO "\xef\x8a\xa9" // U+f2a9
|
||||
#define ICON_FK_VIADEO_SQUARE "\xef\x8a\xaa" // U+f2aa
|
||||
#define ICON_FK_SNAPCHAT "\xef\x8a\xab" // U+f2ab
|
||||
#define ICON_FK_SNAPCHAT_GHOST "\xef\x8a\xac" // U+f2ac
|
||||
#define ICON_FK_SNAPCHAT_SQUARE "\xef\x8a\xad" // U+f2ad
|
||||
#define ICON_FK_FIRST_ORDER "\xef\x8a\xb0" // U+f2b0
|
||||
#define ICON_FK_YOAST "\xef\x8a\xb1" // U+f2b1
|
||||
#define ICON_FK_THEMEISLE "\xef\x8a\xb2" // U+f2b2
|
||||
#define ICON_FK_GOOGLE_PLUS_OFFICIAL "\xef\x8a\xb3" // U+f2b3
|
||||
#define ICON_FK_FONT_AWESOME "\xef\x8a\xb4" // U+f2b4
|
||||
#define ICON_FK_HANDSHAKE_O "\xef\x8a\xb5" // U+f2b5
|
||||
#define ICON_FK_ENVELOPE_OPEN "\xef\x8a\xb6" // U+f2b6
|
||||
#define ICON_FK_ENVELOPE_OPEN_O "\xef\x8a\xb7" // U+f2b7
|
||||
#define ICON_FK_LINODE "\xef\x8a\xb8" // U+f2b8
|
||||
#define ICON_FK_ADDRESS_BOOK "\xef\x8a\xb9" // U+f2b9
|
||||
#define ICON_FK_ADDRESS_BOOK_O "\xef\x8a\xba" // U+f2ba
|
||||
#define ICON_FK_ADDRESS_CARD "\xef\x8a\xbb" // U+f2bb
|
||||
#define ICON_FK_ADDRESS_CARD_O "\xef\x8a\xbc" // U+f2bc
|
||||
#define ICON_FK_USER_CIRCLE "\xef\x8a\xbd" // U+f2bd
|
||||
#define ICON_FK_USER_CIRCLE_O "\xef\x8a\xbe" // U+f2be
|
||||
#define ICON_FK_USER_O "\xef\x8b\x80" // U+f2c0
|
||||
#define ICON_FK_ID_BADGE "\xef\x8b\x81" // U+f2c1
|
||||
#define ICON_FK_ID_CARD "\xef\x8b\x82" // U+f2c2
|
||||
#define ICON_FK_ID_CARD_O "\xef\x8b\x83" // U+f2c3
|
||||
#define ICON_FK_QUORA "\xef\x8b\x84" // U+f2c4
|
||||
#define ICON_FK_FREE_CODE_CAMP "\xef\x8b\x85" // U+f2c5
|
||||
#define ICON_FK_TELEGRAM "\xef\x8b\x86" // U+f2c6
|
||||
#define ICON_FK_THERMOMETER_FULL "\xef\x8b\x87" // U+f2c7
|
||||
#define ICON_FK_THERMOMETER_THREE_QUARTERS "\xef\x8b\x88" // U+f2c8
|
||||
#define ICON_FK_THERMOMETER_HALF "\xef\x8b\x89" // U+f2c9
|
||||
#define ICON_FK_THERMOMETER_QUARTER "\xef\x8b\x8a" // U+f2ca
|
||||
#define ICON_FK_THERMOMETER_EMPTY "\xef\x8b\x8b" // U+f2cb
|
||||
#define ICON_FK_SHOWER "\xef\x8b\x8c" // U+f2cc
|
||||
#define ICON_FK_BATH "\xef\x8b\x8d" // U+f2cd
|
||||
#define ICON_FK_PODCAST "\xef\x8b\x8e" // U+f2ce
|
||||
#define ICON_FK_WINDOW_MAXIMIZE "\xef\x8b\x90" // U+f2d0
|
||||
#define ICON_FK_WINDOW_MINIMIZE "\xef\x8b\x91" // U+f2d1
|
||||
#define ICON_FK_WINDOW_RESTORE "\xef\x8b\x92" // U+f2d2
|
||||
#define ICON_FK_WINDOW_CLOSE "\xef\x8b\x93" // U+f2d3
|
||||
#define ICON_FK_WINDOW_CLOSE_O "\xef\x8b\x94" // U+f2d4
|
||||
#define ICON_FK_BANDCAMP "\xef\x8b\x95" // U+f2d5
|
||||
#define ICON_FK_GRAV "\xef\x8b\x96" // U+f2d6
|
||||
#define ICON_FK_ETSY "\xef\x8b\x97" // U+f2d7
|
||||
#define ICON_FK_IMDB "\xef\x8b\x98" // U+f2d8
|
||||
#define ICON_FK_RAVELRY "\xef\x8b\x99" // U+f2d9
|
||||
#define ICON_FK_EERCAST "\xef\x8b\x9a" // U+f2da
|
||||
#define ICON_FK_MICROCHIP "\xef\x8b\x9b" // U+f2db
|
||||
#define ICON_FK_SNOWFLAKE_O "\xef\x8b\x9c" // U+f2dc
|
||||
#define ICON_FK_SUPERPOWERS "\xef\x8b\x9d" // U+f2dd
|
||||
#define ICON_FK_WPEXPLORER "\xef\x8b\x9e" // U+f2de
|
||||
#define ICON_FK_MEETUP "\xef\x8b\xa0" // U+f2e0
|
||||
#define ICON_FK_MASTODON "\xef\x8b\xa1" // U+f2e1
|
||||
#define ICON_FK_MASTODON_ALT "\xef\x8b\xa2" // U+f2e2
|
||||
#define ICON_FK_FORK_AWESOME "\xef\x8b\xa3" // U+f2e3
|
||||
#define ICON_FK_PEERTUBE "\xef\x8b\xa4" // U+f2e4
|
||||
#define ICON_FK_DIASPORA "\xef\x8b\xa5" // U+f2e5
|
||||
#define ICON_FK_FRIENDICA "\xef\x8b\xa6" // U+f2e6
|
||||
#define ICON_FK_GNU_SOCIAL "\xef\x8b\xa7" // U+f2e7
|
||||
#define ICON_FK_LIBERAPAY_SQUARE "\xef\x8b\xa8" // U+f2e8
|
||||
#define ICON_FK_LIBERAPAY "\xef\x8b\xa9" // U+f2e9
|
||||
#define ICON_FK_SCUTTLEBUTT "\xef\x8b\xaa" // U+f2ea
|
||||
#define ICON_FK_HUBZILLA "\xef\x8b\xab" // U+f2eb
|
||||
#define ICON_FK_SOCIAL_HOME "\xef\x8b\xac" // U+f2ec
|
||||
#define ICON_FK_ARTSTATION "\xef\x8b\xad" // U+f2ed
|
||||
#define ICON_FK_DISCORD "\xef\x8b\xae" // U+f2ee
|
||||
#define ICON_FK_DISCORD_ALT "\xef\x8b\xaf" // U+f2ef
|
||||
#define ICON_FK_PATREON "\xef\x8b\xb0" // U+f2f0
|
||||
#define ICON_FK_SNOWDRIFT "\xef\x8b\xb1" // U+f2f1
|
||||
#define ICON_FK_ACTIVITYPUB "\xef\x8b\xb2" // U+f2f2
|
||||
#define ICON_FK_ETHEREUM "\xef\x8b\xb3" // U+f2f3
|
||||
#define ICON_FK_KEYBASE "\xef\x8b\xb4" // U+f2f4
|
||||
#define ICON_FK_SHAARLI "\xef\x8b\xb5" // U+f2f5
|
||||
#define ICON_FK_SHAARLI_O "\xef\x8b\xb6" // U+f2f6
|
||||
#define ICON_FK_KEY_MODERN "\xef\x8b\xb7" // U+f2f7
|
||||
#define ICON_FK_XMPP "\xef\x8b\xb9" // U+f2f9
|
||||
#define ICON_FK_ARCHIVE_ORG "\xef\x8b\xbc" // U+f2fc
|
||||
#define ICON_FK_FREEDOMBOX "\xef\x8b\xbd" // U+f2fd
|
||||
#define ICON_FK_FACEBOOK_MESSENGER "\xef\x8b\xbe" // U+f2fe
|
||||
#define ICON_FK_DEBIAN "\xef\x8b\xbf" // U+f2ff
|
||||
#define ICON_FK_MASTODON_SQUARE "\xef\x8c\x80" // U+f300
|
||||
#define ICON_FK_TIPEEE "\xef\x8c\x81" // U+f301
|
||||
#define ICON_FK_REACT "\xef\x8c\x82" // U+f302
|
||||
#define ICON_FK_DOGMAZIC "\xef\x8c\x83" // U+f303
|
||||
#define ICON_FK_ZOTERO "\xef\x8c\x89" // U+f309
|
||||
#define ICON_FK_NODEJS "\xef\x8c\x88" // U+f308
|
||||
#define ICON_FK_NEXTCLOUD "\xef\x8c\x86" // U+f306
|
||||
#define ICON_FK_NEXTCLOUD_SQUARE "\xef\x8c\x87" // U+f307
|
||||
#define ICON_FK_HACKADAY "\xef\x8c\x8a" // U+f30a
|
||||
#define ICON_FK_LARAVEL "\xef\x8c\x8b" // U+f30b
|
||||
#define ICON_FK_SIGNALAPP "\xef\x8c\x8c" // U+f30c
|
||||
#define ICON_FK_GNUPG "\xef\x8c\x8d" // U+f30d
|
||||
#define ICON_FK_PHP "\xef\x8c\x8e" // U+f30e
|
||||
#define ICON_FK_FFMPEG "\xef\x8c\x8f" // U+f30f
|
||||
#define ICON_FK_JOPLIN "\xef\x8c\x90" // U+f310
|
||||
#define ICON_FK_SYNCTHING "\xef\x8c\x91" // U+f311
|
||||
#define ICON_FK_INKSCAPE "\xef\x8c\x92" // U+f312
|
||||
#define ICON_FK_MATRIX_ORG "\xef\x8c\x93" // U+f313
|
||||
#define ICON_FK_PIXELFED "\xef\x8c\x94" // U+f314
|
||||
#define ICON_FK_BOOTSTRAP "\xef\x8c\x95" // U+f315
|
||||
#define ICON_FK_DEV_TO "\xef\x8c\x96" // U+f316
|
||||
#define ICON_FK_HASHNODE "\xef\x8c\x97" // U+f317
|
||||
#define ICON_FK_JIRAFEAU "\xef\x8c\x98" // U+f318
|
||||
#define ICON_FK_EMBY "\xef\x8c\x99" // U+f319
|
||||
#define ICON_FK_WIKIDATA "\xef\x8c\x9a" // U+f31a
|
||||
#define ICON_FK_GIMP "\xef\x8c\x9b" // U+f31b
|
||||
#define ICON_FK_C "\xef\x8c\x9c" // U+f31c
|
||||
#define ICON_FK_DIGITALOCEAN "\xef\x8c\x9d" // U+f31d
|
||||
#define ICON_FK_ATT "\xef\x8c\x9e" // U+f31e
|
||||
#define ICON_FK_GITEA "\xef\x8c\x9f" // U+f31f
|
||||
#define ICON_FK_FILE_EPUB "\xef\x8c\xa1" // U+f321
|
||||
#define ICON_FK_PYTHON "\xef\x8c\xa2" // U+f322
|
||||
#define ICON_FK_ARCHLINUX "\xef\x8c\xa3" // U+f323
|
||||
#define ICON_FK_PLEROMA "\xef\x8c\xa4" // U+f324
|
||||
#define ICON_FK_UNSPLASH "\xef\x8c\xa5" // U+f325
|
||||
#define ICON_FK_HACKSTER "\xef\x8c\xa6" // U+f326
|
||||
#define ICON_FK_SPELL_CHECK "\xef\x8c\xa7" // U+f327
|
||||
#define ICON_FK_MOON "\xef\x8c\xa8" // U+f328
|
||||
#define ICON_FK_SUN "\xef\x8c\xa9" // U+f329
|
||||
#define ICON_FK_F_DROID "\xef\x8c\xaa" // U+f32a
|
||||
#define ICON_FK_BIOMETRIC "\xef\x8c\xab" // U+f32b
|
||||
#define ICON_FK_WIRE "\xef\x8c\xac" // U+f32c
|
||||
#define ICON_FK_TOR_ONION "\xef\x8c\xae" // U+f32e
|
||||
#define ICON_FK_VOLUME_MUTE "\xef\x8c\xaf" // U+f32f
|
||||
#define ICON_FK_BELL_RINGING "\xef\x8c\xad" // U+f32d
|
||||
#define ICON_FK_BELL_RINGING_O "\xef\x8c\xb0" // U+f330
|
||||
#define ICON_FK_HAL "\xef\x8c\xb3" // U+f333
|
||||
#define ICON_FK_JUPYTER "\xef\x8c\xb5" // U+f335
|
||||
#define ICON_FK_JULIA "\xef\x8c\xb4" // U+f334
|
||||
#define ICON_FK_CLASSICPRESS "\xef\x8c\xb1" // U+f331
|
||||
#define ICON_FK_CLASSICPRESS_CIRCLE "\xef\x8c\xb2" // U+f332
|
||||
#define ICON_FK_OPEN_COLLECTIVE "\xef\x8c\xb6" // U+f336
|
||||
#define ICON_FK_ORCID "\xef\x8c\xb7" // U+f337
|
||||
#define ICON_FK_RESEARCHGATE "\xef\x8c\xb8" // U+f338
|
||||
#define ICON_FK_FUNKWHALE "\xef\x8c\xb9" // U+f339
|
||||
#define ICON_FK_ASKFM "\xef\x8c\xba" // U+f33a
|
||||
#define ICON_FK_BLOCKSTACK "\xef\x8c\xbb" // U+f33b
|
||||
#define ICON_FK_BOARDGAMEGEEK "\xef\x8c\xbc" // U+f33c
|
||||
#define ICON_FK_BUNNY "\xef\x8d\x9f" // U+f35f
|
||||
#define ICON_FK_BUYMEACOFFEE "\xef\x8c\xbd" // U+f33d
|
||||
#define ICON_FK_CC_BY "\xef\x8c\xbe" // U+f33e
|
||||
#define ICON_FK_CC_CC "\xef\x8c\xbf" // U+f33f
|
||||
#define ICON_FK_CC_NC_EU "\xef\x8d\x81" // U+f341
|
||||
#define ICON_FK_CC_NC_JP "\xef\x8d\x82" // U+f342
|
||||
#define ICON_FK_CC_NC "\xef\x8d\x80" // U+f340
|
||||
#define ICON_FK_CC_ND "\xef\x8d\x83" // U+f343
|
||||
#define ICON_FK_CC_PD "\xef\x8d\x84" // U+f344
|
||||
#define ICON_FK_CC_REMIX "\xef\x8d\x85" // U+f345
|
||||
#define ICON_FK_CC_SA "\xef\x8d\x86" // U+f346
|
||||
#define ICON_FK_CC_SHARE "\xef\x8d\x87" // U+f347
|
||||
#define ICON_FK_CC_ZERO "\xef\x8d\x88" // U+f348
|
||||
#define ICON_FK_CONWAY_GLIDER "\xef\x8d\x89" // U+f349
|
||||
#define ICON_FK_CSHARP "\xef\x8d\x8a" // U+f34a
|
||||
#define ICON_FK_EMAIL_BULK "\xef\x8d\x8b" // U+f34b
|
||||
#define ICON_FK_EMAIL_BULK_O "\xef\x8d\x8c" // U+f34c
|
||||
#define ICON_FK_GNU "\xef\x8d\x8d" // U+f34d
|
||||
#define ICON_FK_GOOGLE_PLAY "\xef\x8d\x8e" // U+f34e
|
||||
#define ICON_FK_HEROKU "\xef\x8d\x8f" // U+f34f
|
||||
#define ICON_FK_HOME_ASSISTANT "\xef\x8d\x90" // U+f350
|
||||
#define ICON_FK_JAVA "\xef\x8d\x91" // U+f351
|
||||
#define ICON_FK_MARIADB "\xef\x8d\x92" // U+f352
|
||||
#define ICON_FK_MARKDOWN "\xef\x8d\x93" // U+f353
|
||||
#define ICON_FK_MYSQL "\xef\x8d\x94" // U+f354
|
||||
#define ICON_FK_NORDCAST "\xef\x8d\x95" // U+f355
|
||||
#define ICON_FK_PLUME "\xef\x8d\x96" // U+f356
|
||||
#define ICON_FK_POSTGRESQL "\xef\x8d\x97" // U+f357
|
||||
#define ICON_FK_SASS_ALT "\xef\x8d\x99" // U+f359
|
||||
#define ICON_FK_SASS "\xef\x8d\x98" // U+f358
|
||||
#define ICON_FK_SKATE "\xef\x8d\x9a" // U+f35a
|
||||
#define ICON_FK_SKETCHFAB "\xef\x8d\x9b" // U+f35b
|
||||
#define ICON_FK_TEX "\xef\x8d\x9c" // U+f35c
|
||||
#define ICON_FK_TEXTPATTERN "\xef\x8d\x9d" // U+f35d
|
||||
#define ICON_FK_UNITY "\xef\x8d\x9e" // U+f35e
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,2 @@
|
||||
/usr/lib/mangohud/lib32
|
||||
/usr/lib/mangohud/lib64
|
@ -0,0 +1 @@
|
||||
@libdir_mangohud@
|
@ -1,16 +1,12 @@
|
||||
option('glibcxx_asserts', type : 'boolean', value : false)
|
||||
option('use_system_spdlog', type : 'feature', value : 'disabled', description: 'Use system spdlog library')
|
||||
option('use_system_vulkan', type : 'feature', value : 'disabled', description: 'Use system vulkan headers instead of the provided ones')
|
||||
option('use_system_nvml', type : 'boolean', value : false, description : 'Use system nvml headers instead of the provided ones')
|
||||
option('mangohud_prefix', type : 'string', value : '', description: 'Add prefix to cross-compiled library, like "lib32-".')
|
||||
option('append_libdir_mangohud', type : 'boolean', value : true, description: 'Append "mangohud" to libdir path or not.')
|
||||
option('include_doc', type : 'boolean', value : true, description: 'Include the example config, man pages, appstream files etc.')
|
||||
option('include_doc', type : 'boolean', value : true, description: 'Include the example config')
|
||||
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)
|
||||
option('mangohudctl', type: 'boolean', value : false)
|
||||
option('mangoapp_layer', type: 'boolean', value : false)
|
||||
option('tests', type: 'feature', value: 'auto', description: 'Run tests')
|
||||
option('mangoplot', type: 'feature', value: 'enabled')
|
||||
option('dynamic_string_tokens', type: 'boolean', value: true, description: 'Use dynamic string tokens in LD_PRELOAD')
|
||||
option('with_dlsym', type : 'feature', value : 'disabled')
|
||||
|
@ -1,16 +0,0 @@
|
||||
[binaries]
|
||||
c = 'i686-w64-mingw32-gcc'
|
||||
cpp = 'i686-w64-mingw32-g++'
|
||||
ar = 'i686-w64-mingw32-ar'
|
||||
strip = 'i686-w64-mingw32-strip'
|
||||
pkg-config = 'i686-w64-mingw32-pkg-config'
|
||||
sh = '/usr/bin/sh'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'x86'
|
||||
cpu = 'i686'
|
||||
endian = 'little'
|
@ -1,16 +0,0 @@
|
||||
[binaries]
|
||||
c = 'x86_64-w64-mingw32-gcc'
|
||||
cpp = 'x86_64-w64-mingw32-g++'
|
||||
ar = 'x86_64-w64-mingw32-ar'
|
||||
strip = 'x86_64-w64-mingw32-strip'
|
||||
pkg-config = 'x86_64-w64-mingw32-pkg-config'
|
||||
sh = '/usr/bin/sh'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
@ -0,0 +1,3 @@
|
||||
# ignore this folder
|
||||
root = true
|
||||
|
@ -0,0 +1,11 @@
|
||||
libimgui_core = static_library(
|
||||
'imgui_core',
|
||||
files('src/imgui.cpp', 'src/imgui_draw.cpp', 'src/imgui_widgets.cpp'),
|
||||
cpp_args : ['-w'],
|
||||
install : false
|
||||
)
|
||||
|
||||
libimgui_core_dep = declare_dependency(
|
||||
link_with : libimgui_core,
|
||||
include_directories : include_directories('src')
|
||||
)
|
@ -0,0 +1 @@
|
||||
Subproject commit 1f02d240b38f445abb0381ade0867752d5d2bc7b
|
@ -1 +0,0 @@
|
||||
Subproject commit df6622659e366c63dfc9591245fa6a9a10ec4759
|
@ -1,97 +0,0 @@
|
||||
# Maintainer: Simon Hallsten <flightlessmangoyt@gmail.com>
|
||||
|
||||
pkgname=('mangohud' 'lib32-mangohud')
|
||||
pkgver=0.7.2.rc3.r13.g5d744d3
|
||||
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')
|
||||
replaces=('vulkan-mesa-layer-mango')
|
||||
license=('MIT')
|
||||
source=(
|
||||
"mangohud"::"git+https://github.com/flightlessmango/MangoHud.git#branch=master"
|
||||
"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"
|
||||
"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"
|
||||
"implot-0.16.zip::https://github.com/epezent/implot/archive/refs/tags/v0.16.zip"
|
||||
"implot_0.16-1_patch.zip::https://wrapdb.mesonbuild.com/v2/implot_0.16-1/get_patch"
|
||||
)
|
||||
|
||||
sha256sums=(
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'1acc27a778b71d859878121a3f7b287cd81c29d720893d2b2bf74455bf9d52d6'
|
||||
'9b21290c597d76bf8d4eeb3f9ffa024b11d9ea6c61e91d648ccc90b42843d584'
|
||||
'1586508029a7d0670dfcb2d97575dcdc242d3868a259742b69f100801ab4e16b'
|
||||
'ae878e732330ea1048f90d7e117c40c0cd2a6fb8ae5492c7955818ce3aaade6c'
|
||||
'b94997df68856753b72f0d7a3703b7d484d4745c567f3584ef97c96c25a5798e'
|
||||
"53361271cfe274df8782e1e47bdc9e61b7af432ba30acbfe31723f9df2c257f3"
|
||||
"860358cf5e73f458cd1e88f8c38116d123ab421d5ce2e4129ec38eaedd820e17"
|
||||
"24f772c688f6b8a6e19d7efc10e4923a04a915f13d487b08b83553aa62ae1708"
|
||||
"1c6b1462066a5452fa50c1da1dd47fed841f28232972c82d778f2962936568c7"
|
||||
)
|
||||
|
||||
_build_args="-Dappend_libdir_mangohud=false -Dwith_xnvctrl=disabled -Dmangoapp_layer=true -Dtests=disabled"
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/mangohud"
|
||||
git describe --tags | sed -r 's/^v//;s/([^-]*-g)/r\1/;s/-/./g'
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/mangohud"
|
||||
git submodule init
|
||||
git config submodule.modules/minhook.url "$srcdir/mangohud-minhook"
|
||||
git -c protocol.file.allow=always submodule update
|
||||
|
||||
# meson subprojects
|
||||
ln -sv "$srcdir/imgui-1.89.9" subprojects
|
||||
ln -sv "$srcdir/spdlog-1.14.1" 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/
|
||||
ln -sv "$srcdir/LICENSE.MIT" subprojects/nlohmann_json-3.10.5/
|
||||
ln -sv "$srcdir/meson.build" subprojects/nlohmann_json-3.10.5/
|
||||
ln -sv "$srcdir/Vulkan-Headers-1.2.158" subprojects
|
||||
ln -sv "$srcdir/implot-0.16" subprojects
|
||||
}
|
||||
|
||||
build() {
|
||||
arch-meson mangohud build64 \
|
||||
${_build_args} -Dmangoapp=true -Dmangohudctl=true
|
||||
|
||||
ninja -C build64
|
||||
export CC="${CC:-gcc} -m32"
|
||||
export CXX="${CXX:-g++} -m32"
|
||||
export PKG_CONFIG_PATH="/usr/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib/pkgconfig:${PKG_CONFIG_PATH_32}"
|
||||
export LLVM_CONFIG="/usr/bin/llvm-config32"
|
||||
|
||||
arch-meson mangohud build32 \
|
||||
--libdir=lib32 \
|
||||
-Dmangoapp=false \
|
||||
-Dmangohudctl=false \
|
||||
${_build_args}
|
||||
|
||||
ninja -C build32
|
||||
}
|
||||
|
||||
package_mangohud() {
|
||||
provides=("mangohud")
|
||||
conflicts=('mangohud-common')
|
||||
DESTDIR="${pkgdir}" ninja -C build64 install
|
||||
}
|
||||
|
||||
package_lib32-mangohud() {
|
||||
provides=("lib32-mangohud")
|
||||
DESTDIR="${pkgdir}" ninja -C build32 install
|
||||
rm -rf "$pkgdir/usr/bin"
|
||||
rm -rf "$pkgdir/usr/share"
|
||||
install -m644 -Dt "$pkgdir/usr/share/vulkan/implicit_layer.d" "$srcdir/build32/src/MangoHud.x86.json"
|
||||
}
|
@ -1,287 +0,0 @@
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <thread>
|
||||
#ifdef __linux__
|
||||
#include <sys/sysinfo.h>
|
||||
#endif
|
||||
#include "amdgpu.h"
|
||||
#include "gpu.h"
|
||||
#include "cpu.h"
|
||||
#include "overlay.h"
|
||||
#include "hud_elements.h"
|
||||
#include "logging.h"
|
||||
#include "mesa/util/macros.h"
|
||||
|
||||
std::string metrics_path = "";
|
||||
struct amdgpu_common_metrics amdgpu_common_metrics;
|
||||
std::mutex amdgpu_common_metrics_m;
|
||||
std::mutex amdgpu_m;
|
||||
std::condition_variable amdgpu_c;
|
||||
bool amdgpu_run_thread = true;
|
||||
std::unique_ptr<Throttling> throttling;
|
||||
|
||||
bool amdgpu_verify_metrics(const std::string& path)
|
||||
{
|
||||
metrics_table_header header {};
|
||||
FILE *f;
|
||||
f = fopen(path.c_str(), "rb");
|
||||
if (!f) {
|
||||
SPDLOG_DEBUG("Failed to read the metrics header of '{}'", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header, sizeof(header), 1, f) == 0)
|
||||
{
|
||||
SPDLOG_DEBUG("Failed to read the metrics header of '{}'", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (header.format_revision)
|
||||
{
|
||||
case 1: // v1_1, v1_2, v1_3
|
||||
if(header.content_revision<=0 || header.content_revision>3)// v1_0, not naturally aligned
|
||||
break;
|
||||
cpuStats.cpu_type = "GPU";
|
||||
return true;
|
||||
case 2: // v2_1, v2_2, v2_3, v2_4
|
||||
if(header.content_revision<=0 || header.content_revision>4)// v2_0, not naturally aligned
|
||||
break;
|
||||
cpuStats.cpu_type = "APU";
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SPDLOG_WARN("Unsupported gpu_metrics version: {}.{}", header.format_revision, header.content_revision);
|
||||
return false;
|
||||
}
|
||||
|
||||
#define IS_VALID_METRIC(FIELD) (FIELD != 0xffff)
|
||||
void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics) {
|
||||
FILE *f;
|
||||
void *buf[MAX(sizeof(struct gpu_metrics_v1_3), sizeof(struct gpu_metrics_v2_4))/sizeof(void*)+1];
|
||||
struct metrics_table_header* header = (metrics_table_header*)buf;
|
||||
|
||||
f = fopen(metrics_path.c_str(), "rb");
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
// Read the whole file
|
||||
if (fread(buf, sizeof(buf), 1, f) != 0) {
|
||||
SPDLOG_DEBUG("amdgpu metrics file '{}' is larger than the buffer", metrics_path.c_str());
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
int64_t indep_throttle_status = 0;
|
||||
if (header->format_revision == 1) {
|
||||
// Desktop GPUs
|
||||
struct gpu_metrics_v1_3 *amdgpu_metrics = (struct gpu_metrics_v1_3 *) buf;
|
||||
metrics->gpu_load_percent = amdgpu_metrics->average_gfx_activity;
|
||||
|
||||
metrics->average_gfx_power_w = amdgpu_metrics->average_socket_power;
|
||||
|
||||
metrics->current_gfxclk_mhz = amdgpu_metrics->current_gfxclk;
|
||||
metrics->current_uclk_mhz = amdgpu_metrics->current_uclk;
|
||||
|
||||
metrics->gpu_temp_c = amdgpu_metrics->temperature_edge;
|
||||
indep_throttle_status = amdgpu_metrics->indep_throttle_status;
|
||||
metrics->fan_speed = amdgpu_metrics->current_fan_speed;
|
||||
} else if (header->format_revision == 2) {
|
||||
// APUs
|
||||
struct gpu_metrics_v2_3 *amdgpu_metrics = (struct gpu_metrics_v2_3 *) buf;
|
||||
|
||||
metrics->gpu_load_percent = amdgpu_metrics->average_gfx_activity;
|
||||
|
||||
metrics->average_gfx_power_w = amdgpu_metrics->average_gfx_power / 1000.f;
|
||||
|
||||
if( IS_VALID_METRIC(amdgpu_metrics->average_cpu_power) ) {
|
||||
// prefered method
|
||||
metrics->average_cpu_power_w = amdgpu_metrics->average_cpu_power / 1000.f;
|
||||
} else if( IS_VALID_METRIC(amdgpu_metrics->average_core_power[0]) ) {
|
||||
// fallback 1: sum of core power
|
||||
metrics->average_cpu_power_w = 0;
|
||||
unsigned i = 0;
|
||||
do metrics->average_cpu_power_w = metrics->average_cpu_power_w + amdgpu_metrics->average_core_power[i] / 1000.f;
|
||||
while (++i < ARRAY_SIZE(amdgpu_metrics->average_core_power) && IS_VALID_METRIC(amdgpu_metrics->average_core_power[i]));
|
||||
} else if( IS_VALID_METRIC(amdgpu_metrics->average_socket_power) && IS_VALID_METRIC(amdgpu_metrics->average_gfx_power) ) {
|
||||
// fallback 2: estimate cpu power from total socket power
|
||||
metrics->average_cpu_power_w = amdgpu_metrics->average_socket_power / 1000.f - amdgpu_metrics->average_gfx_power / 1000.f;
|
||||
} else {
|
||||
// giving up
|
||||
metrics->average_cpu_power_w = 0;
|
||||
}
|
||||
|
||||
if( IS_VALID_METRIC(amdgpu_metrics->current_gfxclk) ) {
|
||||
// prefered method
|
||||
metrics->current_gfxclk_mhz = amdgpu_metrics->current_gfxclk;
|
||||
} else if( IS_VALID_METRIC(amdgpu_metrics->average_gfxclk_frequency) ) {
|
||||
// fallback 1
|
||||
metrics->current_gfxclk_mhz = amdgpu_metrics->average_gfxclk_frequency;
|
||||
} else {
|
||||
// giving up
|
||||
metrics->current_gfxclk_mhz = 0;
|
||||
}
|
||||
if( IS_VALID_METRIC(amdgpu_metrics->current_uclk) ) {
|
||||
// prefered method
|
||||
metrics->current_uclk_mhz = amdgpu_metrics->current_uclk;
|
||||
} else if( IS_VALID_METRIC(amdgpu_metrics->average_uclk_frequency) ) {
|
||||
// fallback 1
|
||||
metrics->current_uclk_mhz = amdgpu_metrics->average_uclk_frequency;
|
||||
} else {
|
||||
// giving up
|
||||
metrics->current_uclk_mhz = 0;
|
||||
}
|
||||
|
||||
if( IS_VALID_METRIC(amdgpu_metrics->temperature_soc) ) {
|
||||
// prefered method
|
||||
metrics->soc_temp_c = amdgpu_metrics->temperature_soc / 100;
|
||||
} else if( header->content_revision >= 3 && IS_VALID_METRIC(amdgpu_metrics->average_temperature_soc) ) {
|
||||
// fallback 1
|
||||
metrics->soc_temp_c = amdgpu_metrics->average_temperature_soc / 100;
|
||||
} else {
|
||||
// giving up
|
||||
metrics->soc_temp_c = 0;
|
||||
}
|
||||
if( IS_VALID_METRIC(amdgpu_metrics->temperature_gfx) ) {
|
||||
// prefered method
|
||||
metrics->gpu_temp_c = amdgpu_metrics->temperature_gfx / 100;
|
||||
} else if( header->content_revision >= 3 && IS_VALID_METRIC(amdgpu_metrics->average_temperature_gfx) ) {
|
||||
// fallback 1
|
||||
metrics->gpu_temp_c = amdgpu_metrics->average_temperature_gfx / 100;
|
||||
} else {
|
||||
// giving up
|
||||
metrics->gpu_temp_c = 0;
|
||||
}
|
||||
|
||||
int cpu_temp = 0;
|
||||
if( IS_VALID_METRIC(amdgpu_metrics->temperature_core[0]) ) {
|
||||
// prefered method
|
||||
unsigned i = 0;
|
||||
do cpu_temp = MAX(cpu_temp, amdgpu_metrics->temperature_core[i]);
|
||||
while (++i < ARRAY_SIZE(amdgpu_metrics->temperature_core) && IS_VALID_METRIC(amdgpu_metrics->temperature_core[i]));
|
||||
metrics->apu_cpu_temp_c = cpu_temp / 100;
|
||||
} else if( header->content_revision >= 3 && IS_VALID_METRIC(amdgpu_metrics->average_temperature_core[0]) ) {
|
||||
// fallback 1
|
||||
unsigned i = 0;
|
||||
do cpu_temp = MAX(cpu_temp, amdgpu_metrics->average_temperature_core[i]);
|
||||
while (++i < ARRAY_SIZE(amdgpu_metrics->average_temperature_core) && IS_VALID_METRIC(amdgpu_metrics->average_temperature_core[i]));
|
||||
metrics->apu_cpu_temp_c = cpu_temp / 100;
|
||||
} else if( cpuStats.ReadcpuTempFile(cpu_temp) ) {
|
||||
// fallback 2: Try temp from file 'm_cpuTempFile' of 'cpu.cpp'
|
||||
metrics->apu_cpu_temp_c = cpu_temp;
|
||||
} else {
|
||||
// giving up
|
||||
metrics->apu_cpu_temp_c = 0;
|
||||
}
|
||||
|
||||
indep_throttle_status = amdgpu_metrics->indep_throttle_status;
|
||||
}
|
||||
|
||||
/* Throttling: See
|
||||
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
|
||||
for the offsets */
|
||||
metrics->is_power_throttled = ((indep_throttle_status >> 0) & 0xFF) != 0;
|
||||
metrics->is_current_throttled = ((indep_throttle_status >> 16) & 0xFF) != 0;
|
||||
metrics->is_temp_throttled = ((indep_throttle_status >> 32) & 0xFFFF) != 0;
|
||||
metrics->is_other_throttled = ((indep_throttle_status >> 56) & 0xFF) != 0;
|
||||
if (throttling)
|
||||
throttling->indep_throttle_status = indep_throttle_status;
|
||||
}
|
||||
|
||||
void amdgpu_get_samples_and_copy(struct amdgpu_common_metrics metrics_buffer[METRICS_SAMPLE_COUNT], bool &gpu_load_needs_dividing) {
|
||||
// Get all the samples
|
||||
for (size_t cur_sample_id=0; cur_sample_id < METRICS_SAMPLE_COUNT; cur_sample_id++) {
|
||||
amdgpu_get_instant_metrics(&metrics_buffer[cur_sample_id]);
|
||||
|
||||
// Detect and fix if the gpu load is reported in centipercent
|
||||
if (gpu_load_needs_dividing || metrics_buffer[cur_sample_id].gpu_load_percent > 100){
|
||||
gpu_load_needs_dividing = true;
|
||||
metrics_buffer[cur_sample_id].gpu_load_percent /= 100;
|
||||
}
|
||||
|
||||
usleep(METRICS_POLLING_PERIOD_MS * 1000);
|
||||
}
|
||||
|
||||
// Copy the results from the different metrics to amdgpu_common_metrics
|
||||
amdgpu_common_metrics_m.lock();
|
||||
UPDATE_METRIC_AVERAGE(gpu_load_percent);
|
||||
UPDATE_METRIC_AVERAGE_FLOAT(average_gfx_power_w);
|
||||
UPDATE_METRIC_AVERAGE_FLOAT(average_cpu_power_w);
|
||||
|
||||
UPDATE_METRIC_AVERAGE(current_gfxclk_mhz);
|
||||
UPDATE_METRIC_AVERAGE(current_uclk_mhz);
|
||||
|
||||
UPDATE_METRIC_AVERAGE(soc_temp_c);
|
||||
UPDATE_METRIC_AVERAGE(gpu_temp_c);
|
||||
UPDATE_METRIC_AVERAGE(apu_cpu_temp_c);
|
||||
|
||||
UPDATE_METRIC_MAX(is_power_throttled);
|
||||
UPDATE_METRIC_MAX(is_current_throttled);
|
||||
UPDATE_METRIC_MAX(is_temp_throttled);
|
||||
UPDATE_METRIC_MAX(is_other_throttled);
|
||||
|
||||
UPDATE_METRIC_MAX(fan_speed);
|
||||
amdgpu_common_metrics_m.unlock();
|
||||
}
|
||||
|
||||
void amdgpu_metrics_polling_thread() {
|
||||
struct amdgpu_common_metrics metrics_buffer[METRICS_SAMPLE_COUNT];
|
||||
bool gpu_load_needs_dividing = false; //some GPUs report load as centipercent
|
||||
|
||||
// Initial poll of the metrics, so that we have values to display as fast as possible
|
||||
amdgpu_get_instant_metrics(&amdgpu_common_metrics);
|
||||
if (amdgpu_common_metrics.gpu_load_percent > 100){
|
||||
gpu_load_needs_dividing = true;
|
||||
amdgpu_common_metrics.gpu_load_percent /= 100;
|
||||
}
|
||||
|
||||
// Set all the fields to 0 by default. Only done once as we're just replacing previous values after
|
||||
memset(metrics_buffer, 0, sizeof(metrics_buffer));
|
||||
|
||||
while (1) {
|
||||
std::unique_lock<std::mutex> lock(amdgpu_m);
|
||||
amdgpu_c.wait(lock, []{return amdgpu_run_thread;});
|
||||
lock.unlock();
|
||||
#ifndef TEST_ONLY
|
||||
if (HUDElements.params->no_display && !logger->is_active())
|
||||
usleep(100000);
|
||||
else
|
||||
#endif
|
||||
amdgpu_get_samples_and_copy(metrics_buffer, gpu_load_needs_dividing);
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_get_metrics(uint32_t deviceID){
|
||||
static bool init = false;
|
||||
if (!init){
|
||||
std::thread(amdgpu_metrics_polling_thread).detach();
|
||||
init = true;
|
||||
}
|
||||
|
||||
amdgpu_common_metrics_m.lock();
|
||||
gpu_info.load = amdgpu_common_metrics.gpu_load_percent;
|
||||
|
||||
gpu_info.powerUsage = amdgpu_common_metrics.average_gfx_power_w;
|
||||
gpu_info.MemClock = amdgpu_common_metrics.current_uclk_mhz;
|
||||
|
||||
// Use hwmon instead, see gpu.cpp
|
||||
if ( deviceID == 0x1435 || deviceID == 0x163f )
|
||||
{
|
||||
// If we are on VANGOGH (Steam Deck), then
|
||||
// always use use core clock from GPU metrics.
|
||||
gpu_info.CoreClock = amdgpu_common_metrics.current_gfxclk_mhz;
|
||||
}
|
||||
// gpu_info.temp = amdgpu_common_metrics.gpu_temp_c;
|
||||
gpu_info.apu_cpu_power = amdgpu_common_metrics.average_cpu_power_w;
|
||||
gpu_info.apu_cpu_temp = amdgpu_common_metrics.apu_cpu_temp_c;
|
||||
|
||||
gpu_info.is_power_throttled = amdgpu_common_metrics.is_power_throttled;
|
||||
gpu_info.is_current_throttled = amdgpu_common_metrics.is_current_throttled;
|
||||
gpu_info.is_temp_throttled = amdgpu_common_metrics.is_temp_throttled;
|
||||
gpu_info.is_other_throttled = amdgpu_common_metrics.is_other_throttled;
|
||||
|
||||
gpu_info.fan_speed = amdgpu_common_metrics.fan_speed;
|
||||
|
||||
amdgpu_common_metrics_m.unlock();
|
||||
}
|
@ -1,310 +0,0 @@
|
||||
#pragma once
|
||||
// #include <fstream>
|
||||
// #include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include "overlay_params.h"
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <vector>
|
||||
#include <sys/param.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define METRICS_UPDATE_PERIOD_MS 500
|
||||
#define METRICS_POLLING_PERIOD_MS 25
|
||||
#define METRICS_SAMPLE_COUNT (METRICS_UPDATE_PERIOD_MS/METRICS_POLLING_PERIOD_MS)
|
||||
#define NUM_HBM_INSTANCES 4
|
||||
|
||||
#define UPDATE_METRIC_AVERAGE(FIELD) do { int value_sum = 0; for (size_t s=0; s < METRICS_SAMPLE_COUNT; s++) { value_sum += metrics_buffer[s].FIELD; } amdgpu_common_metrics.FIELD = value_sum / METRICS_SAMPLE_COUNT; } while(0)
|
||||
#define UPDATE_METRIC_AVERAGE_FLOAT(FIELD) do { float value_sum = 0; for (size_t s=0; s < METRICS_SAMPLE_COUNT; s++) { value_sum += metrics_buffer[s].FIELD; } amdgpu_common_metrics.FIELD = value_sum / METRICS_SAMPLE_COUNT; } while(0)
|
||||
#define UPDATE_METRIC_MAX(FIELD) do { int cur_max = metrics_buffer[0].FIELD; for (size_t s=1; s < METRICS_SAMPLE_COUNT; s++) { cur_max = MAX(cur_max, metrics_buffer[s].FIELD); }; amdgpu_common_metrics.FIELD = cur_max; } while(0)
|
||||
#define UPDATE_METRIC_LAST(FIELD) do { amdgpu_common_metrics.FIELD = metrics_buffer[METRICS_SAMPLE_COUNT - 1].FIELD; } while(0)
|
||||
#ifdef _WIN32
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
struct metrics_table_header {
|
||||
uint16_t structure_size;
|
||||
uint8_t format_revision;
|
||||
uint8_t content_revision;
|
||||
};
|
||||
|
||||
struct gpu_metrics_v1_3 {
|
||||
struct metrics_table_header common_header;
|
||||
|
||||
/* Temperature */
|
||||
uint16_t temperature_edge;
|
||||
uint16_t temperature_hotspot;
|
||||
uint16_t temperature_mem;
|
||||
uint16_t temperature_vrgfx;
|
||||
uint16_t temperature_vrsoc;
|
||||
uint16_t temperature_vrmem;
|
||||
|
||||
/* Utilization */
|
||||
uint16_t average_gfx_activity;
|
||||
uint16_t average_umc_activity; // memory controller
|
||||
uint16_t average_mm_activity; // UVD or VCN
|
||||
|
||||
/* Power/Energy */
|
||||
uint16_t average_socket_power;
|
||||
uint64_t energy_accumulator;
|
||||
|
||||
/* Driver attached timestamp (in ns) */
|
||||
uint64_t system_clock_counter;
|
||||
|
||||
/* Average clocks */
|
||||
uint16_t average_gfxclk_frequency;
|
||||
uint16_t average_socclk_frequency;
|
||||
uint16_t average_uclk_frequency;
|
||||
uint16_t average_vclk0_frequency;
|
||||
uint16_t average_dclk0_frequency;
|
||||
uint16_t average_vclk1_frequency;
|
||||
uint16_t average_dclk1_frequency;
|
||||
|
||||
/* Current clocks */
|
||||
uint16_t current_gfxclk;
|
||||
uint16_t current_socclk;
|
||||
uint16_t current_uclk;
|
||||
uint16_t current_vclk0;
|
||||
uint16_t current_dclk0;
|
||||
uint16_t current_vclk1;
|
||||
uint16_t current_dclk1;
|
||||
|
||||
/* Throttle status */
|
||||
uint32_t throttle_status;
|
||||
|
||||
/* Fans */
|
||||
uint16_t current_fan_speed;
|
||||
|
||||
/* Link width/speed */
|
||||
uint16_t pcie_link_width;
|
||||
uint16_t pcie_link_speed; // in 0.1 GT/s
|
||||
|
||||
uint16_t padding;
|
||||
|
||||
uint32_t gfx_activity_acc;
|
||||
uint32_t mem_activity_acc;
|
||||
|
||||
uint16_t temperature_hbm[NUM_HBM_INSTANCES];
|
||||
|
||||
/* PMFW attached timestamp (10ns resolution) */
|
||||
uint64_t firmware_timestamp;
|
||||
|
||||
/* Voltage (mV) */
|
||||
uint16_t voltage_soc;
|
||||
uint16_t voltage_gfx;
|
||||
uint16_t voltage_mem;
|
||||
|
||||
uint16_t padding1;
|
||||
|
||||
/* Throttle status (ASIC independent) */
|
||||
uint64_t indep_throttle_status;
|
||||
};
|
||||
|
||||
struct gpu_metrics_v2_3 {
|
||||
struct metrics_table_header common_header;
|
||||
|
||||
/* Temperature */
|
||||
uint16_t temperature_gfx; // gfx temperature on APUs
|
||||
uint16_t temperature_soc; // soc temperature on APUs
|
||||
uint16_t temperature_core[8]; // CPU core temperature on APUs
|
||||
uint16_t temperature_l3[2];
|
||||
|
||||
/* Utilization */
|
||||
uint16_t average_gfx_activity;
|
||||
uint16_t average_mm_activity; // UVD or VCN
|
||||
|
||||
/* Driver attached timestamp (in ns) */
|
||||
uint64_t system_clock_counter;
|
||||
|
||||
/* Power/Energy */
|
||||
uint16_t average_socket_power; // dGPU + APU power on A + A platform
|
||||
uint16_t average_cpu_power;
|
||||
uint16_t average_soc_power;
|
||||
uint16_t average_gfx_power;
|
||||
uint16_t average_core_power[8]; // CPU core power on APUs
|
||||
|
||||
/* Average clocks */
|
||||
uint16_t average_gfxclk_frequency;
|
||||
uint16_t average_socclk_frequency;
|
||||
uint16_t average_uclk_frequency;
|
||||
uint16_t average_fclk_frequency;
|
||||
uint16_t average_vclk_frequency;
|
||||
uint16_t average_dclk_frequency;
|
||||
|
||||
/* Current clocks */
|
||||
uint16_t current_gfxclk;
|
||||
uint16_t current_socclk;
|
||||
uint16_t current_uclk;
|
||||
uint16_t current_fclk;
|
||||
uint16_t current_vclk;
|
||||
uint16_t current_dclk;
|
||||
uint16_t current_coreclk[8]; // CPU core clocks
|
||||
uint16_t current_l3clk[2];
|
||||
|
||||
/* Throttle status (ASIC dependent) */
|
||||
uint32_t throttle_status;
|
||||
|
||||
/* Fans */
|
||||
uint16_t fan_pwm;
|
||||
|
||||
uint16_t padding[3];
|
||||
|
||||
/* Throttle status (ASIC independent) */
|
||||
uint64_t indep_throttle_status;
|
||||
|
||||
/* Average Temperature */
|
||||
uint16_t average_temperature_gfx; // average gfx temperature on APUs
|
||||
uint16_t average_temperature_soc; // average soc temperature on APUs
|
||||
uint16_t average_temperature_core[8]; // average CPU core temperature on APUs
|
||||
uint16_t average_temperature_l3[2];
|
||||
};
|
||||
|
||||
|
||||
struct gpu_metrics_v2_4 {
|
||||
struct metrics_table_header common_header;
|
||||
|
||||
/* Temperature (unit: centi-Celsius) */
|
||||
uint16_t temperature_gfx;
|
||||
uint16_t temperature_soc;
|
||||
uint16_t temperature_core[8];
|
||||
uint16_t temperature_l3[2];
|
||||
|
||||
/* Utilization (unit: centi) */
|
||||
uint16_t average_gfx_activity;
|
||||
uint16_t average_mm_activity;
|
||||
|
||||
/* Driver attached timestamp (in ns) */
|
||||
uint64_t system_clock_counter;
|
||||
|
||||
/* Power/Energy (unit: mW) */
|
||||
uint16_t average_socket_power;
|
||||
uint16_t average_cpu_power;
|
||||
uint16_t average_soc_power;
|
||||
uint16_t average_gfx_power;
|
||||
uint16_t average_core_power[8];
|
||||
|
||||
/* Average clocks (unit: MHz) */
|
||||
uint16_t average_gfxclk_frequency;
|
||||
uint16_t average_socclk_frequency;
|
||||
uint16_t average_uclk_frequency;
|
||||
uint16_t average_fclk_frequency;
|
||||
uint16_t average_vclk_frequency;
|
||||
uint16_t average_dclk_frequency;
|
||||
|
||||
/* Current clocks (unit: MHz) */
|
||||
uint16_t current_gfxclk;
|
||||
uint16_t current_socclk;
|
||||
uint16_t current_uclk;
|
||||
uint16_t current_fclk;
|
||||
uint16_t current_vclk;
|
||||
uint16_t current_dclk;
|
||||
uint16_t current_coreclk[8];
|
||||
uint16_t current_l3clk[2];
|
||||
|
||||
/* Throttle status (ASIC dependent) */
|
||||
uint32_t throttle_status;
|
||||
|
||||
/* Fans */
|
||||
uint16_t fan_pwm;
|
||||
|
||||
uint16_t padding[3];
|
||||
|
||||
/* Throttle status (ASIC independent) */
|
||||
uint64_t indep_throttle_status;
|
||||
|
||||
/* Average Temperature (unit: centi-Celsius) */
|
||||
uint16_t average_temperature_gfx;
|
||||
uint16_t average_temperature_soc;
|
||||
uint16_t average_temperature_core[8];
|
||||
uint16_t average_temperature_l3[2];
|
||||
|
||||
/* Power/Voltage (unit: mV) */
|
||||
uint16_t average_cpu_voltage;
|
||||
uint16_t average_soc_voltage;
|
||||
uint16_t average_gfx_voltage;
|
||||
|
||||
/* Power/Current (unit: mA) */
|
||||
uint16_t average_cpu_current;
|
||||
uint16_t average_soc_current;
|
||||
uint16_t average_gfx_current;
|
||||
};
|
||||
|
||||
/* This structure is used to communicate the latest values of the amdgpu metrics.
|
||||
* The direction of communication is amdgpu_polling_thread -> amdgpu_get_metrics().
|
||||
*/
|
||||
struct amdgpu_common_metrics {
|
||||
/* Load level: averaged across the sampling period */
|
||||
uint16_t gpu_load_percent;
|
||||
// uint16_t mem_load_percent;
|
||||
|
||||
/* Power usage: averaged across the sampling period */
|
||||
float average_gfx_power_w;
|
||||
float average_cpu_power_w;
|
||||
|
||||
/* Clocks: latest value of the clock */
|
||||
uint16_t current_gfxclk_mhz;
|
||||
uint16_t current_uclk_mhz;
|
||||
|
||||
/* Temperatures: maximum values over the sampling period */
|
||||
uint16_t soc_temp_c;
|
||||
uint16_t gpu_temp_c;
|
||||
uint16_t apu_cpu_temp_c;
|
||||
|
||||
/* throttling status */
|
||||
bool is_power_throttled;
|
||||
bool is_current_throttled;
|
||||
bool is_temp_throttled;
|
||||
bool is_other_throttled;
|
||||
|
||||
uint16_t fan_speed;
|
||||
};
|
||||
|
||||
bool amdgpu_verify_metrics(const std::string& path);
|
||||
void amdgpu_get_metrics(uint32_t deviceID);
|
||||
extern std::string metrics_path;
|
||||
extern std::condition_variable amdgpu_c;
|
||||
extern bool amdgpu_run_thread;
|
||||
void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics);
|
||||
void amdgpu_metrics_polling_thread();
|
||||
void amdgpu_get_samples_and_copy(struct amdgpu_common_metrics metrics_buffer[METRICS_SAMPLE_COUNT], bool &gpu_load_needs_dividing);
|
||||
void amdgpu_trottling_thread(std::vector<float> &power, std::vector<float> &thermal);
|
||||
|
||||
class Throttling {
|
||||
public:
|
||||
std::vector<float> power;
|
||||
std::vector<float> thermal;
|
||||
int64_t indep_throttle_status;
|
||||
|
||||
Throttling()
|
||||
: power(200, 0.0f),
|
||||
thermal(200, 0.0f) {}
|
||||
|
||||
void update(){
|
||||
if (((indep_throttle_status >> 0) & 0xFF) != 0)
|
||||
power.push_back(0.1);
|
||||
else
|
||||
power.push_back(0);
|
||||
|
||||
|
||||
if (((indep_throttle_status >> 32) & 0xFFFF) != 0)
|
||||
thermal.push_back(0.1);
|
||||
else
|
||||
thermal.push_back(0);
|
||||
|
||||
power.erase(power.begin());
|
||||
thermal.erase(thermal.begin());
|
||||
}
|
||||
|
||||
bool power_throttling(){
|
||||
return std::find(power.begin(), power.end(), 0.1f) != power.end();
|
||||
}
|
||||
|
||||
bool thermal_throttling(){
|
||||
return std::find(thermal.begin(), thermal.end(), 0.1f) != thermal.end();
|
||||
}
|
||||
};
|
||||
|
||||
extern std::unique_ptr<Throttling> throttling;
|
@ -1,79 +0,0 @@
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "mangoapp_proto.h"
|
||||
|
||||
static void help_and_quit() {
|
||||
fprintf(stderr, "Usage: mangohudctl [set|toggle] attribute [value]\n");
|
||||
fprintf(stderr, " mangohudctl reload-cfg\n");
|
||||
fprintf(stderr, "Attributes:\n");
|
||||
fprintf(stderr, " no_display hides or shows hud\n");
|
||||
fprintf(stderr, " log_session handles logging status\n");
|
||||
fprintf(stderr, " reload_config reloads the config\n");
|
||||
fprintf(stderr, "Accepted values:\n");
|
||||
fprintf(stderr, " true\n");
|
||||
fprintf(stderr, " false\n");
|
||||
fprintf(stderr, " 1\n");
|
||||
fprintf(stderr, " 0\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static bool str_to_bool(const char *value)
|
||||
{
|
||||
if (strcasecmp(value, "true") == 0 || strcmp(value, "1") == 0)
|
||||
return true;
|
||||
else if (strcasecmp(value, "false") == 0 || strcmp(value, "0") == 0)
|
||||
return false;
|
||||
|
||||
/* invalid boolean, display a nice error message saying that */
|
||||
fprintf(stderr, "The value '%s' is not an accepted boolean. Use 0/1 or true/false\n", value);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* Set up message queue */
|
||||
int key = ftok("mangoapp", 65);
|
||||
int msgid = msgget(key, 0666 | IPC_CREAT);
|
||||
/* Create the message that we will send to mangohud */
|
||||
struct mangoapp_ctrl_msgid1_v1 ctrl_msg = {
|
||||
.hdr.msg_type = 2,
|
||||
.hdr.ctrl_msg_type = 1,
|
||||
.hdr.version = 1,
|
||||
};
|
||||
uint8_t value;
|
||||
|
||||
if (argc <= 2)
|
||||
help_and_quit();
|
||||
|
||||
if (strcmp(argv[1], "set") == 0) {
|
||||
if (argc != 4)
|
||||
help_and_quit();
|
||||
|
||||
value = str_to_bool(argv[3]) ? 1 : 2;
|
||||
} else if (strcmp(argv[1], "toggle") == 0) {
|
||||
if (argc != 3)
|
||||
help_and_quit();
|
||||
|
||||
value = 3;
|
||||
} else {
|
||||
help_and_quit();
|
||||
}
|
||||
|
||||
if (strcmp(argv[2], "no_display") == 0)
|
||||
ctrl_msg.no_display = value;
|
||||
else if (strcmp(argv[2], "log_session") == 0)
|
||||
ctrl_msg.log_session = value;
|
||||
else if (strcmp(argv[2], "reload_config") == 0)
|
||||
ctrl_msg.reload_config = value;
|
||||
else
|
||||
help_and_quit();
|
||||
|
||||
msgsnd(msgid, &ctrl_msg, sizeof(struct mangoapp_ctrl_msgid1_v1), IPC_NOWAIT);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
#include <mutex>
|
||||
#include <list>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include "mesa/util/macros.h"
|
||||
#include "vk_enum_to_str.h"
|
||||
#include <vulkan/vk_layer.h>
|
||||
#include <vulkan/vk_util.h>
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "engine_types.h"
|
||||
|
||||
using namespace std;
|
||||
using json = nlohmann::json;
|
||||
|
||||
// single global lock, for simplicity
|
||||
std::mutex global_lock;
|
||||
typedef std::lock_guard<std::mutex> scoped_lock;
|
||||
std::unordered_map<uint64_t, void *> vk_object_to_data;
|
||||
|
||||
/* Mapped from VkInstace/VkPhysicalDevice */
|
||||
struct instance_data {
|
||||
struct vk_instance_dispatch_table vtable;
|
||||
VkInstance instance;
|
||||
string engineName, engineVersion;
|
||||
enum EngineTypes engine;
|
||||
};
|
||||
|
||||
#define HKEY(obj) ((uint64_t)(obj))
|
||||
#define FIND(type, obj) (reinterpret_cast<type *>(find_object_data(HKEY(obj))))
|
||||
|
||||
static void *find_object_data(uint64_t obj)
|
||||
{
|
||||
::scoped_lock lk(global_lock);
|
||||
return vk_object_to_data[obj];
|
||||
}
|
||||
|
||||
static void map_object(uint64_t obj, void *data)
|
||||
{
|
||||
::scoped_lock lk(global_lock);
|
||||
vk_object_to_data[obj] = data;
|
||||
}
|
||||
|
||||
static void unmap_object(uint64_t obj)
|
||||
{
|
||||
::scoped_lock lk(global_lock);
|
||||
vk_object_to_data.erase(obj);
|
||||
}
|
||||
|
||||
static VkLayerInstanceCreateInfo *get_instance_chain_info(const VkInstanceCreateInfo *pCreateInfo,
|
||||
VkLayerFunction func)
|
||||
{
|
||||
vk_foreach_struct(item, pCreateInfo->pNext) {
|
||||
if (item->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO &&
|
||||
((VkLayerInstanceCreateInfo *) item)->function == func)
|
||||
return (VkLayerInstanceCreateInfo *) item;
|
||||
}
|
||||
unreachable("instance chain info not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct instance_data *new_instance_data(VkInstance instance)
|
||||
{
|
||||
struct instance_data *data = new instance_data();
|
||||
data->instance = instance;
|
||||
map_object(HKEY(data->instance), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
static void instance_data_map_physical_devices(struct instance_data *instance_data,
|
||||
bool map)
|
||||
{
|
||||
uint32_t physicalDeviceCount = 0;
|
||||
instance_data->vtable.EnumeratePhysicalDevices(instance_data->instance,
|
||||
&physicalDeviceCount,
|
||||
NULL);
|
||||
|
||||
std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
|
||||
instance_data->vtable.EnumeratePhysicalDevices(instance_data->instance,
|
||||
&physicalDeviceCount,
|
||||
physicalDevices.data());
|
||||
|
||||
for (uint32_t i = 0; i < physicalDeviceCount; i++) {
|
||||
if (map)
|
||||
map_object(HKEY(physicalDevices[i]), instance_data);
|
||||
else
|
||||
unmap_object(HKEY(physicalDevices[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static VkResult overlay_CreateInstance(
|
||||
const VkInstanceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkInstance* pInstance)
|
||||
{
|
||||
fprintf(stderr, "MANGOAPP LAYER: Init\n");
|
||||
VkLayerInstanceCreateInfo *chain_info =
|
||||
get_instance_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
|
||||
std::string engineVersion,engineName;
|
||||
enum EngineTypes engine = EngineTypes::UNKNOWN;
|
||||
|
||||
const char* pEngineName = nullptr;
|
||||
if (pCreateInfo->pApplicationInfo)
|
||||
pEngineName = pCreateInfo->pApplicationInfo->pEngineName;
|
||||
if (pEngineName)
|
||||
engineName = pEngineName;
|
||||
if (engineName == "DXVK" || engineName == "vkd3d") {
|
||||
int engineVer = pCreateInfo->pApplicationInfo->engineVersion;
|
||||
engineVersion = to_string(VK_VERSION_MAJOR(engineVer)) + "." + to_string(VK_VERSION_MINOR(engineVer)) + "." + to_string(VK_VERSION_PATCH(engineVer));
|
||||
}
|
||||
|
||||
if (engineName == "DXVK")
|
||||
engine = DXVK;
|
||||
|
||||
else if (engineName == "vkd3d")
|
||||
engine = VKD3D;
|
||||
|
||||
else if(engineName == "mesa zink")
|
||||
engine = ZINK;
|
||||
|
||||
else if (engineName == "Damavand")
|
||||
engine = DAMAVAND;
|
||||
|
||||
else if (engineName == "Feral3D")
|
||||
engine = FERAL3D;
|
||||
|
||||
else
|
||||
engine = VULKAN;
|
||||
|
||||
assert(chain_info->u.pLayerInfo);
|
||||
PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
|
||||
chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
|
||||
PFN_vkCreateInstance fpCreateInstance =
|
||||
(PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
|
||||
if (fpCreateInstance == NULL) {
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
// Advance the link info for the next element on the chain
|
||||
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
|
||||
|
||||
VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
|
||||
if (result != VK_SUCCESS) return result;
|
||||
|
||||
struct instance_data *instance_data = new_instance_data(*pInstance);
|
||||
vk_load_instance_commands(instance_data->instance,
|
||||
fpGetInstanceProcAddr,
|
||||
&instance_data->vtable);
|
||||
instance_data_map_physical_devices(instance_data, true);
|
||||
|
||||
instance_data->engine = engine;
|
||||
instance_data->engineName = engineName;
|
||||
instance_data->engineVersion = engineVersion;
|
||||
|
||||
struct stat info;
|
||||
string path = "/tmp/mangoapp/";
|
||||
string command = "mkdir -p " + path;
|
||||
string json_path = path + to_string(getpid()) + ".json";
|
||||
if( stat(path.c_str(), &info ) != 0 )
|
||||
system(command.c_str());
|
||||
json j;
|
||||
j["engine"] = engine;
|
||||
ofstream o(json_path);
|
||||
if (!o.fail()){
|
||||
o << std::setw(4) << j << std::endl;
|
||||
} else{
|
||||
fprintf(stderr, "MANGOAPP LAYER: failed to write json\n");
|
||||
}
|
||||
o.close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL overlay_GetInstanceProcAddr(VkInstance instance,
|
||||
const char *funcName);
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
void *ptr;
|
||||
} name_to_funcptr_map[] = {
|
||||
{ "vkGetInstanceProcAddr", (void *) overlay_GetInstanceProcAddr },
|
||||
#define ADD_HOOK(fn) { "vk" # fn, (void *) overlay_ ## fn }
|
||||
#define ADD_ALIAS_HOOK(alias, fn) { "vk" # alias, (void *) overlay_ ## fn }
|
||||
ADD_HOOK(CreateInstance),
|
||||
#undef ADD_HOOK
|
||||
};
|
||||
|
||||
static void *find_ptr(const char *name)
|
||||
{
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(name_to_funcptr_map); i++) {
|
||||
if (strcmp(name, name_to_funcptr_map[i].name) == 0)
|
||||
return name_to_funcptr_map[i].ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL overlay_GetInstanceProcAddr(VkInstance instance,
|
||||
const char *funcName)
|
||||
{
|
||||
void *ptr = find_ptr(funcName);
|
||||
if (ptr) return reinterpret_cast<PFN_vkVoidFunction>(ptr);
|
||||
|
||||
if (instance == NULL) return NULL;
|
||||
|
||||
struct instance_data *instance_data = FIND(struct instance_data, instance);
|
||||
if (instance_data->vtable.GetInstanceProcAddr == NULL) return NULL;
|
||||
return instance_data->vtable.GetInstanceProcAddr(instance, funcName);
|
||||
}
|
@ -1,423 +0,0 @@
|
||||
// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline
|
||||
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <stdio.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
#include "../overlay.h"
|
||||
#include "notify.h"
|
||||
#include "mangoapp.h"
|
||||
#include "mangoapp_proto.h"
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "amdgpu.h"
|
||||
#ifdef __linux__
|
||||
#include "implot.h"
|
||||
#endif
|
||||
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#include <GLFW/glfw3native.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
using json = nlohmann::json;
|
||||
using namespace std;
|
||||
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
|
||||
}
|
||||
|
||||
swapchain_stats sw_stats {};
|
||||
overlay_params params {};
|
||||
static ImVec2 window_size;
|
||||
static uint32_t vendorID;
|
||||
static std::string deviceName;
|
||||
static notify_thread notifier;
|
||||
static int msgid;
|
||||
static bool mangoapp_paused = false;
|
||||
std::mutex mangoapp_m;
|
||||
std::condition_variable mangoapp_cv;
|
||||
static uint8_t raw_msg[1024] = {0};
|
||||
static uint32_t screenWidth, screenHeight;
|
||||
|
||||
static unsigned int get_prop(const char* propName){
|
||||
Display *x11_display = glfwGetX11Display();
|
||||
Atom gamescope_focused = XInternAtom(x11_display, propName, false);
|
||||
auto scr = DefaultScreen(x11_display);
|
||||
auto root = RootWindow(x11_display, scr);
|
||||
Atom actual;
|
||||
int format;
|
||||
unsigned long n, left;
|
||||
uint64_t *data;
|
||||
int result = XGetWindowProperty(x11_display, root, gamescope_focused, 0L, 1L, false,
|
||||
XA_CARDINAL, &actual, &format,
|
||||
&n, &left, ( unsigned char** )&data);
|
||||
|
||||
if (result == Success && data != NULL){
|
||||
bool *found = nullptr;
|
||||
unsigned int i;
|
||||
memcpy(&i, data, sizeof(unsigned int));
|
||||
XFree((void *) data);
|
||||
if ( found != nullptr )
|
||||
{
|
||||
*found = true;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void ctrl_thread(){
|
||||
while (1){
|
||||
const struct mangoapp_ctrl_msgid1_v1 *mangoapp_ctrl_v1 = (const struct mangoapp_ctrl_msgid1_v1*) raw_msg;
|
||||
memset(raw_msg, 0, sizeof(raw_msg));
|
||||
msgrcv(msgid, (void *) raw_msg, sizeof(raw_msg), 2, 0);
|
||||
switch (mangoapp_ctrl_v1->log_session) {
|
||||
case 0:
|
||||
// Keep as-is
|
||||
break;
|
||||
case 1:
|
||||
if (!logger->is_active())
|
||||
logger->start_logging();
|
||||
break;
|
||||
case 2:
|
||||
if (logger->is_active())
|
||||
logger->stop_logging();
|
||||
break;
|
||||
case 3:
|
||||
logger->is_active() ? logger->stop_logging() : logger->start_logging();
|
||||
break;
|
||||
}
|
||||
switch (mangoapp_ctrl_v1->reload_config) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG"), false);
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG"), false);
|
||||
break;
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(mangoapp_m);
|
||||
switch (mangoapp_ctrl_v1->no_display){
|
||||
case 0:
|
||||
// Keep as-is
|
||||
break;
|
||||
case 1:
|
||||
params.no_display = 1;
|
||||
break;
|
||||
case 2:
|
||||
params.no_display = 0;
|
||||
break;
|
||||
case 3:
|
||||
params.no_display ? params.no_display = 0 : params.no_display = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mangoapp_cv.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
bool new_frame = false;
|
||||
|
||||
static void gamescope_frametime(uint64_t app_frametime_ns, uint64_t latency_ns){
|
||||
if (app_frametime_ns != uint64_t(-1))
|
||||
{
|
||||
float app_frametime_ms = app_frametime_ns / 1000000.f;
|
||||
HUDElements.gamescope_debug_app.push_back(app_frametime_ms);
|
||||
if (HUDElements.gamescope_debug_app.size() > 200)
|
||||
HUDElements.gamescope_debug_app.erase(HUDElements.gamescope_debug_app.begin());
|
||||
}
|
||||
|
||||
float latency_ms = latency_ns / 1000000.f;
|
||||
if (latency_ns == uint64_t(-1))
|
||||
latency_ms = -1;
|
||||
HUDElements.gamescope_debug_latency.push_back(latency_ms);
|
||||
if (HUDElements.gamescope_debug_latency.size() > 200)
|
||||
HUDElements.gamescope_debug_latency.erase(HUDElements.gamescope_debug_latency.begin());
|
||||
}
|
||||
|
||||
static void msg_read_thread(){
|
||||
for (size_t i = 0; i < 200; i++){
|
||||
HUDElements.gamescope_debug_app.push_back(0);
|
||||
HUDElements.gamescope_debug_latency.push_back(0);
|
||||
}
|
||||
int key = ftok("mangoapp", 65);
|
||||
msgid = msgget(key, 0666 | IPC_CREAT);
|
||||
// uint32_t previous_pid = 0;
|
||||
const struct mangoapp_msg_header *hdr = (const struct mangoapp_msg_header*) raw_msg;
|
||||
const struct mangoapp_msg_v1 *mangoapp_v1 = (const struct mangoapp_msg_v1*) raw_msg;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char *GamescopeOverlayProperty = "GAMESCOPE_EXTERNAL_OVERLAY";
|
||||
|
||||
static GLFWwindow* init(const char* glsl_version){
|
||||
init_spdlog();
|
||||
GLFWwindow *window = glfwCreateWindow(1280, 800, "mangoapp overlay window", NULL, NULL);
|
||||
Display *x11_display = glfwGetX11Display();
|
||||
Window x11_window = glfwGetX11Window(window);
|
||||
if (x11_window && x11_display)
|
||||
{
|
||||
// Set atom for gamescope to render as an overlay.
|
||||
Atom overlay_atom = XInternAtom (x11_display, GamescopeOverlayProperty, False);
|
||||
uint32_t value = 1;
|
||||
XChangeProperty(x11_display, x11_window, overlay_atom, XA_CARDINAL, 32, PropertyNewValue, (unsigned char *)&value, 1);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1); // Enable vsync
|
||||
ImGui::CreateContext();
|
||||
#ifdef __linux__
|
||||
ImPlot::CreateContext();
|
||||
#endif
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.IniFilename = NULL;
|
||||
ImGui::StyleColorsDark();
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
return window;
|
||||
}
|
||||
|
||||
static void shutdown(GLFWwindow* window){
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
glfwDestroyWindow(window);
|
||||
}
|
||||
|
||||
static void get_atom_info(){
|
||||
HUDElements.hdr_status = get_prop("GAMESCOPE_COLOR_APP_WANTS_HDR_FEEDBACK");
|
||||
HUDElements.refresh = get_prop("GAMESCOPE_DISPLAY_REFRESH_RATE_FEEDBACK");
|
||||
}
|
||||
|
||||
static bool render(GLFWwindow* window) {
|
||||
if (HUDElements.colors.update)
|
||||
HUDElements.convert_colors(params);
|
||||
|
||||
ImVec2 last_window_size = window_size;
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
overlay_new_frame(params);
|
||||
position_layer(sw_stats, params, window_size);
|
||||
render_imgui(sw_stats, params, window_size, true);
|
||||
get_atom_info();
|
||||
overlay_end_frame();
|
||||
if (screenWidth && screenHeight)
|
||||
glfwSetWindowSize(window, screenWidth, screenHeight);
|
||||
ImGui::EndFrame();
|
||||
return last_window_size.x != window_size.x || last_window_size.y != window_size.y;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup window
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
if (!glfwInit())
|
||||
return 1;
|
||||
|
||||
const char* glsl_version = "#version 130";
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, 1);
|
||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1);
|
||||
|
||||
// Create window with graphics context
|
||||
GLFWwindow* window = init(glsl_version);
|
||||
|
||||
Display *x11_display = glfwGetX11Display();
|
||||
Window x11_window = glfwGetX11Window(window);
|
||||
Atom overlay_atom = XInternAtom (x11_display, GamescopeOverlayProperty, False);
|
||||
// Initialize OpenGL loader
|
||||
|
||||
bool err = glewInit() != GLEW_OK;
|
||||
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr, "Failed to initialize OpenGL loader!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
int control_client = -1;
|
||||
parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG"), false);
|
||||
create_fonts(nullptr, params, sw_stats.font1, sw_stats.font_text);
|
||||
HUDElements.convert_colors(params);
|
||||
init_cpu_stats(params);
|
||||
notifier.params = ¶ms;
|
||||
start_notifier(notifier);
|
||||
window_size = ImVec2(params.width, params.height);
|
||||
deviceName = (char*)glGetString(GL_RENDERER);
|
||||
sw_stats.deviceName = deviceName;
|
||||
SPDLOG_DEBUG("mangoapp deviceName: {}", deviceName);
|
||||
#define GLX_RENDERER_VENDOR_ID_MESA 0x8183
|
||||
auto pfn_glXQueryCurrentRendererIntegerMESA = (Bool (*)(int, unsigned int*)) (glfwGetProcAddress("glXQueryCurrentRendererIntegerMESA"));
|
||||
// This will return 0x0 vendorID on NVIDIA so just go to else
|
||||
if (pfn_glXQueryCurrentRendererIntegerMESA && vendorID != 0x0) {
|
||||
pfn_glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_VENDOR_ID_MESA, &vendorID);
|
||||
SPDLOG_DEBUG("mangoapp vendorID: {:#x}", vendorID);
|
||||
} else {
|
||||
if (deviceName.find("Radeon") != std::string::npos
|
||||
|| deviceName.find("AMD") != std::string::npos){
|
||||
vendorID = 0x1002;
|
||||
} else if (deviceName.find("Intel") != std::string::npos) {
|
||||
vendorID = 0x8086;
|
||||
} else {
|
||||
vendorID = 0x10de;
|
||||
}
|
||||
}
|
||||
|
||||
HUDElements.vendorID = vendorID;
|
||||
init_gpu_stats(vendorID, 0, params);
|
||||
init_system_info();
|
||||
sw_stats.engine = EngineTypes::GAMESCOPE;
|
||||
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){
|
||||
if (mangoapp_paused){
|
||||
glfwRestoreWindow(window);
|
||||
uint32_t value = 1;
|
||||
XChangeProperty(x11_display, x11_window, overlay_atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&value, 1);
|
||||
XSync(x11_display, 0);
|
||||
mangoapp_paused = false;
|
||||
{
|
||||
amdgpu_run_thread = true;
|
||||
amdgpu_c.notify_one();
|
||||
}
|
||||
}
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(mangoapp_m);
|
||||
mangoapp_cv.wait(lk, []{return new_frame || params.no_display;});
|
||||
new_frame = false;
|
||||
}
|
||||
|
||||
check_keybinds(params, vendorID);
|
||||
// Start the Dear ImGui frame
|
||||
{
|
||||
if (render(window)) {
|
||||
// If we need to resize our window, give it another couple of rounds for the
|
||||
// stupid display size stuff to propagate through ImGUI (using NDC and scaling
|
||||
// in GL makes me a very unhappy boy.)
|
||||
render(window);
|
||||
render(window);
|
||||
}
|
||||
|
||||
if (params.control >= 0) {
|
||||
control_client_check(params.control, control_client, deviceName);
|
||||
process_control_socket(control_client, params);
|
||||
}
|
||||
}
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
} else if (!mangoapp_paused) {
|
||||
glfwIconifyWindow(window);
|
||||
uint32_t value = 0;
|
||||
XChangeProperty(x11_display, x11_window, overlay_atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&value, 1);
|
||||
XSync(x11_display, 0);
|
||||
mangoapp_paused = true;
|
||||
{
|
||||
amdgpu_run_thread = false;
|
||||
amdgpu_c.notify_one();
|
||||
}
|
||||
std::unique_lock<std::mutex> lk(mangoapp_m);
|
||||
mangoapp_cv.wait(lk, []{return !params.no_display;});
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
shutdown(window);
|
||||
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <vector>
|
||||
|
||||
extern std::mutex mangoapp_m;
|
||||
extern std::condition_variable mangoapp_cv;
|
@ -1,39 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
struct mangoapp_msg_header {
|
||||
long msg_type; // Message queue ID, never change
|
||||
uint32_t version; /* for major changes in the way things work */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mangoapp_msg_v1 {
|
||||
struct mangoapp_msg_header hdr;
|
||||
|
||||
uint32_t pid;
|
||||
uint64_t visible_frametime_ns;
|
||||
uint8_t fsrUpscale;
|
||||
uint8_t fsrSharpness;
|
||||
// For debugging
|
||||
uint64_t app_frametime_ns;
|
||||
uint64_t latency_ns;
|
||||
uint32_t outputWidth;
|
||||
uint32_t outputHeight;
|
||||
// WARNING: Always ADD fields, never remove or repurpose fields
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mangoapp_ctrl_header {
|
||||
long msg_type; // Message queue ID, never change
|
||||
uint32_t ctrl_msg_type; /* This is a way to share the same thread between multiple types of messages */
|
||||
uint32_t version; /* version of the message type, for backwards incompatible changes */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mangoapp_ctrl_msgid1_v1 {
|
||||
struct mangoapp_ctrl_header hdr;
|
||||
|
||||
// When a field is set to 0, it should always mean "ignore" or "no changes"
|
||||
uint8_t no_display; // 0x0 = ignore; 0x1 = disable; 0x2 = enable; 0x3 = toggle
|
||||
uint8_t log_session; // 0x0 = ignore; 0x1 = start a session; 0x2 = stop the current session; 0x3 = toggle logging
|
||||
char log_session_name[64]; // if byte 0 is NULL, ignore. Needs to be set when starting/toggling a session if we want to override the default name
|
||||
uint8_t reload_config;
|
||||
|
||||
// WARNING: Always ADD fields, never remove or repurpose fields
|
||||
} __attribute__((packed));
|
@ -1,198 +0,0 @@
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <filesystem.h>
|
||||
#include "battery.h"
|
||||
|
||||
namespace fs = ghc::filesystem;
|
||||
using namespace std;
|
||||
|
||||
void BatteryStats::numBattery() {
|
||||
int batteryCount = 0;
|
||||
if (!fs::exists("/sys/class/power_supply/")) {
|
||||
batteryCount = 0;
|
||||
}
|
||||
fs::path path("/sys/class/power_supply/");
|
||||
for (auto& p : fs::directory_iterator(path)) {
|
||||
string fileName = p.path().filename();
|
||||
if (fileName.find("BAT") != std::string::npos) {
|
||||
battPath[batteryCount] = p.path();
|
||||
batteryCount += 1;
|
||||
}
|
||||
}
|
||||
batt_count = batteryCount;
|
||||
batt_check = true;
|
||||
}
|
||||
|
||||
void BatteryStats::update() {
|
||||
if (!batt_check) {
|
||||
numBattery();
|
||||
if (batt_count == 0) {
|
||||
SPDLOG_ERROR("No battery found");
|
||||
}
|
||||
}
|
||||
|
||||
if (batt_count > 0) {
|
||||
current_watt = getPower();
|
||||
current_percent = getPercent();
|
||||
remaining_time = getTimeRemaining();
|
||||
}
|
||||
}
|
||||
|
||||
float BatteryStats::getPercent()
|
||||
{
|
||||
float charge_n = 0;
|
||||
float charge_f = 0;
|
||||
for(int i = 0; i < batt_count; i++) {
|
||||
string syspath = battPath[i];
|
||||
string charge_now = syspath + "/charge_now";
|
||||
string charge_full = syspath + "/charge_full";
|
||||
string energy_now = syspath + "/energy_now";
|
||||
string energy_full = syspath + "/energy_full";
|
||||
string capacity = syspath + "/capacity";
|
||||
|
||||
if (fs::exists(charge_now)) {
|
||||
std::ifstream input(charge_now);
|
||||
std::string line;
|
||||
if(std::getline(input, line)) {
|
||||
charge_n += (stof(line) / 1000000);
|
||||
}
|
||||
std::ifstream input2(charge_full);
|
||||
if(std::getline(input2, line)) {
|
||||
charge_f += (stof(line) / 1000000);
|
||||
}
|
||||
}
|
||||
|
||||
else if (fs::exists(energy_now)) {
|
||||
std::ifstream input(energy_now);
|
||||
std::string line;
|
||||
if(std::getline(input, line)) {
|
||||
charge_n += (stof(line) / 1000000);
|
||||
}
|
||||
std::ifstream input2(energy_full);
|
||||
if(std::getline(input2, line)) {
|
||||
charge_f += (stof(line) / 1000000);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
// using /sys/class/power_supply/BAT*/capacity
|
||||
// No way to get an accurate reading just average the percents if mutiple batteries
|
||||
std::ifstream input(capacity);
|
||||
std::string line;
|
||||
if(std::getline(input, line)) {
|
||||
charge_n += stof(line) / 100;
|
||||
charge_f = batt_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (charge_n / charge_f) * 100;
|
||||
}
|
||||
|
||||
float BatteryStats::getPower() {
|
||||
float current = 0;
|
||||
float voltage = 0;
|
||||
for(int i = 0; i < batt_count; i++) {
|
||||
string syspath = battPath[i];
|
||||
string current_power = syspath + "/current_now";
|
||||
string current_voltage = syspath + "/voltage_now";
|
||||
string power_now = syspath + "/power_now";
|
||||
string status = syspath + "/status";
|
||||
|
||||
std::ifstream input(status);
|
||||
std::string line;
|
||||
if(std::getline(input,line)) {
|
||||
current_status= line;
|
||||
state[i]=current_status;
|
||||
}
|
||||
|
||||
if (state[i] == "Charging" || state[i] == "Unknown" || state[i] == "Full") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fs::exists(current_power)) {
|
||||
std::ifstream input(current_power);
|
||||
std::string line;
|
||||
if(std::getline(input,line)) {
|
||||
current += (stof(line) / 1000000);
|
||||
}
|
||||
std::ifstream input2(current_voltage);
|
||||
if(std::getline(input2, line)) {
|
||||
voltage += (stof(line) / 1000000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::ifstream input(power_now);
|
||||
std::string line;
|
||||
if(std::getline(input,line)) {
|
||||
current += (stof(line) / 1000000);
|
||||
voltage = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return current * voltage;
|
||||
}
|
||||
|
||||
float BatteryStats::getTimeRemaining(){
|
||||
float current = 0;
|
||||
float charge = 0;
|
||||
for(int i = 0; i < batt_count; i++) {
|
||||
string syspath = battPath[i];
|
||||
string current_now = syspath + "/current_now";
|
||||
string charge_now = syspath + "/charge_now";
|
||||
string energy_now = syspath + "/energy_now";
|
||||
string voltage_now = syspath + "/voltage_now";
|
||||
string power_now = syspath + "/power_now";
|
||||
|
||||
if (fs::exists(current_now)) {
|
||||
std::ifstream input(current_now);
|
||||
std::string line;
|
||||
if(std::getline(input, line)){
|
||||
current_now_vec.push_back(stof(line));
|
||||
}
|
||||
} else if (fs::exists(power_now)){
|
||||
float voltage = 0;
|
||||
float power = 0;
|
||||
std::ifstream input_power(power_now);
|
||||
std::ifstream input_voltage(voltage_now);
|
||||
std::string line;
|
||||
if(std::getline(input_voltage, line)){
|
||||
voltage = stof(line);
|
||||
}
|
||||
if(std::getline(input_power, line)){
|
||||
power = stof(line);
|
||||
}
|
||||
current_now_vec.push_back(power / voltage);
|
||||
}
|
||||
if (fs::exists(charge_now)){
|
||||
std::string line;
|
||||
std::ifstream input(charge_now);
|
||||
if(std::getline(input, line)){
|
||||
charge += stof(line);
|
||||
}
|
||||
}
|
||||
else if (fs::exists(energy_now)) {
|
||||
float energy = 0;
|
||||
float voltage = 0;
|
||||
std::string line;
|
||||
std::ifstream input_energy(energy_now);
|
||||
std::ifstream input_voltage(voltage_now);
|
||||
if(std::getline(input_energy, line)){
|
||||
energy = stof(line);
|
||||
}
|
||||
if(std::getline(input_voltage, line)){
|
||||
voltage = stof(line);
|
||||
}
|
||||
charge += energy / voltage;
|
||||
}
|
||||
if (current_now_vec.size() > 25)
|
||||
current_now_vec.erase(current_now_vec.begin());
|
||||
}
|
||||
|
||||
for(auto& current_now : current_now_vec){
|
||||
current += current_now;
|
||||
}
|
||||
current /= current_now_vec.size();
|
||||
|
||||
return charge / current;
|
||||
}
|
||||
|
||||
BatteryStats Battery_Stats;
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
class BatteryStats{
|
||||
public:
|
||||
void numBattery();
|
||||
void update();
|
||||
float getPower();
|
||||
float getPercent();
|
||||
float getTimeRemaining();
|
||||
std::string battPath[2];
|
||||
float current_watt = 0;
|
||||
float current_percent = 0;
|
||||
float remaining_time = 0;
|
||||
std::string current_status;
|
||||
std::string state [2];
|
||||
int batt_count=0;
|
||||
bool batt_check = false;
|
||||
std::vector<float> current_now_vec = {};
|
||||
};
|
||||
|
||||
extern BatteryStats Battery_Stats;
|
@ -1,9 +1,3 @@
|
||||
#pragma once
|
||||
#ifndef MANGOHUD_BLACKLIST_H
|
||||
#define MANGOHUD_BLACKLIST_H
|
||||
#include<string>
|
||||
bool is_blacklisted(bool force_recheck = false);
|
||||
void add_blacklist(const std::string& proc);
|
||||
extern std::string global_proc_name;
|
||||
|
||||
#endif //MANGOHUD_BLACKLIST_H
|
||||
bool is_blacklisted();
|
||||
|
@ -1,217 +0,0 @@
|
||||
#include <cstdint>
|
||||
#include <assert.h>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <sys/socket.h>
|
||||
#include "mesa/util/os_socket.h"
|
||||
#include "overlay.h"
|
||||
#include "version.h"
|
||||
#include "app/mangoapp.h"
|
||||
|
||||
int global_control_client;
|
||||
|
||||
using namespace std;
|
||||
static void parse_command(overlay_params ¶ms,
|
||||
const char *cmd, unsigned cmdlen,
|
||||
const char *param, unsigned paramlen)
|
||||
{
|
||||
if (!strncmp(cmd, "hud", cmdlen)) {
|
||||
params.no_display = !params.no_display;
|
||||
} else if (!strncmp(cmd, "logging", cmdlen)) {
|
||||
if (param && param[0])
|
||||
{
|
||||
int value = atoi(param);
|
||||
if (!value && logger->is_active())
|
||||
logger->stop_logging();
|
||||
else if (value > 0 && !logger->is_active())
|
||||
logger->start_logging();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger->is_active())
|
||||
logger->stop_logging();
|
||||
else
|
||||
logger->start_logging();
|
||||
}
|
||||
} else if (!strncmp(cmd, "fcat", cmdlen)) {
|
||||
params.enabled[OVERLAY_PARAM_ENABLED_fcat] = !params.enabled[OVERLAY_PARAM_ENABLED_fcat];
|
||||
}
|
||||
}
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
/**
|
||||
* This function will process commands through the control file.
|
||||
*
|
||||
* A command starts with a colon, followed by the command, and followed by an
|
||||
* option '=' and a parameter. It has to end with a semi-colon. A full command
|
||||
* + parameter looks like:
|
||||
*
|
||||
* :cmd=param;
|
||||
*/
|
||||
static void process_char(const int control_client, overlay_params ¶ms, char c)
|
||||
{
|
||||
static char cmd[BUFSIZE];
|
||||
static char param[BUFSIZE];
|
||||
|
||||
static unsigned cmdpos = 0;
|
||||
static unsigned parampos = 0;
|
||||
static bool reading_cmd = false;
|
||||
static bool reading_param = false;
|
||||
|
||||
switch (c) {
|
||||
case ':':
|
||||
cmdpos = 0;
|
||||
parampos = 0;
|
||||
reading_cmd = true;
|
||||
reading_param = false;
|
||||
break;
|
||||
case ';':
|
||||
if (!reading_cmd)
|
||||
break;
|
||||
cmd[cmdpos++] = '\0';
|
||||
param[parampos++] = '\0';
|
||||
parse_command(params, cmd, cmdpos, param, parampos);
|
||||
reading_cmd = false;
|
||||
reading_param = false;
|
||||
break;
|
||||
case '=':
|
||||
if (!reading_cmd)
|
||||
break;
|
||||
reading_param = true;
|
||||
break;
|
||||
default:
|
||||
if (!reading_cmd)
|
||||
break;
|
||||
|
||||
if (reading_param) {
|
||||
/* overflow means an invalid parameter */
|
||||
if (parampos >= BUFSIZE - 1) {
|
||||
reading_cmd = false;
|
||||
reading_param = false;
|
||||
break;
|
||||
}
|
||||
|
||||
param[parampos++] = c;
|
||||
} else {
|
||||
/* overflow means an invalid command */
|
||||
if (cmdpos >= BUFSIZE - 1) {
|
||||
reading_cmd = false;
|
||||
break;
|
||||
}
|
||||
|
||||
cmd[cmdpos++] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void control_send(int control_client,
|
||||
const char *cmd, unsigned cmdlen,
|
||||
const char *param, unsigned paramlen)
|
||||
{
|
||||
unsigned msglen = 0;
|
||||
char buffer[BUFSIZE];
|
||||
|
||||
assert(cmdlen + paramlen + 3 < BUFSIZE);
|
||||
|
||||
buffer[msglen++] = ':';
|
||||
|
||||
memcpy(&buffer[msglen], cmd, cmdlen);
|
||||
msglen += cmdlen;
|
||||
|
||||
if (paramlen > 0) {
|
||||
buffer[msglen++] = '=';
|
||||
memcpy(&buffer[msglen], param, paramlen);
|
||||
msglen += paramlen;
|
||||
buffer[msglen++] = ';';
|
||||
}
|
||||
|
||||
os_socket_send(control_client, buffer, msglen, MSG_NOSIGNAL);
|
||||
}
|
||||
|
||||
static void control_send_connection_string(int control_client, const std::string& deviceName)
|
||||
{
|
||||
const char *controlVersionCmd = "MangoHudControlVersion";
|
||||
const char *controlVersionString = "1";
|
||||
|
||||
control_send(control_client, controlVersionCmd, strlen(controlVersionCmd),
|
||||
controlVersionString, strlen(controlVersionString));
|
||||
|
||||
const char *deviceCmd = "DeviceName";
|
||||
|
||||
control_send(control_client, deviceCmd, strlen(deviceCmd),
|
||||
deviceName.c_str(), deviceName.size());
|
||||
|
||||
const char *versionCmd = "MangoHudVersion";
|
||||
const char *versionString = "MangoHud " MANGOHUD_VERSION;
|
||||
|
||||
control_send(control_client, versionCmd, strlen(versionCmd),
|
||||
versionString, strlen(versionString));
|
||||
|
||||
}
|
||||
|
||||
void control_client_check(int control, int& control_client, const std::string& deviceName)
|
||||
{
|
||||
/* Already connected, just return. */
|
||||
if (control_client >= 0){
|
||||
global_control_client = control_client;
|
||||
return;
|
||||
}
|
||||
|
||||
int socket = os_socket_accept(control);
|
||||
if (socket == -1) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != ECONNABORTED)
|
||||
fprintf(stderr, "ERROR on socket: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (socket >= 0) {
|
||||
os_socket_block(socket, false);
|
||||
control_client = socket;
|
||||
control_send_connection_string(control_client, deviceName);
|
||||
}
|
||||
}
|
||||
|
||||
static void control_client_disconnected(int& control_client)
|
||||
{
|
||||
os_socket_close(control_client);
|
||||
control_client = -1;
|
||||
}
|
||||
|
||||
void process_control_socket(int& control_client, overlay_params ¶ms)
|
||||
{
|
||||
if (control_client >= 0) {
|
||||
char buf[BUFSIZE];
|
||||
|
||||
while (true) {
|
||||
ssize_t n = os_socket_recv(control_client, buf, BUFSIZE, 0);
|
||||
|
||||
if (n == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
/* nothing to read, try again later */
|
||||
break;
|
||||
}
|
||||
|
||||
if (errno != ECONNRESET)
|
||||
fprintf(stderr, "ERROR on connection: %s\n", strerror(errno));
|
||||
|
||||
control_client_disconnected(control_client);
|
||||
} else if (n == 0) {
|
||||
/* recv() returns 0 when the client disconnects */
|
||||
control_client_disconnected(control_client);
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < n; i++) {
|
||||
process_char(control_client, params, buf[i]);
|
||||
}
|
||||
|
||||
/* If we try to read BUFSIZE and receive BUFSIZE bytes from the
|
||||
* socket, there's a good chance that there's still more data to be
|
||||
* read, so we will try again. Otherwise, simply be done for this
|
||||
* iteration and try again on the next frame.
|
||||
*/
|
||||
if (n < BUFSIZE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <thread>
|
||||
#include <string.h>
|
||||
#include "cpu.h"
|
||||
#include <iostream>
|
||||
#define SystemProcessorPerformanceInformation 0x8
|
||||
#define SystemBasicInformation 0x0
|
||||
FILETIME last_userTime, last_kernelTime, last_idleTime;
|
||||
|
||||
uint64_t FileTimeToInt64( const FILETIME& ft ) {
|
||||
ULARGE_INTEGER uli = { 0 };
|
||||
uli.LowPart = ft.dwLowDateTime;
|
||||
uli.HighPart = ft.dwHighDateTime;
|
||||
return uli.QuadPart;
|
||||
}
|
||||
|
||||
bool CPUStats::UpdateCPUData()
|
||||
{
|
||||
#define NUMBER_OF_PROCESSORS (8)
|
||||
#define PROCESSOR_BUFFER_SIZE (NUMBER_OF_PROCESSORS * 8)
|
||||
static ULONG64 ProcessorIdleTimeBuffer [ PROCESSOR_BUFFER_SIZE ];
|
||||
|
||||
FILETIME IdleTime, KernelTime, UserTime;
|
||||
static unsigned long long PrevTotal = 0;
|
||||
static unsigned long long PrevIdle = 0;
|
||||
static unsigned long long PrevUser = 0;
|
||||
unsigned long long ThisTotal;
|
||||
unsigned long long ThisIdle, ThisKernel, ThisUser;
|
||||
unsigned long long TotalSinceLast, IdleSinceLast, UserSinceLast;
|
||||
|
||||
|
||||
// GET THE KERNEL / USER / IDLE times.
|
||||
// And oh, BTW, kernel time includes idle time
|
||||
GetSystemTimes( & IdleTime, & KernelTime, & UserTime);
|
||||
|
||||
ThisIdle = FileTimeToInt64(IdleTime);
|
||||
ThisKernel = FileTimeToInt64 (KernelTime);
|
||||
ThisUser = FileTimeToInt64 (UserTime);
|
||||
|
||||
ThisTotal = ThisKernel + ThisUser;
|
||||
TotalSinceLast = ThisTotal - PrevTotal;
|
||||
IdleSinceLast = ThisIdle - PrevIdle;
|
||||
UserSinceLast = ThisUser - PrevUser;
|
||||
double Headroom;
|
||||
Headroom = (double)IdleSinceLast / (double)TotalSinceLast ;
|
||||
double Load;
|
||||
Load = 1.0 - Headroom;
|
||||
Headroom *= 100.0; // to make it percent
|
||||
Load *= 100.0; // percent
|
||||
|
||||
PrevTotal = ThisTotal;
|
||||
PrevIdle = ThisIdle;
|
||||
PrevUser = ThisUser;
|
||||
|
||||
// print results to output window of VS when run in Debug
|
||||
m_cpuDataTotal.percent = Load;
|
||||
return true;
|
||||
}
|
||||
CPUStats::CPUStats()
|
||||
{
|
||||
}
|
||||
CPUStats::~CPUStats()
|
||||
{
|
||||
}
|
||||
CPUStats cpuStats;
|
File diff suppressed because it is too large
Load Diff
@ -1,370 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef MANGOHUD_DBUS_HELPERS
|
||||
#define MANGOHUD_DBUS_HELPERS
|
||||
|
||||
#include <vector>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "loaders/loader_dbus.h"
|
||||
|
||||
namespace DBus_helpers {
|
||||
namespace detail {
|
||||
// clang-format off
|
||||
template<class T> struct dbus_type_traits{};
|
||||
template<> struct dbus_type_traits<bool> { const int value = DBUS_TYPE_BOOLEAN; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<uint8_t> { const int value = DBUS_TYPE_BYTE; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<uint16_t> { const int value = DBUS_TYPE_UINT16; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<uint32_t> { const int value = DBUS_TYPE_UINT32; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<uint64_t> { const int value = DBUS_TYPE_UINT64; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<int16_t> { const int value = DBUS_TYPE_INT16; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<int32_t> { const int value = DBUS_TYPE_INT32; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<int64_t> { const int value = DBUS_TYPE_INT64; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<double> { const int value = DBUS_TYPE_DOUBLE; const bool is_fixed = true; };
|
||||
template<> struct dbus_type_traits<const char*> { const int value = DBUS_TYPE_STRING; const bool is_fixed = false; };
|
||||
// clang-format on
|
||||
|
||||
template <class T>
|
||||
const int dbus_type_identifier = dbus_type_traits<T>().value;
|
||||
|
||||
template <class T>
|
||||
const bool is_fixed = dbus_type_traits<T>().is_fixed;
|
||||
} // namespace detail
|
||||
|
||||
class DBusMessageIter_wrap {
|
||||
public:
|
||||
DBusMessageIter_wrap(DBusMessage* msg, libdbus_loader* loader);
|
||||
DBusMessageIter_wrap(DBusMessageIter iter, libdbus_loader* loader);
|
||||
|
||||
// Type accessors
|
||||
int type() const noexcept { return m_type; }
|
||||
bool is_unsigned() const noexcept;
|
||||
bool is_signed() const noexcept;
|
||||
bool is_string() const noexcept;
|
||||
bool is_double() const noexcept;
|
||||
bool is_primitive() const noexcept;
|
||||
bool is_array() const noexcept;
|
||||
operator bool() const noexcept { return type() != DBUS_TYPE_INVALID; }
|
||||
|
||||
// Value accessors
|
||||
// Primitives
|
||||
template <class T>
|
||||
auto get_primitive() -> T;
|
||||
auto get_unsigned() -> uint64_t;
|
||||
auto get_signed() -> int64_t;
|
||||
auto get_stringified() -> std::string;
|
||||
// Composites
|
||||
auto get_array_iter() -> DBusMessageIter_wrap;
|
||||
auto get_dict_entry_iter() -> DBusMessageIter_wrap;
|
||||
|
||||
// Looping
|
||||
template <class Callable>
|
||||
void array_for_each(Callable);
|
||||
template <class Callable>
|
||||
void array_for_each_stringify(Callable);
|
||||
template <class T, class Callable>
|
||||
void array_for_each_value(Callable);
|
||||
|
||||
template <class Callable>
|
||||
void string_map_for_each(Callable);
|
||||
template <class Callable>
|
||||
void string_multimap_for_each_stringify(Callable);
|
||||
|
||||
auto next() -> DBusMessageIter_wrap&;
|
||||
|
||||
private:
|
||||
DBusMessageIter resolve_variants() {
|
||||
auto iter = m_Iter;
|
||||
auto field_type = m_DBus->message_iter_get_arg_type(&m_Iter);
|
||||
while (field_type == DBUS_TYPE_VARIANT) {
|
||||
m_DBus->message_iter_recurse(&iter, &iter);
|
||||
field_type = m_DBus->message_iter_get_arg_type(&iter);
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
DBusMessageIter m_Iter;
|
||||
DBusMessageIter m_resolved_iter;
|
||||
int m_type;
|
||||
libdbus_loader* m_DBus;
|
||||
};
|
||||
|
||||
DBusMessageIter_wrap::DBusMessageIter_wrap(DBusMessage* msg,
|
||||
libdbus_loader* loader) {
|
||||
m_DBus = loader;
|
||||
if (msg) {
|
||||
m_DBus->message_iter_init(msg, &m_Iter);
|
||||
m_resolved_iter = resolve_variants();
|
||||
m_type = m_DBus->message_iter_get_arg_type(&m_resolved_iter);
|
||||
} else {
|
||||
m_type = DBUS_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
DBusMessageIter_wrap::DBusMessageIter_wrap(DBusMessageIter iter,
|
||||
libdbus_loader* loader)
|
||||
: m_Iter(iter), m_DBus(loader) {
|
||||
m_resolved_iter = resolve_variants();
|
||||
m_type = m_DBus->message_iter_get_arg_type(&m_resolved_iter);
|
||||
}
|
||||
|
||||
bool DBusMessageIter_wrap::is_unsigned() const noexcept {
|
||||
return ((type() == DBUS_TYPE_BYTE) || (type() == DBUS_TYPE_INT16) ||
|
||||
(type() == DBUS_TYPE_INT32) || (type() == DBUS_TYPE_INT64));
|
||||
}
|
||||
|
||||
bool DBusMessageIter_wrap::is_signed() const noexcept {
|
||||
return ((type() == DBUS_TYPE_INT16) || (type() == DBUS_TYPE_INT32) ||
|
||||
(type() == DBUS_TYPE_INT64));
|
||||
}
|
||||
|
||||
bool DBusMessageIter_wrap::is_string() const noexcept {
|
||||
return (type() == DBUS_TYPE_STRING);
|
||||
}
|
||||
|
||||
bool DBusMessageIter_wrap::is_double() const noexcept {
|
||||
return (type() == DBUS_TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
bool DBusMessageIter_wrap::is_primitive() const noexcept {
|
||||
return (is_double() || is_signed() || is_unsigned() || is_string());
|
||||
}
|
||||
|
||||
bool DBusMessageIter_wrap::is_array() const noexcept {
|
||||
return (type() == DBUS_TYPE_ARRAY);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto DBusMessageIter_wrap::get_primitive() -> T {
|
||||
auto requested_type = detail::dbus_type_identifier<T>;
|
||||
if (type() == DBUS_TYPE_OBJECT_PATH && requested_type == DBUS_TYPE_STRING) {
|
||||
// no special type, just a string
|
||||
}
|
||||
else if (requested_type != type()) {
|
||||
SPDLOG_ERROR("Type mismatch: '{}' vs '{}'",
|
||||
((char)requested_type), (char)type());
|
||||
#ifndef NDEBUG
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
return T();
|
||||
}
|
||||
|
||||
T ret;
|
||||
m_DBus->message_iter_get_basic(&m_resolved_iter, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
auto DBusMessageIter_wrap::get_primitive<std::string>() -> std::string {
|
||||
auto s = get_primitive<const char*>();
|
||||
if (!s)
|
||||
return std::string();
|
||||
return std::string(s);
|
||||
}
|
||||
|
||||
uint64_t DBusMessageIter_wrap::get_unsigned() {
|
||||
auto t = type();
|
||||
switch (t) {
|
||||
case DBUS_TYPE_BYTE:
|
||||
return get_primitive<uint8_t>();
|
||||
case DBUS_TYPE_UINT16:
|
||||
return get_primitive<uint16_t>();
|
||||
case DBUS_TYPE_UINT32:
|
||||
return get_primitive<uint32_t>();
|
||||
case DBUS_TYPE_UINT64:
|
||||
return get_primitive<uint64_t>();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t DBusMessageIter_wrap::get_signed() {
|
||||
auto t = type();
|
||||
switch (t) {
|
||||
case DBUS_TYPE_INT16:
|
||||
return get_primitive<int16_t>();
|
||||
case DBUS_TYPE_INT32:
|
||||
return get_primitive<int32_t>();
|
||||
case DBUS_TYPE_INT64:
|
||||
return get_primitive<int64_t>();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto DBusMessageIter_wrap::get_stringified() -> std::string {
|
||||
if (is_string()) return get_primitive<std::string>();
|
||||
if (is_unsigned()) return std::to_string(get_unsigned());
|
||||
if (is_signed()) return std::to_string(get_signed());
|
||||
if (is_double()) return std::to_string(get_primitive<double>());
|
||||
SPDLOG_ERROR("stringify failed");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
auto DBusMessageIter_wrap::get_array_iter() -> DBusMessageIter_wrap {
|
||||
if (!is_array()) {
|
||||
SPDLOG_ERROR("Not an array; {}", (char)type());
|
||||
return DBusMessageIter_wrap(DBusMessageIter{}, m_DBus);
|
||||
}
|
||||
|
||||
DBusMessageIter ret;
|
||||
m_DBus->message_iter_recurse(&m_resolved_iter, &ret);
|
||||
return DBusMessageIter_wrap(ret, m_DBus);
|
||||
}
|
||||
|
||||
auto DBusMessageIter_wrap::get_dict_entry_iter() -> DBusMessageIter_wrap {
|
||||
if (type() != DBUS_TYPE_DICT_ENTRY) {
|
||||
SPDLOG_ERROR("Not a dict entry {}", (char)type());
|
||||
return DBusMessageIter_wrap(DBusMessageIter{}, m_DBus);
|
||||
}
|
||||
|
||||
DBusMessageIter ret;
|
||||
m_DBus->message_iter_recurse(&m_resolved_iter, &ret);
|
||||
return DBusMessageIter_wrap(ret, m_DBus);
|
||||
}
|
||||
|
||||
template <class T, class Callable>
|
||||
void DBusMessageIter_wrap::array_for_each_value(Callable action) {
|
||||
auto iter = get_array_iter();
|
||||
for (; iter; iter.next()) {
|
||||
action(iter.get_primitive<T>());
|
||||
}
|
||||
}
|
||||
|
||||
template <class Callable>
|
||||
void DBusMessageIter_wrap::array_for_each(Callable action) {
|
||||
auto iter = get_array_iter();
|
||||
for (; iter; iter.next()) {
|
||||
action(iter);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Callable>
|
||||
void DBusMessageIter_wrap::array_for_each_stringify(Callable action) {
|
||||
auto iter = get_array_iter();
|
||||
for (; iter; iter.next()) {
|
||||
action(iter.get_stringified());
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void DBusMessageIter_wrap::string_map_for_each(T action) {
|
||||
auto iter = get_array_iter();
|
||||
for (; iter; iter.next()) {
|
||||
auto it = iter.get_dict_entry_iter();
|
||||
auto key = it.get_primitive<std::string>();
|
||||
|
||||
it.next();
|
||||
action(key, it);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void DBusMessageIter_wrap::string_multimap_for_each_stringify(T action) {
|
||||
string_map_for_each([&action](const std::string& key, DBusMessageIter_wrap it) {
|
||||
if (it.is_array()) {
|
||||
it.array_for_each_stringify(
|
||||
[&](const std::string& val) { action(key, val); });
|
||||
} else if (it.is_primitive()) {
|
||||
action(key, it.get_stringified());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
auto DBusMessageIter_wrap::next() -> DBusMessageIter_wrap& {
|
||||
if (!*this) return *this;
|
||||
m_DBus->message_iter_next(&m_Iter);
|
||||
// Resolve any variants
|
||||
m_resolved_iter = resolve_variants();
|
||||
m_type = m_DBus->message_iter_get_arg_type(&m_resolved_iter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
class DBusMessage_wrap {
|
||||
public:
|
||||
DBusMessage_wrap(DBusMessage* msg, libdbus_loader* ldr, bool owning = false)
|
||||
: m_owning(owning), m_msg(msg), m_DBus(ldr) {}
|
||||
|
||||
~DBusMessage_wrap() { free_if_owning(); }
|
||||
|
||||
DBusMessage_wrap(const DBusMessage_wrap&) = delete;
|
||||
DBusMessage_wrap(DBusMessage_wrap&&) = default;
|
||||
|
||||
operator bool() const noexcept { return m_msg != nullptr; }
|
||||
|
||||
template <class T>
|
||||
DBusMessage_wrap& argument(T arg);
|
||||
|
||||
DBusMessage_wrap send_with_reply_and_block(DBusConnection* conn,
|
||||
int timeout);
|
||||
|
||||
DBusMessageIter_wrap iter() { return DBusMessageIter_wrap(m_msg, m_DBus); }
|
||||
|
||||
static DBusMessage_wrap new_method_call(const std::string& bus_name,
|
||||
const std::string& path,
|
||||
const std::string& iface,
|
||||
const std::string& method,
|
||||
libdbus_loader* loader);
|
||||
|
||||
private:
|
||||
void free_if_owning();
|
||||
bool m_owning;
|
||||
DBusMessage* m_msg;
|
||||
libdbus_loader* m_DBus;
|
||||
std::vector<std::string> m_args;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
DBusMessage_wrap& DBusMessage_wrap::argument(T arg) {
|
||||
if (!m_msg) return *this;
|
||||
if (!m_DBus->message_append_args(m_msg, detail::dbus_type_identifier<T>,
|
||||
&arg, DBUS_TYPE_INVALID)) {
|
||||
free_if_owning();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <>
|
||||
DBusMessage_wrap& DBusMessage_wrap::argument<const std::string&>(
|
||||
const std::string& str) {
|
||||
return argument<const char*>(str.c_str());
|
||||
}
|
||||
|
||||
DBusMessage_wrap DBusMessage_wrap::send_with_reply_and_block(
|
||||
DBusConnection* conn, int timeout) {
|
||||
if (!m_msg) {
|
||||
return DBusMessage_wrap(nullptr, m_DBus);
|
||||
}
|
||||
DBusError err;
|
||||
m_DBus->error_init(&err);
|
||||
auto reply = m_DBus->connection_send_with_reply_and_block(conn, m_msg,
|
||||
timeout, &err);
|
||||
if (reply == nullptr) {
|
||||
SPDLOG_ERROR("[{}]: {}", __func__, err.message);
|
||||
free_if_owning();
|
||||
m_DBus->error_free(&err);
|
||||
}
|
||||
return DBusMessage_wrap(reply, m_DBus, true);
|
||||
}
|
||||
|
||||
DBusMessage_wrap DBusMessage_wrap::new_method_call(const std::string& bus_name,
|
||||
const std::string& path,
|
||||
const std::string& iface,
|
||||
const std::string& method,
|
||||
libdbus_loader* loader) {
|
||||
auto msg = loader->message_new_method_call(
|
||||
(bus_name.empty()) ? nullptr : bus_name.c_str(), path.c_str(),
|
||||
(iface.empty()) ? nullptr : iface.c_str(), method.c_str());
|
||||
return DBusMessage_wrap(msg, loader, true);
|
||||
}
|
||||
|
||||
void DBusMessage_wrap::free_if_owning() {
|
||||
if (m_msg and m_owning) {
|
||||
m_DBus->message_unref(m_msg);
|
||||
}
|
||||
m_msg = nullptr;
|
||||
}
|
||||
} // namespace DBus_helpers
|
||||
|
||||
#endif // MANGOHUD_DBUS_HELPERS
|
@ -1,225 +0,0 @@
|
||||
#include "device.h"
|
||||
#include <filesystem.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
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;
|
||||
bool check_gamepad = false;
|
||||
bool check_mouse = false;
|
||||
int device_count = 0;
|
||||
int xbox_count = 0;
|
||||
int ds4_count = 0;
|
||||
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"};
|
||||
|
||||
static bool operator<(const device_batt& a, const device_batt& b)
|
||||
{
|
||||
return a.name < b.name;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
ds4_count = 0;
|
||||
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
|
||||
if (std::find(params.device_battery.begin(), params.device_battery.end(), "gamepad") != params.device_battery.end()){
|
||||
check_gamepad = true;
|
||||
//CHECK XONE AND XPADNEO DEVICES
|
||||
for (string n : xbox_paths ) {
|
||||
if (fileName.find(n) != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
xbox_count += 1;
|
||||
}
|
||||
}
|
||||
//CHECK FOR DUAL SHOCK 4 DEVICES
|
||||
if (fileName.find("sony_controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
ds4_count +=1 ;
|
||||
}
|
||||
if (fileName.find("ps-controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
ds5_count +=1 ;
|
||||
}
|
||||
//CHECK FOR NINTENDO SWITCH DEVICES
|
||||
if (fileName.find("nintendo_switch_controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
switch_count += 1;
|
||||
}
|
||||
//CHECK * BITDO DEVICES
|
||||
if (fileName.find("hid-e4") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
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()) {
|
||||
check_mouse = true;
|
||||
if (fileName.find("hidpp_battery") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void device_info () {
|
||||
std::unique_lock<std::mutex> l(device_lock);
|
||||
device_count = 0;
|
||||
device_data.clear();
|
||||
//gamepad counters
|
||||
int xbox_counter = 0;
|
||||
int ds4_counter = 0;
|
||||
int ds5_counter = 0;
|
||||
int switch_counter = 0;
|
||||
int bitdo_counter = 0;
|
||||
int shield_counter = 0;
|
||||
|
||||
for (auto &path : list ) {
|
||||
//Set devices paths
|
||||
std::string capacity = path + "/capacity";
|
||||
std::string capacity_level = path + "/capacity_level";
|
||||
std::string status = path + "/status";
|
||||
std::string model = path + "/model_name";
|
||||
std::ifstream input_capacity(capacity);
|
||||
std::ifstream input_capacity_level(capacity_level);
|
||||
std::ifstream input_status(status);
|
||||
std::ifstream device_name(model);
|
||||
std::string line;
|
||||
|
||||
device_data.push_back(device_batt());
|
||||
|
||||
// GAMEPADS
|
||||
//Xone and xpadneo devices
|
||||
if (check_gamepad == true) {
|
||||
if (path.find("gip") != std::string::npos || path.find("xpadneo") != std::string::npos) {
|
||||
if (xbox_count == 1 )
|
||||
device_data[device_count].name = "XBOX PAD";
|
||||
else
|
||||
device_data[device_count].name = "XBOX PAD-" + to_string(xbox_counter + 1);
|
||||
xbox_counter++;
|
||||
}
|
||||
//DualShock 4 devices
|
||||
if (path.find("sony_controller") != std::string::npos) {
|
||||
if (ds4_count == 1)
|
||||
device_data[device_count].name = "DS4 PAD";
|
||||
else
|
||||
device_data[device_count].name = "DS4 PAD-" + to_string(ds4_counter + 1);
|
||||
ds4_counter++;
|
||||
}
|
||||
//DualSense 5 devices
|
||||
//Dual Shock 4 added to hid-playstation in Linux 6.2
|
||||
if (path.find("ps-controller") != std::string::npos) {
|
||||
if (ds5_count == 1)
|
||||
device_data[device_count].name = "DS4/5 PAD";
|
||||
else
|
||||
device_data[device_count].name = "DS4/5 PAD-" + to_string(ds5_counter + 1);
|
||||
ds5_counter++;
|
||||
}
|
||||
//Nintendo Switch devices
|
||||
if (path.find("nintendo_switch_controller") != std::string::npos) {
|
||||
if (switch_count == 1)
|
||||
device_data[device_count].name = "SWITCH PAD";
|
||||
else
|
||||
device_data[device_count].name = "SWITCH PAD-" + to_string(switch_counter + 1);
|
||||
switch_counter++;
|
||||
}
|
||||
//8bitdo devices
|
||||
if (path.find("hid-e4") != std::string::npos) {
|
||||
if (bitdo_count == 1)
|
||||
device_data[device_count].name = "8BITDO PAD";
|
||||
else
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
//Get device charging status
|
||||
if (std::getline(input_status, line)) {
|
||||
if (line == "Charging" || line == "Full")
|
||||
device_data[device_count].is_charging = true;
|
||||
}
|
||||
//Get device Battery
|
||||
if (fs::exists(capacity)) {
|
||||
if (std::getline(input_capacity, line)) {
|
||||
device_data[device_count].battery_percent = line;
|
||||
device_data[device_count].report_percent = true;
|
||||
switch(std::stoi(line)) {
|
||||
case 0 ... 25:
|
||||
device_data[device_count].battery = "Low";
|
||||
break;
|
||||
case 26 ... 49:
|
||||
device_data[device_count].battery = "Normal";
|
||||
break;
|
||||
case 50 ... 74:
|
||||
device_data[device_count].battery = "High";
|
||||
break;
|
||||
case 75 ... 100:
|
||||
device_data[device_count].battery = "Full";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (std::getline(input_capacity_level, line)) {
|
||||
device_data[device_count].battery = line;
|
||||
}
|
||||
}
|
||||
std::sort(device_data.begin(), device_data.end());
|
||||
device_count += 1;
|
||||
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef MANGOHUD_DEVICE_H
|
||||
#define MANGOHUD_DEVICE_H
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "overlay_params.h"
|
||||
struct overlay_params;
|
||||
struct device_batt {
|
||||
std::string battery;
|
||||
std::string name;
|
||||
bool report_percent;
|
||||
std::string battery_percent;
|
||||
bool is_charging;
|
||||
};
|
||||
|
||||
extern std::vector<device_batt> device_data;
|
||||
extern std::mutex device_lock;
|
||||
|
||||
extern bool device_found;
|
||||
extern int device_count;
|
||||
void device_update(const overlay_params& params);
|
||||
void device_info();
|
||||
|
||||
|
||||
#endif // MANGOHUD_DEVICE_H
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
enum EngineTypes
|
||||
{
|
||||
UNKNOWN,
|
||||
|
||||
OPENGL,
|
||||
VULKAN,
|
||||
|
||||
DXVK,
|
||||
VKD3D,
|
||||
DAMAVAND,
|
||||
ZINK,
|
||||
|
||||
WINED3D,
|
||||
FERAL3D,
|
||||
TOGL,
|
||||
|
||||
GAMESCOPE
|
||||
};
|
||||
|
||||
extern const char* engines[];
|
||||
extern const char* engines_short[];
|
@ -1,63 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef MANGOHUD_FCAT_H
|
||||
#define MANGOHUD_FCAT_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
#include <array>
|
||||
|
||||
#include "timing.hpp"
|
||||
|
||||
#include "overlay_params.h"
|
||||
#include "overlay.h"
|
||||
|
||||
struct fcatoverlay{
|
||||
const struct overlay_params* params = nullptr;
|
||||
const std::array<const ImColor,16> sequence={{{255, 255, 255},{0, 255, 0},{0, 0, 255},{255, 0, 0},{0, 128, 128},{0, 0, 128},{0, 128, 0},{0, 255, 255},{128, 0, 0},{192, 192, 192},{128, 0, 128},{128, 128, 0},{128, 128, 128},{255, 0, 255},{255, 255, 0},{255, 128, 0}}};
|
||||
void update(const struct overlay_params* params_){
|
||||
params=params_;
|
||||
};
|
||||
ImColor get_next_color (const swapchain_stats& sw_stats){
|
||||
size_t currentColor = sw_stats.n_frames % 16;// should probably be sequence.size(); but this doesn't matter as all FCAT analysis tools use this exact 16 colour sequence.
|
||||
ImColor output = sequence[currentColor];
|
||||
return output;
|
||||
};
|
||||
std::array<ImVec2,3> get_overlay_corners()
|
||||
{
|
||||
unsigned short screen_edge=params->fcat_screen_edge;
|
||||
auto window_size = ImVec2(params->fcat_overlay_width,ImGui::GetIO().DisplaySize.y);
|
||||
auto p_min = ImVec2(0.,0.);
|
||||
auto p_max = ImVec2(window_size.x,ImGui::GetIO().DisplaySize.y);
|
||||
//Switch the used screen edge, this enables capture from devices with any screen orientation.
|
||||
//This goes counter-clockwise from the left edge (0)
|
||||
switch (screen_edge)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
window_size = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.x);
|
||||
p_min = ImVec2(0,ImGui::GetIO().DisplaySize.y - window_size.y);
|
||||
p_max = ImVec2(ImGui::GetIO().DisplaySize.x,ImGui::GetIO().DisplaySize.y);
|
||||
break;
|
||||
case 2:
|
||||
window_size = ImVec2(window_size.x,ImGui::GetIO().DisplaySize.y);
|
||||
p_min = ImVec2(ImGui::GetIO().DisplaySize.x-window_size.x,0);
|
||||
p_max = ImVec2(ImGui::GetIO().DisplaySize.x,ImGui::GetIO().DisplaySize.y);
|
||||
break;
|
||||
case 3:
|
||||
window_size = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.x);
|
||||
p_min = ImVec2(0,0);
|
||||
p_max = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.y);
|
||||
break;
|
||||
}
|
||||
std::array<ImVec2,3> output={{p_min,p_max,window_size}};
|
||||
return output;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
@ -1,48 +0,0 @@
|
||||
#include "file_utils.h"
|
||||
#include "string_utils.h"
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
std::vector<std::string> ls(const char* root, const char* prefix, LS_FLAGS flags)
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
return list;
|
||||
}
|
||||
|
||||
bool file_exists(const std::string& path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dir_exists(const std::string& path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string get_exe_path()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string get_wine_exe_name(bool keep_ext)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string get_home_dir()
|
||||
{
|
||||
std::string path;
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string get_data_dir()
|
||||
{
|
||||
std::string path;
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string get_config_dir()
|
||||
{
|
||||
std::string path;
|
||||
return path;
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
#include <cstdint>
|
||||
#include "overlay.h"
|
||||
#include "file_utils.h"
|
||||
#include "font_default.h"
|
||||
#include "IconsForkAwesome.h"
|
||||
#include "forkawesome.h"
|
||||
|
||||
void create_fonts(ImFontAtlas* font_atlas, const overlay_params& params, ImFont*& small_font, ImFont*& text_font)
|
||||
{
|
||||
auto& io = ImGui::GetIO();
|
||||
if (!font_atlas)
|
||||
font_atlas = io.Fonts;
|
||||
font_atlas->Clear();
|
||||
|
||||
ImGui::GetIO().FontGlobalScale = params.font_scale; // set here too so ImGui::CalcTextSize is correct
|
||||
float font_size = params.font_size;
|
||||
if (font_size < FLT_EPSILON)
|
||||
font_size = 24;
|
||||
|
||||
float font_size_text = params.font_size_text;
|
||||
if (font_size_text < FLT_EPSILON)
|
||||
font_size_text = font_size;
|
||||
static const ImWchar default_range[] =
|
||||
{
|
||||
0x0020, 0x00FF, // Basic Latin + Latin Supplement
|
||||
0x2018, 0x201F, // Bunch of quotation marks
|
||||
//0x0100, 0x017F, // Latin Extended-A
|
||||
//0x2103, 0x2103, // Degree Celsius
|
||||
//0x2109, 0x2109, // Degree Fahrenheit
|
||||
0,
|
||||
};
|
||||
// Load Icon file and merge to exisitng font
|
||||
ImFontConfig config;
|
||||
config.MergeMode = true;
|
||||
// ImGui changed OversampleH default to 2, but it appears to sometimes cause
|
||||
// crashing issues in 32bit applications.
|
||||
config.OversampleH = 3;
|
||||
static const ImWchar icon_ranges[] = { ICON_MIN_FK, ICON_MAX_FK, 0 };
|
||||
|
||||
ImVector<ImWchar> glyph_ranges;
|
||||
ImFontGlyphRangesBuilder builder;
|
||||
builder.AddRanges(font_atlas->GetGlyphRangesDefault());
|
||||
if (params.font_glyph_ranges & FG_KOREAN)
|
||||
builder.AddRanges(font_atlas->GetGlyphRangesKorean());
|
||||
if (params.font_glyph_ranges & FG_CHINESE_FULL)
|
||||
builder.AddRanges(font_atlas->GetGlyphRangesChineseFull());
|
||||
if (params.font_glyph_ranges & FG_CHINESE_SIMPLIFIED)
|
||||
builder.AddRanges(font_atlas->GetGlyphRangesChineseSimplifiedCommon());
|
||||
if (params.font_glyph_ranges & FG_JAPANESE)
|
||||
builder.AddRanges(font_atlas->GetGlyphRangesJapanese()); // Not exactly Shift JIS compatible?
|
||||
if (params.font_glyph_ranges & FG_CYRILLIC)
|
||||
builder.AddRanges(font_atlas->GetGlyphRangesCyrillic());
|
||||
if (params.font_glyph_ranges & FG_THAI)
|
||||
builder.AddRanges(font_atlas->GetGlyphRangesThai());
|
||||
if (params.font_glyph_ranges & FG_VIETNAMESE)
|
||||
builder.AddRanges(font_atlas->GetGlyphRangesVietnamese());
|
||||
if (params.font_glyph_ranges & FG_LATIN_EXT_A) {
|
||||
constexpr ImWchar latin_ext_a[] { 0x0100, 0x017F, 0 };
|
||||
builder.AddRanges(latin_ext_a);
|
||||
}
|
||||
if (params.font_glyph_ranges & FG_LATIN_EXT_B) {
|
||||
constexpr ImWchar latin_ext_b[] { 0x0180, 0x024F, 0 };
|
||||
builder.AddRanges(latin_ext_b);
|
||||
}
|
||||
builder.BuildRanges(&glyph_ranges);
|
||||
|
||||
bool same_font = (params.font_file == params.font_file_text || params.font_file_text.empty());
|
||||
bool same_size = (font_size == font_size_text);
|
||||
|
||||
// ImGui takes ownership of the data, no need to free it
|
||||
if (!params.font_file.empty() && file_exists(params.font_file)) {
|
||||
font_atlas->AddFontFromFileTTF(params.font_file.c_str(), font_size, nullptr, same_font && same_size ? glyph_ranges.Data : default_range);
|
||||
font_atlas->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size, &config, icon_ranges);
|
||||
if (params.no_small_font)
|
||||
small_font = font_atlas->Fonts[0];
|
||||
else {
|
||||
small_font = font_atlas->AddFontFromFileTTF(params.font_file.c_str(), font_size * 0.55f, nullptr, default_range);
|
||||
font_atlas->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size * 0.55f, &config, icon_ranges);
|
||||
}
|
||||
} else {
|
||||
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
|
||||
font_atlas->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size, nullptr, default_range);
|
||||
font_atlas->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size, &config, icon_ranges);
|
||||
if (params.no_small_font)
|
||||
small_font = font_atlas->Fonts[0];
|
||||
else {
|
||||
small_font = font_atlas->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size * 0.55f, nullptr, default_range);
|
||||
font_atlas->AddFontFromMemoryCompressedBase85TTF(forkawesome_compressed_data_base85, font_size * 0.55f, &config, icon_ranges);
|
||||
}
|
||||
}
|
||||
|
||||
auto font_file_text = params.font_file_text;
|
||||
if (font_file_text.empty())
|
||||
font_file_text = params.font_file;
|
||||
|
||||
if ((!same_font || !same_size) && file_exists(font_file_text))
|
||||
text_font = font_atlas->AddFontFromFileTTF(font_file_text.c_str(), font_size_text, nullptr, glyph_ranges.Data);
|
||||
else
|
||||
text_font = font_atlas->Fonts[0];
|
||||
|
||||
font_atlas->Build();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,165 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <mesa/util/os_time.h>
|
||||
#include <numeric>
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
#include <condition_variable>
|
||||
#include <stdexcept>
|
||||
#include <iomanip>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
struct metric_t {
|
||||
std::string name;
|
||||
float value;
|
||||
std::string display_name;
|
||||
};
|
||||
|
||||
class fpsMetrics {
|
||||
private:
|
||||
std::vector<std::pair<uint64_t, float>> fps_stats;
|
||||
std::thread thread;
|
||||
std::mutex mtx;
|
||||
std::condition_variable cv;
|
||||
bool run = false;
|
||||
bool thread_init = false;
|
||||
bool terminate = false;
|
||||
bool resetting = false;
|
||||
|
||||
void calculate(){
|
||||
thread_init = true;
|
||||
while (true){
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
cv.wait(lock, [this] { return run; });
|
||||
|
||||
if (terminate)
|
||||
break;
|
||||
|
||||
std::vector<float> sorted_values;
|
||||
for (const auto& p : fps_stats)
|
||||
sorted_values.push_back(p.second);
|
||||
|
||||
std::sort(sorted_values.begin(), sorted_values.end());
|
||||
|
||||
auto it = metrics.begin();
|
||||
while (it != metrics.end()) {
|
||||
if (it->name == "AVG") {
|
||||
it->display_name = it->name;
|
||||
if (!fps_stats.empty()) {
|
||||
float sum = std::accumulate(fps_stats.begin(), fps_stats.end(), 0.0f,
|
||||
[](float acc, const std::pair<uint64_t, float>& p) {
|
||||
return acc + p.second;
|
||||
});
|
||||
it->value = sum / fps_stats.size();
|
||||
++it;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
float val = std::stof(it->name);
|
||||
if (val <= 0 || val >= 1 ) {
|
||||
SPDLOG_DEBUG("Failed to use fps metric, it's out of range {}", it->name);
|
||||
it = metrics.erase(it);
|
||||
break;
|
||||
}
|
||||
float multiplied_val = val * 100;
|
||||
std::ostringstream stream;
|
||||
if (multiplied_val == static_cast<int>(multiplied_val)) {
|
||||
stream << std::fixed << std::setprecision(0) << multiplied_val << "%";
|
||||
} else {
|
||||
stream << std::fixed << std::setprecision(1) << multiplied_val << "%";
|
||||
}
|
||||
it->display_name = stream.str();
|
||||
uint64_t idx = val * sorted_values.size() - 1;
|
||||
if (idx >= sorted_values.size())
|
||||
break;
|
||||
|
||||
it->value = sorted_values[idx];
|
||||
++it;
|
||||
} catch (const std::invalid_argument& e) {
|
||||
SPDLOG_DEBUG("Failed to use fps metric value {}", it->name);
|
||||
it = metrics.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::vector<metric_t> metrics;
|
||||
|
||||
fpsMetrics(std::vector<std::string> values){
|
||||
// capitalize string
|
||||
for (auto& val : values){
|
||||
for(char& c : val) {
|
||||
c = std::toupper(static_cast<unsigned char>(c));
|
||||
}
|
||||
|
||||
metrics.push_back({val, 0.0f});
|
||||
}
|
||||
|
||||
if (!thread_init){
|
||||
thread = std::thread(&fpsMetrics::calculate, this);
|
||||
}
|
||||
};
|
||||
|
||||
void update(uint64_t now, double fps){
|
||||
if (resetting)
|
||||
return;
|
||||
|
||||
if (fps > 0.0001)
|
||||
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
|
||||
if (now >= ten_minute_duration) {
|
||||
uint64_t ten_minutes_ago = now - ten_minute_duration;
|
||||
|
||||
fps_stats.erase(
|
||||
std::remove_if(
|
||||
fps_stats.begin(),
|
||||
fps_stats.end(),
|
||||
[ten_minutes_ago](const std::pair<uint64_t, float>& entry) {
|
||||
return entry.first < ten_minutes_ago;
|
||||
}
|
||||
),
|
||||
fps_stats.end()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void update_thread(){
|
||||
if (resetting)
|
||||
return;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
run = true;
|
||||
}
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
void reset_metrics(){
|
||||
resetting = true;
|
||||
while (run){}
|
||||
fps_stats.clear();
|
||||
resetting = false;
|
||||
}
|
||||
|
||||
~fpsMetrics(){
|
||||
terminate = true;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
run = true;
|
||||
}
|
||||
cv.notify_one();
|
||||
thread.join();
|
||||
}
|
||||
};
|
||||
|
||||
extern std::unique_ptr<fpsMetrics> fpsmetrics;
|
@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef MANGOHUD_GL_IMGUI_HUD_H
|
||||
#define MANGOHUD_GL_IMGUI_HUD_H
|
||||
|
||||
#include "overlay.h"
|
||||
#include "gl_renderer.h"
|
||||
|
||||
namespace MangoHud { namespace GL {
|
||||
|
||||
enum gl_wsi
|
||||
{
|
||||
GL_WSI_UNKNOWN,
|
||||
GL_WSI_GLX,
|
||||
GL_WSI_EGL,
|
||||
};
|
||||
|
||||
extern overlay_params params;
|
||||
void imgui_init();
|
||||
void imgui_create(void *ctx, const gl_wsi plat);
|
||||
void imgui_shutdown();
|
||||
void imgui_set_context(void *ctx, const gl_wsi plat);
|
||||
void imgui_render(unsigned int width, unsigned int height);
|
||||
|
||||
}} // namespace
|
||||
|
||||
#endif //MANGOHUD_GL_IMGUI_HUD_H
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
|
||||
namespace MangoHud { namespace GL {
|
||||
|
||||
extern overlay_params params;
|
||||
void imgui_init();
|
||||
void imgui_create(void *ctx);
|
||||
void imgui_shutdown();
|
||||
void imgui_set_context(void *ctx);
|
||||
void imgui_render(unsigned int width, unsigned int height);
|
||||
|
||||
}} // namespace
|
File diff suppressed because it is too large
Load Diff
@ -1,168 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <imgui.h>
|
||||
#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
|
||||
std::string name;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
struct overlay_params;
|
||||
class HudElements{
|
||||
public:
|
||||
struct swapchain_stats *sw_stats;
|
||||
struct overlay_params *params;
|
||||
struct exec_entry {
|
||||
int pos;
|
||||
std::string value;
|
||||
std::string ret;
|
||||
};
|
||||
float ralign_width;
|
||||
float old_scale;
|
||||
float res_width, res_height;
|
||||
bool is_vulkan = true, gamemode_bol = false, vkbasalt_bol = false;
|
||||
int place;
|
||||
int text_column = 1;
|
||||
int table_columns_count = 0;
|
||||
int g_fsrUpscale = -1;
|
||||
int g_fsrSharpness = -1;
|
||||
Clock::time_point last_exec;
|
||||
std::vector<std::pair<std::string, std::string>> options;
|
||||
std::vector<Function> ordered_functions;
|
||||
std::vector<float> gamescope_debug_latency {};
|
||||
std::vector<float> gamescope_debug_app {};
|
||||
int min, max, gpu_core_max, gpu_mem_max, cpu_temp_max, gpu_temp_max;
|
||||
const std::vector<std::string> permitted_params = {
|
||||
"gpu_load", "cpu_load", "gpu_core_clock", "gpu_mem_clock",
|
||||
"vram", "ram", "cpu_temp", "gpu_temp"
|
||||
};
|
||||
std::vector<exec_entry> exec_list;
|
||||
std::chrono::steady_clock::time_point overlay_start = std::chrono::steady_clock::now();
|
||||
uint32_t vendorID;
|
||||
int hdr_status = 0;
|
||||
int refresh = 0;
|
||||
unsigned int vsync = 10;
|
||||
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();
|
||||
void update_exec();
|
||||
int convert_to_fahrenheit(int celsius);
|
||||
static void version();
|
||||
static void time();
|
||||
static void gpu_stats();
|
||||
static void cpu_stats();
|
||||
static void core_load();
|
||||
static void io_stats();
|
||||
static void vram();
|
||||
static void ram();
|
||||
static void procmem();
|
||||
static void fps();
|
||||
static void engine_version();
|
||||
static void gpu_name();
|
||||
static void vulkan_driver();
|
||||
static void arch();
|
||||
static void wine();
|
||||
static void frame_timing();
|
||||
static void media_player();
|
||||
static void resolution();
|
||||
static void show_fps_limit();
|
||||
static void custom_text_center();
|
||||
static void custom_text();
|
||||
static void vkbasalt();
|
||||
static void gamemode();
|
||||
static void graphs();
|
||||
static void _exec();
|
||||
static void battery();
|
||||
static void fps_only();
|
||||
static void gamescope_fsr();
|
||||
static void gamescope_frame_timing();
|
||||
static void device_battery();
|
||||
static void frame_count();
|
||||
static void fan();
|
||||
static void throttling_status();
|
||||
static void exec_name();
|
||||
static void duration();
|
||||
static void fps_metrics();
|
||||
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);
|
||||
struct hud_colors {
|
||||
bool convert, update;
|
||||
ImVec4 cpu,
|
||||
gpu,
|
||||
vram,
|
||||
ram,
|
||||
swap,
|
||||
engine,
|
||||
io,
|
||||
frametime,
|
||||
background,
|
||||
text,
|
||||
media_player,
|
||||
wine,
|
||||
battery,
|
||||
gpu_load_low,
|
||||
gpu_load_med,
|
||||
gpu_load_high,
|
||||
cpu_load_low,
|
||||
cpu_load_med,
|
||||
cpu_load_high,
|
||||
fps_value_low,
|
||||
fps_value_med,
|
||||
fps_value_high,
|
||||
text_outline,
|
||||
network;
|
||||
} 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];
|
||||
else
|
||||
return vsync == 0 ? "OFF" : "ON";
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
extern HudElements HUDElements;
|
@ -1,132 +0,0 @@
|
||||
#include "intel.h"
|
||||
std::unique_ptr<Intel> intel;
|
||||
|
||||
void Intel::intel_gpu_thread(){
|
||||
init = true;
|
||||
static char stdout_buffer[1024];
|
||||
static FILE* intel_gpu_top;
|
||||
if (runtime)
|
||||
intel_gpu_top = popen("steam-runtime-launch-client --alongside-steam --host -- intel_gpu_top -J -s 500", "r");
|
||||
else
|
||||
intel_gpu_top = popen("intel_gpu_top -J -s 500", "r");
|
||||
|
||||
int num_line = 0;
|
||||
std::string buf;
|
||||
int num_iterations = 0;
|
||||
while (fgets(stdout_buffer, sizeof(stdout_buffer), intel_gpu_top)) {
|
||||
if (num_line > 0)
|
||||
buf += stdout_buffer;
|
||||
|
||||
num_line++;
|
||||
if (strlen(stdout_buffer) < 4 && !strchr(stdout_buffer, '{') && !strchr(stdout_buffer, ',')) {
|
||||
if (buf[0] != '{')
|
||||
buf = "{\n" + buf;
|
||||
|
||||
if (num_iterations > 0){
|
||||
buf += "\n}";
|
||||
json j = json::parse(buf);
|
||||
if (j.contains("engines"))
|
||||
if (j["engines"].contains("Render/3D/0"))
|
||||
if (j["engines"]["Render/3D/0"].contains("busy"))
|
||||
gpu_info_intel.load = j["engines"]["Render/3D/0"]["busy"].get<int>();
|
||||
|
||||
if (j.contains("engines"))
|
||||
if (j["engines"].contains("Render/3D"))
|
||||
if (j["engines"]["Render/3D"].contains("busy"))
|
||||
gpu_info_intel.load = j["engines"]["Render/3D"]["busy"].get<int>();
|
||||
|
||||
if (j.contains("frequency"))
|
||||
if (j["frequency"].contains("actual"))
|
||||
gpu_info_intel.CoreClock = j["frequency"]["actual"].get<int>();
|
||||
if (j.contains("power")){
|
||||
if (j["power"].contains("GPU"))
|
||||
gpu_info_intel.powerUsage = j["power"]["GPU"].get<float>();
|
||||
if (j["power"].contains("Package"))
|
||||
gpu_info_intel.apu_cpu_power = j["power"]["Package"].get<float>();
|
||||
}
|
||||
|
||||
}
|
||||
buf = "";
|
||||
num_line = 0;
|
||||
}
|
||||
num_iterations++;
|
||||
if (stop)
|
||||
break;
|
||||
}
|
||||
|
||||
int exitcode = pclose(intel_gpu_top) / 256;
|
||||
if (exitcode > 0){
|
||||
if (exitcode == 127)
|
||||
SPDLOG_INFO("Failed to open '{}'", "intel_gpu_top");
|
||||
|
||||
if (exitcode == 1)
|
||||
SPDLOG_INFO("Missing permissions for '{}'", "intel_gpu_top");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Intel::get_gpu_time() {
|
||||
rewind(fdinfo);
|
||||
fflush(fdinfo);
|
||||
char line[256];
|
||||
uint64_t val;
|
||||
while (fgets(line, sizeof(line), fdinfo)){
|
||||
if(strstr(line, "drm-engine-render"))
|
||||
sscanf(line, "drm-engine-render: %" SCNu64 " ns", &val);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
FILE* Intel::find_fd() {
|
||||
DIR* dir = opendir("/proc/self/fdinfo");
|
||||
if (!dir) {
|
||||
perror("Failed to open directory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint64_t val;
|
||||
static bool found_driver;
|
||||
|
||||
for (const auto& entry : fs::directory_iterator("/proc/self/fdinfo")){
|
||||
FILE* file = fopen(entry.path().string().c_str(), "r");
|
||||
if (file) {
|
||||
char line[256];
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
if (strstr(line, "i915") != NULL)
|
||||
found_driver = true;
|
||||
|
||||
if (found_driver){
|
||||
if(strstr(line, "drm-engine-render")){
|
||||
sscanf(line, "drm-engine-render: %" SCNu64 " ns", &val);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return NULL; // Return NULL if no matching file is found
|
||||
}
|
||||
|
||||
void Intel::get_fdinfo(){
|
||||
static uint64_t previous_gpu_time, previous_time, now, gpu_time_now;
|
||||
gpu_time_now = get_gpu_time();
|
||||
now = os_time_get_nano();
|
||||
|
||||
if (previous_time && previous_gpu_time && gpu_time_now > previous_gpu_time){
|
||||
float time_since_last = now - previous_time;
|
||||
float gpu_since_last = gpu_time_now - previous_gpu_time;
|
||||
auto result = int((gpu_since_last / time_since_last) * 100);
|
||||
if (result > 100)
|
||||
result = 100;
|
||||
|
||||
gpu_info_intel.load = result;
|
||||
previous_gpu_time = gpu_time_now;
|
||||
previous_time = now;
|
||||
} else {
|
||||
previous_gpu_time = gpu_time_now;
|
||||
previous_time = now;
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
#include <sys/stat.h>
|
||||
#include <thread>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <filesystem.h>
|
||||
#include <inttypes.h>
|
||||
#include <mesa/util/os_time.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include "gpu.h"
|
||||
#include "hud_elements.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
class Intel {
|
||||
private:
|
||||
bool init = false;
|
||||
bool runtime = false;
|
||||
bool stop = false;
|
||||
struct gpuInfo gpu_info_intel {};
|
||||
FILE* fdinfo;
|
||||
struct stat stat_buffer;
|
||||
std::thread thread;
|
||||
|
||||
FILE* find_fd();
|
||||
void intel_gpu_thread();
|
||||
uint64_t get_gpu_time();
|
||||
void get_fdinfo();
|
||||
|
||||
public:
|
||||
Intel() {
|
||||
if (stat("/run/pressure-vessel", &stat_buffer) == 0)
|
||||
runtime = true;
|
||||
|
||||
fdinfo = find_fd();
|
||||
// thread = std::thread(&Intel::intel_gpu_thread, this);
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (fdinfo)
|
||||
get_fdinfo();
|
||||
|
||||
gpu_info = gpu_info_intel;
|
||||
}
|
||||
|
||||
// ~Intel(){
|
||||
// stop = true;
|
||||
// thread.join();
|
||||
// }
|
||||
};
|
||||
|
||||
extern std::unique_ptr<Intel> intel;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue