refactor(render): compose render frame orchestrator
Move the accepted draw transaction and failure recovery behind typed frame-phase owners so GameWindow only supplies immutable frame input. Preserve retail draw order, make ImGui/bootstrap shutdown ownership explicit, and restore exact text-render GL state on failures.\n\nCo-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
28e1cf8029
commit
9d7df1bfc5
25 changed files with 1675 additions and 279 deletions
156
src/AcDream.App/Rendering/TextRenderGlStateScope.cs
Normal file
156
src/AcDream.App/Rendering/TextRenderGlStateScope.cs
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace AcDream.App.Rendering;
|
||||
|
||||
internal interface ITextRenderGlStateApi
|
||||
{
|
||||
bool IsEnabled(EnableCap capability);
|
||||
|
||||
int GetInteger(GetPName parameter);
|
||||
|
||||
bool GetBoolean(GetPName parameter);
|
||||
|
||||
void SetCapability(EnableCap capability, bool enabled);
|
||||
|
||||
void DepthMask(bool enabled);
|
||||
|
||||
void BlendFuncSeparate(
|
||||
BlendingFactor sourceRgb,
|
||||
BlendingFactor destinationRgb,
|
||||
BlendingFactor sourceAlpha,
|
||||
BlendingFactor destinationAlpha);
|
||||
|
||||
void UseProgram(uint program);
|
||||
|
||||
void BindVertexArray(uint vertexArray);
|
||||
|
||||
void BindBuffer(BufferTargetARB target, uint buffer);
|
||||
|
||||
void ActiveTexture(TextureUnit unit);
|
||||
|
||||
void BindTexture(TextureTarget target, uint texture);
|
||||
}
|
||||
|
||||
internal sealed class SilkTextRenderGlStateApi : ITextRenderGlStateApi
|
||||
{
|
||||
private readonly GL _gl;
|
||||
|
||||
public SilkTextRenderGlStateApi(GL gl) =>
|
||||
_gl = gl ?? throw new ArgumentNullException(nameof(gl));
|
||||
|
||||
public bool IsEnabled(EnableCap capability) => _gl.IsEnabled(capability);
|
||||
|
||||
public int GetInteger(GetPName parameter) => _gl.GetInteger(parameter);
|
||||
|
||||
public bool GetBoolean(GetPName parameter) => _gl.GetBoolean(parameter);
|
||||
|
||||
public void SetCapability(EnableCap capability, bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
_gl.Enable(capability);
|
||||
else
|
||||
_gl.Disable(capability);
|
||||
}
|
||||
|
||||
public void DepthMask(bool enabled) => _gl.DepthMask(enabled);
|
||||
|
||||
public void BlendFuncSeparate(
|
||||
BlendingFactor sourceRgb,
|
||||
BlendingFactor destinationRgb,
|
||||
BlendingFactor sourceAlpha,
|
||||
BlendingFactor destinationAlpha) =>
|
||||
_gl.BlendFuncSeparate(
|
||||
sourceRgb,
|
||||
destinationRgb,
|
||||
sourceAlpha,
|
||||
destinationAlpha);
|
||||
|
||||
public void UseProgram(uint program) => _gl.UseProgram(program);
|
||||
|
||||
public void BindVertexArray(uint vertexArray) => _gl.BindVertexArray(vertexArray);
|
||||
|
||||
public void BindBuffer(BufferTargetARB target, uint buffer) =>
|
||||
_gl.BindBuffer(target, buffer);
|
||||
|
||||
public void ActiveTexture(TextureUnit unit) => _gl.ActiveTexture(unit);
|
||||
|
||||
public void BindTexture(TextureTarget target, uint texture) =>
|
||||
_gl.BindTexture(target, texture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exact, focused state transaction for <see cref="TextRenderer.Flush"/>. It
|
||||
/// captures every GL value that Flush or DrawLayer mutates, while avoiding the
|
||||
/// dozens of unrelated synchronous reads made by the broad diagnostic scope.
|
||||
/// </summary>
|
||||
internal readonly struct TextRenderGlStateScope : IDisposable
|
||||
{
|
||||
private readonly ITextRenderGlStateApi _gl;
|
||||
private readonly bool _depthTest;
|
||||
private readonly bool _blend;
|
||||
private readonly bool _cullFace;
|
||||
private readonly bool _alphaToCoverage;
|
||||
private readonly bool _multisample;
|
||||
private readonly bool _depthWrite;
|
||||
private readonly int _blendSourceRgb;
|
||||
private readonly int _blendDestinationRgb;
|
||||
private readonly int _blendSourceAlpha;
|
||||
private readonly int _blendDestinationAlpha;
|
||||
private readonly int _program;
|
||||
private readonly int _vertexArray;
|
||||
private readonly int _arrayBuffer;
|
||||
private readonly int _activeTexture;
|
||||
private readonly int _texture0Binding2D;
|
||||
|
||||
public TextRenderGlStateScope(ITextRenderGlStateApi gl)
|
||||
{
|
||||
_gl = gl ?? throw new ArgumentNullException(nameof(gl));
|
||||
_depthTest = gl.IsEnabled(EnableCap.DepthTest);
|
||||
_blend = gl.IsEnabled(EnableCap.Blend);
|
||||
_cullFace = gl.IsEnabled(EnableCap.CullFace);
|
||||
_alphaToCoverage = gl.IsEnabled(EnableCap.SampleAlphaToCoverage);
|
||||
_multisample = gl.IsEnabled(EnableCap.Multisample);
|
||||
_depthWrite = gl.GetBoolean(GetPName.DepthWritemask);
|
||||
_blendSourceRgb = gl.GetInteger(GetPName.BlendSrcRgb);
|
||||
_blendDestinationRgb = gl.GetInteger(GetPName.BlendDstRgb);
|
||||
_blendSourceAlpha = gl.GetInteger(GetPName.BlendSrcAlpha);
|
||||
_blendDestinationAlpha = gl.GetInteger(GetPName.BlendDstAlpha);
|
||||
_program = gl.GetInteger(GetPName.CurrentProgram);
|
||||
_vertexArray = gl.GetInteger(GetPName.VertexArrayBinding);
|
||||
_arrayBuffer = gl.GetInteger(GetPName.ArrayBufferBinding);
|
||||
_activeTexture = gl.GetInteger(GetPName.ActiveTexture);
|
||||
|
||||
try
|
||||
{
|
||||
gl.ActiveTexture(TextureUnit.Texture0);
|
||||
_texture0Binding2D = gl.GetInteger(GetPName.TextureBinding2D);
|
||||
}
|
||||
finally
|
||||
{
|
||||
gl.ActiveTexture((TextureUnit)_activeTexture);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_gl.UseProgram((uint)_program);
|
||||
_gl.BindVertexArray((uint)_vertexArray);
|
||||
_gl.BindBuffer(BufferTargetARB.ArrayBuffer, (uint)_arrayBuffer);
|
||||
|
||||
_gl.ActiveTexture(TextureUnit.Texture0);
|
||||
_gl.BindTexture(TextureTarget.Texture2D, (uint)_texture0Binding2D);
|
||||
_gl.ActiveTexture((TextureUnit)_activeTexture);
|
||||
|
||||
_gl.DepthMask(_depthWrite);
|
||||
_gl.BlendFuncSeparate(
|
||||
(BlendingFactor)_blendSourceRgb,
|
||||
(BlendingFactor)_blendDestinationRgb,
|
||||
(BlendingFactor)_blendSourceAlpha,
|
||||
(BlendingFactor)_blendDestinationAlpha);
|
||||
_gl.SetCapability(EnableCap.DepthTest, _depthTest);
|
||||
_gl.SetCapability(EnableCap.Blend, _blend);
|
||||
_gl.SetCapability(EnableCap.CullFace, _cullFace);
|
||||
_gl.SetCapability(EnableCap.SampleAlphaToCoverage, _alphaToCoverage);
|
||||
_gl.SetCapability(EnableCap.Multisample, _multisample);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue