csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
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
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;
|
|
}
|
|
}
|
|
|