void a_fps__reset(int NumFramesToSkip) { g_skipNum = NumFramesToSkip; g_skipCounter = 0; g_fpsRate = g_idealFps / (1 + g_skipNum); g_msPerFrame = 1000 / g_fpsRate; g_fps = g_fpsRate; g_maxFps = g_fpsRate; for(int i = g_bufferLen; i--; ) { g_fpsBuffer[i] = g_fpsRate; g_maxFpsBuffer[i] = g_fpsRate; } g_fpsBufferSum = g_fpsRate * g_bufferLen; g_maxFpsBufferSum = g_fpsRate * g_bufferLen; if(g_skipNum > 0) { g_fpsThresholdFast = g_idealFps / g_skipNum; } g_fpsThresholdSlow = g_fpsRate - 2; if(g_timer == NULL) { g_timer = a_timer_new(g_msPerFrame); } else { a_timer_setPeriod(g_timer, g_msPerFrame); } a_timer_start(g_timer); }
void a_fps__set(void) { milisPerFrame = 1000 / a2x_int("fps"); timer = a_timer_set(milisPerFrame); a_timer_start(timer); fps = 0; max = 0; if(a2x_bool("trackFps")) { for(int i = BUFFER_SIZE; i--; ) { fpsBuffer[i] = milisPerFrame; maxBuffer[i] = milisPerFrame; } } counter = 0; }
void a_fps__init(void) { g_idealFps = a_settings_getInt("video.fps"); g_skipFrames = a_settings_getBool("video.fps.skip"); g_skipMax = a_settings_getInt("video.fps.skip.max"); g_timer = NULL; g_frameCounter = 0; g_bufferHead = 0; g_bufferLen = g_idealFps * AVERAGE_WINDOW_SEC; g_fpsBuffer = a_mem_malloc(g_bufferLen * sizeof(uint32_t)); g_maxFpsBuffer = a_mem_malloc(g_bufferLen * sizeof(uint32_t)); g_skipAdjustTimer = a_timer_new(FRAMESKIP_ADJUST_DELAY_SEC * 1000); a_timer_start(g_skipAdjustTimer); g_noSleepTimer = a_timer_new(NO_SLEEP_RESET_SEC * 1000); g_canSleep = true; a_fps__reset(0); }
void a_fps_frame(void) { if(a_fps_notSkipped()) { a_screen_show(); const bool done = a_timer_expired(g_timer); const uint32_t elapsedMs = a_timer_elapsed(g_timer); if(elapsedMs > 0) { g_maxFpsBufferSum -= g_maxFpsBuffer[g_bufferHead]; g_maxFpsBuffer[g_bufferHead] = 1000 / elapsedMs; g_maxFpsBufferSum += g_maxFpsBuffer[g_bufferHead]; g_maxFps = g_maxFpsBufferSum / g_bufferLen; } if(!done) { while(!a_timer_expired(g_timer)) { if(!g_canSleep) { continue; } const uint32_t waitMs = g_msPerFrame - a_timer_elapsed(g_timer); #if A_PLATFORM_GP2X // GP2X timer granularity is too coarse if(waitMs >= 10) { a_time_waitMs(10); } #else a_time_waitMs(waitMs); #endif } } g_fpsBufferSum -= g_fpsBuffer[g_bufferHead]; g_fpsBuffer[g_bufferHead] = 1000 / a_timer_elapsed(g_timer); g_fpsBufferSum += g_fpsBuffer[g_bufferHead]; g_fps = g_fpsBufferSum / g_bufferLen; g_bufferHead = (g_bufferHead + 1) % g_bufferLen; } a_input__get(); g_frameCounter++; if(g_skipFrames) { if(a_fps_notSkipped() && a_timer_expired(g_skipAdjustTimer)) { int newFrameSkip = -1; if(g_maxFps <= g_fpsThresholdSlow && g_skipNum < g_skipMax) { newFrameSkip = g_skipNum + 1; } else if(g_maxFps >= g_fpsThresholdFast && g_skipNum > 0) { newFrameSkip = g_skipNum - 1; } if(newFrameSkip != -1) { if(newFrameSkip == 0) { a_timer_start(g_noSleepTimer); } else { a_timer_stop(g_noSleepTimer); } g_canSleep = false; a_fps__reset(newFrameSkip); } else if(!g_canSleep && a_timer_expired(g_noSleepTimer)) { g_canSleep = true; } } if(g_skipCounter++ == g_skipNum) { g_skipCounter = 0; } } }