mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-08-09 20:24:14 +00:00
[client] all: use imgui for FPS/UPS display
This commit is contained in:
117
client/src/app.c
117
client/src/app.c
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user