Skip to content

Commit

Permalink
Use Avalonia GlInterface in iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkatz6 committed Feb 15, 2022
1 parent aebec46 commit 3c94cdc
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 41 deletions.
2 changes: 1 addition & 1 deletion samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-ios</TargetFramework>
<SupportedOSPlatformVersion>14.2</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion>10.0</SupportedOSPlatformVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\iOS\Avalonia.iOS\Avalonia.iOS.csproj" />
Expand Down
2 changes: 1 addition & 1 deletion samples/ControlCatalog.iOS/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>8.0</string>
<string>10.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
Expand Down
4 changes: 4 additions & 0 deletions src/Avalonia.OpenGL/GlInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,10 @@ public int GetUniformLocationString(int program, string name)
public delegate void GlDeleteShader(int shader);
[GlEntryPoint("glDeleteShader")]
public GlDeleteShader DeleteShader { get; }

public delegate void GLGetRenderbufferParameteriv(int target, int name, int[] value);
[GlEntryPoint("glGetRenderbufferParameteriv")]
public GLGetRenderbufferParameteriv GetRenderbufferParameteriv { get; }
// ReSharper restore UnassignedGetOnlyAutoProperty
}
}
5 changes: 2 additions & 3 deletions src/iOS/Avalonia.iOS/EaglLayerSurface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Avalonia.OpenGL;
using Avalonia.OpenGL.Surfaces;
using CoreAnimation;
using OpenTK.Graphics.ES30;

namespace Avalonia.iOS
{
Expand Down Expand Up @@ -35,7 +34,7 @@ public RenderSession(GlContext ctx, IDisposable restoreContext, SizeSynchronized

public void Dispose()
{
GL.Finish();
_ctx.GlInterface.Finish();
_fbo.Present();
_restoreContext.Dispose();
}
Expand Down Expand Up @@ -85,7 +84,7 @@ public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget()
var ctx = Platform.GlFeature.Context;
using (ctx.MakeCurrent())
{
var fbo = new SizeSynchronizedLayerFbo(ctx.Context, _layer);
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);
Expand Down
3 changes: 2 additions & 1 deletion src/iOS/Avalonia.iOS/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using Avalonia.Media;
using CoreGraphics;
using ObjCRuntime;
using UIKit;

namespace Avalonia.iOS
Expand All @@ -20,4 +21,4 @@ static class Extensions
ColorComponent(color.B),
ColorComponent(color.A));
}
}
}
79 changes: 44 additions & 35 deletions src/iOS/Avalonia.iOS/LayerFbo.cs
Original file line number Diff line number Diff line change
@@ -1,64 +1,72 @@
using System;
using Avalonia.OpenGL;
using CoreAnimation;
using ObjCRuntime;
using OpenGLES;
using OpenTK.Graphics.ES20;

namespace Avalonia.iOS
{
public class LayerFbo
{
private readonly EAGLContext _context;
private readonly GlInterface _gl;
private readonly CAEAGLLayer _layer;
private int _framebuffer;
private int _renderbuffer;
private int _depthBuffer;
private int[] _framebuffer;
private int[] _renderbuffer;
private int[] _depthBuffer;
private bool _disposed;

private LayerFbo(EAGLContext context, CAEAGLLayer layer, in int framebuffer, in int renderbuffer, in int depthBuffer)
private LayerFbo(EAGLContext context, GlInterface gl, CAEAGLLayer layer, int[] framebuffer, int[] renderbuffer, int[] depthBuffer)
{
_context = context;
_gl = gl;
_layer = layer;
_framebuffer = framebuffer;
_renderbuffer = renderbuffer;
_depthBuffer = depthBuffer;
}

public static LayerFbo TryCreate(EAGLContext context, CAEAGLLayer layer)
public static LayerFbo TryCreate(EAGLContext context, GlInterface gl, CAEAGLLayer layer)
{
if (context != EAGLContext.CurrentContext)
return null;
GL.GenFramebuffers(1, out int fb);
GL.GenRenderbuffers(1, out int rb);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, fb);
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, rb);
context.RenderBufferStorage((uint) All.Renderbuffer, layer);

var fb = new int[2];
var rb = new int[2];
var db = new int[2];

GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, RenderbufferTarget.Renderbuffer, rb);
gl.GenFramebuffers(1, fb);
gl.GenRenderbuffers(1, rb);
gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, fb[0]);
gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, rb[0]);
context.RenderBufferStorage(GlConsts.GL_RENDERBUFFER, layer);

gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_COLOR_ATTACHMENT0, GlConsts.GL_RENDERBUFFER, rb[0]);

int w;
int h;
GL.GetRenderbufferParameter(RenderbufferTarget.Renderbuffer, RenderbufferParameterName.RenderbufferWidth, out w);
GL.GetRenderbufferParameter(RenderbufferTarget.Renderbuffer, RenderbufferParameterName.RenderbufferHeight, out h);
int[] w = new int[1];
int[] h = new int[1];
gl.GetRenderbufferParameteriv(GlConsts.GL_RENDERBUFFER, GlConsts.GL_RENDERBUFFER_WIDTH, w);
gl.GetRenderbufferParameteriv(GlConsts.GL_RENDERBUFFER, GlConsts.GL_RENDERBUFFER_HEIGHT, h);

GL.GenRenderbuffers(1, out int depthBuffer);
gl.GenRenderbuffers(1, db);

//GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer);
//GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferInternalFormat.DepthComponent16, w, h);
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.DepthAttachment, RenderbufferTarget.Renderbuffer, depthBuffer);
gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_DEPTH_ATTACHMENT, GlConsts.GL_RENDERBUFFER, db[0]);

var frameBufferError = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
if(frameBufferError != FramebufferErrorCode.FramebufferComplete)
var frameBufferError = gl.CheckFramebufferStatus(GlConsts.GL_FRAMEBUFFER);
if(frameBufferError != GlConsts.GL_FRAMEBUFFER_COMPLETE)
{
GL.DeleteFramebuffers(1, ref fb);
GL.DeleteRenderbuffers(1, ref depthBuffer);
GL.DeleteRenderbuffers(1, ref rb);
gl.DeleteFramebuffers(1, fb);
gl.DeleteRenderbuffers(1, db);
gl.DeleteRenderbuffers(1, rb);
return null;
}

return new LayerFbo(context, layer, fb, rb, depthBuffer)
return new LayerFbo(context, gl, layer, fb, rb, db)
{
Width = w,
Height = h
Width = w[0],
Height = h[0]
};
}

Expand All @@ -67,23 +75,23 @@ public static LayerFbo TryCreate(EAGLContext context, CAEAGLLayer layer)

public void Bind()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _framebuffer);
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, _framebuffer[0]);
}

public void Present()
{
Bind();
var success = _context.PresentRenderBuffer((uint) All.Renderbuffer);
var success = _context.PresentRenderBuffer(GlConsts.GL_RENDERBUFFER);
}

public void Dispose()
{
if(_disposed)
return;
_disposed = true;
GL.DeleteFramebuffers(1, ref _framebuffer);
GL.DeleteRenderbuffers(1, ref _depthBuffer);
GL.DeleteRenderbuffers(1, ref _renderbuffer);
_gl.DeleteFramebuffers(1, _framebuffer);
_gl.DeleteRenderbuffers(1, _depthBuffer);
_gl.DeleteRenderbuffers(1, _renderbuffer);
if (_context != EAGLContext.CurrentContext)
throw new InvalidOperationException("Associated EAGLContext is not current");
}
Expand All @@ -92,15 +100,16 @@ public void Dispose()
class SizeSynchronizedLayerFbo : IDisposable
{
private readonly EAGLContext _context;
private readonly GlInterface _gl;
private readonly CAEAGLLayer _layer;
private LayerFbo _fbo;
private nfloat _oldLayerWidth, _oldLayerHeight, _oldLayerScale;

public SizeSynchronizedLayerFbo(EAGLContext context, CAEAGLLayer layer)
public SizeSynchronizedLayerFbo(EAGLContext context, GlInterface gl, CAEAGLLayer layer)
{
_context = context;
_gl = gl;
_layer = layer;

}

public bool Sync()
Expand All @@ -112,7 +121,7 @@ public bool Sync()
return true;
_fbo?.Dispose();
_fbo = null;
_fbo = LayerFbo.TryCreate(_context, _layer);
_fbo = LayerFbo.TryCreate(_context, _gl, _layer);
_oldLayerWidth = _layer.Bounds.Width;
_oldLayerHeight = _layer.Bounds.Height;
_oldLayerScale = _layer.ContentsScale;
Expand Down Expand Up @@ -140,4 +149,4 @@ public void Bind()
public int Height => _fbo?.Height ?? 0;
public double Scaling => _oldLayerScale;
}
}
}

0 comments on commit 3c94cdc

Please sign in to comment.