[client] all: use imgui for FPS/UPS display

This commit is contained in:
Geoffrey McRae
2021-07-18 20:43:17 +10:00
parent 45e1b5bce0
commit ab31040d5f
14 changed files with 87 additions and 479 deletions

View File

@@ -612,14 +612,6 @@ void app_showHelp(bool show)
free(help);
}
void app_showFPS(bool showFPS)
{
if (!g_state.lgr)
return;
g_state.lgr->on_show_fps(g_state.lgrData, showFPS);
}
struct ImGuiGraph
{
const char * name;
@@ -676,7 +668,8 @@ static bool rbCalcMetrics(int index, void * value_, void * udata_)
bool app_renderImGui(void)
{
if (!g_state.showTiming)
if (!g_state.showFPS &&
!g_state.showTiming)
return false;
igNewFrame();
@@ -684,53 +677,79 @@ bool app_renderImGui(void)
ImGuiStyle * style = igGetStyle();
style->WindowBorderSize = 0.0f;
const ImVec2 pos = {0.0f, 0.0f};
igSetNextWindowBgAlpha(0.4f);
igSetNextWindowPos(pos, 0, pos);
igBegin(
"Performance Metrics",
NULL,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoTitleBar
);
GraphHandle graph;
for (ll_reset(g_state.graphs); ll_walk(g_state.graphs, (void **)&graph); )
if (g_state.showFPS)
{
if (!graph->enabled)
continue;
const ImVec2 pos = {0.0f, 0.0f};
igSetNextWindowPos(pos, 0, pos);
struct BufferMetrics metrics = {};
ringbuffer_forEach(graph->buffer, rbCalcMetrics, &metrics);
igBegin(
"FPS",
NULL,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoTitleBar
);
if (metrics.sum > 0.0f)
{
metrics.avg = metrics.sum / ringbuffer_getCount(graph->buffer);
metrics.freq = 1000.0f / metrics.avg;
}
const float fps = 1000.0f / (g_state.renderTimeTotal /
ringbuffer_getCount(g_state.renderTimings));
const float ups = 1000.0f / (g_state.frameTimeTotal /
ringbuffer_getCount(g_state.frameTimings));
char title[64];
const ImVec2 size = {400.0f, 100.0f};
igText("FPS:%4.2f UPS:%4.2f", fps, ups);
snprintf(title, sizeof(title),
"%s: min:%4.2f max:%4.2f avg:%4.2f/%4.2fHz",
graph->name, metrics.min, metrics.max, metrics.avg, metrics.freq);
igPlotLinesFloatPtr(
"",
(float *)ringbuffer_getValues(graph->buffer),
ringbuffer_getLength(graph->buffer),
ringbuffer_getStart (graph->buffer),
title,
0.0f,
50.0f,
size,
sizeof(float));
igEnd();
}
igEnd();
if (g_state.showTiming)
{
const ImVec2 pos = {0.0f, 0.0f};
igSetNextWindowBgAlpha(0.4f);
igSetNextWindowPos(pos, 0, pos);
igBegin(
"Performance Metrics",
NULL,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoTitleBar
);
GraphHandle graph;
for (ll_reset(g_state.graphs); ll_walk(g_state.graphs, (void **)&graph); )
{
if (!graph->enabled)
continue;
struct BufferMetrics metrics = {};
ringbuffer_forEach(graph->buffer, rbCalcMetrics, &metrics);
if (metrics.sum > 0.0f)
{
metrics.avg = metrics.sum / ringbuffer_getCount(graph->buffer);
metrics.freq = 1000.0f / metrics.avg;
}
char title[64];
const ImVec2 size = {400.0f, 100.0f};
snprintf(title, sizeof(title),
"%s: min:%4.2f max:%4.2f avg:%4.2f/%4.2fHz",
graph->name, metrics.min, metrics.max, metrics.avg, metrics.freq);
igPlotLinesFloatPtr(
"",
(float *)ringbuffer_getValues(graph->buffer),
ringbuffer_getLength(graph->buffer),
ringbuffer_getStart (graph->buffer),
title,
0.0f,
50.0f,
size,
sizeof(float));
}
igEnd();
}
igRender();
return true;

View File

@@ -51,7 +51,6 @@ static void bind_video(int sc, void * opaque)
static void bind_showFPS(int sc, void * opaque)
{
g_state.showFPS = !g_state.showFPS;
app_showFPS(g_state.showFPS);
}
static void bind_showTiming(int sc, void * opaque)

View File

@@ -108,8 +108,6 @@ static int renderThread(void * unused)
LG_LOCK_INIT(g_state.lgrLock);
g_state.lgr->on_show_fps(g_state.lgrData, g_state.showFPS);
/* signal to other threads that the renderer is ready */
lgSignalEvent(e_startup);
@@ -157,31 +155,10 @@ static int renderThread(void * unused)
{
const float fdelta = (float)delta / 1000000.0f;
ringbuffer_push(g_state.renderTimings, &fdelta);
g_state.renderTimeTotal += fdelta;
}
g_state.lastRenderTimeValid = true;
if (g_state.showFPS)
{
g_state.renderTime += delta;
++g_state.renderCount;
if (g_state.renderTime > 1e9)
{
const float avgUPS = 1000.0f / (((float)g_state.renderTime /
atomic_exchange_explicit(&g_state.frameCount, 0, memory_order_acquire)) /
1e6f);
const float avgFPS = 1000.0f / (((float)g_state.renderTime /
g_state.renderCount) /
1e6f);
g_state.lgr->update_fps(g_state.lgrData, avgUPS, avgFPS);
g_state.renderTime = 0;
g_state.renderCount = 0;
}
}
const uint64_t now = microtime();
if (!g_state.resizeDone && g_state.resizeTimeout < now)
{
@@ -614,10 +591,10 @@ int main_frameThread(void * unused)
{
const float fdelta = (float)delta / 1000000.0f;
ringbuffer_push(g_state.frameTimings, &fdelta);
g_state.frameTimeTotal += fdelta;
}
g_state.lastFrameTimeValid = true;
atomic_fetch_add_explicit(&g_state.frameCount, 1, memory_order_relaxed);
lgSignalEvent(e_frame);
lgmpClientMessageDone(queue);
}
@@ -702,6 +679,13 @@ static bool tryRenderer(const int index, const LG_RendererParams lgrParams,
return true;
}
static void rbSubtractFloat(void * value_, void * udata_)
{
float * value = (float *)value_;
float * udata = (float *)udata_;
*udata -= *value;
}
static int lg_run(void)
{
memset(&g_state, 0, sizeof(g_state));
@@ -726,6 +710,11 @@ static int lg_run(void)
g_state.renderTimings = ringbuffer_new(256, sizeof(float));
g_state.frameTimings = ringbuffer_new(256, sizeof(float));
ringbuffer_setPreOverwriteFn(g_state.renderTimings, rbSubtractFloat,
&g_state.renderTimeTotal);
ringbuffer_setPreOverwriteFn(g_state.frameTimings , rbSubtractFloat,
&g_state.frameTimeTotal);
app_registerGraph("RENDER", g_state.renderTimings);
app_registerGraph("UPLOAD", g_state.frameTimings);

View File

@@ -99,13 +99,12 @@ struct AppState
atomic_uint_least64_t frameTime;
uint64_t lastFrameTime;
bool lastFrameTimeValid;
uint64_t renderTime;
uint64_t lastRenderTime;
bool lastRenderTimeValid;
atomic_uint_least64_t frameCount;
uint64_t renderCount;
RingBuffer renderTimings;
RingBuffer frameTimings;
float renderTimeTotal;
float frameTimeTotal;
uint64_t resizeTimeout;
bool resizeDone;