Implement a much better / more accurate framecounter.

The old framecounter had two problems:

* It measured only the time of the current render frame, not the total
  time spend between the last and the current render frame. Therefor the
  calculated value was too high.
* It was based upon milliseconds and rather inaccurate.

This new frame counter solves both problems. The total time spend
between two render frames is measured and the measurement done in
microseconds.

There're three modes:

* cl_drawfps 1 displayes the average frame rate calculated over the last
  60 frames.
* cl_drawfps 2 displays a nice string with minimal framerate, maximum
  framerate and average framerate. All three values are calculated over
  the last 60 frames.
* cl_drawfps 3 is the same as number 2 but with a second line showing the
  raw values.

TODO:

* Discuss if cl_drawfps should be renamed to cl_showfps. All other
  status displays are named cl_show*.

While at it remove several unsused drawing functions.
This commit is contained in:
Yamagi Burmeister 2017-09-03 13:38:24 +02:00
parent 0fafaf735f
commit 79f73da62b
3 changed files with 1 additions and 143 deletions

View file

@ -35,12 +35,6 @@ extern char key_lines[NUM_KEY_LINES][MAXCMDLINE];
extern int edit_line;
extern int key_linepos;
void
DrawString(int x, int y, char *s)
{
DrawStringScaled(x, y, s, 1.0f);
}
void
DrawStringScaled(int x, int y, char *s, float factor)
{
@ -52,12 +46,6 @@ DrawStringScaled(int x, int y, char *s, float factor)
}
}
void
DrawAltString(int x, int y, char *s)
{
DrawAltStringScaled(x, y, s, 1.0f);
}
void
DrawAltStringScaled(int x, int y, char *s, float factor)
{
@ -452,29 +440,6 @@ Con_Print(char *txt)
}
}
void
Con_CenteredPrint(char *text)
{
int l;
char buffer[1024];
l = strlen(text);
l = (con.linewidth - l) / 2;
if (l <= 0)
{
l = 0;
}
else
{
memset(buffer, ' ', l);
}
strcpy(buffer + l, text);
strcat(buffer, "\n");
Con_Print(buffer);
}
/*
* The input line scrolls horizontally if
* typing goes beyond the right edge

View file

@ -812,22 +812,6 @@ CL_Frame(int msec)
{
miscframe = false;
}
// Evil hack for vsync. Because the vsync is effectively a break, delaying each frame
// by up 1000.0 / display_hz milliseconds we can't effort to lose even more time with
// synchronizing between render- and packageframes. This lost time would accumulate,
// delaying the renderframe which leads to microstuttering. Bite the bullet and force
// renderframe == clientframe. But only if rframetime and nframetime differ, otherwise
// the movement predictions breaks.
if (R_IsVSyncActive())
{
if ((packetframe || renderframe) && (cls.nframetime != cls.rframetime))
{
renderframe = true;
packetframe = true;
miscframe = true;
}
}
}
else
{

View file

@ -1410,89 +1410,6 @@ SCR_DrawLayout(void)
SCR_ExecuteLayoutString(cl.layout);
}
<<<<<<< HEAD
||||||| parent of 12f21e2... Fix Sys_Microseconds(), on Unix use it in Sys_Milliseconds()
// ----
void
SCR_Framecounter(void) {
long long newtime;
static int frame;
static int frametimes[60] = {0};
static long long oldtime;
newtime = Sys_Microseconds();
frametimes[frame] = (int)(newtime - oldtime);
float scale = SCR_GetConsoleScale();
if (cl_drawfps->value == 1) {
// Calculate average of frames.
int avg = 0;
int num = 0;
for (int i = 0; i < 60; i++) {
if (frametimes[i] != 0) {
avg += frametimes[i];
num++;
}
}
char str[10];
snprintf(str, sizeof(str), "%3.2ffps", (1000.0 * 1000.0) / (avg / num));
DrawStringScaled(scale*(viddef.width - 80), 0, str, scale);
} else if (cl_drawfps->value >= 2) {
// Calculate average of frames.
int avg = 0;
int num = 0;
for (int i = 0; i < 60; i++) {
if (frametimes[i] != 0) {
avg += frametimes[i];
num++;
}
}
// Find lowest and highest
int min = frametimes[0];
int max = frametimes[1];
for (int i = 1; i < 60; i++) {
if ((frametimes[i] > 0) && (min < frametimes[i])) {
min = frametimes[i];
}
if ((frametimes[i] > 0) && (max > frametimes[i])) {
max = frametimes[i];
}
}
char str[64];
snprintf(str, sizeof(str), "Min: %7.2ffps, Max: %7.2ffps, Avg: %7.2ffps",
(1000.0 * 1000.0) / min, (1000.0 * 1000.0) / max, (1000.0 * 1000.0) / (avg / num));
DrawStringScaled(viddef.width - scale*(strlen(str)*8 + 2), 0, str, scale);
if (cl_drawfps->value > 2)
{
snprintf(str, sizeof(str), "Max: %5.2fms, Min: %5.2fms, Avg: %5.2fms",
0.001f*min, 0.001f*max, 0.001f*(avg / num));
DrawStringScaled(viddef.width - scale*(strlen(str)*8 + 2), scale*10, str, scale);
}
}
frame++;
if (frame > 59) {
frame = 0;
}
oldtime = newtime;
}
// ----
=======
// ----
void
@ -1571,8 +1488,6 @@ SCR_Framecounter(void) {
}
// ----
>>>>>>> 12f21e2... Fix Sys_Microseconds(), on Unix use it in Sys_Milliseconds()
/*
* This is called every frame, and can also be called
* explicitly to flush text to the screen.
@ -1698,13 +1613,6 @@ SCR_UpdateScreen(void)
SCR_DrawNet();
SCR_CheckDrawCenterString();
if (cl_drawfps->value)
{
char s[8];
sprintf(s, "%3.0ffps", 1 / cls.rframetime);
DrawString(viddef.width - 64, 0, s);
}
if (scr_timegraph->value)
{
SCR_DebugGraph(cls.rframetime * 300, 0);
@ -1726,6 +1634,7 @@ SCR_UpdateScreen(void)
}
}
SCR_Framecounter();
R_EndFrame();
}