fixed #4951: Added support to limit region capture/image editor fps

This commit is contained in:
Jaex 2022-01-17 09:13:58 +03:00
parent 2ad22fa510
commit 29dc478e2b
4 changed files with 50 additions and 16 deletions

View file

@ -25,45 +25,68 @@ You should have received a copy of the GNU General Public License
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading;
namespace ShareX.HelpersLib namespace ShareX.HelpersLib
{ {
public class FPSManager public class FPSManager
{ {
public event Action FPSChanged; public event Action FPSUpdated;
public int FPS { get; private set; } public int FPS { get; private set; }
public int FPSLimit { get; set; } = 100;
private int frameCount; private int frameCount;
private Stopwatch timer; private Stopwatch fpsTimer, frameTimer;
public FPSManager() public FPSManager()
{ {
timer = new Stopwatch(); fpsTimer = new Stopwatch();
frameTimer = new Stopwatch();
} }
protected void OnFPSChanged() protected void OnFPSUpdated()
{ {
FPSChanged?.Invoke(); FPSUpdated?.Invoke();
} }
public void Update() public void Update()
{ {
if (!timer.IsRunning)
{
timer.Start();
}
frameCount++; frameCount++;
if (timer.ElapsedMilliseconds >= 1000) if (!fpsTimer.IsRunning)
{ {
FPS = (int)(frameCount / timer.Elapsed.TotalSeconds); fpsTimer.Start();
}
else if (fpsTimer.ElapsedMilliseconds >= 1000)
{
FPS = (int)(frameCount / fpsTimer.Elapsed.TotalSeconds);
OnFPSChanged(); OnFPSUpdated();
frameCount = 0; frameCount = 0;
timer.Restart(); fpsTimer.Restart();
}
if (FPSLimit > 0)
{
if (!frameTimer.IsRunning)
{
frameTimer.Start();
}
else
{
double currentFrameDuration = frameTimer.Elapsed.TotalMilliseconds;
double targetFrameDuration = 1000d / FPSLimit;
if (currentFrameDuration < targetFrameDuration)
{
int diff = (int)Math.Round(targetFrameDuration - currentFrameDuration);
Thread.Sleep(diff);
}
frameTimer.Restart();
}
} }
} }
} }

View file

@ -28,13 +28,23 @@ You should have received a copy of the GNU General Public License
namespace ShareX.HelpersLib namespace ShareX.HelpersLib
{ {
public static class TimerResolutionManager public class TimerResolutionManager : IDisposable
{ {
private static readonly object thisLock = new object(); private static readonly object thisLock = new object();
private static bool enabled; private static bool enabled;
private static uint lastPeriod; private static uint lastPeriod;
public TimerResolutionManager(uint period = 1)
{
Enable(period);
}
public void Dispose()
{
Disable();
}
public static bool Enable(uint period = 1) public static bool Enable(uint period = 1)
{ {
lock (thisLock) lock (thisLock)

View file

@ -109,7 +109,7 @@ public RegionCaptureForm(RegionCaptureMode mode, RegionCaptureOptions options, B
Duration = TimeSpan.FromMilliseconds(200) Duration = TimeSpan.FromMilliseconds(200)
}; };
fpsManager = new FPSManager(); fpsManager = new FPSManager();
fpsManager.FPSChanged += FpsManager_FPSChanged; fpsManager.FPSUpdated += FpsManager_FPSChanged;
if (IsEditorMode && Options.ShowEditorPanTip) if (IsEditorMode && Options.ShowEditorPanTip)
{ {

View file

@ -296,6 +296,7 @@ private static void Main(string[] args)
MultiInstance = CLI.IsCommandExist("multi", "m"); MultiInstance = CLI.IsCommandExist("multi", "m");
using (ApplicationInstanceManager instanceManager = new ApplicationInstanceManager(!MultiInstance, args, SingleInstanceCallback)) using (ApplicationInstanceManager instanceManager = new ApplicationInstanceManager(!MultiInstance, args, SingleInstanceCallback))
using (TimerResolutionManager timerResolutionManager = new TimerResolutionManager())
{ {
Run(); Run();
} }