Advertisement
Guest User

Adaptive framerate limiter

a guest
Oct 7th, 2014
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. sf::Clock frameClock;
  2.            
  3. double desiredRefreshRate = 60.0;
  4. double frameSkipPreventionPenalty = desiredRefreshRate / 300;
  5. double definiteFramerateTarget = desiredRefreshRate - frameSkipPreventionPenalty;
  6. const sf::Time minAdaptiveFrameTimeMicros = sf::microseconds((sf::Int64) (1000000.0f / (definiteFramerateTarget * 2.0)));
  7. const sf::Time maxAdaptiveFrameTimeMicros = sf::microseconds((sf::Int64) (1000000.0f / (definiteFramerateTarget * 0.5)));
  8.  
  9. const sf::Time idealFrameTime = sf::microseconds((sf::Int64) (1000000.0 / definiteFramerateTarget));
  10.  
  11. // Frame time backlog
  12. const int frameTimeMemorySize = (int) (desiredRefreshRate * 1.5 + 2); // Adapt within 1.5 seconds
  13. sf::Int64* frameTimeMemoryMicros = (sf::Int64*) malloc(sizeof(sf::Int64) * frameTimeMemorySize);
  14.  
  15. // Start filled with ideal frame time
  16. std::fill_n(frameTimeMemoryMicros, frameTimeMemorySize, idealFrameTime.asMicroseconds());
  17. sf::Int64 frameTimeMemoryMicrosSum = frameTimeMemorySize * idealFrameTime.asMicroseconds();
  18.  
  19. int frameTimeOldestMemorySlot = 0;
  20. sf::Int64 recentMicros;
  21. sf::Int64 oldMicros;
  22.            
  23. sf::Time assumedFrameTime = idealFrameTime;
  24. sf::Time elapsedFrameTime;
  25. sf::Time frameTime;
  26. sf::Time sceneTime;
  27. sf::Time previousSceneTime;
  28. sf::Time intendedSleepDuration;
  29. sf::Time afterSleepTime;
  30. sf::Time actualSleepDuration;
  31. sf::Time oversleepDuration;
  32. sf::Time correctiveFrameTime;
  33.            
  34. while (window->isOpen()) {
  35.  
  36.     frameClock.restart();
  37.  
  38.     sceneTime = sceneClock.getElapsedTime();
  39.     frameTime = sceneTime - previousSceneTime;
  40.  
  41.     if (frameTime < sf::Time::Zero) { // The clock was reset
  42.         frameTime = sceneTime;
  43.         previousSceneTime = sf::Time::Zero;
  44.     } else {
  45.         previousSceneTime = sceneTime;
  46.     }
  47.  
  48.     if (frameTime > sf::Time::Zero) {
  49.         parseInput(frameTime);
  50.         renderScene(sceneTime);
  51.         window->display(); // Swap buffers
  52.         glFlush();
  53.     }
  54.  
  55.     if (definiteFramerateTarget > 0.0) { // Use our method?
  56.  
  57.         elapsedFrameTime = frameClock.getElapsedTime();
  58.         intendedSleepDuration = assumedFrameTime - elapsedFrameTime;
  59.  
  60.         // There is time to sleep
  61.         if (intendedSleepDuration > sf::Time::Zero) {
  62.  
  63.             //timeBeginPeriod(1); // Setting this at program start gives better accuracy
  64.             sf::sleep(intendedSleepDuration);
  65.             //timeEndPeriod(1);
  66.  
  67.             afterSleepTime = frameClock.getElapsedTime();
  68.             actualSleepDuration = afterSleepTime - elapsedFrameTime;
  69.             oversleepDuration = actualSleepDuration - intendedSleepDuration;
  70.             correctiveFrameTime = idealFrameTime - oversleepDuration;
  71.  
  72.             if (correctiveFrameTime < minAdaptiveFrameTimeMicros) {
  73.                 correctiveFrameTime = minAdaptiveFrameTimeMicros;
  74.             } else if (correctiveFrameTime > maxAdaptiveFrameTimeMicros) {
  75.                 correctiveFrameTime = maxAdaptiveFrameTimeMicros;
  76.             }
  77.                        
  78.             recentMicros = correctiveFrameTime.asMicroseconds();
  79.             oldMicros = frameTimeMemoryMicros[frameTimeOldestMemorySlot];
  80.  
  81.             frameTimeMemoryMicrosSum += recentMicros - oldMicros;
  82.             frameTimeMemoryMicros[frameTimeOldestMemorySlot] = recentMicros;
  83.             frameTimeOldestMemorySlot = (frameTimeOldestMemorySlot + 1) % frameTimeMemorySize;
  84.  
  85.             assumedFrameTime = sf::microseconds(frameTimeMemoryMicrosSum / frameTimeMemorySize);
  86.         } // else don't touch the adaptive FPS we have "learned" so far, and just move on.
  87.     }
  88.  
  89.     glFinish(); // If the frame is still not done rendering, block.
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement