Dodałem jeszcze małe usprawnienie, dzięki któremu obniżyłem zużycie mocy CPU o 5-15%.
Skoro Round
może zaokrąglić w górę i nakazać procedurze Sleep
poczekać nieco więcej, to można tę drugą milisekundę odjąć tylko wtedy, gdy ten zaokrągli w górę. W przeciwnym razie – gdy zaokrągli w dół – dodatkowa milisekunda nie jest odejmowana.
SleepTime := 1000 / FFramerateLimit * (1 - (FFrameTicksEnd - FFrameTicksBegin) / FTicksPerFrame) - 1;
SleepTime -= Ord(Round(SleepTime) > SleepTime);
SleepTime := Max(SleepTime, 0);
Sleep(Round(SleepTime));
NextFrameTicks := FFrameTicksBegin + FTicksPerFrame;
repeat
CurrentTicks := GetHardwareCounterValue();
until CurrentTicks >= NextFrameTicks;
W pierwszej linijce odejmujemy milisekundę, co zabezpiecza przed niedokładnością Sleep
. W drugiej linijce odejmujemy drugą milisekundę, jeśli wynik zaokrąglenia jest większy niż bez zaokrąglenia – to skraca czas do zjedzenia w końcowej pętli, oszczędzając moc procesora. W trzeciej linijce przerabiamy wynik na liczbę nieujemną, bo tylko taką obsługuje Sleep
– to zabezpiecza przed wywaleniem wyjątku gdy nastąpi lag, czyli gdy czas generowania klatki będzie dłuższy niż czas przydzielony na jej obsługę.