Add per process memory usage (`procmem` etc)

pull/595/head
jackun 3 years ago
parent 891abdf3b9
commit 866fd8bc24
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3

@ -153,6 +153,7 @@ Parameters that are enabled by default have to be explicitly disabled. These (cu
| `gpu_core_clock`<br>`gpu_mem_clock`| Displays GPU core/memory frequency |
| `ram`<br>`vram` | Displays system RAM/VRAM usage |
| `swap` | Displays swap space usage next to system RAM usage |
| `procmem`<br>`procmem_shared`, `procmem_virt`| Displays process' memory usage: resident, shared and/or virtual. `procmem` (resident) also toggles others off if disabled. |
| `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) |

@ -110,6 +110,12 @@ position=top-left
# swap
# vram
### Display per process memory usage
## Show resident memory and other types, if enabled
# procmem
# procmem_shared
# procmem_virt
### Display MangoHud, engine or Wine version
# version
# engine_version

@ -3,6 +3,7 @@
#include <thread>
#include <string>
#include <iostream>
#include <sstream>
#include <memory>
#include <unistd.h>
#include <imgui.h>

@ -1,6 +1,13 @@
#include <spdlog/spdlog.h>
#include <algorithm>
#include <functional>
#include <sstream>
#include <cmath>
#include "overlay.h"
#include "overlay_params.h"
#include "hud_elements.h"
#include "logging.h"
#include "battery.h"
#include "cpu.h"
#include "memory.h"
#include "mesa/util/macros.h"
@ -48,6 +55,20 @@ ImVec4 LinearToSRGB(ImVec4 col)
return col;
}
template<typename T, typename R = float>
R format_units(T value, const char*& unit)
{
static const char* const units[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"};
size_t u = 0;
R out_value = value;
while (out_value > 1023 && u < ARRAY_SIZE(units)) {
out_value /= 1024;
++u;
}
unit = units[u];
return out_value;
}
void HudElements::convert_colors(struct overlay_params& params)
{
HUDElements.colors.update = false;
@ -273,6 +294,7 @@ void HudElements::core_load(){
}
}
}
void HudElements::io_stats(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_read] || HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_write]){
ImGui::TableNextRow(); ImGui::TableNextColumn();
@ -324,6 +346,7 @@ void HudElements::vram(){
}
}
}
void HudElements::ram(){
#ifdef __gnu_linux__
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_ram]){
@ -335,7 +358,7 @@ void HudElements::ram(){
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("GiB");
ImGui::PopFont();
}
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_ram] && HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_swap]){
ImGui::TableNextColumn();
@ -348,6 +371,45 @@ void HudElements::ram(){
#endif
}
void HudElements::procmem()
{
const char* unit = nullptr;
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem])
return;
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::TextColored(HUDElements.colors.ram, "PMEM");
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem.resident, unit));
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("%s", unit);
ImGui::PopFont();
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_shared]){
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem.shared, unit));
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("%s", unit);
ImGui::PopFont();
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_shared] && HUDElements.params->table_columns < 4){
ImGui::TableNextRow();
ImGui::TableNextColumn();
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_virt]){
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem.virt, unit));
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("%s", unit);
ImGui::PopFont();
}
}
void HudElements::fps(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_fps]){
ImGui::TableNextRow(); ImGui::TableNextColumn();
@ -540,7 +602,7 @@ void HudElements::show_fps_limit(){
void HudElements::custom_text_center(){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::PushFont(HUDElements.sw_stats->font1);
std::string value = HUDElements.ordered_functions[HUDElements.place].second;
const std::string& value = HUDElements.ordered_functions[HUDElements.place].second;
center_text(value);
ImGui::TextColored(HUDElements.colors.text, "%s",value.c_str());
ImGui::NewLine();
@ -550,13 +612,13 @@ void HudElements::custom_text_center(){
void HudElements::custom_text(){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::PushFont(HUDElements.sw_stats->font1);
std::string value = HUDElements.ordered_functions[HUDElements.place].second;
const std::string& value = HUDElements.ordered_functions[HUDElements.place].second;
ImGui::TextColored(HUDElements.colors.text, "%s",value.c_str());
ImGui::PopFont();
}
void HudElements::_exec(){
std::string value = HUDElements.ordered_functions[HUDElements.place].second;
//const std::string& value = HUDElements.ordered_functions[HUDElements.place].second;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TableNextColumn();
for (auto& item : HUDElements.exec_list){
@ -633,7 +695,7 @@ void HudElements::battery(){
void HudElements::graphs(){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
std::string value = HUDElements.ordered_functions[HUDElements.place].second;
const std::string& value = HUDElements.ordered_functions[HUDElements.place].second;
std::vector<float> arr(50, 0);
ImGui::PushFont(HUDElements.sw_stats->font1);
@ -765,6 +827,7 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
if (param == "io_stats") { ordered_functions.push_back({io_stats, value}); }
if (param == "vram") { ordered_functions.push_back({vram, value}); }
if (param == "ram") { ordered_functions.push_back({ram, value}); }
if (param == "procmem") { ordered_functions.push_back({procmem, value}); }
if (param == "fps") { ordered_functions.push_back({fps, value}); }
if (param == "engine_version") { ordered_functions.push_back({engine_version, value}); }
if (param == "gpu_name") { ordered_functions.push_back({gpu_name, value}); }
@ -790,7 +853,9 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
if (find(permitted_params.begin(), permitted_params.end(), value) != permitted_params.end())
ordered_functions.push_back({graphs, value});
else
printf("MANGOHUD: Unrecognized graph type: %s\n", value.c_str());
{
spdlog::info("Unrecognized graph type: {}", value);
}
}
}
return;

@ -1,17 +1,16 @@
#pragma once
#include "overlay.h"
#include "overlay_params.h"
#include <functional>
#include <map>
#include <sstream>
#include <logging.h>
#include <battery.h>
#include <vector>
#include <string>
#include <utility>
#include <imgui.h>
#include "timing.hpp"
struct overlay_params;
class HudElements{
public:
struct swapchain_stats *sw_stats;
struct overlay_params *params;
struct exec_list {
struct exec_entry {
int pos;
std::string value;
std::string ret;
@ -29,7 +28,7 @@ class HudElements{
"gpu_load", "cpu_load", "gpu_core_clock", "gpu_mem_clock",
"vram", "ram", "cpu_temp", "gpu_temp"
};
std::vector<exec_list> exec_list;
std::vector<exec_entry> exec_list;
void sort_elements(const std::pair<std::string, std::string>& option);
void legacy_elements();
void update_exec();
@ -41,6 +40,7 @@ class HudElements{
static void io_stats();
static void vram();
static void ram();
static void procmem();
static void fps();
static void engine_version();
static void gpu_name();

@ -1,12 +1,15 @@
#include <spdlog/spdlog.h>
#include "memory.h"
#include <iomanip>
#include <cstring>
#include <stdio.h>
#include <iostream>
#include <thread>
#include <unistd.h>
struct memory_information mem_info;
float memused, memmax, swapused, swapmax;
struct process_mem proc_mem {};
FILE *open_file(const char *file, int *reported) {
FILE *fp = nullptr;
@ -15,7 +18,7 @@ FILE *open_file(const char *file, int *reported) {
if (fp == nullptr) {
if ((reported == nullptr) || *reported == 0) {
// NORM_ERR("can't open %s: %s", file, strerror(errno));
SPDLOG_ERROR("can't open {}: {}", file, strerror(errno));
if (reported != nullptr) { *reported = 1; }
}
return nullptr;
@ -100,3 +103,29 @@ void update_meminfo(void) {
fclose(meminfo_fp);
}
void update_procmem()
{
static int reported = 0;
FILE *statm = open_file("/proc/self/statm", &reported);
if (!statm)
return;
static auto pageSize = sysconf(_SC_PAGESIZE);
if (pageSize < 0) pageSize = 4096;
long int temp[7];
if (fscanf(statm, "%ld %ld %ld %ld %ld %ld %ld",
&temp[0], &temp[1], &temp[2], &temp[3],
&temp[4], /* unused since Linux 2.6; always 0 */
&temp[5], &temp[6]) == 7)
{
proc_mem.virt = temp[0] * pageSize;// / (1024.f * 1024.f); //MiB
proc_mem.resident = temp[1] * pageSize;// / (1024.f * 1024.f); //MiB
proc_mem.shared = temp[2] * pageSize;// / (1024.f * 1024.f); //MiB;
proc_mem.text = temp[3];
proc_mem.data = temp[5];
proc_mem.dirty = temp[6];
}
fclose(statm);
}

@ -15,7 +15,15 @@ struct memory_information {
unsigned long long bufmem, buffers, cached;
};
struct process_mem
{
float virt, resident, shared;
long int text, data, dirty;
};
extern process_mem proc_mem;
void update_meminfo(void);
void update_procmem();
FILE *open_file(const char *file, int *reported);
#endif //MANGOHUD_MEMORY_H

@ -70,6 +70,8 @@ void update_hw_info(struct swapchain_stats& sw_stats, struct overlay_params& par
#ifdef __gnu_linux__
if (params.enabled[OVERLAY_PARAM_ENABLED_ram] || params.enabled[OVERLAY_PARAM_ENABLED_swap] || logger->is_active())
update_meminfo();
if (params.enabled[OVERLAY_PARAM_ENABLED_procmem])
update_procmem();
if (params.enabled[OVERLAY_PARAM_ENABLED_io_read] || params.enabled[OVERLAY_PARAM_ENABLED_io_write])
getIoStats(&sw_stats.io);
#endif
@ -248,7 +250,7 @@ void right_aligned_text(ImVec4& col, float off_x, const char *fmt, ...)
ImGui::TextColored(col,"%s",buffer);
}
void center_text(std::string& text)
void center_text(const std::string& text)
{
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(text.c_str()).x / 2));
}

@ -5,7 +5,7 @@
#include <string>
#include <stdint.h>
#include <vector>
#include "imgui.h"
#include <imgui.h>
#include "overlay_params.h"
#include "iostats.h"
#include "timing.hpp"
@ -119,7 +119,7 @@ void get_device_name(int32_t vendorID, int32_t deviceID, struct swapchain_stats&
void calculate_benchmark_data(void *params_void);
void create_fonts(const overlay_params& params, ImFont*& small_font, ImFont*& text_font);
void right_aligned_text(ImVec4& col, float off_x, const char *fmt, ...);
void center_text(std::string& text);
void center_text(const std::string& text);
ImVec4 change_on_load_temp(LOAD_DATA& data, unsigned current);
float get_time_stat(void *_data, int _idx);

@ -559,6 +559,9 @@ parse_overlay_config(struct overlay_params *params,
{
if (!spdlog::get("MANGOHUD"))
spdlog::set_default_logger(spdlog::stderr_color_mt("MANGOHUD")); // Just to get the name in log
#ifndef NDEBUG
spdlog::set_level(spdlog::level::level_enum::debug);
#endif
spdlog::cfg::load_env_levels();
*params = {};
@ -784,8 +787,9 @@ parse_overlay_config(struct overlay_params *params,
}
#endif
if(!params->output_file.empty())
printf("MANGOHUD: output_file is Deprecated, use output_folder instead\n");
if(!params->output_file.empty()) {
SPDLOG_INFO("output_file is deprecated, use output_folder instead");
}
auto real_size = params->font_size * params->font_scale;
real_font_size = ImVec2(real_size, real_size / 2);

@ -36,6 +36,9 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_BOOL(ram) \
OVERLAY_PARAM_BOOL(swap) \
OVERLAY_PARAM_BOOL(vram) \
OVERLAY_PARAM_BOOL(procmem) \
OVERLAY_PARAM_BOOL(procmem_shared) \
OVERLAY_PARAM_BOOL(procmem_virt) \
OVERLAY_PARAM_BOOL(time) \
OVERLAY_PARAM_BOOL(full) \
OVERLAY_PARAM_BOOL(read_cfg) \

Loading…
Cancel
Save