2020-09-06 08:30:57 +00:00
|
|
|
#include <sstream>
|
|
|
|
#include <iomanip>
|
2020-09-06 08:58:16 +00:00
|
|
|
#include <algorithm>
|
2020-03-10 05:19:18 +00:00
|
|
|
#include "overlay.h"
|
2020-01-28 04:11:05 +00:00
|
|
|
#include "logging.h"
|
2020-02-01 23:55:24 +00:00
|
|
|
#include "cpu.h"
|
2020-09-06 08:30:57 +00:00
|
|
|
#include "gpu.h"
|
2020-03-10 05:19:18 +00:00
|
|
|
#include "memory.h"
|
2020-06-24 12:41:34 +00:00
|
|
|
#include "timing.hpp"
|
2020-09-06 08:30:57 +00:00
|
|
|
#include "mesa/util/macros.h"
|
2020-09-06 08:58:16 +00:00
|
|
|
#include "string_utils.h"
|
2020-12-16 22:26:48 +00:00
|
|
|
|
|
|
|
#include "server/common.h"
|
|
|
|
|
|
|
|
// getpid, getuid
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
2020-11-17 18:23:33 +00:00
|
|
|
#ifdef HAVE_DBUS
|
|
|
|
float g_overflow = 50.f /* 3333ms * 0.5 / 16.6667 / 2 (to edge and back) */;
|
|
|
|
#endif
|
2020-09-06 08:58:16 +00:00
|
|
|
|
2020-11-17 18:23:33 +00:00
|
|
|
bool open = false;
|
2020-09-06 08:58:16 +00:00
|
|
|
struct benchmark_stats benchmark;
|
2020-09-06 11:52:18 +00:00
|
|
|
struct fps_limit fps_limit_stats {};
|
2020-09-23 10:23:29 +00:00
|
|
|
ImVec2 real_font_size;
|
2020-11-06 23:01:23 +00:00
|
|
|
std::vector<logData> graph_data;
|
2020-02-04 08:39:27 +00:00
|
|
|
|
2020-12-16 22:26:48 +00:00
|
|
|
extern std::string program_name;
|
|
|
|
|
|
|
|
static int mango_message_generator(Message* message, void* my_state) {
|
|
|
|
assert(message != NULL);
|
|
|
|
assert(my_state != NULL);
|
|
|
|
|
|
|
|
struct swapchain_stats *const sw_stats = (struct swapchain_stats *)my_state;
|
|
|
|
|
2020-12-17 15:39:51 +00:00
|
|
|
PB_MALLOC_SET(message->protocol_version, 1);
|
|
|
|
PB_MALLOC_SET(message->pid, getpid());
|
|
|
|
PB_MALLOC_SET(message->uid, getuid());
|
|
|
|
PB_MALLOC_SET(message->fps, fps);
|
2020-12-16 22:26:48 +00:00
|
|
|
if (program_name.size()) {
|
|
|
|
message->program_name = strndup(program_name.data(), program_name.length());
|
|
|
|
}
|
2020-12-17 15:39:51 +00:00
|
|
|
PB_MALLOC_SET(message->render_info, RenderInfo_init_zero);
|
2020-12-16 22:26:48 +00:00
|
|
|
if (sw_stats->version_gl.major && sw_stats->version_gl.minor) {
|
2020-12-17 15:39:51 +00:00
|
|
|
PB_MALLOC_SET(message->render_info->opengl, true);
|
2020-12-16 22:26:48 +00:00
|
|
|
}
|
|
|
|
if (sw_stats->version_vk.major && sw_stats->version_vk.minor) {
|
2020-12-17 15:39:51 +00:00
|
|
|
PB_MALLOC_SET(message->render_info->vulkan, true);
|
2020-12-16 22:26:48 +00:00
|
|
|
}
|
|
|
|
RenderInfo *const render_info = message->render_info;
|
|
|
|
render_info->engine_name = strndup(sw_stats->engineName.data(), sw_stats->engineName.length());
|
|
|
|
render_info->vulkan_driver_name = strndup(sw_stats->driverName.data(), sw_stats->driverName.length());
|
|
|
|
|
|
|
|
// More stuff to copy from sw_stats
|
|
|
|
/*
|
|
|
|
std::string engineName;
|
|
|
|
std::string engineVersion;
|
|
|
|
std::string deviceName;
|
|
|
|
std::string gpuName;
|
|
|
|
std::string driverName;
|
|
|
|
|
|
|
|
uint64_t n_frames;
|
|
|
|
enum overlay_plots stat_selector;
|
|
|
|
double time_dividor;
|
|
|
|
struct frame_stat stats_min, stats_max;
|
|
|
|
struct frame_stat frames_stats[200];
|
|
|
|
|
|
|
|
|
|
|
|
std::string time;
|
|
|
|
double fps;
|
|
|
|
struct iostats io;
|
|
|
|
uint64_t last_present_time;
|
|
|
|
unsigned n_frames_since_update;
|
|
|
|
uint64_t last_fps_update;
|
|
|
|
ImVec2 main_window_pos;
|
|
|
|
|
|
|
|
|
|
|
|
struct {
|
|
|
|
int32_t major;
|
|
|
|
int32_t minor;
|
|
|
|
bool is_gles;
|
|
|
|
} version_gl;
|
|
|
|
struct {
|
|
|
|
int32_t major;
|
|
|
|
int32_t minor;
|
|
|
|
int32_t patch;
|
|
|
|
} version_vk;
|
|
|
|
*/
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mango_message_handler(const Message* const message, void* my_state) {
|
|
|
|
assert(message != NULL);
|
|
|
|
assert(my_state != NULL);
|
|
|
|
|
|
|
|
// DEBUG(fprintf(stderr, "client_request_handler called\n"));
|
|
|
|
|
|
|
|
struct swapchain_stats *const sw_stats = (struct swapchain_stats *)my_state;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-08-11 18:45:42 +00:00
|
|
|
void update_hw_info(struct swapchain_stats& sw_stats, struct overlay_params& params, uint32_t vendorID)
|
|
|
|
{
|
|
|
|
if (params.enabled[OVERLAY_PARAM_ENABLED_cpu_stats] || logger->is_active()) {
|
|
|
|
cpuStats.UpdateCPUData();
|
2020-09-06 11:52:18 +00:00
|
|
|
#ifdef __gnu_linux__
|
2020-08-11 18:45:42 +00:00
|
|
|
|
2020-11-12 12:19:22 +00:00
|
|
|
if (params.enabled[OVERLAY_PARAM_ENABLED_core_load] || params.enabled[OVERLAY_PARAM_ENABLED_cpu_mhz])
|
2020-08-11 18:45:42 +00:00
|
|
|
cpuStats.UpdateCoreMhz();
|
2020-11-27 18:15:51 +00:00
|
|
|
if (params.enabled[OVERLAY_PARAM_ENABLED_cpu_temp] || logger->is_active() || params.enabled[OVERLAY_PARAM_ENABLED_graphs])
|
2020-08-11 18:45:42 +00:00
|
|
|
cpuStats.UpdateCpuTemp();
|
2020-11-12 21:27:35 +00:00
|
|
|
if (params.enabled[OVERLAY_PARAM_ENABLED_cpu_power])
|
|
|
|
cpuStats.UpdateCpuPower();
|
2020-09-06 11:52:18 +00:00
|
|
|
#endif
|
2020-08-11 18:45:42 +00:00
|
|
|
}
|
|
|
|
if (params.enabled[OVERLAY_PARAM_ENABLED_gpu_stats] || logger->is_active()) {
|
|
|
|
if (vendorID == 0x1002)
|
|
|
|
getAmdGpuInfo();
|
2020-06-21 11:44:12 +00:00
|
|
|
|
2020-08-11 18:45:42 +00:00
|
|
|
if (vendorID == 0x10de)
|
|
|
|
getNvidiaGpuInfo();
|
|
|
|
}
|
2020-06-21 11:44:12 +00:00
|
|
|
|
2020-08-11 18:45:42 +00:00
|
|
|
// get ram usage/max
|
2020-09-06 08:58:16 +00:00
|
|
|
|
2020-09-06 11:52:18 +00:00
|
|
|
#ifdef __gnu_linux__
|
2020-08-11 18:45:42 +00:00
|
|
|
if (params.enabled[OVERLAY_PARAM_ENABLED_ram] || logger->is_active())
|
|
|
|
update_meminfo();
|
|
|
|
if (params.enabled[OVERLAY_PARAM_ENABLED_io_read] || params.enabled[OVERLAY_PARAM_ENABLED_io_write])
|
|
|
|
getIoStats(&sw_stats.io);
|
2020-09-06 11:52:18 +00:00
|
|
|
#endif
|
2020-06-21 11:44:12 +00:00
|
|
|
|
2020-08-11 18:45:42 +00:00
|
|
|
currentLogData.gpu_load = gpu_info.load;
|
|
|
|
currentLogData.gpu_temp = gpu_info.temp;
|
|
|
|
currentLogData.gpu_core_clock = gpu_info.CoreClock;
|
|
|
|
currentLogData.gpu_mem_clock = gpu_info.MemClock;
|
|
|
|
currentLogData.gpu_vram_used = gpu_info.memoryUsed;
|
2020-09-06 11:52:18 +00:00
|
|
|
#ifdef __gnu_linux__
|
2020-08-11 18:45:42 +00:00
|
|
|
currentLogData.ram_used = memused;
|
2020-09-06 11:52:18 +00:00
|
|
|
#endif
|
2020-06-21 11:44:12 +00:00
|
|
|
|
2020-08-11 18:45:42 +00:00
|
|
|
currentLogData.cpu_load = cpuStats.GetCPUDataTotal().percent;
|
|
|
|
currentLogData.cpu_temp = cpuStats.GetCPUDataTotal().temp;
|
2020-11-06 23:01:23 +00:00
|
|
|
// Save data for graphs
|
|
|
|
if (graph_data.size() > 50)
|
|
|
|
graph_data.erase(graph_data.begin());
|
2020-12-03 20:26:00 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
float memused = 0;
|
|
|
|
#endif
|
2020-11-06 23:01:23 +00:00
|
|
|
graph_data.push_back({0, 0, cpuStats.GetCPUDataTotal().percent, gpu_info.load, cpuStats.GetCPUDataTotal().temp,
|
|
|
|
gpu_info.temp, gpu_info.CoreClock, gpu_info.MemClock, gpu_info.memoryUsed, memused});
|
2020-08-11 18:45:42 +00:00
|
|
|
logger->notify_data_valid();
|
2020-06-21 11:44:12 +00:00
|
|
|
}
|
|
|
|
|
2020-03-10 05:19:18 +00:00
|
|
|
void update_hud_info(struct swapchain_stats& sw_stats, struct overlay_params& params, uint32_t vendorID){
|
|
|
|
uint32_t f_idx = sw_stats.n_frames % ARRAY_SIZE(sw_stats.frames_stats);
|
|
|
|
uint64_t now = os_time_get(); /* us */
|
|
|
|
double elapsed = (double)(now - sw_stats.last_fps_update); /* us */
|
|
|
|
fps = 1000000.0f * sw_stats.n_frames_since_update / elapsed;
|
2020-06-21 16:52:38 +00:00
|
|
|
if (logger->is_active())
|
2020-05-16 11:35:50 +00:00
|
|
|
benchmark.fps_data.push_back(fps);
|
2020-01-28 04:11:05 +00:00
|
|
|
|
2020-03-10 05:19:18 +00:00
|
|
|
if (sw_stats.last_present_time) {
|
2020-03-24 19:38:08 +00:00
|
|
|
sw_stats.frames_stats[f_idx].stats[OVERLAY_PLOTS_frame_timing] =
|
2020-03-10 05:19:18 +00:00
|
|
|
now - sw_stats.last_present_time;
|
|
|
|
}
|
2020-03-14 16:47:03 +00:00
|
|
|
|
2020-09-06 05:56:29 +00:00
|
|
|
frametime = now - sw_stats.last_present_time;
|
|
|
|
if (elapsed >= params.fps_sampling_period) {
|
2020-12-14 05:54:29 +00:00
|
|
|
HUDElements.update_exec();
|
2020-09-06 05:56:29 +00:00
|
|
|
std::thread(update_hw_info, std::ref(sw_stats), std::ref(params), vendorID).detach();
|
|
|
|
sw_stats.fps = fps;
|
2020-03-14 17:11:34 +00:00
|
|
|
|
2020-09-06 05:56:29 +00:00
|
|
|
if (params.enabled[OVERLAY_PARAM_ENABLED_time]) {
|
|
|
|
std::time_t t = std::time(nullptr);
|
|
|
|
std::stringstream time;
|
|
|
|
time << std::put_time(std::localtime(&t), params.time_format.c_str());
|
|
|
|
sw_stats.time = time.str();
|
|
|
|
}
|
2020-03-14 17:11:34 +00:00
|
|
|
|
2020-09-06 05:56:29 +00:00
|
|
|
sw_stats.n_frames_since_update = 0;
|
|
|
|
sw_stats.last_fps_update = now;
|
2020-03-14 17:11:34 +00:00
|
|
|
|
2020-09-06 05:56:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (params.log_interval == 0){
|
|
|
|
logger->try_log();
|
|
|
|
}
|
2020-01-28 04:11:05 +00:00
|
|
|
|
2020-03-10 05:19:18 +00:00
|
|
|
sw_stats.last_present_time = now;
|
|
|
|
sw_stats.n_frames++;
|
|
|
|
sw_stats.n_frames_since_update++;
|
2020-12-16 22:26:48 +00:00
|
|
|
|
|
|
|
struct ClientState *const client_state = &(sw_stats.client_state);
|
|
|
|
|
|
|
|
if (!sw_stats.client_state_initialized) {
|
|
|
|
if (client_connect(client_state) == 0) {
|
|
|
|
client_state->connected = 1;
|
|
|
|
}
|
|
|
|
// Even if we fail to connect. Still mark as initialized.
|
|
|
|
sw_stats.client_state_initialized = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
client_maybe_communicate(client_state,
|
|
|
|
&mango_message_generator, (void*)(&sw_stats),
|
|
|
|
&mango_message_handler, (void*)(&sw_stats));
|
2020-09-06 08:58:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void calculate_benchmark_data(void *params_void){
|
|
|
|
overlay_params *params = reinterpret_cast<overlay_params *>(params_void);
|
|
|
|
|
|
|
|
vector<float> sorted = benchmark.fps_data;
|
|
|
|
std::sort(sorted.begin(), sorted.end());
|
|
|
|
benchmark.percentile_data.clear();
|
|
|
|
|
|
|
|
benchmark.total = 0.f;
|
|
|
|
for (auto fps_ : sorted){
|
|
|
|
benchmark.total = benchmark.total + fps_;
|
|
|
|
}
|
|
|
|
|
|
|
|
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(), ' ');
|
|
|
|
}
|
2020-08-17 06:09:01 +00:00
|
|
|
}
|
2020-11-17 18:23:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2020-12-06 22:03:42 +00:00
|
|
|
void center_text(std::string& text)
|
|
|
|
{
|
2020-12-08 00:45:13 +00:00
|
|
|
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(text.c_str()).x / 2));
|
2020-12-06 22:03:42 +00:00
|
|
|
}
|
|
|
|
|
2020-11-17 18:23:33 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2020-11-17 18:25:20 +00:00
|
|
|
ImVec4 change_on_load_temp(LOAD_DATA& data, unsigned current)
|
2020-11-17 18:23:33 +00:00
|
|
|
{
|
|
|
|
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 = ¶ms;
|
|
|
|
HUDElements.is_vulkan = is_vulkan;
|
|
|
|
ImGui::GetIO().FontGlobalScale = params.font_scale;
|
2020-12-04 05:59:20 +00:00
|
|
|
if(!logger) logger = std::make_unique<Logger>(¶ms);
|
2020-11-17 18:23:33 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|