mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-10 08:38:20 +00:00
[client] all: use imgui for FPS/UPS display
This commit is contained in:
parent
45e1b5bce0
commit
ab31040d5f
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
@ -1,11 +0,0 @@
|
||||
#version 300 es
|
||||
|
||||
in highp vec2 uv;
|
||||
out highp vec4 color;
|
||||
|
||||
uniform sampler2D sampler1;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = texture(sampler1, uv);
|
||||
}
|
@ -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;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#version 300 es
|
||||
|
||||
out highp vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vec4(0.0, 0.0, 1.0, 0.5);
|
||||
}
|
@ -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)
|
||||
|
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;
|
||||
|
Loading…
Reference in New Issue
Block a user