2 changed files with 112 additions and 75 deletions
@ -0,0 +1,103 @@ |
|||
using System; |
|||
|
|||
namespace Avalonia.OpenGL |
|||
{ |
|||
public abstract class EglGlPlatformSurfaceBase : IGlPlatformSurface |
|||
{ |
|||
public interface IEglWindowGlPlatformSurfaceInfo |
|||
{ |
|||
IntPtr Handle { get; } |
|||
PixelSize Size { get; } |
|||
double Scaling { get; } |
|||
} |
|||
|
|||
public abstract IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(); |
|||
} |
|||
|
|||
public abstract class EglPlatformSurfaceRenderTargetBase : IGlPlatformSurfaceRenderTargetWithCorruptionInfo |
|||
{ |
|||
private readonly EglDisplay _display; |
|||
private readonly EglContext _context; |
|||
|
|||
protected EglPlatformSurfaceRenderTargetBase(EglDisplay display, EglContext context) |
|||
{ |
|||
_display = display; |
|||
_context = context; |
|||
} |
|||
|
|||
public abstract bool IsCorrupted { get; } |
|||
|
|||
public virtual void Dispose() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public abstract IGlPlatformSurfaceRenderingSession BeginDraw(); |
|||
|
|||
protected IGlPlatformSurfaceRenderingSession BeginDraw(EglSurface surface, |
|||
EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info, Action onFinish = null, bool isYFlipped = false) |
|||
{ |
|||
var l = _context.Lock(); |
|||
try |
|||
{ |
|||
if (IsCorrupted) |
|||
throw new RenderTargetCorruptedException(); |
|||
var restoreContext = _context.MakeCurrent(surface); |
|||
_display.EglInterface.WaitClient(); |
|||
_display.EglInterface.WaitGL(); |
|||
_display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); |
|||
|
|||
return new Session(_display, _context, surface, info, l, restoreContext, onFinish, isYFlipped); |
|||
} |
|||
catch |
|||
{ |
|||
l.Dispose(); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
class Session : IGlPlatformSurfaceRenderingSession |
|||
{ |
|||
private readonly EglContext _context; |
|||
private readonly EglSurface _glSurface; |
|||
private readonly EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo _info; |
|||
private readonly EglDisplay _display; |
|||
private readonly IDisposable _lock; |
|||
private readonly IDisposable _restoreContext; |
|||
private readonly Action _onFinish; |
|||
|
|||
|
|||
public Session(EglDisplay display, EglContext context, |
|||
EglSurface glSurface, EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info, |
|||
IDisposable @lock, IDisposable restoreContext, Action onFinish, bool isYFlipped) |
|||
{ |
|||
IsYFlipped = isYFlipped; |
|||
_context = context; |
|||
_display = display; |
|||
_glSurface = glSurface; |
|||
_info = info; |
|||
_lock = @lock; |
|||
_restoreContext = restoreContext; |
|||
_onFinish = onFinish; |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
_context.GlInterface.Flush(); |
|||
_display.EglInterface.WaitGL(); |
|||
_glSurface.SwapBuffers(); |
|||
_display.EglInterface.WaitClient(); |
|||
_display.EglInterface.WaitGL(); |
|||
_display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); |
|||
_restoreContext.Dispose(); |
|||
_lock.Dispose(); |
|||
_onFinish?.Invoke(); |
|||
} |
|||
|
|||
public IGlContext Context => _context; |
|||
public PixelSize Size => _info.Size; |
|||
public double Scaling => _info.Scaling; |
|||
public bool IsYFlipped { get; } |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue