[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

@ -127,9 +127,4 @@ void app_releaseAllKeybinds(void);
*/
void app_showHelp(bool show);
/**
* Changes whether the FPS is displayed or not.
*/
void app_showFPS(bool showFPS);
#endif

View file

@ -37,10 +37,8 @@
(x)->on_mouse_event && \
(x)->on_alert && \
(x)->on_help && \
(x)->on_show_fps && \
(x)->render_startup && \
(x)->render && \
(x)->update_fps)
(x)->render)
typedef struct LG_RendererParams
{
@ -117,10 +115,8 @@ typedef bool (* LG_RendererOnFrameFormat)(void * opaque, const LG_Render
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame, int dmaFD, const FrameDamageRect * damage, int damageCount);
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
typedef void (* LG_RendererOnHelp )(void * opaque, const char * message);
typedef void (* LG_RendererOnShowFPS )(void * opaque, bool showFPS);
typedef bool (* LG_RendererRenderStartup)(void * opaque);
typedef bool (* LG_RendererRender )(void * opaque, LG_RendererRotate rotate);
typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS);
typedef struct LG_Renderer
{
@ -139,9 +135,7 @@ typedef struct LG_Renderer
LG_RendererOnFrame on_frame;
LG_RendererOnAlert on_alert;
LG_RendererOnHelp on_help;
LG_RendererOnShowFPS on_show_fps;
LG_RendererRenderStartup render_startup;
LG_RendererRender render;
LG_RendererUpdateFPS update_fps;
}
LG_Renderer;

View file

@ -21,9 +21,6 @@ make_object(
shader/cursor_mono.frag
shader/damage.vert
shader/damage.frag
shader/fps.vert
shader/fps.frag
shader/fps_bg.frag
shader/help.vert
shader/help.frag
shader/help_bg.frag
@ -49,7 +46,6 @@ add_library(renderer_EGL STATIC
model.c
desktop.c
cursor.c
fps.c
help.c
draw.c
splash.c

View file

@ -46,7 +46,6 @@
#include "damage.h"
#include "desktop.h"
#include "cursor.h"
#include "fps.h"
#include "splash.h"
#include "alert.h"
#include "help.h"
@ -74,7 +73,6 @@ struct Inst
EGL_Desktop * desktop; // the desktop
EGL_Cursor * cursor; // the mouse cursor
EGL_FPS * fps; // the fps display
EGL_Splash * splash; // the splash screen
EGL_Alert * alert; // the alert display
EGL_Help * help; // the help display
@ -214,9 +212,6 @@ static bool egl_update_font(struct Inst * this)
if (this->alert)
egl_alert_set_font(this->alert, fontObj);
if (this->fps)
egl_fps_set_font(this->fps, fontObj);
if (this->fontObj)
this->font->destroy(this->fontObj);
this->fontObj = fontObj;
@ -314,7 +309,6 @@ void egl_deinitialize(void * opaque)
egl_desktop_free(&this->desktop);
egl_cursor_free (&this->cursor);
egl_fps_free (&this->fps );
egl_splash_free (&this->splash);
egl_alert_free (&this->alert );
egl_help_free (&this->help );
@ -647,12 +641,6 @@ void egl_on_help(void * opaque, const char * message)
this->cursorLastValid = false;
}
void egl_on_show_fps(void * opaque, bool showFPS)
{
struct Inst * this = (struct Inst *)opaque;
egl_fps_set_display(this->fps, showFPS);
}
static void debugCallback(GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei length, const GLchar * message,
const void * userParam)
@ -894,12 +882,6 @@ bool egl_render_startup(void * opaque)
return false;
}
if (!egl_fps_init(&this->fps, this->font, this->fontObj))
{
DEBUG_ERROR("Failed to initialize the FPS display");
return false;
}
if (!egl_splash_init(&this->splash))
{
DEBUG_ERROR("Failed to initialize the splash screen");
@ -1021,7 +1003,6 @@ bool egl_render(void * opaque, LG_RendererRotate rotate)
}
}
hasOverlay |= egl_fps_render(this->fps, this->screenScaleX, this->screenScaleY);
hasOverlay |= egl_help_render(this->help, this->screenScaleX, this->screenScaleY);
hasOverlay |= egl_damage_render(this->damage, desktopDamage);
@ -1088,13 +1069,6 @@ bool egl_render(void * opaque, LG_RendererRotate rotate)
return true;
}
void egl_update_fps(void * opaque, const float avgUPS, const float avgFPS)
{
struct Inst * this = (struct Inst *)opaque;
egl_fps_update(this->fps, avgUPS, avgFPS);
this->cursorLastValid = false;
}
struct LG_Renderer LGR_EGL =
{
.get_name = egl_get_name,
@ -1111,8 +1085,6 @@ struct LG_Renderer LGR_EGL =
.on_frame = egl_on_frame,
.on_alert = egl_on_alert,
.on_help = egl_on_help,
.on_show_fps = egl_on_show_fps,
.render_startup = egl_render_startup,
.render = egl_render,
.update_fps = egl_update_fps
.render = egl_render
};

View file

@ -1,212 +0,0 @@
/**
* Looking Glass
* Copyright (C) 2017-2021 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "fps.h"
#include "common/debug.h"
#include "texture.h"
#include "shader.h"
#include "model.h"
#include <stdlib.h>
#include <string.h>
// these headers are auto generated by cmake
#include "fps.vert.h"
#include "fps.frag.h"
#include "fps_bg.frag.h"
struct EGL_FPS
{
const LG_Font * font;
LG_FontObj fontObj;
EGL_Texture * texture;
EGL_Shader * shader;
EGL_Shader * shaderBG;
EGL_Model * model;
bool display;
bool ready;
int iwidth, iheight;
float width, height;
// uniforms
GLint uScreen , uSize;
GLint uScreenBG, uSizeBG;
};
bool egl_fps_init(EGL_FPS ** fps, const LG_Font * font, LG_FontObj fontObj)
{
*fps = (EGL_FPS *)malloc(sizeof(EGL_FPS));
if (!*fps)
{
DEBUG_ERROR("Failed to malloc EGL_FPS");
return false;
}
memset(*fps, 0, sizeof(EGL_FPS));
(*fps)->font = font;
(*fps)->fontObj = fontObj;
if (!egl_texture_init(&(*fps)->texture, NULL))
{
DEBUG_ERROR("Failed to initialize the fps texture");
return false;
}
if (!egl_shader_init(&(*fps)->shader))
{
DEBUG_ERROR("Failed to initialize the fps shader");
return false;
}
if (!egl_shader_init(&(*fps)->shaderBG))
{
DEBUG_ERROR("Failed to initialize the fps bg shader");
return false;
}
if (!egl_shader_compile((*fps)->shader,
b_shader_fps_vert, b_shader_fps_vert_size,
b_shader_fps_frag, b_shader_fps_frag_size))
{
DEBUG_ERROR("Failed to compile the fps shader");
return false;
}
if (!egl_shader_compile((*fps)->shaderBG,
b_shader_fps_vert , b_shader_fps_vert_size,
b_shader_fps_bg_frag, b_shader_fps_bg_frag_size))
{
DEBUG_ERROR("Failed to compile the fps shader");
return false;
}
(*fps)->uSize = egl_shader_get_uniform_location((*fps)->shader , "size" );
(*fps)->uScreen = egl_shader_get_uniform_location((*fps)->shader , "screen");
(*fps)->uSizeBG = egl_shader_get_uniform_location((*fps)->shaderBG, "size" );
(*fps)->uScreenBG = egl_shader_get_uniform_location((*fps)->shaderBG, "screen");
if (!egl_model_init(&(*fps)->model))
{
DEBUG_ERROR("Failed to initialize the fps model");
return false;
}
egl_model_set_default((*fps)->model);
egl_model_set_texture((*fps)->model, (*fps)->texture);
return true;
}
void egl_fps_free(EGL_FPS ** fps)
{
if (!*fps)
return;
egl_texture_free(&(*fps)->texture );
egl_shader_free (&(*fps)->shader );
egl_shader_free (&(*fps)->shaderBG);
egl_model_free (&(*fps)->model );
free(*fps);
*fps = NULL;
}
void egl_fps_set_display(EGL_FPS * fps, bool display)
{
fps->display = display;
}
void egl_fps_set_font(EGL_FPS * fps, LG_Font * fontObj)
{
fps->fontObj = fontObj;
}
void egl_fps_update(EGL_FPS * fps, const float avgFPS, const float renderFPS)
{
if (!fps->display)
return;
char str[128];
snprintf(str, sizeof(str), "UPS: %8.4f, FPS: %8.4f", avgFPS, renderFPS);
LG_FontBitmap * bmp = fps->font->render(fps->fontObj, 0xffffff00, str);
if (!bmp)
{
DEBUG_ERROR("Failed to render fps text");
return;
}
if (fps->iwidth != bmp->width || fps->iheight != bmp->height)
{
fps->iwidth = bmp->width;
fps->iheight = bmp->height;
fps->width = (float)bmp->width;
fps->height = (float)bmp->height;
egl_texture_setup(
fps->texture,
EGL_PF_BGRA,
bmp->width ,
bmp->height,
bmp->width * bmp->bpp,
false,
false
);
}
egl_texture_update
(
fps->texture,
bmp->pixels
);
fps->ready = true;
fps->font->release(fps->fontObj, bmp);
}
bool egl_fps_render(EGL_FPS * fps, const float scaleX, const float scaleY)
{
if (!fps->display || !fps->ready)
return false;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// render the background first
egl_shader_use(fps->shaderBG);
glUniform2f(fps->uScreenBG, scaleX , scaleY );
glUniform2f(fps->uSizeBG , fps->width, fps->height);
egl_model_render(fps->model);
// render the texture over the background
egl_shader_use(fps->shader);
glUniform2f(fps->uScreen, scaleX , scaleY );
glUniform2f(fps->uSize , fps->width, fps->height);
egl_model_render(fps->model);
glDisable(GL_BLEND);
return true;
}

View file

@ -1,35 +0,0 @@
/**
* Looking Glass
* Copyright (C) 2017-2021 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#include <stdbool.h>
#include "interface/font.h"
typedef struct EGL_FPS EGL_FPS;
bool egl_fps_init(EGL_FPS ** fps, const LG_Font * font, LG_FontObj fontObj);
void egl_fps_free(EGL_FPS ** fps);
void egl_fps_set_display(EGL_FPS * fps, bool display);
void egl_fps_set_font (EGL_FPS * fps, LG_Font * fontObj);
void egl_fps_update(EGL_FPS * fps, const float avgUPS, const float avgFPS);
bool egl_fps_render(EGL_FPS * fps, const float scaleX, const float scaleY);

View file

@ -1,11 +0,0 @@
#version 300 es
in highp vec2 uv;
out highp vec4 color;
uniform sampler2D sampler1;
void main()
{
color = texture(sampler1, uv);
}

View file

@ -1,22 +0,0 @@
#version 300 es
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;
uniform vec2 screen;
uniform vec2 size;
out highp vec2 uv;
void main()
{
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
gl_Position.xy *= screen.xy * size.xy;
gl_Position.x -= 1.0 - (screen.x * size.x);
gl_Position.y += 1.0 - (screen.y * size.y);
gl_Position.x += screen.x * 10.0;
gl_Position.y -= screen.y * 10.0;
uv = vertexUV;
}

View file

@ -1,8 +0,0 @@
#version 300 es
out highp vec4 color;
void main()
{
color = vec4(0.0, 0.0, 1.0, 0.5);
}

View file

@ -151,7 +151,6 @@ struct Inst
bool texReady;
int texWIndex, texRIndex;
int texList;
int fpsList;
int mouseList;
LG_RendererRect destRect;
@ -166,10 +165,6 @@ struct Inst
uint64_t waitFadeTime;
bool waitDone;
bool showFPS;
bool fpsTexture;
struct IntRect fpsRect;
LG_Lock mouseLock;
LG_RendererCursor mouseCursor;
int mouseWidth;
@ -279,7 +274,6 @@ void opengl_deinitialize(void * opaque)
glDeleteLists(this->texList , BUFFER_COUNT);
glDeleteLists(this->mouseList, 1);
glDeleteLists(this->fpsList , 1);
glDeleteLists(this->alertList, 1);
}
@ -502,12 +496,6 @@ void opengl_on_help(void * opaque, const char * message)
// TODO: Implement this.
}
void opengl_on_show_fps(void * opaque, bool showFPS)
{
struct Inst * this = (struct Inst *)opaque;
this->showFPS = showFPS;
}
void bitmap_to_texture(LG_FontBitmap * bitmap, GLuint texture)
{
glBindTexture(GL_TEXTURE_2D , texture );
@ -574,7 +562,6 @@ bool opengl_render_startup(void * opaque)
// generate lists for drawing
this->texList = glGenLists(BUFFER_COUNT);
this->mouseList = glGenLists(1);
this->fpsList = glGenLists(1);
this->alertList = glGenLists(1);
// create the overlay textures
@ -632,9 +619,6 @@ bool opengl_render(void * opaque, LG_RendererRotate rotate)
render_wait(this);
}
if (this->showFPS && this->fpsTexture)
glCallList(this->fpsList);
struct Alert * alert;
while(ll_peek_head(this->alerts, (void **)&alert))
{
@ -721,55 +705,6 @@ bool opengl_render(void * opaque, LG_RendererRotate rotate)
return true;
}
void opengl_update_fps(void * opaque, const float avgUPS, const float avgFPS)
{
struct Inst * this = (struct Inst *)opaque;
if (!this->showFPS)
return;
char str[128];
snprintf(str, sizeof(str), "UPS: %8.4f, FPS: %8.4f", avgUPS, avgFPS);
LG_FontBitmap *textSurface = NULL;
if (!(textSurface = this->font->render(this->fontObj, 0xffffff00, str)))
DEBUG_ERROR("Failed to render text");
bitmap_to_texture(textSurface, this->textures[FPS_TEXTURE]);
this->fpsRect.x = 5;
this->fpsRect.y = 5;
this->fpsRect.w = textSurface->width;
this->fpsRect.h = textSurface->height;
this->font->release(this->fontObj, textSurface);
this->fpsTexture = true;
glNewList(this->fpsList, GL_COMPILE);
glEnable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glColor4f(0.0f, 0.0f, 1.0f, 0.5f);
glBegin(GL_TRIANGLE_STRIP);
glVertex2i(this->fpsRect.x , this->fpsRect.y );
glVertex2i(this->fpsRect.x + this->fpsRect.w, this->fpsRect.y );
glVertex2i(this->fpsRect.x , this->fpsRect.y + this->fpsRect.h);
glVertex2i(this->fpsRect.x + this->fpsRect.w, this->fpsRect.y + this->fpsRect.h);
glEnd();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, this->textures[FPS_TEXTURE]);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0f , 0.0f); glVertex2i(this->fpsRect.x , this->fpsRect.y );
glTexCoord2f(1.0f , 0.0f); glVertex2i(this->fpsRect.x + this->fpsRect.w, this->fpsRect.y );
glTexCoord2f(0.0f , 1.0f); glVertex2i(this->fpsRect.x , this->fpsRect.y + this->fpsRect.h);
glTexCoord2f(1.0f, 1.0f); glVertex2i(this->fpsRect.x + this->fpsRect.w, this->fpsRect.y + this->fpsRect.h);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_BLEND);
glEndList();
}
void draw_torus(float x, float y, float inner, float outer, unsigned int pts)
{
glBegin(GL_QUAD_STRIP);
@ -880,10 +815,8 @@ const LG_Renderer LGR_OpenGL =
.on_frame = opengl_on_frame,
.on_alert = opengl_on_alert,
.on_help = opengl_on_help,
.on_show_fps = opengl_on_show_fps,
.render_startup = opengl_render_startup,
.render = opengl_render,
.update_fps = opengl_update_fps
.render = opengl_render
};
static bool _check_gl_error(unsigned int line, const char * name)

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;