diff --git a/README.md b/README.md
index 3741e4e2..38f82a09 100644
--- a/README.md
+++ b/README.md
@@ -126,6 +126,7 @@ You can also customize the hud by using the `MANGOHUD_CONFIG` environment variab
You can also specify configuration file with `MANGOHUD_CONFIGFILE=/path/to/config` for applications whose names are hard to guess (java, python etc).
A partial list of parameters are below. See the config file for a complete list.
+Parameters that are enabled by default have to be explicitly disabled. These (currently) are `fps`, `frame_timing`, `cpu_stats` (cpu load), `gpu_stats` (gpu load).
| Variable | Description |
|------------------------------------|---------------------------------------------------------------------------------------|
@@ -133,7 +134,7 @@ A partial list of parameters are below. See the config file for a complete list.
| `core_load` | Displays load & frequency per core |
| `gpu_core_clock`
`gpu_mem_clock`| Displays GPU core/memory frequency |
| `ram`
`vram` | Displays system RAM/VRAM usage |
-| `full` | Enables all of the above config options |
+| `full` | Enables most of the toggleable parameters (currently excludes `histogram`) |
| `font_size=` | Customizeable font size (default=24) |
| `font_size_text=` | Customizeable font size for other text like media metadata (default=24) |
| `font_scale=` | Set global font scale (default=1.0) |
@@ -146,7 +147,7 @@ A partial list of parameters are below. See the config file for a complete list.
| `no_display` | Hide the hud by default |
| `toggle_hud=`
`toggle_logging=` | Modifiable toggle hotkeys. Default are `Shift_R+F12` and `Shift_L+F2`, respectively. |
| `reload_cfg=` | Change keybind for reloading the config. Default = `Shift_L+F4` |
-| `time`
`time_format=%T` | Displays local time. See [std::put_time](https://en.cppreference.com/w/cpp/io/manip/put_time) for formatting help. NOTE: Sometimes apps (or AMDVLK) may set `TZ` environment variable to `GMT+0` |
+| `time`
`time_format=%T` | Displays local time. See [std::put_time](https://en.cppreference.com/w/cpp/io/manip/put_time) for formatting help. NOTE: Sometimes apps (or AMDVLK (should be fixed in latest)) may set `TZ` (timezone) environment variable to UTC/GMT |
| `gpu_color`
`gpu_color`
`vram_color`
`ram_color`
`io_color`
`engine_color`
`frametime_color`
`background_color`
`text_color`
`media_player_color` | Change default colors: `gpu_color=RRGGBB`|
| `alpha` | Set the opacity of all text and frametime graph `0.0-1.0` |
| `background_alpha` | Set the opacity of the background `0.0-1.0` |
@@ -172,6 +173,7 @@ A partial list of parameters are below. See the config file for a complete list.
| `engine_version` | Display OpenGL or vulkan and vulkan-based render engine's version |
| `permit_upload` | Allow uploading of logs to Flightlessmango.com |
| `upload_log` | Change keybind for uploading log |
+| `benchmark_percentiles` | Configure which framerate percentiles are shown in the logging summary. Default is `97+AVG+1+0.1` |
Example: `MANGOHUD_CONFIG=cpu_temp,gpu_temp,position=top-right,height=500,font_size=32`
diff --git a/bin/MangoHud.conf b/bin/MangoHud.conf
index 4ab60e1e..9038a494 100644
--- a/bin/MangoHud.conf
+++ b/bin/MangoHud.conf
@@ -130,3 +130,6 @@ background_alpha=0.5
# output_file
### Permit uploading logs directly to Flightlessmango.com
# permit_upload=1
+### 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
+# benchmark_percentiles=
\ No newline at end of file
diff --git a/build.sh b/build.sh
index a6ed768b..30325000 100755
--- a/build.sh
+++ b/build.sh
@@ -69,7 +69,7 @@ dependencies() {
DEPS="{glibc-devel.i686,libstdc++-devel.i686,libX11-devel.i686}"
dep_install
;;
- *"buntu"|"Linux Mint"|"Debian GNU/Linux"|"Zorin OS"|"Pop!_OS"|"elementary OS")
+ *"buntu"|"Linux Mint"|"Debian GNU/Linux"|"Zorin OS"|"Pop!_OS"|"elementary OS"|"KDE neon")
MANAGER_QUERY="dpkg-query -s"
MANAGER_INSTALL="apt install"
DEPS="{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}"
@@ -79,7 +79,7 @@ dependencies() {
$SU_CMD pip3 install 'meson>=0.54' mako
fi
if [[ ! -f /usr/local/bin/glslangValidator ]]; then
- wget https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-linux-Release.zip
+ 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
$SU_CMD install -m755 bin/glslangValidator /usr/local/bin/
rm bin/glslangValidator glslang-master-linux-Release.zip
diff --git a/src/logging.cpp b/src/logging.cpp
index f433dc2a..143801aa 100644
--- a/src/logging.cpp
+++ b/src/logging.cpp
@@ -119,7 +119,7 @@ void Logger::stop_logging() {
m_logging_on = false;
m_log_end = Clock::now();
- std::thread(calculate_benchmark_data).detach();
+ std::thread(calculate_benchmark_data, m_params).detach();
if(not m_params->output_file.empty()) {
m_log_files.emplace_back(m_params->output_file + get_log_suffix());
diff --git a/src/overlay.cpp b/src/overlay.cpp
index 2d5e9466..de63a0c1 100644
--- a/src/overlay.cpp
+++ b/src/overlay.cpp
@@ -766,6 +766,7 @@ void check_keybinds(struct swapchain_stats& sw_stats, struct overlay_params& par
#endif
if (pressed && (now - logger->last_log_end() > 11s)) {
last_f2_press = now;
+
if (logger->is_active()) {
logger->stop_logging();
} else {
@@ -826,27 +827,43 @@ void check_keybinds(struct swapchain_stats& sw_stats, struct overlay_params& par
}
}
-void calculate_benchmark_data(){
- vector sorted;
- sorted = benchmark.fps_data;
+void calculate_benchmark_data(void *params_void){
+ overlay_params *params = reinterpret_cast(params_void);
+
+ vector sorted = benchmark.fps_data;
sort(sorted.begin(), sorted.end());
- // 97th percentile
- int index = sorted.size() * 0.97;
- benchmark.ninety = sorted[index];
- // avg
+ benchmark.percentile_data.clear();
+
benchmark.total = 0.f;
for (auto fps_ : sorted){
benchmark.total = benchmark.total + fps_;
}
- benchmark.avg = benchmark.total / sorted.size();
- // 1% min
- benchmark.total = 0.f;
- for (size_t i = 0; i < sorted.size() * 0.01; i++){
- benchmark.total = sorted[i];
+
+ size_t max_label_size = 0;
+
+ for (std::string percentile : params->benchmark_percentiles) {
+ float result;
+
+ // special case handling for a mean-based average
+ if (percentile == "AVG") {
+ result = benchmark.total / sorted.size();
+ } else {
+ // the percentiles are already validated when they're parsed from the config.
+ float fraction = parse_float(percentile) / 100;
+
+ result = sorted[(fraction * sorted.size()) - 1];
+ percentile += "%";
+ }
+
+ if (percentile.length() > max_label_size)
+ max_label_size = percentile.length();
+
+ benchmark.percentile_data.push_back({percentile, result});
+ }
+
+ for (auto& entry : benchmark.percentile_data) {
+ entry.first.append(max_label_size - entry.first.length(), ' ');
}
- benchmark.oneP = benchmark.total;
- // 0.1% min
- benchmark.pointOneP = sorted[sorted.size() * 0.001];
}
void update_hud_info(struct swapchain_stats& sw_stats, struct overlay_params& params, uint32_t vendorID){
@@ -1061,14 +1078,13 @@ static void render_mpris_metadata(struct overlay_params& params, mutexed_metadat
void render_benchmark(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, unsigned height, Clock::time_point now){
// TODO, FIX LOG_DURATION FOR BENCHMARK
- int benchHeight = 6 * params.font_size * params.font_scale + 10.0f + 58;
+ int benchHeight = (2 + benchmark.percentile_data.size()) * params.font_size + 10.0f + 58;
ImGui::SetNextWindowSize(ImVec2(window_size.x, benchHeight), ImGuiCond_Always);
if (height - (window_size.y + data.main_window_pos.y + 5) < benchHeight)
ImGui::SetNextWindowPos(ImVec2(data.main_window_pos.x, data.main_window_pos.y - benchHeight - 5), ImGuiCond_Always);
else
ImGui::SetNextWindowPos(ImVec2(data.main_window_pos.x, data.main_window_pos.y + window_size.y + 5), ImGuiCond_Always);
- vector> benchmark_data = {{"97% ", benchmark.ninety}, {"AVG ", benchmark.avg}, {"1% ", benchmark.oneP}, {"0.1%", benchmark.pointOneP}};
float display_time = std::chrono::duration(now - logger->last_log_end()).count();
static float display_for = 10.0f;
float alpha;
@@ -1106,7 +1122,7 @@ void render_benchmark(swapchain_stats& data, struct overlay_params& params, ImVe
snprintf(duration, sizeof(duration), "Duration: %.1fs", std::chrono::duration(logger->last_log_end() - logger->last_log_begin()).count());
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(duration).x / 2));
ImGui::TextColored(ImVec4(1.0, 1.0, 1.0, alpha / params.background_alpha), "%s", duration);
- for (auto& data_ : benchmark_data){
+ for (auto& data_ : benchmark.percentile_data){
char buffer[20];
snprintf(buffer, sizeof(buffer), "%s %.1f", data_.first.c_str(), data_.second);
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(buffer).x / 2));
diff --git a/src/overlay.h b/src/overlay.h
index 871c8fcc..9a6b2025 100644
--- a/src/overlay.h
+++ b/src/overlay.h
@@ -69,12 +69,9 @@ struct fps_limit {
};
struct benchmark_stats {
- float ninety;
- float avg;
- float oneP;
- float pointOneP;
float total;
std::vector fps_data;
+ std::vector> percentile_data;
};
extern struct fps_limit fps_limit_stats;
@@ -91,8 +88,8 @@ void check_keybinds(struct swapchain_stats& sw_stats, struct overlay_params& par
void init_system_info(void);
void FpsLimiter(struct fps_limit& stats);
void get_device_name(int32_t vendorID, int32_t deviceID, struct swapchain_stats& sw_stats);
-void calculate_benchmark_data(void);
+void calculate_benchmark_data(void *params_void);
void create_fonts(const overlay_params& params, ImFont*& small_font, ImFont*& text_font);
void convert_colors(bool do_conv, struct swapchain_stats& sw_stats, struct overlay_params& params);
-#endif //MANGOHUD_OVERLAY_H
+#endif //MANGOHUD_OVERLAY_H
\ No newline at end of file
diff --git a/src/overlay_params.cpp b/src/overlay_params.cpp
index bf1e772b..8c97b0eb 100644
--- a/src/overlay_params.cpp
+++ b/src/overlay_params.cpp
@@ -209,6 +209,48 @@ parse_media_player_order(const char *str)
return order;
}
+
+static std::vector
+parse_benchmark_percentiles(const char *str)
+{
+ std::vector percentiles;
+ std::stringstream percent_strings(str);
+ std::string value;
+
+ while (std::getline(percent_strings, value, '+')) {
+ trim(value);
+
+ if (value == "AVG") {
+ percentiles.push_back(value);
+ continue;
+ }
+
+ float as_float;
+ size_t float_len = 0;
+
+ try {
+ as_float = parse_float(value, &float_len);
+ } catch (const std::invalid_argument&) {
+ std::cerr << "MANGOHUD: invalid benchmark percentile: '" << value << "'\n";
+ continue;
+ }
+
+ if (float_len != value.length()) {
+ std::cerr << "MANGOHUD: invalid benchmark percentile: '" << value << "'\n";
+ continue;
+ }
+
+ if (as_float > 100 || as_float < 0) {
+ std::cerr << "MANGOHUD: benchmark percentile is not between 0 and 100 (" << value << ")\n";
+ continue;
+ }
+
+ percentiles.push_back(value);
+ }
+
+ return percentiles;
+}
+
static uint32_t
parse_font_glyph_ranges(const char *str)
{
@@ -239,6 +281,7 @@ parse_font_glyph_ranges(const char *str)
fg |= FG_LATIN_EXT_B;
}
return fg;
+
}
#define parse_width(s) parse_unsigned(s)
@@ -438,6 +481,7 @@ parse_overlay_config(struct overlay_params *params,
params->media_player_order = { MP_ORDER_TITLE, MP_ORDER_ARTIST, MP_ORDER_ALBUM };
params->permit_upload = 0;
params->render_mango = 0;
+ params->benchmark_percentiles = { "97", "AVG", "1", "0.1" };
#ifdef HAVE_X11
params->toggle_hud = { XK_Shift_R, XK_F12 };
diff --git a/src/overlay_params.h b/src/overlay_params.h
index 7488136c..3f463800 100644
--- a/src/overlay_params.h
+++ b/src/overlay_params.h
@@ -97,6 +97,7 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(log_interval) \
OVERLAY_PARAM_CUSTOM(permit_upload) \
OVERLAY_PARAM_CUSTOM(render_mango) \
+ OVERLAY_PARAM_CUSTOM(benchmark_percentiles) \
OVERLAY_PARAM_CUSTOM(help)
enum overlay_param_position {
@@ -174,6 +175,7 @@ struct overlay_params {
std::string cpu_text, gpu_text;
unsigned log_interval;
std::vector media_player_order;
+ std::vector benchmark_percentiles;
std::string font_file, font_file_text;
uint32_t font_glyph_ranges;