A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

115 lines
3.8 KiB

using System;
using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
namespace Avalonia.OpenGL.Egl
{
public abstract class EglGlPlatformSurfaceBase : IGlPlatformSurface
{
public abstract IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context);
}
public abstract class EglPlatformSurfaceRenderTargetBase : IGlPlatformSurfaceRenderTarget
{
protected EglContext Context { get; }
protected EglPlatformSurfaceRenderTargetBase(EglContext context)
{
Context = context;
}
public virtual void Dispose()
{
}
public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{
if (Context.IsLost)
throw new RenderTargetCorruptedException();
return BeginDrawCore(sceneInfo);
}
private protected virtual bool SkipWaits => false;
public abstract IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo);
protected IGlPlatformSurfaceRenderingSession BeginDraw(EglSurface surface,
PixelSize size, double scaling, Action? onFinish = null, bool isYFlipped = false)
{
var restoreContext = Context.MakeCurrent(surface);
var success = false;
try
{
var egli = Context.Display.EglInterface;
if (!SkipWaits)
{
egli.WaitClient();
egli.WaitGL();
egli.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE);
}
Context.GlInterface.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, 0);
success = true;
return new Session(Context.Display, Context, surface, size, scaling, restoreContext, onFinish, isYFlipped, SkipWaits);
}
finally
{
if(!success)
restoreContext.Dispose();
}
}
private class Session : IGlPlatformSurfaceRenderingSession
{
private readonly EglContext _context;
private readonly EglSurface _glSurface;
private readonly EglDisplay _display;
private readonly IDisposable _restoreContext;
private readonly Action? _onFinish;
private readonly bool _skipWaits;
public Session(EglDisplay display, EglContext context,
EglSurface glSurface, PixelSize size, double scaling,
IDisposable restoreContext, Action? onFinish, bool isYFlipped, bool skipWaits)
{
Size = size;
Scaling = scaling;
IsYFlipped = isYFlipped;
_context = context;
_display = display;
_glSurface = glSurface;
_restoreContext = restoreContext;
_onFinish = onFinish;
_skipWaits = skipWaits;
}
public void Dispose()
{
_context.GlInterface.Flush();
if (!_skipWaits)
_display.EglInterface.WaitGL();
_glSurface.SwapBuffers();
if (!_skipWaits)
{
_display.EglInterface.WaitClient();
_display.EglInterface.WaitGL();
_display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE);
}
_restoreContext.Dispose();
_onFinish?.Invoke();
}
public IGlContext Context => _context;
public PixelSize Size { get; }
public double Scaling { get; }
public bool IsYFlipped { get; }
}
public virtual bool IsCorrupted => Context.IsLost;
}
}