зеркало из https://github.com/mono/SkiaSharp.git
Many improvements to the iOS/tvOS/macOS views and layers
This commit is contained in:
Родитель
7f8a09e946
Коммит
9f022eb461
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
#if __IOS__ || __TVOS__
|
||||
using OpenTK.Graphics.ES20;
|
||||
#elif __MAC__
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
#endif
|
||||
|
||||
namespace SkiaSharp.Views
|
||||
{
|
||||
internal static class SKGLDrawable
|
||||
{
|
||||
public static GRBackendRenderTargetDesc CreateRenderTarget()
|
||||
{
|
||||
int framebuffer, stencil, samples;
|
||||
GL.GetInteger(GetPName.FramebufferBinding, out framebuffer);
|
||||
GL.GetInteger(GetPName.StencilBits, out stencil);
|
||||
GL.GetInteger(GetPName.Samples, out samples);
|
||||
|
||||
int bufferWidth = 0;
|
||||
int bufferHeight = 0;
|
||||
#if __IOS__ || __TVOS__
|
||||
GL.GetRenderbufferParameter(RenderbufferTarget.Renderbuffer, RenderbufferParameterName.RenderbufferWidth, out bufferWidth);
|
||||
GL.GetRenderbufferParameter(RenderbufferTarget.Renderbuffer, RenderbufferParameterName.RenderbufferHeight, out bufferHeight);
|
||||
#endif
|
||||
|
||||
return new GRBackendRenderTargetDesc
|
||||
{
|
||||
Width = bufferWidth,
|
||||
Height = bufferHeight,
|
||||
Config = GRPixelConfig.Rgba8888,
|
||||
Origin = GRSurfaceOrigin.TopLeft,
|
||||
SampleCount = samples,
|
||||
StencilBits = stencil,
|
||||
RenderTargetHandle = (IntPtr)framebuffer,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ namespace SkiaSharp.Views
|
|||
drawable = new SKDrawable();
|
||||
|
||||
SetNeedsDisplay();
|
||||
NeedsDisplayOnBoundsChange = true;
|
||||
}
|
||||
|
||||
public ISKLayerDelegate SKDelegate { get; set; }
|
||||
|
@ -36,13 +37,6 @@ namespace SkiaSharp.Views
|
|||
{
|
||||
}
|
||||
|
||||
public override void LayoutSublayers()
|
||||
{
|
||||
base.LayoutSublayers();
|
||||
|
||||
SetNeedsDisplay();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
|
|
@ -14,5 +14,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)SKDrawable.cs">
|
||||
<Link>SKDrawable.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ISKGLLayerDelegate.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SKGLDrawable.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using CoreAnimation;
|
||||
using CoreGraphics;
|
||||
using OpenGLES;
|
||||
using OpenTK.Graphics.ES20;
|
||||
|
||||
|
@ -8,50 +8,38 @@ namespace SkiaSharp.Views
|
|||
public class SKGLLayer : CAEAGLLayer
|
||||
{
|
||||
private EAGLContext glContext;
|
||||
private uint colorRenderBuffer;
|
||||
private int renderBuffer;
|
||||
private int framebuffer;
|
||||
|
||||
private GRContext context;
|
||||
private int framebuffer;
|
||||
private int bufferWidth;
|
||||
private int bufferHeight;
|
||||
private GRBackendRenderTargetDesc renderTarget;
|
||||
|
||||
public SKGLLayer()
|
||||
{
|
||||
Opaque = true;
|
||||
|
||||
}
|
||||
|
||||
public ISKGLLayerDelegate SKDelegate { get; set; }
|
||||
|
||||
public virtual void DrawInSurface(SKSurface surface, GRBackendRenderTargetDesc renderTarget)
|
||||
public virtual void Render()
|
||||
{
|
||||
}
|
||||
|
||||
public override void LayoutSublayers()
|
||||
{
|
||||
base.LayoutSublayers();
|
||||
|
||||
if (glContext == null)
|
||||
CreateGlContext();
|
||||
if (context == null)
|
||||
CreateSkiaContext();
|
||||
{
|
||||
PrepareGLContexts();
|
||||
}
|
||||
|
||||
EAGLContext.SetCurrentContext(glContext);
|
||||
|
||||
// create the surface
|
||||
var renderTarget = new GRBackendRenderTargetDesc
|
||||
if (renderTarget.Width == 0 || renderTarget.Height == 0)
|
||||
{
|
||||
Width = bufferWidth,
|
||||
Height = bufferHeight,
|
||||
Config = GRPixelConfig.Rgba8888,
|
||||
Origin = GRSurfaceOrigin.TopLeft,
|
||||
SampleCount = 0,
|
||||
StencilBits = 8,
|
||||
RenderTargetHandle = (IntPtr)framebuffer,
|
||||
};
|
||||
renderTarget = SKGLDrawable.CreateRenderTarget();
|
||||
}
|
||||
using (var surface = SKSurface.Create(context, renderTarget))
|
||||
{
|
||||
// draw on the surface
|
||||
DrawInSurface(surface, renderTarget);
|
||||
SKDelegate.DrawInSurface(surface, renderTarget);
|
||||
SKDelegate?.DrawInSurface(surface, renderTarget);
|
||||
|
||||
surface.Canvas.Flush();
|
||||
}
|
||||
|
@ -61,36 +49,64 @@ namespace SkiaSharp.Views
|
|||
|
||||
// present the GL buffers
|
||||
glContext.PresentRenderBuffer((uint)RenderbufferTarget.Renderbuffer);
|
||||
EAGLContext.SetCurrentContext(null);
|
||||
}
|
||||
|
||||
private void CreateSkiaContext()
|
||||
public override CGRect Frame
|
||||
{
|
||||
EAGLContext.SetCurrentContext(glContext);
|
||||
|
||||
// get the bits for SkiaSharp
|
||||
var glInterface = GRGlInterface.CreateNativeInterface();
|
||||
context = GRContext.Create(GRBackend.OpenGL, glInterface);
|
||||
get { return base.Frame; }
|
||||
set
|
||||
{
|
||||
base.Frame = value;
|
||||
if (glContext != null)
|
||||
{
|
||||
ResizeGLContexts();
|
||||
renderTarget = default(GRBackendRenderTargetDesc);
|
||||
}
|
||||
Render();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateGlContext()
|
||||
public virtual void DrawInSurface(SKSurface surface, GRBackendRenderTargetDesc renderTarget)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void PrepareGLContexts()
|
||||
{
|
||||
// create GL context
|
||||
glContext = new EAGLContext(EAGLRenderingAPI.OpenGLES2);
|
||||
EAGLContext.SetCurrentContext(glContext);
|
||||
|
||||
// create render buffer
|
||||
GL.GenRenderbuffers(1, out colorRenderBuffer);
|
||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, colorRenderBuffer);
|
||||
GL.GenRenderbuffers(1, out renderBuffer);
|
||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderBuffer);
|
||||
glContext.RenderBufferStorage((uint)RenderbufferTarget.Renderbuffer, this);
|
||||
|
||||
// get dimensions from buffer
|
||||
GL.GetRenderbufferParameter(RenderbufferTarget.Renderbuffer, RenderbufferParameterName.RenderbufferWidth, out bufferWidth);
|
||||
GL.GetRenderbufferParameter(RenderbufferTarget.Renderbuffer, RenderbufferParameterName.RenderbufferHeight, out bufferHeight);
|
||||
|
||||
// create frame buffer
|
||||
GL.GenFramebuffers(1, out framebuffer);
|
||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer);
|
||||
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, RenderbufferTarget.Renderbuffer, colorRenderBuffer);
|
||||
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, RenderbufferTarget.Renderbuffer, renderBuffer);
|
||||
|
||||
// get the bits for SkiaSharp
|
||||
var glInterface = GRGlInterface.CreateNativeInterface();
|
||||
context = GRContext.Create(GRBackend.OpenGL, glInterface);
|
||||
|
||||
// finished
|
||||
EAGLContext.SetCurrentContext(null);
|
||||
}
|
||||
|
||||
public virtual void ResizeGLContexts()
|
||||
{
|
||||
// nuke old buffers
|
||||
GL.DeleteRenderbuffers(1, ref renderBuffer);
|
||||
|
||||
// re-create render buffer
|
||||
GL.GenRenderbuffers(1, out renderBuffer);
|
||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderBuffer);
|
||||
glContext.RenderBufferStorage((uint)RenderbufferTarget.Renderbuffer, this);
|
||||
|
||||
// re-link
|
||||
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, RenderbufferTarget.Renderbuffer, renderBuffer);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using CoreGraphics;
|
||||
using GLKit;
|
||||
using OpenGLES;
|
||||
using OpenTK.Graphics.ES20;
|
||||
|
||||
namespace SkiaSharp.Views
|
||||
{
|
||||
|
@ -11,7 +9,7 @@ namespace SkiaSharp.Views
|
|||
public class SKGLView : GLKView, IGLKViewDelegate
|
||||
{
|
||||
private GRContext context;
|
||||
private int framebuffer;
|
||||
private GRBackendRenderTargetDesc renderTarget;
|
||||
|
||||
public SKGLView()
|
||||
{
|
||||
|
@ -33,28 +31,20 @@ namespace SkiaSharp.Views
|
|||
|
||||
public new void DrawInRect(GLKView view, CGRect rect)
|
||||
{
|
||||
// get the bits for SkiaSharp
|
||||
if (context == null)
|
||||
{
|
||||
// create the context
|
||||
var glInterface = GRGlInterface.CreateNativeInterface();
|
||||
context = GRContext.Create(GRBackend.OpenGL, glInterface);
|
||||
|
||||
// get the current frame buffer
|
||||
GL.GetInteger(GetPName.FramebufferBinding, out framebuffer);
|
||||
// get the initial details
|
||||
renderTarget = SKGLDrawable.CreateRenderTarget();
|
||||
}
|
||||
|
||||
// set the dimensions as they might have changed
|
||||
renderTarget.Width = (int)DrawableWidth;
|
||||
renderTarget.Height = (int)DrawableHeight;
|
||||
|
||||
// create the surface
|
||||
var renderTarget = new GRBackendRenderTargetDesc
|
||||
{
|
||||
Width = (int)DrawableWidth,
|
||||
Height = (int)DrawableHeight,
|
||||
Config = GRPixelConfig.Rgba8888,
|
||||
Origin = GRSurfaceOrigin.TopLeft,
|
||||
SampleCount = 0,
|
||||
StencilBits = 8,
|
||||
RenderTargetHandle = (IntPtr)framebuffer,
|
||||
};
|
||||
using (var surface = SKSurface.Create(context, renderTarget))
|
||||
{
|
||||
// draw on the surface
|
||||
|
@ -71,11 +61,14 @@ namespace SkiaSharp.Views
|
|||
{
|
||||
}
|
||||
|
||||
public override void LayoutSubviews()
|
||||
public override CGRect Frame
|
||||
{
|
||||
base.LayoutSubviews();
|
||||
|
||||
SetNeedsDisplay();
|
||||
get { return base.Frame; }
|
||||
set
|
||||
{
|
||||
base.Frame = value;
|
||||
SetNeedsDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,5 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)SKView.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SKGLLayer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SKGLView.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ISKGLLayerDelegate.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,61 @@
|
|||
using CoreAnimation;
|
||||
using CoreVideo;
|
||||
using OpenGL;
|
||||
|
||||
namespace SkiaSharp.Views
|
||||
{
|
||||
public class SKGLLayer : CAOpenGLLayer
|
||||
{
|
||||
private GRContext context;
|
||||
private GRBackendRenderTargetDesc renderTarget;
|
||||
|
||||
public SKGLLayer()
|
||||
{
|
||||
Opaque = true;
|
||||
NeedsDisplayOnBoundsChange = true;
|
||||
}
|
||||
|
||||
public ISKGLLayerDelegate SKDelegate { get; set; }
|
||||
|
||||
public virtual void DrawInSurface(SKSurface surface, GRBackendRenderTargetDesc renderTarget)
|
||||
{
|
||||
}
|
||||
|
||||
public override void DrawInCGLContext(CGLContext glContext, CGLPixelFormat pixelFormat, double timeInterval, ref CVTimeStamp timeStamp)
|
||||
{
|
||||
CGLContext.CurrentContext = glContext;
|
||||
|
||||
if (context == null)
|
||||
{
|
||||
// get the bits for SkiaSharp
|
||||
var glInterface = GRGlInterface.CreateNativeInterface();
|
||||
context = GRContext.Create(GRBackend.OpenGL, glInterface);
|
||||
}
|
||||
|
||||
// create the surface
|
||||
renderTarget = SKGLDrawable.CreateRenderTarget();
|
||||
renderTarget.Width = (int)(Bounds.Width * ContentsScale);
|
||||
renderTarget.Height = (int)(Bounds.Height * ContentsScale);
|
||||
using (var surface = SKSurface.Create(context, renderTarget))
|
||||
{
|
||||
// draw on the surface
|
||||
DrawInSurface(surface, renderTarget);
|
||||
SKDelegate?.DrawInSurface(surface, renderTarget);
|
||||
|
||||
surface.Canvas.Flush();
|
||||
}
|
||||
|
||||
// flush the SkiaSharp context to the GL context
|
||||
context.Flush();
|
||||
|
||||
base.DrawInCGLContext(glContext, pixelFormat, timeInterval, ref timeStamp);
|
||||
}
|
||||
|
||||
public override void Release(CGLContext glContext)
|
||||
{
|
||||
context.Dispose();
|
||||
|
||||
base.Release(glContext);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using AppKit;
|
||||
using CoreGraphics;
|
||||
|
@ -30,28 +29,7 @@ namespace SkiaSharp.Views
|
|||
var glInterface = GRGlInterface.CreateNativeInterface();
|
||||
context = GRContext.Create(GRBackend.OpenGL, glInterface);
|
||||
|
||||
// get the current frame buffer
|
||||
int framebuffer;
|
||||
GL.GetInteger(GetPName.FramebufferBinding, out framebuffer);
|
||||
|
||||
// get samples
|
||||
var screen = OpenGLContext.CurrentVirtualScreen;
|
||||
int samples = 0;
|
||||
OpenGLContext.PixelFormat.GetValue(ref samples, NSOpenGLPixelFormatAttribute.Samples, screen);
|
||||
int stencils = 0;
|
||||
OpenGLContext.PixelFormat.GetValue(ref stencils, NSOpenGLPixelFormatAttribute.StencilSize, screen);
|
||||
|
||||
// create the surface
|
||||
renderTarget = new GRBackendRenderTargetDesc
|
||||
{
|
||||
Width = 0, // set later
|
||||
Height = 0, // set later
|
||||
Config = GRPixelConfig.Rgba8888,
|
||||
Origin = GRSurfaceOrigin.TopLeft,
|
||||
SampleCount = samples,
|
||||
StencilBits = stencils,
|
||||
RenderTargetHandle = (IntPtr)framebuffer,
|
||||
};
|
||||
renderTarget = SKGLDrawable.CreateRenderTarget();
|
||||
}
|
||||
|
||||
public override void DrawRect(CGRect dirtyRect)
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SKView.cs" />
|
||||
<Compile Include="SKGLView.cs" />
|
||||
<Compile Include="SKGLLayer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче