using StgSharp; using System; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; namespace StgSharp.Graphics { /// /// A timer counting frames after its construction. /// public class FrameTimer { private Form timeProvider; internal readonly uint bornTick; /// /// Frames after this timer created. /// public uint Time { get { return timeProvider.timer.totalFrame - bornTick; } } public FrameTimer(Form provaider) { timeProvider = provaider; bornTick = timeProvider.timer.totalFrame; } /// /// Convert a into uint value. /// this will get total frames since the timer was created. /// /// to be converted [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator uint(FrameTimer timer) { return timer.Time; } } public partial class Form { internal class FrameUpdateTimer { private Counter tickCounter; private float frameLength; private double frameTime; private bool refreshed; private SemaphoreSlim pong; private bool isOnceFulFrame = false; public uint totalFrame { get { return tickCounter; } } public double timeAfterFrame { get { return InternalIO.glfw.GetTime() - frameTime; } } internal bool IsOnceFullFrame { get { return isOnceFulFrame; } set { if (!isOnceFulFrame) { isOnceFulFrame = value; } } } internal void Init(SemaphoreSlim semaphore) { pong = semaphore; } internal void Refresh() { refreshed = false; } internal bool GoNextFrame() { try { while (refreshed) { } refreshed = true; return refreshed; } catch (Exception ex) { InternalIO.InternalWriteLog(ex.Message, LogType.Error); return false; } } } private bool isFullyRendered = false; /// /// Wait until the next frame of a certain started, /// all GL function after this method will be blocked until the next frame started. /// When a frame refreshed before /// It should be noticed that do not use this method too often to avoid unexpected performance problem /// /// The that can provide a frame refresh benchmark /// to be done and aligned. /// /// A bool value indicating if the successfully refresh the frame. /// If the retur value is false, please set a new as benchmark. /// protected bool AlignFrame(Form form, Action action) { try { bool isAligned = form.timer.GoNextFrame(); action(); return isAligned; } catch (Exception) { return false; } } } }