UI: Separate sleep time in frame time graph.

It's useful to know how much of the frame time is active vs inactive.
This commit is contained in:
Unknown W. Brackets 2020-02-17 11:17:16 -08:00
parent e7ddc94fb9
commit ce694da5ff
3 changed files with 29 additions and 7 deletions

View File

@ -154,7 +154,8 @@ static int fpsHistorySize = (int)ARRAY_SIZE(fpsHistory);
static int fpsHistoryPos = 0;
static int fpsHistoryValid = 0;
static double frameTimeHistory[600];
static int frameTimeHistorySize = (int)ARRAY_SIZE(frameTimeHistory);
static double frameSleepHistory[600];
static const int frameTimeHistorySize = (int)ARRAY_SIZE(frameTimeHistory);
static int frameTimeHistoryPos = 0;
static int frameTimeHistoryValid = 0;
static double lastFrameTimeHistory = 0.0;
@ -479,12 +480,14 @@ static void CalculateFPS() {
if (frameTimeHistoryValid < frameTimeHistorySize) {
++frameTimeHistoryValid;
}
frameSleepHistory[frameTimeHistoryPos] = 0.0;
}
}
double* __DisplayGetFrameTimes(int *out_valid, int *out_pos) {
double *__DisplayGetFrameTimes(int *out_valid, int *out_pos, double **out_sleep) {
*out_valid = frameTimeHistoryValid;
*out_pos = frameTimeHistoryPos;
*out_sleep = frameSleepHistory;
return frameTimeHistory;
}
@ -638,7 +641,8 @@ static void DoFrameIdleTiming() {
time_update();
double dist = time_now_d() - lastFrameTime;
double before = time_now_d();
double dist = before - lastFrameTime;
// Ignore if the distance is just crazy. May mean wrap or pause.
if (dist < 0.0 || dist >= 15 * timePerVblank) {
return;
@ -656,7 +660,7 @@ static void DoFrameIdleTiming() {
// This prevents fast forward during loading screens.
// Give a little extra wiggle room in case the next vblank does more work.
const double goal = lastFrameTime + (numVBlanksSinceFlip - 1) * scaledVblank - 0.001;
if (numVBlanksSinceFlip >= 2 && time_now_d() < goal) {
if (numVBlanksSinceFlip >= 2 && before < goal) {
while (time_now_d() < goal) {
#ifdef _WIN32
sleep_ms(1);
@ -666,6 +670,10 @@ static void DoFrameIdleTiming() {
#endif
time_update();
}
if (g_Config.bDrawFrameGraph) {
frameSleepHistory[frameTimeHistoryPos] += time_now_d() - before;
}
}
}
@ -736,6 +744,7 @@ void __DisplayFlip(int cyclesLate) {
postEffectRequiresFlip = shaderInfo->requires60fps;
const bool fbDirty = gpu->FramebufferDirty();
if (fbDirty || noRecentFlip || postEffectRequiresFlip) {
int frameSleepPos = frameTimeHistoryPos;
CalculateFPS();
// Let the user know if we're running slow, so they know to adjust settings.
@ -797,6 +806,11 @@ void __DisplayFlip(int cyclesLate) {
CoreTiming::ScheduleEvent(0 - cyclesLate, afterFlipEvent, 0);
numVBlanksSinceFlip = 0;
if (g_Config.bDrawFrameGraph) {
// Track how long we sleep (whether vsync or sleep_ms.)
frameSleepHistory[frameSleepPos] += real_time_now() - lastFrameTimeHistory;
}
} else {
// Okay, there's no new frame to draw. But audio may be playing, so we need to time still.
DoFrameIdleTiming();
@ -843,6 +857,7 @@ void hleLagSync(u64 userdata, int cyclesLate) {
const double goal = lastLagSync + (scale / 1000.0f);
time_update();
double before = time_now_d();
// Don't lag too long ever, if they leave it paused.
while (time_now_d() < goal && goal < time_now_d() + 0.01) {
#ifndef _WIN32
@ -855,6 +870,10 @@ void hleLagSync(u64 userdata, int cyclesLate) {
const int emuOver = (int)cyclesToUs(cyclesLate);
const int over = (int)((time_now_d() - goal) * 1000000);
ScheduleLagSync(over - emuOver);
if (g_Config.bDrawFrameGraph) {
frameSleepHistory[frameTimeHistoryPos] += time_now_d() - before;
}
}
static u32 sceDisplayIsVblank() {

View File

@ -40,7 +40,7 @@ void __DisplayGetDebugStats(char stats[], size_t bufsize);
void __DisplayGetFPS(float *out_vps, float *out_fps, float *out_actual_fps);
void __DisplayGetVPS(float *out_vps);
void __DisplayGetAveragedFPS(float *out_vps, float *out_fps);
double* __DisplayGetFrameTimes(int *out_valid, int *out_pos);
double *__DisplayGetFrameTimes(int *out_valid, int *out_pos, double **out_sleep);
int __DisplayGetNumVblanks();
int __DisplayGetVCount();
int __DisplayGetFlipCount();

View File

@ -1192,7 +1192,8 @@ static void DrawFPS(DrawBuffer *draw2d, const Bounds &bounds) {
static void DrawFrameTimes(UIContext *ctx) {
int valid, pos;
double *history = __DisplayGetFrameTimes(&valid, &pos);
double *sleepHistory;
double *history = __DisplayGetFrameTimes(&valid, &pos, &sleepHistory);
int scale = 7000;
int width = 600;
@ -1200,7 +1201,9 @@ static void DrawFrameTimes(UIContext *ctx) {
ctx->BeginNoTex();
int bottom = ctx->GetBounds().y2();
for (int i = 0; i < valid; ++i) {
ctx->Draw()->vLine(i, bottom, bottom - history[i]*scale, 0xFF3fFF3f);
double activeTime = history[i] - sleepHistory[i];
ctx->Draw()->vLine(i, bottom, bottom - activeTime * scale, 0xFF3FFF3F);
ctx->Draw()->vLine(i, bottom - activeTime * scale, bottom - history[i] * scale, 0x7F3FFF3F);
}
ctx->Draw()->vLine(pos, bottom, bottom - 512, 0xFFff3F3f);