Move color conversion to HudElements; move some overlay related functions back to overlay.cpp

pull/400/head
jackun 4 years ago
parent 44d5546ba5
commit 1e8487c991
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3

@ -117,7 +117,7 @@ void imgui_create(void *ctx)
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
convert_colors(false, sw_stats, params);
HUDElements.convert_colors(false, params);
glGetIntegerv (GL_VIEWPORT, last_vp.v);
glGetIntegerv (GL_SCISSOR_BOX, last_sb.v);
@ -175,6 +175,8 @@ void imgui_render(unsigned int width, unsigned int height)
ImGuiContext *saved_ctx = ImGui::GetCurrentContext();
ImGui::SetCurrentContext(state.imgui_ctx);
ImGui::GetIO().DisplaySize = ImVec2(width, height);
if (HUDElements.colors.update)
HUDElements.convert_colors(params);
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();

@ -1,9 +1,90 @@
#include <algorithm>
#include <cmath>
#include "hud_elements.h"
#include "cpu.h"
#include "memory.h"
#include "mesa/util/macros.h"
// Cut from https://github.com/ocornut/imgui/pull/2943
// Probably move to ImGui
float SRGBToLinear(float in)
{
if (in <= 0.04045f)
return in / 12.92f;
else
return powf((in + 0.055f) / 1.055f, 2.4f);
}
float LinearToSRGB(float in)
{
if (in <= 0.0031308f)
return in * 12.92f;
else
return 1.055f * powf(in, 1.0f / 2.4f) - 0.055f;
}
ImVec4 SRGBToLinear(ImVec4 col)
{
col.x = SRGBToLinear(col.x);
col.y = SRGBToLinear(col.y);
col.z = SRGBToLinear(col.z);
// Alpha component is already linear
return col;
}
ImVec4 LinearToSRGB(ImVec4 col)
{
col.x = LinearToSRGB(col.x);
col.y = LinearToSRGB(col.y);
col.z = LinearToSRGB(col.z);
// Alpha component is already linear
return col;
}
void HudElements::convert_colors(struct overlay_params& params)
{
HUDElements.colors.update = false;
auto convert = [](unsigned color) -> ImVec4 {
ImVec4 fc = ImGui::ColorConvertU32ToFloat4(color);
if (HUDElements.colors.convert)
return SRGBToLinear(fc);
return fc;
};
HUDElements.colors.cpu = convert(params.cpu_color);
HUDElements.colors.gpu = convert(params.gpu_color);
HUDElements.colors.vram = convert(params.vram_color);
HUDElements.colors.ram = convert(params.ram_color);
HUDElements.colors.engine = convert(params.engine_color);
HUDElements.colors.io = convert(params.io_color);
HUDElements.colors.frametime = convert(params.frametime_color);
HUDElements.colors.background = convert(params.background_color);
HUDElements.colors.text = convert(params.text_color);
HUDElements.colors.media_player = convert(params.media_player_color);
HUDElements.colors.wine = convert(params.wine_color);
HUDElements.colors.gpu_load_high = convert(params.gpu_load_color[0]);
HUDElements.colors.gpu_load_med = convert(params.gpu_load_color[1]);
HUDElements.colors.gpu_load_low = convert(params.gpu_load_color[2]);
HUDElements.colors.cpu_load_high = convert(params.cpu_load_color[0]);
HUDElements.colors.cpu_load_med = convert(params.cpu_load_color[1]);
HUDElements.colors.cpu_load_low = convert(params.cpu_load_color[2]);
ImGuiStyle& style = ImGui::GetStyle();
style.Colors[ImGuiCol_PlotLines] = convert(params.frametime_color);
style.Colors[ImGuiCol_PlotHistogram] = convert(params.frametime_color);
style.Colors[ImGuiCol_WindowBg] = convert(params.background_color);
style.Colors[ImGuiCol_Text] = convert(params.text_color);
style.CellPadding.y = params.cellpadding_y * real_font_size.y;
}
void HudElements::convert_colors(bool do_conv, struct overlay_params& params)
{
HUDElements.colors.convert = do_conv;
convert_colors(params);
}
void HudElements::time(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_time]){
ImGui::TableNextRow();
@ -23,56 +104,56 @@ void HudElements::gpu_stats(){
ImGui::TableNextRow();
const char* gpu_text;
if (HUDElements.params->gpu_text.empty())
gpu_text = "GPU";
gpu_text = "GPU";
else
gpu_text = HUDElements.params->gpu_text.c_str();
ImGui::TextColored(HUDElements.sw_stats->colors.gpu, "%s", gpu_text);
gpu_text = HUDElements.params->gpu_text.c_str();
ImGui::TextColored(HUDElements.colors.gpu, "%s", gpu_text);
ImGui::TableNextCell();
auto text_color = HUDElements.sw_stats->colors.text;
auto text_color = HUDElements.colors.text;
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_load_change]){
struct LOAD_DATA gpu_data = {HUDElements.sw_stats->colors.gpu_load_high,
HUDElements.sw_stats->colors.gpu_load_med,
HUDElements.sw_stats->colors.gpu_load_low,
HUDElements.params->gpu_load_value[0],
HUDElements.params->gpu_load_value[1]
};
auto load_color = change_on_load_temp(gpu_data, gpu_info.load);
right_aligned_text(load_color, HUDElements.ralign_width, "%i", gpu_info.load);
ImGui::SameLine(0, 1.0f);
ImGui::TextColored(load_color,"%%");
struct LOAD_DATA gpu_data = {
HUDElements.colors.gpu_load_high,
HUDElements.colors.gpu_load_med,
HUDElements.colors.gpu_load_low,
HUDElements.params->gpu_load_value[0],
HUDElements.params->gpu_load_value[1]
};
auto load_color = change_on_load_temp(gpu_data, gpu_info.load);
right_aligned_text(load_color, HUDElements.ralign_width, "%i", gpu_info.load);
ImGui::SameLine(0, 1.0f);
ImGui::TextColored(load_color,"%%");
}
else {
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.load);
ImGui::SameLine(0, 1.0f);
ImGui::TextColored(text_color,"%%");
// ImGui::SameLine(150);
// ImGui::Text("%s", "%");
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.load);
ImGui::SameLine(0, 1.0f);
ImGui::TextColored(text_color,"%%");
// ImGui::SameLine(150);
// ImGui::Text("%s", "%");
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_temp]){
ImGui::TableNextCell();
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.temp);
ImGui::SameLine(0, 1.0f);
ImGui::Text("°C");
ImGui::TableNextCell();
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.temp);
ImGui::SameLine(0, 1.0f);
ImGui::Text("°C");
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_core_clock] || HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_power])
ImGui::TableNextRow();
ImGui::TableNextRow();
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_core_clock]){
ImGui::TableNextCell();
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.CoreClock);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MHz");
ImGui::PopFont();
ImGui::TableNextCell();
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.CoreClock);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MHz");
ImGui::PopFont();
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_power]) {
ImGui::TableNextCell();
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.powerUsage);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("W");
ImGui::PopFont();
ImGui::TableNextCell();
right_aligned_text(text_color, HUDElements.ralign_width, "%i", gpu_info.powerUsage);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("W");
ImGui::PopFont();
}
}
}
@ -82,22 +163,23 @@ void HudElements::cpu_stats(){
ImGui::TableNextRow();
const char* cpu_text;
if (HUDElements.params->cpu_text.empty())
cpu_text = "CPU";
cpu_text = "CPU";
else
cpu_text = HUDElements.params->cpu_text.c_str();
ImGui::TextColored(HUDElements.sw_stats->colors.cpu, "%s", cpu_text);
cpu_text = HUDElements.params->cpu_text.c_str();
ImGui::TextColored(HUDElements.colors.cpu, "%s", cpu_text);
ImGui::TableNextCell();
auto text_color = HUDElements.sw_stats->colors.text;
auto text_color = HUDElements.colors.text;
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_load_change]){
int cpu_load_percent = int(cpuStats.GetCPUDataTotal().percent);
struct LOAD_DATA cpu_data = {HUDElements.sw_stats->colors.cpu_load_high,
HUDElements.sw_stats->colors.cpu_load_med,
HUDElements.sw_stats->colors.cpu_load_low,
HUDElements.params->cpu_load_value[0],
HUDElements.params->cpu_load_value[1]
};
struct LOAD_DATA cpu_data = {
HUDElements.colors.cpu_load_high,
HUDElements.colors.cpu_load_med,
HUDElements.colors.cpu_load_low,
HUDElements.params->cpu_load_value[0],
HUDElements.params->cpu_load_value[1]
};
auto load_color = change_on_load_temp(cpu_data, cpu_load_percent);
right_aligned_text(load_color, HUDElements.ralign_width, "%d", cpu_load_percent);
ImGui::SameLine(0, 1.0f);
@ -111,7 +193,7 @@ void HudElements::cpu_stats(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_temp]){
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%i", cpuStats.GetCPUDataTotal().temp);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", cpuStats.GetCPUDataTotal().temp);
ImGui::SameLine(0, 1.0f);
ImGui::Text("°C");
}
@ -119,7 +201,7 @@ void HudElements::cpu_stats(){
ImGui::TableNextRow();
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_mhz]){
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%i", cpuStats.GetCPUDataTotal().cpu_mhz);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", cpuStats.GetCPUDataTotal().cpu_mhz);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MHz");
@ -127,7 +209,7 @@ void HudElements::cpu_stats(){
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_power]){
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%i", cpuStats.GetCPUDataTotal().power);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", cpuStats.GetCPUDataTotal().power);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("W");
@ -142,17 +224,17 @@ void HudElements::core_load(){
for (const CPUData &cpuData : cpuStats.GetCPUData())
{
ImGui::TableNextRow();
ImGui::TextColored(HUDElements.sw_stats->colors.cpu, "CPU");
ImGui::TextColored(HUDElements.colors.cpu, "CPU");
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.cpu,"%i", i);
ImGui::TextColored(HUDElements.colors.cpu,"%i", i);
ImGui::PopFont();
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%i", int(cpuData.percent));
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", int(cpuData.percent));
ImGui::SameLine(0, 1.0f);
ImGui::Text("%%");
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%i", cpuData.mhz);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", cpuData.mhz);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MHz");
@ -166,29 +248,29 @@ void HudElements::io_stats(){
auto sampling = HUDElements.params->fps_sampling_period;
ImGui::TableNextRow();
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_read] && !HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_write])
ImGui::TextColored(HUDElements.sw_stats->colors.io, "IO RD");
ImGui::TextColored(HUDElements.colors.io, "IO RD");
else if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_read] && HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_write])
ImGui::TextColored(HUDElements.sw_stats->colors.io, "IO RW");
ImGui::TextColored(HUDElements.colors.io, "IO RW");
else if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_write] && !HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_read])
ImGui::TextColored(HUDElements.sw_stats->colors.io, "IO WR");
ImGui::TextColored(HUDElements.colors.io, "IO WR");
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_read]){
ImGui::TableNextCell();
float val = HUDElements.sw_stats->io.diff.read * 1000000 / sampling;
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, val < 100 ? "%.1f" : "%.f", val);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MiB/s");
ImGui::PopFont();
ImGui::TableNextCell();
float val = HUDElements.sw_stats->io.diff.read * 1000000 / sampling;
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, val < 100 ? "%.1f" : "%.f", val);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MiB/s");
ImGui::PopFont();
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_io_write]){
ImGui::TableNextCell();
float val = HUDElements.sw_stats->io.diff.write * 1000000 / sampling;
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, val < 100 ? "%.1f" : "%.f", val);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MiB/s");
ImGui::PopFont();
ImGui::TableNextCell();
float val = HUDElements.sw_stats->io.diff.write * 1000000 / sampling;
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, val < 100 ? "%.1f" : "%.f", val);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MiB/s");
ImGui::PopFont();
}
}
}
@ -196,16 +278,16 @@ void HudElements::io_stats(){
void HudElements::vram(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_vram]){
ImGui::TableNextRow();
ImGui::TextColored(HUDElements.sw_stats->colors.vram, "VRAM");
ImGui::TextColored(HUDElements.colors.vram, "VRAM");
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%.1f", gpu_info.memoryUsed);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", gpu_info.memoryUsed);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("GiB");
ImGui::PopFont();
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_mem_clock]){
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%i", gpu_info.MemClock);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", gpu_info.MemClock);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("MHz");
@ -214,12 +296,12 @@ void HudElements::vram(){
}
}
void HudElements::ram(){
#ifdef __gnu_linux__
#ifdef __gnu_linux__
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_ram]){
ImGui::TableNextRow();
ImGui::TextColored(HUDElements.sw_stats->colors.ram, "RAM");
ImGui::TextColored(HUDElements.colors.ram, "RAM");
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%.1f", memused);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", memused);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("GiB");
@ -232,18 +314,18 @@ void HudElements::fps(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_fps]){
ImGui::TableNextRow();
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_fps] && HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_engine_version]){
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", HUDElements.is_vulkan ? HUDElements.sw_stats->engineName.c_str() : "OpenGL");
ImGui::TextColored(HUDElements.colors.engine, "%s", HUDElements.is_vulkan ? HUDElements.sw_stats->engineName.c_str() : "OpenGL");
}
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", HUDElements.is_vulkan ? HUDElements.sw_stats->engineName.c_str() : "OpenGL");
ImGui::TextColored(HUDElements.colors.engine, "%s", HUDElements.is_vulkan ? HUDElements.sw_stats->engineName.c_str() : "OpenGL");
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%.0f", HUDElements.sw_stats->fps);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.0f", HUDElements.sw_stats->fps);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("FPS");
ImGui::PopFont();
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_frametime]){
ImGui::TableNextCell();
right_aligned_text(HUDElements.sw_stats->colors.text, HUDElements.ralign_width, "%.1f", 1000 / HUDElements.sw_stats->fps);
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", 1000 / HUDElements.sw_stats->fps);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("ms");
@ -256,33 +338,34 @@ void HudElements::gpu_name(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_name] && !HUDElements.sw_stats->gpuName.empty()){
ImGui::TableNextRow();
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine,
ImGui::TextColored(HUDElements.colors.engine,
"%s", HUDElements.sw_stats->gpuName.c_str());
ImGui::PopFont();
}
}
void HudElements::engine_version(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_engine_version]){
ImGui::TableNextRow();
ImGui::PushFont(HUDElements.sw_stats->font1);
if (HUDElements.is_vulkan) {
if ((HUDElements.sw_stats->engineName == "DXVK" || HUDElements.sw_stats->engineName == "VKD3D")){
ImGui::TextColored(HUDElements.sw_stats->colors.engine,
ImGui::TextColored(HUDElements.colors.engine,
"%s/%d.%d.%d", HUDElements.sw_stats->engineVersion.c_str(),
HUDElements.sw_stats->version_vk.major,
HUDElements.sw_stats->version_vk.minor,
HUDElements.sw_stats->version_vk.patch);
} else {
ImGui::TextColored(HUDElements.sw_stats->colors.engine,
ImGui::TextColored(HUDElements.colors.engine,
"%d.%d.%d",
HUDElements.sw_stats->version_vk.major,
HUDElements.sw_stats->version_vk.minor,
HUDElements.sw_stats->version_vk.patch);
}
} else {
ImGui::TextColored(HUDElements.sw_stats->colors.engine,
"%d.%d%s", HUDElements.sw_stats->version_gl.major, HUDElements.sw_stats->version_gl.minor,
HUDElements.sw_stats->version_gl.is_gles ? " ES" : "");
ImGui::TextColored(HUDElements.colors.engine,
"%d.%d%s", HUDElements.sw_stats->version_gl.major, HUDElements.sw_stats->version_gl.minor,
HUDElements.sw_stats->version_gl.is_gles ? " ES" : "");
}
ImGui::PopFont();
}
@ -292,7 +375,7 @@ void HudElements::vulkan_driver(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_vulkan_driver] && !HUDElements.sw_stats->driverName.empty()){
ImGui::TableNextRow();
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine,
ImGui::TextColored(HUDElements.colors.engine,
"%s", HUDElements.sw_stats->driverName.c_str());
ImGui::PopFont();
}
@ -302,7 +385,7 @@ void HudElements::arch(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_arch]){
ImGui::TableNextRow();
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "" MANGOHUD_ARCH);
ImGui::TextColored(HUDElements.colors.engine, "%s", "" MANGOHUD_ARCH);
ImGui::PopFont();
}
}
@ -312,7 +395,7 @@ void HudElements::wine(){
ImGui::TableNextRow();
if (!wineVersion.empty()){
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.wine, "%s", wineVersion.c_str());
ImGui::TextColored(HUDElements.colors.wine, "%s", wineVersion.c_str());
ImGui::PopFont();
}
}
@ -323,7 +406,7 @@ void HudElements::frame_timing(){
ImGui::TableNextRow();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "Frametime");
ImGui::TextColored(HUDElements.colors.engine, "%s", "Frametime");
ImGui::PopFont();
ImGui::TableNextRow();
char hash[40];
@ -334,20 +417,20 @@ void HudElements::frame_timing(){
double min_time = 0.0f;
double max_time = 50.0f;
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_histogram]){
ImGui::PlotHistogram(hash, get_time_stat, HUDElements.sw_stats,
ImGui::PlotHistogram(hash, get_time_stat, HUDElements.sw_stats,
ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0,
NULL, min_time, max_time,
ImVec2(ImGui::GetContentRegionAvailWidth() * 2.5, 50));
} else {
ImGui::PlotLines(hash, get_time_stat, HUDElements.sw_stats,
ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0,
NULL, min_time, max_time,
ImVec2(ImGui::GetContentRegionAvailWidth() * 2.5, 50));
ImGui::PlotLines(hash, get_time_stat, HUDElements.sw_stats,
ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0,
NULL, min_time, max_time,
ImVec2(ImGui::GetContentRegionAvailWidth() * 2.5, 50));
}
ImGui::PopStyleColor();
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("%.1f ms", 1000 / HUDElements.sw_stats->fps); //frame_timing / 1000.f);
ImGui::Text("%.1f ms", 1000 / HUDElements.sw_stats->fps);
ImGui::PopFont();
}
}
@ -378,6 +461,7 @@ void HudElements::graphs(){
{
arr.push_back(0);
}
if (value == "cpu_load"){
for (auto& it : graph_data){
arr.push_back(float(it.cpu_load));
@ -385,7 +469,7 @@ void HudElements::graphs(){
}
HUDElements.max = 100; HUDElements.min = 0;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "CPU Load");
ImGui::TextColored(HUDElements.colors.engine, "%s", "CPU Load");
ImGui::PopFont();
}
@ -396,7 +480,7 @@ void HudElements::graphs(){
}
HUDElements.max = 100; HUDElements.min = 0;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "GPU Load");
ImGui::TextColored(HUDElements.colors.engine, "%s", "GPU Load");
ImGui::PopFont();
}
@ -409,10 +493,11 @@ void HudElements::graphs(){
}
if (int(arr.back()) > HUDElements.cpu_temp_max)
HUDElements.cpu_temp_max = arr.back();
HUDElements.max = HUDElements.cpu_temp_max;
HUDElements.min = 0;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "CPU Temp");
ImGui::TextColored(HUDElements.colors.engine, "%s", "CPU Temp");
ImGui::PopFont();
}
@ -425,13 +510,14 @@ void HudElements::graphs(){
}
if (int(arr.back()) > HUDElements.gpu_temp_max)
HUDElements.gpu_temp_max = arr.back();
HUDElements.max = HUDElements.gpu_temp_max;
HUDElements.min = 0;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "GPU Temp");
ImGui::TextColored(HUDElements.colors.engine, "%s", "GPU Temp");
ImGui::PopFont();
}
if (value == "gpu_core_clock"){
for (auto& it : graph_data){
arr.push_back(float(it.gpu_core_clock));
@ -439,10 +525,11 @@ void HudElements::graphs(){
}
if (int(arr.back()) > HUDElements.gpu_core_max)
HUDElements.gpu_core_max = arr.back();
HUDElements.max = HUDElements.gpu_core_max;
HUDElements.min = 0;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "GPU Core Clock");
ImGui::TextColored(HUDElements.colors.engine, "%s", "GPU Core Clock");
ImGui::PopFont();
}
@ -453,22 +540,24 @@ void HudElements::graphs(){
}
if (int(arr.back()) > HUDElements.gpu_mem_max)
HUDElements.gpu_mem_max = arr.back();
HUDElements.max = HUDElements.gpu_mem_max;
HUDElements.min = 0;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "GPU Mem Clock");
ImGui::TextColored(HUDElements.colors.engine, "%s", "GPU Mem Clock");
ImGui::PopFont();
}
if (value == "vram"){
for (auto& it : graph_data){
arr.push_back(float(it.gpu_vram_used));
arr.erase(arr.begin());
}
HUDElements.max = gpu_info.memoryTotal;
HUDElements.min = 0;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "VRAM");
ImGui::TextColored(HUDElements.colors.engine, "%s", "VRAM");
ImGui::PopFont();
}
@ -479,12 +568,14 @@ void HudElements::graphs(){
arr.push_back(float(it.ram_used));
arr.erase(arr.begin());
}
HUDElements.max = memmax;
HUDElements.min = 0;
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.sw_stats->colors.engine, "%s", "RAM");
ImGui::TextColored(HUDElements.colors.engine, "%s", "RAM");
ImGui::PopFont();
}
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
ImGui::TableNextRow();
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_histogram]){
@ -518,7 +609,7 @@ void HudElements::sort_elements(std::pair<std::string, std::string> option){
if (param == "engine_version") { ordered_functions.push_back({engine_version, value}); }
if (param == "gpu_name") { ordered_functions.push_back({gpu_name, value}); }
if (param == "vulkan_driver") { ordered_functions.push_back({vulkan_driver, value}); }
if (param == "arch") { ordered_functions.push_back({arch, value}); }
if (param == "arch") { ordered_functions.push_back({arch, value}); }
if (param == "wine") { ordered_functions.push_back({wine, value}); }
if (param == "frame_timing") { ordered_functions.push_back({frame_timing, value}); }
if (param == "media_player") { ordered_functions.push_back({media_player, value}); }

@ -39,6 +39,29 @@ class HudElements{
static void frame_timing();
static void media_player();
static void graphs();
void convert_colors(struct overlay_params& params);
void convert_colors(bool do_conv, struct overlay_params& params);
struct hud_colors {
bool convert, update;
ImVec4 cpu,
gpu,
vram,
ram,
engine,
io,
frametime,
background,
text,
media_player,
wine,
gpu_load_high,
gpu_load_med,
gpu_load_low,
cpu_load_high,
cpu_load_med,
cpu_load_low;
} colors {};
};
extern HudElements HUDElements;

@ -1,6 +1,5 @@
#include <sstream>
#include <iomanip>
#include <ctime>
#include <algorithm>
#include "overlay.h"
#include "logging.h"
@ -10,7 +9,11 @@
#include "timing.hpp"
#include "mesa/util/macros.h"
#include "string_utils.h"
#ifdef HAVE_DBUS
float g_overflow = 50.f /* 3333ms * 0.5 / 16.6667 / 2 (to edge and back) */;
#endif
bool open = false;
struct benchmark_stats benchmark;
struct fps_limit fps_limit_stats {};
ImVec2 real_font_size;
@ -144,3 +147,286 @@ void calculate_benchmark_data(void *params_void){
entry.first.append(max_label_size - entry.first.length(), ' ');
}
}
float get_time_stat(void *_data, int _idx)
{
struct swapchain_stats *data = (struct swapchain_stats *) _data;
if ((ARRAY_SIZE(data->frames_stats) - _idx) > data->n_frames)
return 0.0f;
int idx = ARRAY_SIZE(data->frames_stats) +
data->n_frames < ARRAY_SIZE(data->frames_stats) ?
_idx - data->n_frames :
_idx + data->n_frames;
idx %= ARRAY_SIZE(data->frames_stats);
/* Time stats are in us. */
return data->frames_stats[idx].stats[data->stat_selector] / data->time_dividor;
}
void position_layer(struct swapchain_stats& data, struct overlay_params& params, ImVec2 window_size)
{
unsigned width = ImGui::GetIO().DisplaySize.x;
unsigned height = ImGui::GetIO().DisplaySize.y;
float margin = 10.0f;
if (params.offset_x > 0 || params.offset_y > 0)
margin = 0.0f;
ImGui::SetNextWindowBgAlpha(params.background_alpha);
ImGui::SetNextWindowSize(window_size, ImGuiCond_Always);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8,-3));
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, params.alpha);
switch (params.position) {
case LAYER_POSITION_TOP_LEFT:
data.main_window_pos = ImVec2(margin + params.offset_x, margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
case LAYER_POSITION_TOP_RIGHT:
data.main_window_pos = ImVec2(width - window_size.x - margin + params.offset_x, margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
case LAYER_POSITION_BOTTOM_LEFT:
data.main_window_pos = ImVec2(margin + params.offset_x, height - window_size.y - margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
case LAYER_POSITION_BOTTOM_RIGHT:
data.main_window_pos = ImVec2(width - window_size.x - margin + params.offset_x, height - window_size.y - margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
case LAYER_POSITION_TOP_CENTER:
data.main_window_pos = ImVec2((width / 2) - (window_size.x / 2), margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
}
}
void right_aligned_text(ImVec4& col, float off_x, const char *fmt, ...)
{
ImVec2 pos = ImGui::GetCursorPos();
char buffer[32] {};
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
ImVec2 sz = ImGui::CalcTextSize(buffer);
ImGui::SetCursorPosX(pos.x + off_x - sz.x);
//ImGui::Text("%s", buffer);
ImGui::TextColored(col,"%s",buffer);
}
float get_ticker_limited_pos(float pos, float tw, float& left_limit, float& right_limit)
{
//float cw = ImGui::GetContentRegionAvailWidth() * 3; // only table cell worth of width
float cw = ImGui::GetWindowContentRegionMax().x - ImGui::GetStyle().WindowPadding.x;
float new_pos_x = ImGui::GetCursorPosX();
left_limit = cw - tw + new_pos_x;
right_limit = new_pos_x;
if (cw < tw) {
new_pos_x += pos;
// acts as a delay before it starts scrolling again
if (new_pos_x < left_limit)
return left_limit;
else if (new_pos_x > right_limit)
return right_limit;
else
return new_pos_x;
}
return new_pos_x;
}
#ifdef HAVE_DBUS
void render_mpris_metadata(struct overlay_params& params, mutexed_metadata& meta, uint64_t frame_timing, bool is_main)
{
if (meta.meta.valid) {
auto color = ImGui::ColorConvertU32ToFloat4(params.media_player_color);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8,0));
ImGui::Dummy(ImVec2(0.0f, 20.0f));
//ImGui::PushFont(data.font1);
if (meta.ticker.needs_recalc) {
meta.ticker.tw0 = ImGui::CalcTextSize(meta.meta.title.c_str()).x;
meta.ticker.tw1 = ImGui::CalcTextSize(meta.meta.artists.c_str()).x;
meta.ticker.tw2 = ImGui::CalcTextSize(meta.meta.album.c_str()).x;
meta.ticker.longest = std::max(std::max(
meta.ticker.tw0,
meta.ticker.tw1),
meta.ticker.tw2);
meta.ticker.needs_recalc = false;
}
float new_pos, left_limit = 0, right_limit = 0;
get_ticker_limited_pos(meta.ticker.pos, meta.ticker.longest, left_limit, right_limit);
if (meta.ticker.pos < left_limit - g_overflow * .5f) {
meta.ticker.dir = -1;
meta.ticker.pos = (left_limit - g_overflow * .5f) + 1.f /* random */;
} else if (meta.ticker.pos > right_limit + g_overflow) {
meta.ticker.dir = 1;
meta.ticker.pos = (right_limit + g_overflow) - 1.f /* random */;
}
meta.ticker.pos -= .5f * (frame_timing / 16666.7f) * meta.ticker.dir;
for (auto order : params.media_player_order) {
switch (order) {
case MP_ORDER_TITLE:
{
new_pos = get_ticker_limited_pos(meta.ticker.pos, meta.ticker.tw0, left_limit, right_limit);
ImGui::SetCursorPosX(new_pos);
ImGui::TextColored(color, "%s", meta.meta.title.c_str());
}
break;
case MP_ORDER_ARTIST:
{
new_pos = get_ticker_limited_pos(meta.ticker.pos, meta.ticker.tw1, left_limit, right_limit);
ImGui::SetCursorPosX(new_pos);
ImGui::TextColored(color, "%s", meta.meta.artists.c_str());
}
break;
case MP_ORDER_ALBUM:
{
//ImGui::NewLine();
if (!meta.meta.album.empty()) {
new_pos = get_ticker_limited_pos(meta.ticker.pos, meta.ticker.tw2, left_limit, right_limit);
ImGui::SetCursorPosX(new_pos);
ImGui::TextColored(color, "%s", meta.meta.album.c_str());
}
}
break;
default: break;
}
}
if (!meta.meta.playing) {
ImGui::TextColored(color, "(paused)");
}
//ImGui::PopFont();
ImGui::PopStyleVar();
}
}
#endif
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 = (2 + benchmark.percentile_data.size()) * real_font_size.x + 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);
float display_time = std::chrono::duration<float>(now - logger->last_log_end()).count();
static float display_for = 10.0f;
float alpha;
if(params.background_alpha != 0){
if (display_for >= display_time){
alpha = display_time * params.background_alpha;
if (alpha >= params.background_alpha){
ImGui::SetNextWindowBgAlpha(params.background_alpha);
}else{
ImGui::SetNextWindowBgAlpha(alpha);
}
} else {
alpha = 6.0 - display_time * params.background_alpha;
if (alpha >= params.background_alpha){
ImGui::SetNextWindowBgAlpha(params.background_alpha);
}else{
ImGui::SetNextWindowBgAlpha(alpha);
}
}
} else {
if (display_for >= display_time){
alpha = display_time * 0.0001;
ImGui::SetNextWindowBgAlpha(params.background_alpha);
} else {
alpha = 6.0 - display_time * 0.0001;
ImGui::SetNextWindowBgAlpha(params.background_alpha);
}
}
ImGui::Begin("Benchmark", &open, ImGuiWindowFlags_NoDecoration);
static const char* finished = "Logging Finished";
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(finished).x / 2));
ImGui::TextColored(ImVec4(1.0, 1.0, 1.0, alpha / params.background_alpha), "%s", finished);
ImGui::Dummy(ImVec2(0.0f, 8.0f));
char duration[20];
snprintf(duration, sizeof(duration), "Duration: %.1fs", std::chrono::duration<float>(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.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));
ImGui::TextColored(ImVec4(1.0, 1.0, 1.0, alpha / params.background_alpha), "%s %.1f", data_.first.c_str(), data_.second);
}
float max = *max_element(benchmark.fps_data.begin(), benchmark.fps_data.end());
ImVec4 plotColor = HUDElements.colors.frametime;
plotColor.w = alpha / params.background_alpha;
ImGui::PushStyleColor(ImGuiCol_PlotLines, plotColor);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0, 0.0, 0.0, alpha / params.background_alpha));
ImGui::Dummy(ImVec2(0.0f, 8.0f));
if (params.enabled[OVERLAY_PARAM_ENABLED_histogram])
ImGui::PlotHistogram("", benchmark.fps_data.data(), benchmark.fps_data.size(), 0, "", 0.0f, max + 10, ImVec2(ImGui::GetContentRegionAvailWidth(), 50));
else
ImGui::PlotLines("", benchmark.fps_data.data(), benchmark.fps_data.size(), 0, "", 0.0f, max + 10, ImVec2(ImGui::GetContentRegionAvailWidth(), 50));
ImGui::PopStyleColor(2);
ImGui::End();
}
ImVec4 change_on_load_temp(LOAD_DATA& data, int current)
{
if (current >= data.high_load){
return data.color_high;
}
else if (current >= data.med_load){
float diff = float(current - data.med_load) / float(data.high_load - data.med_load);
float x = (data.color_high.x - data.color_med.x) * diff;
float y = (data.color_high.y - data.color_med.y) * diff;
float z = (data.color_high.z - data.color_med.z) * diff;
return ImVec4(data.color_med.x + x, data.color_med.y + y, data.color_med.z + z, 1.0);
} else {
float diff = float(current) / float(data.med_load);
float x = (data.color_med.x - data.color_low.x) * diff;
float y = (data.color_med.y - data.color_low.y) * diff;
float z = (data.color_med.z - data.color_low.z) * diff;
return ImVec4(data.color_low.x + x, data.color_low.y + y, data.color_low.z + z, 1.0);
}
}
void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, bool is_vulkan)
{
HUDElements.sw_stats = &data; HUDElements.params = &params;
HUDElements.is_vulkan = is_vulkan;
ImGui::GetIO().FontGlobalScale = params.font_scale;
if(not logger) logger = std::make_unique<Logger>(&params);
static float ralign_width = 0, old_scale = 0;
window_size = ImVec2(params.width, params.height);
unsigned height = ImGui::GetIO().DisplaySize.y;
auto now = Clock::now();
if (old_scale != params.font_scale) {
HUDElements.ralign_width = ralign_width = ImGui::CalcTextSize("A").x * 4 /* characters */;
old_scale = params.font_scale;
}
if (!params.no_display){
ImGui::Begin("Main", &open, ImGuiWindowFlags_NoDecoration);
ImGui::BeginTable("hud", params.table_columns, ImGuiTableFlags_NoClipX);
HUDElements.place = 0;
for (auto& func : HUDElements.ordered_functions){
func.first();
HUDElements.place += 1;
}
ImGui::EndTable();
if(logger->is_active())
ImGui::GetWindowDrawList()->AddCircleFilled(ImVec2(data.main_window_pos.x + window_size.x - 15, data.main_window_pos.y + 15), 10, params.engine_color, 20);
window_size = ImVec2(window_size.x, ImGui::GetCursorPosY() + 10.0f);
ImGui::End();
if((now - logger->last_log_end()) < 12s)
render_benchmark(data, params, window_size, height, now);
}
}

@ -53,25 +53,6 @@ struct swapchain_stats {
std::string deviceName;
std::string gpuName;
std::string driverName;
struct {
ImVec4 cpu,
gpu,
vram,
ram,
engine,
io,
frametime,
background,
text,
media_player,
wine,
gpu_load_high,
gpu_load_med,
gpu_load_low,
cpu_load_high,
cpu_load_med,
cpu_load_low;
} colors;
};
struct fps_limit {
@ -116,9 +97,8 @@ 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 *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);
void right_aligned_text(ImVec4& col, float off_x, const char *fmt, ...);
ImVec4 change_on_load_temp (struct LOAD_DATA& data, int current);
ImVec4 change_on_load_temp(LOAD_DATA& data, int current);
float get_time_stat(void *_data, int _idx);
#ifdef HAVE_DBUS

@ -633,16 +633,15 @@ parse_overlay_config(struct overlay_params *params,
&params->cpu_load_color[0],
&params->cpu_load_color[1],
&params->cpu_load_color[2],
};
for (auto color : colors){
*color =
IM_COL32(RGBGetRValue(*color),
*color =
IM_COL32(RGBGetRValue(*color),
RGBGetGValue(*color),
RGBGetBValue(*color),
255);
}
}
if (!params->table_columns)
params->table_columns = 3;
@ -678,8 +677,10 @@ parse_overlay_config(struct overlay_params *params,
main_metadata.meta.valid = false;
}
#endif
if(!params->output_file.empty())
printf("MANGOHUD: output_file is Deprecated, use output_folder instead\n");
auto real_size = params->font_size * params->font_scale;
real_font_size = ImVec2(real_size, real_size / 2);
HUDElements.params = params;
@ -689,4 +690,7 @@ parse_overlay_config(struct overlay_params *params,
for (auto& option : HUDElements.options)
HUDElements.sort_elements(option);
}
// Needs ImGui context but it is null here for OpenGL so just note it and update somewhere else
HUDElements.colors.update = true;
}

@ -33,7 +33,6 @@
#include <vector>
#include <list>
#include <array>
#include <cmath>
#include <libgen.h>
#include <vulkan/vulkan.h>
@ -64,11 +63,6 @@
#include "pci_ids.h"
#include "timing.hpp"
#ifdef HAVE_DBUS
float g_overflow = 50.f /* 3333ms * 0.5 / 16.6667 / 2 (to edge and back) */;
#endif
bool open = false;
string gpuString,wineVersion,wineProcess;
float offset_x, offset_y, hudSpacing;
int hudFirstRow, hudSecondRow;
@ -689,293 +683,15 @@ static void snapshot_swapchain_frame(struct swapchain_data *data)
// }
}
float get_time_stat(void *_data, int _idx)
{
struct swapchain_stats *data = (struct swapchain_stats *) _data;
if ((ARRAY_SIZE(data->frames_stats) - _idx) > data->n_frames)
return 0.0f;
int idx = ARRAY_SIZE(data->frames_stats) +
data->n_frames < ARRAY_SIZE(data->frames_stats) ?
_idx - data->n_frames :
_idx + data->n_frames;
idx %= ARRAY_SIZE(data->frames_stats);
/* Time stats are in us. */
return data->frames_stats[idx].stats[data->stat_selector] / data->time_dividor;
}
void position_layer(struct swapchain_stats& data, struct overlay_params& params, ImVec2 window_size)
{
unsigned width = ImGui::GetIO().DisplaySize.x;
unsigned height = ImGui::GetIO().DisplaySize.y;
float margin = 10.0f;
if (params.offset_x > 0 || params.offset_y > 0)
margin = 0.0f;
ImGui::SetNextWindowBgAlpha(params.background_alpha);
ImGui::SetNextWindowSize(window_size, ImGuiCond_Always);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8,-3));
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, params.alpha);
switch (params.position) {
case LAYER_POSITION_TOP_LEFT:
data.main_window_pos = ImVec2(margin + params.offset_x, margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
case LAYER_POSITION_TOP_RIGHT:
data.main_window_pos = ImVec2(width - window_size.x - margin + params.offset_x, margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
case LAYER_POSITION_BOTTOM_LEFT:
data.main_window_pos = ImVec2(margin + params.offset_x, height - window_size.y - margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
case LAYER_POSITION_BOTTOM_RIGHT:
data.main_window_pos = ImVec2(width - window_size.x - margin + params.offset_x, height - window_size.y - margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
case LAYER_POSITION_TOP_CENTER:
data.main_window_pos = ImVec2((width / 2) - (window_size.x / 2), margin + params.offset_y);
ImGui::SetNextWindowPos(data.main_window_pos, ImGuiCond_Always);
break;
}
}
void right_aligned_text(ImVec4& col, float off_x, const char *fmt, ...)
{
ImVec2 pos = ImGui::GetCursorPos();
char buffer[32] {};
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
ImVec2 sz = ImGui::CalcTextSize(buffer);
ImGui::SetCursorPosX(pos.x + off_x - sz.x);
//ImGui::Text("%s", buffer);
ImGui::TextColored(col,"%s",buffer);
}
float get_ticker_limited_pos(float pos, float tw, float& left_limit, float& right_limit)
{
float cw = ImGui::GetContentRegionAvailWidth();
float new_pos_x = ImGui::GetCursorPosX();
left_limit = cw - tw + new_pos_x;
right_limit = new_pos_x;
if (cw < tw) {
new_pos_x += pos;
// acts as a delay before it starts scrolling again
if (new_pos_x < left_limit)
return left_limit;
else if (new_pos_x > right_limit)
return right_limit;
else
return new_pos_x;
}
return new_pos_x;
}
#ifdef HAVE_DBUS
void render_mpris_metadata(struct overlay_params& params, mutexed_metadata& meta, uint64_t frame_timing, bool is_main)
{
if (meta.meta.valid) {
auto color = ImGui::ColorConvertU32ToFloat4(params.media_player_color);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8,0));
ImGui::Dummy(ImVec2(0.0f, 20.0f));
//ImGui::PushFont(data.font1);
if (meta.ticker.needs_recalc) {
meta.ticker.tw0 = ImGui::CalcTextSize(meta.meta.title.c_str()).x;
meta.ticker.tw1 = ImGui::CalcTextSize(meta.meta.artists.c_str()).x;
meta.ticker.tw2 = ImGui::CalcTextSize(meta.meta.album.c_str()).x;
meta.ticker.longest = std::max(std::max(
meta.ticker.tw0,
meta.ticker.tw1),
meta.ticker.tw2);
meta.ticker.needs_recalc = false;
}
float new_pos, left_limit = 0, right_limit = 0;
get_ticker_limited_pos(meta.ticker.pos, meta.ticker.longest, left_limit, right_limit);
if (meta.ticker.pos < left_limit - g_overflow * .5f) {
meta.ticker.dir = -1;
meta.ticker.pos = (left_limit - g_overflow * .5f) + 1.f /* random */;
} else if (meta.ticker.pos > right_limit + g_overflow) {
meta.ticker.dir = 1;
meta.ticker.pos = (right_limit + g_overflow) - 1.f /* random */;
}
meta.ticker.pos -= .5f * (frame_timing / 16666.7f) * meta.ticker.dir;
for (auto order : params.media_player_order) {
switch (order) {
case MP_ORDER_TITLE:
{
new_pos = get_ticker_limited_pos(meta.ticker.pos, meta.ticker.tw0, left_limit, right_limit);
ImGui::SetCursorPosX(new_pos);
ImGui::TextColored(color, "%s", meta.meta.title.c_str());
}
break;
case MP_ORDER_ARTIST:
{
new_pos = get_ticker_limited_pos(meta.ticker.pos, meta.ticker.tw1, left_limit, right_limit);
ImGui::SetCursorPosX(new_pos);
ImGui::TextColored(color, "%s", meta.meta.artists.c_str());
}
break;
case MP_ORDER_ALBUM:
{
//ImGui::NewLine();
if (!meta.meta.album.empty()) {
new_pos = get_ticker_limited_pos(meta.ticker.pos, meta.ticker.tw2, left_limit, right_limit);
ImGui::SetCursorPosX(new_pos);
ImGui::TextColored(color, "%s", meta.meta.album.c_str());
}
}
break;
default: break;
}
}
if (!meta.meta.playing) {
ImGui::TextColored(color, "(paused)");
}
//ImGui::PopFont();
ImGui::PopStyleVar();
}
}
#endif
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 = (2 + benchmark.percentile_data.size()) * real_font_size.x + 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);
float display_time = std::chrono::duration<float>(now - logger->last_log_end()).count();
static float display_for = 10.0f;
float alpha;
if(params.background_alpha != 0){
if (display_for >= display_time){
alpha = display_time * params.background_alpha;
if (alpha >= params.background_alpha){
ImGui::SetNextWindowBgAlpha(params.background_alpha);
}else{
ImGui::SetNextWindowBgAlpha(alpha);
}
} else {
alpha = 6.0 - display_time * params.background_alpha;
if (alpha >= params.background_alpha){
ImGui::SetNextWindowBgAlpha(params.background_alpha);
}else{
ImGui::SetNextWindowBgAlpha(alpha);
}
}
} else {
if (display_for >= display_time){
alpha = display_time * 0.0001;
ImGui::SetNextWindowBgAlpha(params.background_alpha);
} else {
alpha = 6.0 - display_time * 0.0001;
ImGui::SetNextWindowBgAlpha(params.background_alpha);
}
}
ImGui::Begin("Benchmark", &open, ImGuiWindowFlags_NoDecoration);
static const char* finished = "Logging Finished";
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(finished).x / 2));
ImGui::TextColored(ImVec4(1.0, 1.0, 1.0, alpha / params.background_alpha), "%s", finished);
ImGui::Dummy(ImVec2(0.0f, 8.0f));
char duration[20];
snprintf(duration, sizeof(duration), "Duration: %.1fs", std::chrono::duration<float>(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.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));
ImGui::TextColored(ImVec4(1.0, 1.0, 1.0, alpha / params.background_alpha), "%s %.1f", data_.first.c_str(), data_.second);
}
float max = *max_element(benchmark.fps_data.begin(), benchmark.fps_data.end());
ImVec4 plotColor = data.colors.frametime;
plotColor.w = alpha / params.background_alpha;
ImGui::PushStyleColor(ImGuiCol_PlotLines, plotColor);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0, 0.0, 0.0, alpha / params.background_alpha));
ImGui::Dummy(ImVec2(0.0f, 8.0f));
if (params.enabled[OVERLAY_PARAM_ENABLED_histogram])
ImGui::PlotHistogram("", benchmark.fps_data.data(), benchmark.fps_data.size(), 0, "", 0.0f, max + 10, ImVec2(ImGui::GetContentRegionAvailWidth(), 50));
else
ImGui::PlotLines("", benchmark.fps_data.data(), benchmark.fps_data.size(), 0, "", 0.0f, max + 10, ImVec2(ImGui::GetContentRegionAvailWidth(), 50));
ImGui::PopStyleColor(2);
ImGui::End();
}
ImVec4 change_on_load_temp (struct LOAD_DATA& data, int current) {
if (current >= data.high_load){
return data.color_high;
}
else if (current >= data.med_load){
float diff = float(current - data.med_load) / float(data.high_load - data.med_load);
float x = (data.color_high.x - data.color_med.x) * diff;
float y = (data.color_high.y - data.color_med.y) * diff;
float z = (data.color_high.z - data.color_med.z) * diff;
return ImVec4(data.color_med.x + x, data.color_med.y + y, data.color_med.z + z, 1.0);
} else {
float diff = float(current) / float(data.med_load);
float x = (data.color_med.x - data.color_low.x) * diff;
float y = (data.color_med.y - data.color_low.y) * diff;
float z = (data.color_med.z - data.color_low.z) * diff;
return ImVec4(data.color_low.x + x, data.color_low.y + y, data.color_low.z + z, 1.0);
}
}
void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, bool is_vulkan)
{
HUDElements.sw_stats = &data; HUDElements.params = &params;
HUDElements.is_vulkan = is_vulkan;
ImGui::GetIO().FontGlobalScale = params.font_scale;
if(not logger) logger = std::make_unique<Logger>(&params);
static float ralign_width = 0, old_scale = 0;
window_size = ImVec2(params.width, params.height);
unsigned height = ImGui::GetIO().DisplaySize.y;
auto now = Clock::now();
if (old_scale != params.font_scale) {
HUDElements.ralign_width = ralign_width = ImGui::CalcTextSize("A").x * 4 /* characters */;
old_scale = params.font_scale;
}
if (!params.no_display){
ImGui::Begin("Main", &open, ImGuiWindowFlags_NoDecoration);
ImGui::BeginTable("hud", params.table_columns, ImGuiTableFlags_NoClipX);
HUDElements.place = 0;
for (auto& func : HUDElements.ordered_functions){
func.first();
HUDElements.place += 1;
}
ImGui::EndTable();
if(logger->is_active())
ImGui::GetWindowDrawList()->AddCircleFilled(ImVec2(data.main_window_pos.x + window_size.x - 15, data.main_window_pos.y + 15), 10, params.engine_color, 20);
window_size = ImVec2(window_size.x, ImGui::GetCursorPosY() + 10.0f);
ImGui::End();
if((now - logger->last_log_end()) < 12s)
render_benchmark(data, params, window_size, height, now);
}
}
static void compute_swapchain_display(struct swapchain_data *data)
{
struct device_data *device_data = data->device;
struct instance_data *instance_data = device_data->instance;
ImGui::SetCurrentContext(data->imgui_context);
if (HUDElements.colors.update)
HUDElements.convert_colors(instance_data->params);
ImGui::NewFrame();
{
scoped_lock lk(instance_data->notifier.mutex);
@ -1712,81 +1428,6 @@ static void setup_swapchain_data_pipeline(struct swapchain_data *data)
// update_image_descriptor(data, data->font_image_view[0], data->descriptor_set);
}
// Cut from https://github.com/ocornut/imgui/pull/2943
// Probably move to ImGui
float SRGBToLinear(float in)
{
if (in <= 0.04045f)
return in / 12.92f;
else
return powf((in + 0.055f) / 1.055f, 2.4f);
}
float LinearToSRGB(float in)
{
if (in <= 0.0031308f)
return in * 12.92f;
else
return 1.055f * powf(in, 1.0f / 2.4f) - 0.055f;
}
ImVec4 SRGBToLinear(ImVec4 col)
{
col.x = SRGBToLinear(col.x);
col.y = SRGBToLinear(col.y);
col.z = SRGBToLinear(col.z);
// Alpha component is already linear
return col;
}
ImVec4 LinearToSRGB(ImVec4 col)
{
col.x = LinearToSRGB(col.x);
col.y = LinearToSRGB(col.y);
col.z = LinearToSRGB(col.z);
// Alpha component is already linear
return col;
}
void convert_colors(bool do_conv, struct swapchain_stats& sw_stats, struct overlay_params& params)
{
auto convert = [&do_conv](unsigned color) -> ImVec4 {
ImVec4 fc = ImGui::ColorConvertU32ToFloat4(color);
if (do_conv)
return SRGBToLinear(fc);
return fc;
};
sw_stats.colors.cpu = convert(params.cpu_color);
sw_stats.colors.gpu = convert(params.gpu_color);
sw_stats.colors.vram = convert(params.vram_color);
sw_stats.colors.ram = convert(params.ram_color);
sw_stats.colors.engine = convert(params.engine_color);
sw_stats.colors.io = convert(params.io_color);
sw_stats.colors.frametime = convert(params.frametime_color);
sw_stats.colors.background = convert(params.background_color);
sw_stats.colors.text = convert(params.text_color);
sw_stats.colors.media_player = convert(params.media_player_color);
sw_stats.colors.wine = convert(params.wine_color);
sw_stats.colors.gpu_load_high = convert(params.gpu_load_color[0]);
sw_stats.colors.gpu_load_med = convert(params.gpu_load_color[1]);
sw_stats.colors.gpu_load_low = convert(params.gpu_load_color[2]);
sw_stats.colors.cpu_load_high = convert(params.cpu_load_color[0]);
sw_stats.colors.cpu_load_med = convert(params.cpu_load_color[1]);
sw_stats.colors.cpu_load_low = convert(params.cpu_load_color[2]);
ImGuiStyle& style = ImGui::GetStyle();
style.Colors[ImGuiCol_PlotLines] = convert(params.frametime_color);
style.Colors[ImGuiCol_PlotHistogram] = convert(params.frametime_color);
style.Colors[ImGuiCol_WindowBg] = convert(params.background_color);
style.Colors[ImGuiCol_Text] = convert(params.text_color);
style.CellPadding.y = params.cellpadding_y * real_font_size.y;
}
// TODO probably needs colorspace check too
static void convert_colors_vk(VkFormat format, struct swapchain_stats& sw_stats, struct overlay_params& params)
{
@ -1831,7 +1472,7 @@ static void convert_colors_vk(VkFormat format, struct swapchain_stats& sw_stats,
break;
}
convert_colors(do_conv, sw_stats, params);
HUDElements.convert_colors(do_conv, params);
}
static void setup_swapchain_data(struct swapchain_data *data,

Loading…
Cancel
Save