Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 1 file). Show all
Unified · Split
| @@ -828,42 +828,44 @@ void ScriptEngine::run() { · 827 unmodified lines | ||
| 828 | 828 | |
| 829 | 829 | _lastUpdate = usecTimestampNow(); |
| 830 | 830 | |
| 831 | − qint64 totalSleepFor = 0; | |
| 832 | 831 | std::chrono::microseconds totalUpdates; |
| 833 | − auto lastLoopStart = clock::now(); | |
| 834 | 832 | |
| 835 | 833 | // TODO: Integrate this with signals/slots instead of reimplementing throttling for ScriptEngine |
| 836 | 834 | while (!_isFinished) { |
| 837 | − auto thisLoopStart = clock::now(); | |
| 835 | + auto beforeSleep = clock::now(); | |
| 838 | 836 | |
| 839 | 837 | // Throttle to SCRIPT_FPS |
| 838 | + // We'd like to try to keep the script at a solid SCRIPT_FPS update rate. And so we will | |
| 839 | + // calculate a sleepUntil to be the time from our start time until the original target | |
| 840 | + // sleepUntil for this frame. | |
| 840 | 841 | const std::chrono::microseconds FRAME_DURATION(USECS_PER_SECOND / SCRIPT_FPS + 1); |
| 841 | − const std::chrono::microseconds MINIMUM_SLEEP { FRAME_DURATION / 2 }; | |
| 842 | + clock::time_point sleepUntil(startTime + thisFrame++ * FRAME_DURATION); | |
| 842 | 843 | |
| 843 | − auto beforeSleep = clock::now(); | |
| 844 | − clock::time_point sleepTime(startTime + thisFrame++ * FRAME_DURATION); | |
| 845 | − auto wouldSleep = (sleepTime - clock::now()); | |
| 846 | − auto avgUpdates = totalUpdates / thisFrame; | |
| 844 | + // However, if our sleepUntil is not at least our average update time into the future | |
| 845 | + // it means our script is taking too long in it's updates, and we want to punish the | |
| 846 | + // script a little bit. So we will force the sleepUntil to be at least our averageUpdate | |
| 847 | + // time into the future. | |
| 848 | + auto wouldSleep = (sleepUntil - clock::now()); | |
| 849 | + auto avgerageUpdate = totalUpdates / thisFrame; | |
| 847 | 850 | |
| 848 | − if (wouldSleep < avgUpdates) { | |
| 849 | − sleepTime = beforeSleep + avgUpdates; | |
| 851 | + if (wouldSleep < avgerageUpdate) { | |
| 852 | + sleepUntil = beforeSleep + avgerageUpdate; | |
| 850 | 853 | } |
| 851 | 854 | |
| 852 | − std::this_thread::sleep_until(sleepTime); | |
| 855 | + std::this_thread::sleep_until(sleepUntil); | |
| 853 | 856 | |
| 854 | 857 | #ifdef SCRIPT_DELAY_DEBUG |
| 855 | 858 | { |
| 856 | − auto sleptTill = clock::now(); | |
| 857 | − uint64_t seconds = std::chrono::duration_cast<std::chrono::seconds>(sleptTill - startTime).count(); | |
| 859 | + auto actuallySleptUntil = clock::now(); | |
| 860 | + uint64_t seconds = std::chrono::duration_cast<std::chrono::seconds>(actuallySleptUntil - startTime).count(); | |
| 858 | 861 | if (seconds > 0) { // avoid division by zero and time travel |
| 859 | 862 | uint64_t fps = thisFrame / seconds; |
| 860 | 863 | // Overreporting artificially reduces the reported rate |
| 861 | 864 | if (thisFrame % SCRIPT_FPS == 0) { |
| 862 | 865 | qCDebug(scriptengine) << |
| 863 | 866 | "Frame:" << thisFrame << |
| 864 | − "Slept (us):" << std::chrono::duration_cast<std::chrono::microseconds>(sleptTill - beforeSleep).count() << | |
| 865 | − "Avg Updates (us):" << avgUpdates.count() << | |
| 866 | − "Last loop time (us):" << std::chrono::duration_cast<std::chrono::microseconds>(thisLoopStart - lastLoopStart).count() << | |
| 867 | + "Slept (us):" << std::chrono::duration_cast<std::chrono::microseconds>(actuallySleptUntil - beforeSleep).count() << | |
| 868 | + "Avg Updates (us):" << avgerageUpdate.count() << | |
| 867 | 869 | "FPS:" << fps; |
| 868 | 870 | } |
| 869 | 871 | } |
| @@ -906,7 +908,6 @@ void ScriptEngine::run() { · 36 unmodified lines | ||
| 906 | 908 | |
| 907 | 909 | // Debug and clear exceptions |
| 908 | 910 | hadUncaughtExceptions(*this, _fileNameString); |
| 909 | − lastLoopStart = thisLoopStart; | |
| 910 | 911 | } |
| 911 | 912 | |
| 912 | 913 | qCDebug(scriptengine) << "Script Engine stopping:" << getFilename(); |