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.
96 lines
2.9 KiB
96 lines
2.9 KiB
|
|
using System;
|
|
using System.Threading;
|
|
using Avalonia.OpenGL;
|
|
using Avalonia.OpenGL.Surfaces;
|
|
using CoreAnimation;
|
|
|
|
namespace Avalonia.iOS
|
|
{
|
|
class EaglLayerSurface : IGlPlatformSurface
|
|
{
|
|
private readonly CAEAGLLayer _layer;
|
|
|
|
public EaglLayerSurface(CAEAGLLayer layer)
|
|
{
|
|
_layer = layer;
|
|
}
|
|
|
|
class RenderSession : IGlPlatformSurfaceRenderingSession
|
|
{
|
|
private readonly GlContext _ctx;
|
|
private readonly IDisposable _restoreContext;
|
|
private readonly SizeSynchronizedLayerFbo _fbo;
|
|
|
|
public RenderSession(GlContext ctx, IDisposable restoreContext, SizeSynchronizedLayerFbo fbo)
|
|
{
|
|
_ctx = ctx;
|
|
_restoreContext = restoreContext;
|
|
_fbo = fbo;
|
|
Size = new PixelSize(_fbo.Width, _fbo.Height);
|
|
Scaling = _fbo.Scaling;
|
|
Context = ctx;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_ctx.GlInterface.Finish();
|
|
_fbo.Present();
|
|
_restoreContext.Dispose();
|
|
}
|
|
|
|
public IGlContext Context { get; }
|
|
public PixelSize Size { get; }
|
|
public double Scaling { get; }
|
|
public bool IsYFlipped { get; }
|
|
}
|
|
|
|
class RenderTarget : IGlPlatformSurfaceRenderTarget
|
|
{
|
|
private readonly GlContext _ctx;
|
|
private readonly SizeSynchronizedLayerFbo _fbo;
|
|
|
|
public RenderTarget(GlContext ctx, SizeSynchronizedLayerFbo fbo)
|
|
{
|
|
_ctx = ctx;
|
|
_fbo = fbo;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
CheckThread();
|
|
using (_ctx.MakeCurrent())
|
|
_fbo.Dispose();
|
|
}
|
|
|
|
public IGlPlatformSurfaceRenderingSession BeginDraw()
|
|
{
|
|
CheckThread();
|
|
var restoreContext = _ctx.MakeCurrent();
|
|
_fbo.Bind();
|
|
return new RenderSession(_ctx, restoreContext, _fbo);
|
|
}
|
|
}
|
|
|
|
static void CheckThread()
|
|
{
|
|
if (Platform.Timer.TimerThread != Thread.CurrentThread)
|
|
throw new InvalidOperationException("Invalid thread, go away");
|
|
}
|
|
|
|
public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context)
|
|
{
|
|
CheckThread();
|
|
var ctx = Platform.GlFeature.Context;
|
|
if (ctx != context)
|
|
throw new InvalidOperationException("Platform surface is only usable with tha main context");
|
|
using (ctx.MakeCurrent())
|
|
{
|
|
var fbo = new SizeSynchronizedLayerFbo(ctx.Context, ctx.GlInterface, _layer);
|
|
if (!fbo.Sync())
|
|
throw new InvalidOperationException("Unable to create render target");
|
|
return new RenderTarget(ctx, fbo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|