daily update on 20231214 by nitload youmu

This commit is contained in:
Nitload
2023-12-14 07:01:01 +08:00
parent f97fb137ba
commit 8b14599233
54 changed files with 537 additions and 241 deletions
+31 -33
View File
@@ -15,14 +15,6 @@ using System.Threading;
namespace StgSharp.Graphics
{
[StructLayout(LayoutKind.Sequential)]
internal struct formInfo
{
public int width;
public int height;
public Vector4 color;
public string name;
}
/// <summary>
///
@@ -39,12 +31,15 @@ namespace StgSharp.Graphics
internal int width;
internal IntPtr windowID;
private GLonRender glRender;
private GLonUpdate glUpdate;
protected IglFunc GL;
internal FormUpdateBuffer UpdateBuffer;
internal FormRenderBuffer RenderBuffer;
internal FrameUpdateTimer timer = new FrameUpdateTimer();
private SemaphoreSlim ping = new SemaphoreSlim(1, 1);
private SemaphoreSlim pong = new SemaphoreSlim(0, 1);
internal readonly SemaphoreSlim ouetrPong = new SemaphoreSlim(0, 1);
private UpdateWhenRender updateWhenRender;
private DynamicMethod updateWhenRenderDM;
@@ -83,18 +78,18 @@ namespace StgSharp.Graphics
unsafe ~Form()
{
Marshal.FreeHGlobal((IntPtr)contextID);
glRender.api = default;
RenderBuffer.GL.api = default;
}
#region form main
public abstract void Deinit(object[] args, IglFunc GL);
public abstract void Deinit(object[] args);
public abstract void Init(object[] args, IglFunc GL);
public abstract void Init(object[] args);
public abstract void OnRenderFrame(object[] args, IglFunc GL);
public abstract void OnRenderFrame(object[] args);
public abstract void OnUpdateFrame(object[] args, IglFunc GL);
public abstract void OnUpdateFrame(object[] args);
/// <summary>
/// Init this form and render it on screen, and respond with operation
@@ -103,16 +98,20 @@ namespace StgSharp.Graphics
{
if (args == null)
{
args = new object[3] { null, null, null };
args = new object[4] { null, null, null, null };
}
Operation.RegistForm(this);
if (!TimeLine.RenderStarted)
{
TimeLine.RenderAll();
}
try
{
Thread updateThread = new Thread(InternalUpdateFrame);
Thread renderThread = new Thread(InternalRenderFrame);
updateThread.Start();
renderThread.Start();
updateThread.Start(args[1]);
renderThread.Start(args[2]);
updateThread.Join();
renderThread.Join();
@@ -120,6 +119,8 @@ namespace StgSharp.Graphics
ping.Dispose();
pong.Dispose();
InternalDeinit(args[3]);
}
catch (Exception)
{
@@ -127,7 +128,12 @@ namespace StgSharp.Graphics
}
}
internal void InternalInit(object[] args)
internal void InternalDeinit(object args)
{
Deinit((object[])args);
}
internal void InternalInit(object args)
{
updateWhenRenderDM = new DynamicMethod(
name: "updateWhenRender",
@@ -137,7 +143,7 @@ namespace StgSharp.Graphics
);
updateWhenRenderIL = updateWhenRenderDM.GetILGenerator();
Init((object[])args, this.glRender);
Init((object[])args);
}
@@ -149,9 +155,9 @@ namespace StgSharp.Graphics
ping.Wait();
try
{
OnRenderFrame((object[])args, glRender);
timer.GoNextFrame();
throw new Exception("Forget to reload GL apis");
OnRenderFrame((object[])args);
timer.WaitNextFrame();
pong.Release();
}
catch (NullReferenceException)
@@ -162,7 +168,6 @@ namespace StgSharp.Graphics
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void InternalUpdateFrame(object args)
{
while (InternalIO.glfw.WindowShouldClose(windowID) != 0)
@@ -170,8 +175,8 @@ namespace StgSharp.Graphics
pong.Wait();
try
{
OnUpdateFrame((object[])args, glUpdate);
timer.GoNextFrame();
OnUpdateFrame((object[])args);
timer.WaitNextFrame();
throw new Exception("Forget to reload GL apis");
ping.Release();
}
@@ -297,12 +302,5 @@ namespace StgSharp.Graphics
}
/// <summary>
/// Bind this form to StgSharp platform.
/// </summary>
protected void BindToPlatform()
{
TimeLine.allForm.Add(this);
}
}
}
+52 -97
View File
@@ -1,4 +1,5 @@
using StgSharp;
using StgSharp.Logic;
using System;
using System.Runtime.CompilerServices;
using System.Threading;
@@ -6,13 +7,63 @@ using System.Threading.Tasks;
namespace StgSharp.Graphics
{
public partial class Form
{
private bool isFullyRendered = false;
internal class FrameUpdateTimer
{
internal Bool2 alignSign;
private float frameLength;
private double frameBegin;
private bool refreshed;
private Counter<uint> tickCounter;
public double timeAfterFrame
{
get { return InternalIO.glfw.GetTime() - frameBegin; }
}
public uint totalFrame
{
get { return tickCounter; }
}
internal void Refresh()
{
refreshed = false;
}
internal bool WaitNextFrame()
{
try
{
while (refreshed) { }
refreshed = true;
return true;
}
catch (Exception ex)
{
InternalIO.InternalWriteLog(ex.Message, LogType.Error);
return false;
}
}
}
}
/// <summary>
/// A timer counting frames after its construction.
/// </summary>
public class FrameTimer
{
private Form timeProvider;
internal readonly uint bornTick;
private Form timeProvider;
public FrameTimer(Form provaider)
{
timeProvider = provaider;
bornTick = timeProvider.timer.totalFrame;
}
/// <summary>
/// Frames after this timer created.
@@ -22,12 +73,6 @@ namespace StgSharp.Graphics
get { return timeProvider.timer.totalFrame - bornTick; }
}
public FrameTimer(Form provaider)
{
timeProvider = provaider;
bornTick = timeProvider.timer.totalFrame;
}
/// <summary>
/// Convert a <see cref="FrameTimer"/> into uint value.
/// this will get total frames since the timer was created.
@@ -39,94 +84,4 @@ namespace StgSharp.Graphics
return timer.Time;
}
}
public partial class Form
{
internal class FrameUpdateTimer
{
private Counter<uint> 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;
/// <summary>
/// Wait until the next frame of a certain <see cref="Form"/> 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
/// </summary>
/// <param name="form">The <see cref="Form"/> that can provide a frame refresh benchmark</param>
/// <param name="action"><see cref="Action"/> to be done and aligned.</param>
/// <returns>
/// A bool value indicating if the <see cref="Form"/> successfully refresh the frame.
/// If the retur value is false, please set a new <see cref="Form"/> as benchmark.
/// </returns>
protected bool AlignFrame(Form form, Action action)
{
try
{
bool isAligned = form.timer.GoNextFrame();
action();
return isAligned;
}
catch (Exception)
{
return false;
}
}
}
}
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Graphics
{
internal class FormRenderBuffer
{
internal GLonRender GL;
internal InternalFormBuffer data;
}
internal class FormUpdateBuffer
{
internal GLonUpdate GL;
internal InternalFormBuffer data;
}
internal class InternalFormBuffer
{
}
}
@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Graphics
{
internal class FrameBuffer
{
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ namespace StgSharp.Graphics
internal uint[] _bufferID;
private IglFunc GL;
internal VertexArray(int n, IglFunc glFunc)
internal VertexArray(int n)
{
_bufferID = new uint[n];
GL = glFunc;
@@ -18,6 +18,24 @@ namespace StgSharp.Graphics
api.ActiveTexture(type);
}
void IglFunc.AfterAlign(Form form, Action action)
{
throw new NotImplementedException();
}
void IglFunc.AlignFrame(Form form)
{
if (form.timer.alignSign.byte0 > 0)
{
throw new InvalidOperationException();
}
form.timer.WaitNextFrame();
form.timer.alignSign.byte0++;
if (form.timer.)
{
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void IglFunc.AttachShader(uint program, uint shader)
@@ -0,0 +1,223 @@
using StgSharp.Logic;
using StgSharp.Math;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Graphics
{
internal class GLonTimeout : IglFunc
{
private static readonly GLonTimeout singleInstance
= new GLonTimeout();
private GLonTimeout() { }
internal static GLonTimeout Set()
{
return singleInstance;
}
void IglFunc.ActiveTexture(uint type)
{
throw new FrameTimeoutException();
}
void IglFunc.AfterAlign(Form form, Action action)
{
throw new FrameTimeoutException();
}
void IglFunc.AlignFrame(Form form)
{
throw new FrameTimeoutException();
}
void IglFunc.AttachShader(uint program, uint shader)
{
throw new FrameTimeoutException();
}
void IglFunc.BindBuffer(BufferType bufferType, uint index)
{
throw new FrameTimeoutException();
}
void IglFunc.BindTexture(uint type, uint texture)
{
throw new FrameTimeoutException();
}
void IglFunc.BindVertexArray(uint index)
{
throw new FrameTimeoutException();
}
void IglFunc.Clear(MaskBufferBit mask)
{
throw new FrameTimeoutException();
}
void IglFunc.ClearColor(float R, float G, float B, float A)
{
throw new FrameTimeoutException();
}
void IglFunc.ClearGraphicError()
{
throw new FrameTimeoutException();
}
uint IglFunc.CompileShader(string shaderCode, ShaderType shaderType)
{
throw new FrameTimeoutException();
}
uint IglFunc.CreateProgram()
{
throw new FrameTimeoutException();
}
IntPtr IglFunc.CreateWindowHandle(int width, int height, string tittle, IntPtr monitor, Form share)
{
throw new FrameTimeoutException();
}
uint IglFunc.CreatGraphicProgram()
{
throw new FrameTimeoutException();
}
unsafe void IglFunc.DeleteBuffers(int count, uint* ptr)
{
throw new FrameTimeoutException();
}
unsafe void IglFunc.DeleteVertexArrays(int count, uint* ptr)
{
throw new FrameTimeoutException();
}
void IglFunc.DrawElements(GepmetryType mode, int count, Type type, IntPtr ptr)
{
throw new FrameTimeoutException();
}
unsafe void IglFunc.GenBuffers(int count, uint* ptr)
{
throw new FrameTimeoutException();
}
unsafe void IglFunc.GenTextures(int count, uint* ptr)
{
throw new FrameTimeoutException();
}
unsafe void IglFunc.GenVertexArrays(int count, uint* ptr)
{
throw new FrameTimeoutException();
}
void IglFunc.GetGraphicError()
{
throw new FrameTimeoutException();
}
unsafe int IglFunc.GetUniformLocation(uint program, byte* ptr)
{
throw new FrameTimeoutException();
}
bool IglFunc.GetWindowShouldClose(Form form)
{
throw new FrameTimeoutException();
}
void IglFunc.MakeContexCurrent(Form form)
{
throw new FrameTimeoutException();
}
void IglFunc.SetBufferData<T>(BufferType bufferType, T bufferData, BufferUsage usage)
{
throw new FrameTimeoutException();
}
void IglFunc.SetBufferData<T>(BufferType bufferType, T[] bufferArray, BufferUsage usage)
{
throw new FrameTimeoutException();
}
void IglFunc.SetFrameBufferSizeCallback(IntPtr id, FrameBufferSizeHandler handler)
{
throw new FrameTimeoutException();
}
void IglFunc.SetValue(Uniform<float, float, float, float> uniform, float v0, float v1, float v2, float v3)
{
throw new FrameTimeoutException();
}
void IglFunc.SetValue(Uniform<float, float, float, float> uniform, Vec4d vec)
{
throw new FrameTimeoutException();
}
void IglFunc.SetValue(Uniform<float, float, float> uniform, float v0, float v1, float v2)
{
throw new FrameTimeoutException();
}
void IglFunc.SetValue(Uniform<float, float> uniform, float v0, float v1)
{
throw new FrameTimeoutException();
}
void IglFunc.SetValue(Uniform<float> uniform, float v0)
{
throw new FrameTimeoutException();
}
void IglFunc.SetValue(Uniform<int> uniform, int i0)
{
throw new FrameTimeoutException();
}
void IglFunc.SetValue(Uniform<Vec4d> uniform, Vec4d vec)
{
throw new FrameTimeoutException();
}
void IglFunc.SetVertexAttribute(uint index, int size, Type t, bool normalized, int stride, int pointer)
{
throw new FrameTimeoutException();
}
void IglFunc.SwapBuffers(Form form)
{
throw new FrameTimeoutException();
}
unsafe void IglFunc.TextureImage2d(uint target, int level, uint internalformat, int width, int height, uint format, uint type, void* pixels)
{
throw new FrameTimeoutException();
}
void IglFunc.TextureParameter(uint target, uint pname, int param)
{
throw new FrameTimeoutException();
}
void IglFunc.UseProgram(uint program)
{
throw new FrameTimeoutException();
}
void IglFunc.Viewport(int x, int y, int width, int height)
{
throw new FrameTimeoutException();
}
}
}
+22
View File
@@ -5,6 +5,28 @@ namespace StgSharp.Graphics
{
public interface IglFunc
{
/// <summary>
/// Align a sets of code to frame update of a <see cref="Form"/>.
/// Usually, a call of <see cref="AfterAlign(Form,Action)"/> is required.
/// This method is used as sigle thread method. If more than one
/// alignment is requested, a <see cref="InvalidOperationException"/> will throw.
/// </summary>
/// <param name="form">The form used as frame update benchmark.</param>
/// <exception cref="InvalidOperationException">More than one alingment attached to one form timer</exception>
void AlignFrame(Form form);
/// <summary>
/// Operation after alignment by calling <see cref="AlignFrame(Form)"/>.
/// No calling of this method is acceptable, but it will bring the risk
/// of that relevant code will not run if it is interrupted by frame overtime.
/// Please call this method immediately after calling <see cref="AlignFrame(Form)"/>,
/// too early or sonner may cause <see cref="InvalidOperationException"/>.
/// </summary>
/// <param name="form">The form used as frame update benchmark.</param>
/// <param name="action">Operation after frame update alignment.</param>
/// <exception cref="InvalidOperationException">The action binded to a wrong alignment.</exception>
void AfterAlign(Form form, Action action);
/// <summary>
/// Same function as OpenGL api glActiveTexture
/// </summary>