daily update on 20240326 by nitload youmu, removing old MT

This commit is contained in:
YoumuLiu
2024-03-27 02:27:00 +08:00
parent f0d91b6d51
commit ea2a4a7dcb
59 changed files with 623 additions and 295 deletions
+70 -118
View File
@@ -34,6 +34,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
@@ -47,10 +48,41 @@ namespace StgSharp.Graphics
public abstract unsafe partial class Form
{
private int _frameCount;
private int _frameSpeed;
private short fpsCount;
#region form thread setting
private List<FrameAsyncThread> frameAsyncTaskList;
#endregion form thread setting
private IntPtr windowID;
internal LinkedList<Control> allControl;
internal Vector4 backgroundColor;
internal TimeSpanProvider fpsCountProvider;
internal TimeSpanProvider frameTimeProvider;
internal IglFunc gl;
internal IntPtr graphicContextID;
internal int height;
internal IntPtr monitor;
internal string name;
internal Form sharedForm;
internal int width;
protected Form()
{
frameAsyncTaskList = new List<FrameAsyncThread>();
fpsCountProvider = new TimeSpanProvider(1.0, TimeSpanProvider.DefaultProvider);
}
public int CurrentFrameCount => frameTimeProvider.CurrentSpan;
public int FrameSpeed => _frameSpeed;
/// <summary>
/// OpenGL package binded to current form context.
/// A OpenGL context is only binded to current form.
@@ -66,15 +98,9 @@ namespace StgSharp.Graphics
set => height = value;
}
/// <summary>
/// Representing
/// </summary>
public bool IsDoubleRendering => isSingleThread;
public bool ShouldClose
{
get => InternalIO.glfwWindowShouldClose(windowID) != 0;
set => InternalIO.glfwSetWindowShouldClose(windowID, value ? 1 : 0);
}
@@ -102,6 +128,8 @@ namespace StgSharp.Graphics
public unsafe IntPtr WindowID => windowID;
internal unsafe IntPtr id => windowID;
protected FrameBufferSizeHandler FrameBufferSizeCallback
{
set
@@ -111,24 +139,16 @@ namespace StgSharp.Graphics
}
}
internal unsafe IntPtr id => windowID;
internal bool IsSingleThread => isSingleThread;
public abstract void Deinit(params object[] args);
public abstract void Deinit();
/// <summary>
/// Necessary operation to init this form.
/// </summary>
/// <param name="args"></param>
public abstract void Init(params object[] args);
public abstract void Init();
/// <summary>
/// Behaviour of current form when in a frame cycle.
/// </summary>
/// <param name="args"></param>
public abstract void Main();
/// <summary>
@@ -244,33 +264,6 @@ namespace StgSharp.Graphics
public void SetSizeLimit(int minWidth, int minHeight, int maxWidth, int maxHeight)
{ InternalIO.glfwSetWindowSizeLimits(this.windowID, minWidth, minHeight, maxWidth, maxHeight); }
#region metadata
internal LinkedList<Control> allControl;
internal Vector4 backgroundColor;
internal IglFunc gl;
internal IntPtr graphicContextID;
internal int height;
internal IntPtr monitor;
internal string name;
internal Form sharedForm;
internal int width;
private IntPtr windowID;
#endregion metadata
#region form time
private short fpsCount;
internal TimeSpanProvider frameTimeProvider;
internal TimeSpanProvider fpsCountProvider = new TimeSpanProvider(1.0, TimeSpanProvider.DefaultProvider);
#endregion
#region form thread setting
private bool isSingleThread = true;
private List<FrameAsyncThread> frameAsyncTaskList = new List<FrameAsyncThread>();
#endregion form thread setting
#region form main
@@ -287,58 +280,38 @@ namespace StgSharp.Graphics
else
{
frameTimeProvider = new TimeSpanProvider(1 / 60.0, TimeSpanProvider.DefaultProvider);
if (isSingleThread)
{
while (!ShouldClose)
MethodInfo[] methods = this.GetType().GetMethods(
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly);
if (methods.Length != 0)
foreach (MethodInfo m in methods)
{
Main();
SwapBuffers();
PollEvents();
frameTimeProvider.WaitNextSpan();
Console.WriteLine(frameTimeProvider.CurrentSpan);
if (m.GetCustomAttribute<RenderActivityAttribute>(false) != null)
{
if (!m.IsStatic && m.GetParameters().Length == 0 && m.ReturnType == typeof(void) )
{
if (m.Name != "Main")
{
FrameAsyncThread t = new();
}
}
else
{
throw new NotSupportedException("A render activity cannot have parameters, returning value or be static.");
}
}
}
}
else
while (!ShouldClose)
{
GLonUpdate update = new GLonUpdate((GLcontext*)graphicContextID); //更换GL库至双线程模式
AsyncUpdateDataTask updateT = new AsyncUpdateDataTask(this); //建立两个异步线程
AsyncRenderFrameTask renderT = new AsyncRenderFrameTask(this);
frameAsyncTaskList.Add(renderT);
frameAsyncTaskList.Add(updateT);
gl = update;
update.ActivatedOperationBuffer = updateT.opBuffer;
Barrier frameBarrier = FrameAsyncThread.CombineBeginningAsync(true, renderT, updateT);
Barrier swapBufferBarrier = renderT.TodoCompleteBarrier;
Barrier exchangeBufferBarrier = updateT.TodoCompleteBarrier;
renderT.AsyncStart();
updateT.AsyncStart();
while (!ShouldClose)
{
swapBufferBarrier.SignalAndWait();
SwapBuffers(); //绘制帧必要操作
PollEvents();
exchangeBufferBarrier.SignalAndWait();
FrameAsyncThread.ExchangeBuffer(updateT, renderT); //交换两个线程的缓冲区
update.ActivatedOperationBuffer = updateT.opBuffer;
frameTimeProvider.WaitNextSpan(); //等待下一帧开始
frameBarrier.SignalAndWait();
Console.WriteLine(frameTimeProvider.CurrentSpan);
}
updateT.Terminate();
renderT.Terminate();
Main();
SwapBuffers();
PollEvents();
frameTimeProvider.WaitNextSpan();
}
}
}
public int CurrentFrameCount
=> frameTimeProvider.CurrentSpan;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void InternalDeinit(params object[] args) { Deinit(args); }
@@ -369,38 +342,17 @@ namespace StgSharp.Graphics
}
}
/// <summary>
/// Define how current form render in one frame.
/// </summary>
/// <param name="leastThreds">
/// Please define this befor calling any OpenGL api and other graphic methods.
/// </param>
protected unsafe void SetRenderThreads(int leastThreds)
{
if (gl != default)
{
throw new InvalidOperationException("Cannot define threads after loading gl context.");
}
if (leastThreds == 1)
{
isSingleThread = true;
}
else if (leastThreds >= 2)
{
isSingleThread = false;
}
else
{
throw new ArgumentException("Amount of threads should be bigger than 0");
}
}
unsafe ~Form() { Marshal.FreeHGlobal(graphicContextID); }
#endregion form main
}
/// <summary>
/// Mark that a method in a <see cref="Form"/>
/// should be called when rendering.
/// </summary>
public class RenderActivityAttribute : Attribute
{
}
}