Add Metal APIs for macOS and iOS (#1394)

This commit is contained in:
Matthew Leibowitz 2021-02-02 13:59:41 +02:00
Родитель 112025bbbe
Коммит 29e8f26751
15 изменённых файлов: 454 добавлений и 51 удалений

Просмотреть файл

@ -43,6 +43,21 @@ namespace SkiaSharp
CreateVulkan (width, height, sampleCount, vkImageInfo);
}
#if __IOS__ || __MACOS__
public GRBackendRenderTarget (int width, int height, int sampleCount, GRMetalTextureInfo mtlInfo)
: this (IntPtr.Zero, true)
{
var info = mtlInfo.ToNative ();
Handle = SkiaApi.gr_backendrendertarget_new_metal (width, height, sampleCount, &info);
if (Handle == IntPtr.Zero) {
throw new InvalidOperationException ("Unable to create a new GRBackendRenderTarget instance.");
}
}
#endif
private void CreateGl (int width, int height, int sampleCount, int stencilBits, GRGlFramebufferInfo glInfo)
{
Handle = SkiaApi.gr_backendrendertarget_new_gl (width, height, sampleCount, stencilBits, &glInfo);

Просмотреть файл

@ -47,6 +47,21 @@ namespace SkiaSharp
CreateVulkan (width, height, vkInfo);
}
#if __IOS__ || __MACOS__
public GRBackendTexture (int width, int height, bool mipmapped, GRMetalTextureInfo mtlInfo)
: this (IntPtr.Zero, true)
{
var info = mtlInfo.ToNative ();
Handle = SkiaApi.gr_backendtexture_new_metal (width, height, mipmapped, &info);
if (Handle == IntPtr.Zero) {
throw new InvalidOperationException ("Unable to create a new GRBackendTexture instance.");
}
}
#endif
private void CreateGl (int width, int height, bool mipmapped, GRGlTextureInfo glInfo)
{
Handle = SkiaApi.gr_backendtexture_new_gl (width, height, mipmapped, &glInfo);

Просмотреть файл

@ -69,6 +69,22 @@ namespace SkiaSharp
return GetObject (SkiaApi.gr_context_make_vulkan (backendContext.ToNative ()));
}
#if __IOS__ || __MACOS__
// CreateMetal
public static GRContext CreateMetal (Metal.IMTLDevice device, Metal.IMTLCommandQueue queue)
{
if (device == null)
throw new ArgumentNullException (nameof (device));
if (queue == null)
throw new ArgumentNullException (nameof (queue));
return GetObject (SkiaApi.gr_context_make_metal ((void*)device.Handle, (void*)queue.Handle));
}
#endif
//
public GRBackend Backend => SkiaApi.gr_context_get_backend (Handle).FromNative ();

Просмотреть файл

@ -110,6 +110,44 @@ namespace SkiaSharp
}
}
#if __IOS__ || __MACOS__
public unsafe partial struct GRMetalTextureInfo
{
public GRMetalTextureInfo (Metal.IMTLTexture texture)
{
Texture = texture;
}
public Metal.IMTLTexture Texture { get; set; }
internal GRMetalTextureInfoNative ToNative () =>
new GRMetalTextureInfoNative {
fTexture = (void*)Texture.Handle
};
public readonly bool Equals (GRMetalTextureInfo obj) =>
Texture == obj.Texture;
public readonly override bool Equals (object obj) =>
obj is GRMetalTextureInfo f && Equals (f);
public static bool operator == (GRMetalTextureInfo left, GRMetalTextureInfo right) =>
left.Equals (right);
public static bool operator != (GRMetalTextureInfo left, GRMetalTextureInfo right) =>
!left.Equals (right);
public readonly override int GetHashCode ()
{
var hash = new HashCode ();
hash.Add (Texture);
return hash.ToHashCode ();
}
}
#endif
[EditorBrowsable (EditorBrowsableState.Never)]
[Flags]
[Obsolete]

Просмотреть файл

@ -284,6 +284,24 @@ namespace SkiaSharp
return GetObject (SkiaApi.sk_surface_new_render_target (context.Handle, budgeted, &cinfo, sampleCount, origin, props?.Handle ?? IntPtr.Zero, shouldCreateWithMips));
}
#if __MACOS__ || __IOS__
public static SKSurface Create (GRContext context, CoreAnimation.CAMetalLayer layer, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, out CoreAnimation.ICAMetalDrawable drawable) =>
Create (context, layer, origin, sampleCount, colorType, null, null, out drawable);
public static SKSurface Create (GRContext context, CoreAnimation.CAMetalLayer layer, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace, out CoreAnimation.ICAMetalDrawable drawable) =>
Create (context, layer, origin, sampleCount, colorType, colorspace, null, out drawable);
public static SKSurface Create (GRContext context, CoreAnimation.CAMetalLayer layer, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace, SKSurfaceProperties props, out CoreAnimation.ICAMetalDrawable drawable)
{
void* drawablePtr;
var surface = GetObject (SkiaApi.sk_surface_new_metal_layer (context.Handle, (void*)layer.Handle, origin, sampleCount, colorType.ToNative (), colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero, &drawablePtr));
drawable = ObjCRuntime.Runtime.GetINativeObject<CoreAnimation.ICAMetalDrawable> ((IntPtr)drawablePtr, true);
return surface;
}
#endif
// NULL surface
public static SKSurface CreateNull (int width, int height) =>
@ -354,6 +372,9 @@ namespace SkiaSharp
return result;
}
public void Flush () =>
SkiaApi.sk_surface_flush (Handle);
internal static SKSurface GetObject (IntPtr handle) =>
handle == IntPtr.Zero ? null : new SKSurface (handle, true);
}

Просмотреть файл

@ -221,6 +221,20 @@ namespace SkiaSharp
(gr_backendrendertarget_new_gl_delegate ??= GetSymbol<Delegates.gr_backendrendertarget_new_gl> ("gr_backendrendertarget_new_gl")).Invoke (width, height, samples, stencils, glInfo);
#endif
// gr_backendrendertarget_t* gr_backendrendertarget_new_metal(int width, int height, int samples, const gr_mtl_textureinfo_t* mtlInfo)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_backendrendertarget_t gr_backendrendertarget_new_metal (Int32 width, Int32 height, Int32 samples, GRMetalTextureInfoNative* mtlInfo);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate gr_backendrendertarget_t gr_backendrendertarget_new_metal (Int32 width, Int32 height, Int32 samples, GRMetalTextureInfoNative* mtlInfo);
}
private static Delegates.gr_backendrendertarget_new_metal gr_backendrendertarget_new_metal_delegate;
internal static gr_backendrendertarget_t gr_backendrendertarget_new_metal (Int32 width, Int32 height, Int32 samples, GRMetalTextureInfoNative* mtlInfo) =>
(gr_backendrendertarget_new_metal_delegate ??= GetSymbol<Delegates.gr_backendrendertarget_new_metal> ("gr_backendrendertarget_new_metal")).Invoke (width, height, samples, mtlInfo);
#endif
// gr_backendrendertarget_t* gr_backendrendertarget_new_vulkan(int width, int height, int samples, const gr_vk_imageinfo_t* vkImageInfo)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
@ -353,6 +367,20 @@ namespace SkiaSharp
(gr_backendtexture_new_gl_delegate ??= GetSymbol<Delegates.gr_backendtexture_new_gl> ("gr_backendtexture_new_gl")).Invoke (width, height, mipmapped, glInfo);
#endif
// gr_backendtexture_t* gr_backendtexture_new_metal(int width, int height, bool mipmapped, const gr_mtl_textureinfo_t* mtlInfo)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_backendtexture_t gr_backendtexture_new_metal (Int32 width, Int32 height, [MarshalAs (UnmanagedType.I1)] bool mipmapped, GRMetalTextureInfoNative* mtlInfo);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate gr_backendtexture_t gr_backendtexture_new_metal (Int32 width, Int32 height, [MarshalAs (UnmanagedType.I1)] bool mipmapped, GRMetalTextureInfoNative* mtlInfo);
}
private static Delegates.gr_backendtexture_new_metal gr_backendtexture_new_metal_delegate;
internal static gr_backendtexture_t gr_backendtexture_new_metal (Int32 width, Int32 height, [MarshalAs (UnmanagedType.I1)] bool mipmapped, GRMetalTextureInfoNative* mtlInfo) =>
(gr_backendtexture_new_metal_delegate ??= GetSymbol<Delegates.gr_backendtexture_new_metal> ("gr_backendtexture_new_metal")).Invoke (width, height, mipmapped, mtlInfo);
#endif
// gr_backendtexture_t* gr_backendtexture_new_vulkan(int width, int height, const gr_vk_imageinfo_t* vkInfo)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
@ -493,6 +521,20 @@ namespace SkiaSharp
(gr_context_make_gl_delegate ??= GetSymbol<Delegates.gr_context_make_gl> ("gr_context_make_gl")).Invoke (glInterface);
#endif
// gr_context_t* gr_context_make_metal(void* device, void* queue)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_context_t gr_context_make_metal (void* device, void* queue);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate gr_context_t gr_context_make_metal (void* device, void* queue);
}
private static Delegates.gr_context_make_metal gr_context_make_metal_delegate;
internal static gr_context_t gr_context_make_metal (void* device, void* queue) =>
(gr_context_make_metal_delegate ??= GetSymbol<Delegates.gr_context_make_metal> ("gr_context_make_metal")).Invoke (device, queue);
#endif
// gr_context_t* gr_context_make_vulkan(const gr_vk_backendcontext_t vkBackendContext)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
@ -11429,6 +11471,20 @@ namespace SkiaSharp
(sk_surface_draw_delegate ??= GetSymbol<Delegates.sk_surface_draw> ("sk_surface_draw")).Invoke (surface, canvas, x, y, paint);
#endif
// void sk_surface_flush(sk_surface_t* surface)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_surface_flush (sk_surface_t surface);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate void sk_surface_flush (sk_surface_t surface);
}
private static Delegates.sk_surface_flush sk_surface_flush_delegate;
internal static void sk_surface_flush (sk_surface_t surface) =>
(sk_surface_flush_delegate ??= GetSymbol<Delegates.sk_surface_flush> ("sk_surface_flush")).Invoke (surface);
#endif
// sk_canvas_t* sk_surface_get_canvas(sk_surface_t*)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
@ -11527,6 +11583,20 @@ namespace SkiaSharp
(sk_surface_new_image_snapshot_with_crop_delegate ??= GetSymbol<Delegates.sk_surface_new_image_snapshot_with_crop> ("sk_surface_new_image_snapshot_with_crop")).Invoke (surface, bounds);
#endif
// sk_surface_t* sk_surface_new_metal_layer(gr_context_t* context, const void* layer, gr_surfaceorigin_t origin, int sampleCount, sk_colortype_t colorType, sk_colorspace_t* colorspace, const sk_surfaceprops_t* props, const void** drawable)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_surface_t sk_surface_new_metal_layer (gr_context_t context, void* layer, GRSurfaceOrigin origin, Int32 sampleCount, SKColorTypeNative colorType, sk_colorspace_t colorspace, sk_surfaceprops_t props, void** drawable);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_surface_t sk_surface_new_metal_layer (gr_context_t context, void* layer, GRSurfaceOrigin origin, Int32 sampleCount, SKColorTypeNative colorType, sk_colorspace_t colorspace, sk_surfaceprops_t props, void** drawable);
}
private static Delegates.sk_surface_new_metal_layer sk_surface_new_metal_layer_delegate;
internal static sk_surface_t sk_surface_new_metal_layer (gr_context_t context, void* layer, GRSurfaceOrigin origin, Int32 sampleCount, SKColorTypeNative colorType, sk_colorspace_t colorspace, sk_surfaceprops_t props, void** drawable) =>
(sk_surface_new_metal_layer_delegate ??= GetSymbol<Delegates.sk_surface_new_metal_layer> ("sk_surface_new_metal_layer")).Invoke (context, layer, origin, sampleCount, colorType, colorspace, props, drawable);
#endif
// sk_surface_t* sk_surface_new_null(int width, int height)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
@ -13262,6 +13332,33 @@ namespace SkiaSharp
}
// gr_mtl_textureinfo_t
[StructLayout (LayoutKind.Sequential)]
internal unsafe partial struct GRMetalTextureInfoNative : IEquatable<GRMetalTextureInfoNative> {
// public const void* fTexture
public void* fTexture;
public readonly bool Equals (GRMetalTextureInfoNative obj) =>
fTexture == obj.fTexture;
public readonly override bool Equals (object obj) =>
obj is GRMetalTextureInfoNative f && Equals (f);
public static bool operator == (GRMetalTextureInfoNative left, GRMetalTextureInfoNative right) =>
left.Equals (right);
public static bool operator != (GRMetalTextureInfoNative left, GRMetalTextureInfoNative right) =>
!left.Equals (right);
public readonly override int GetHashCode ()
{
var hash = new HashCode ();
hash.Add (fTexture);
return hash.ToHashCode ();
}
}
// gr_vk_alloc_t
[StructLayout (LayoutKind.Sequential)]
public unsafe partial struct GRVkAlloc : IEquatable<GRVkAlloc> {

Просмотреть файл

@ -69,6 +69,10 @@
"cs": "GRVkBackendContextNative",
"internal": true
},
"gr_mtl_textureinfo_t": {
"cs": "GRMetalTextureInfoNative",
"internal": true
},
"sk_color4f_t": {
"cs": "SKColorF",
"readonly": true,

2
externals/skia поставляемый

@ -1 +1 @@
Subproject commit d8e22c4421640690c7bbedf865663b0dba6c7e2d
Subproject commit ff500f669415211a1f2b0a3021a7320a9690e4fc

Просмотреть файл

@ -31,6 +31,7 @@ Task("libSkiaSharp")
$"target_cpu='{skiaArch}' " +
$"target_os='ios' " +
$"skia_use_icu=false " +
$"skia_use_metal=true " +
$"skia_use_piex=true " +
$"skia_use_sfntly=false " +
$"skia_use_system_expat=false " +

Просмотреть файл

@ -14,6 +14,9 @@
345A7E581E7635B10046F543 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 345A7E571E7635B10046F543 /* CoreGraphics.framework */; };
345A7E5A1E7635B50046F543 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 345A7E591E7635B50046F543 /* CoreFoundation.framework */; };
345A7E5C1E7635B90046F543 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 345A7E5B1E7635B90046F543 /* CoreText.framework */; };
34AC596F24B80BAD009CDA1D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34AC596E24B80BAD009CDA1D /* Foundation.framework */; };
34AC597224B80BB4009CDA1D /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34AC597024B80BB4009CDA1D /* MetalKit.framework */; };
34AC597324B80BB4009CDA1D /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34AC597124B80BB4009CDA1D /* Metal.framework */; };
34B07C3A24EF0BE700FE3EC9 /* sk_managedtracememorydump.h in Headers */ = {isa = PBXBuildFile; fileRef = 34B07C3624EF0BE700FE3EC9 /* sk_managedtracememorydump.h */; };
34B07C3B24EF0BE700FE3EC9 /* SkManagedTraceMemoryDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 34B07C3724EF0BE700FE3EC9 /* SkManagedTraceMemoryDump.h */; };
34B07C3C24EF0BE700FE3EC9 /* SkManagedTraceMemoryDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34B07C3824EF0BE700FE3EC9 /* SkManagedTraceMemoryDump.cpp */; };
@ -44,6 +47,9 @@
345A7E571E7635B10046F543 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
345A7E591E7635B50046F543 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
345A7E5B1E7635B90046F543 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
34AC596E24B80BAD009CDA1D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
34AC597024B80BB4009CDA1D /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/MetalKit.framework; sourceTree = DEVELOPER_DIR; };
34AC597124B80BB4009CDA1D /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Metal.framework; sourceTree = DEVELOPER_DIR; };
34B07C3624EF0BE700FE3EC9 /* sk_managedtracememorydump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sk_managedtracememorydump.h; path = ../../../../externals/skia/include/xamarin/sk_managedtracememorydump.h; sourceTree = "<group>"; };
34B07C3724EF0BE700FE3EC9 /* SkManagedTraceMemoryDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkManagedTraceMemoryDump.h; path = ../../../../externals/skia/include/xamarin/SkManagedTraceMemoryDump.h; sourceTree = "<group>"; };
34B07C3824EF0BE700FE3EC9 /* SkManagedTraceMemoryDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkManagedTraceMemoryDump.cpp; path = ../../../../externals/skia/src/xamarin/SkManagedTraceMemoryDump.cpp; sourceTree = "<group>"; };
@ -72,6 +78,9 @@
345A7E5C1E7635B90046F543 /* CoreText.framework in Frameworks */,
345A7E5A1E7635B50046F543 /* CoreFoundation.framework in Frameworks */,
345A7E581E7635B10046F543 /* CoreGraphics.framework in Frameworks */,
34AC597224B80BB4009CDA1D /* MetalKit.framework in Frameworks */,
34AC597324B80BB4009CDA1D /* Metal.framework in Frameworks */,
34AC596F24B80BAD009CDA1D /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -129,6 +138,9 @@
345A7E561E7635B00046F543 /* Frameworks */ = {
isa = PBXGroup;
children = (
34AC597124B80BB4009CDA1D /* Metal.framework */,
34AC597024B80BB4009CDA1D /* MetalKit.framework */,
34AC596E24B80BAD009CDA1D /* Foundation.framework */,
345A7E5B1E7635B90046F543 /* CoreText.framework */,
345A7E591E7635B50046F543 /* CoreFoundation.framework */,
345A7E571E7635B10046F543 /* CoreGraphics.framework */,

Просмотреть файл

@ -23,6 +23,7 @@ Task("libSkiaSharp")
$"target_os='mac' " +
$"target_cpu='{skiaArch}' " +
$"skia_use_icu=false " +
$"skia_use_metal=true " +
$"skia_use_piex=true " +
$"skia_use_sfntly=false " +
$"skia_use_system_expat=false " +
@ -30,8 +31,8 @@ Task("libSkiaSharp")
$"skia_use_system_libpng=false " +
$"skia_use_system_libwebp=false " +
$"skia_use_system_zlib=false " +
$"extra_cflags=[ '-DSKIA_C_DLL', '-DHAVE_ARC4RANDOM_BUF', '-mmacosx-version-min=10.7', '-stdlib=libc++' ] " +
$"extra_ldflags=[ '-Wl,macosx_version_min=10.7', '-stdlib=libc++' ]");
$"extra_cflags=[ '-DSKIA_C_DLL', '-DHAVE_ARC4RANDOM_BUF', '-mmacosx-version-min=10.8', '-stdlib=libc++' ] " +
$"extra_ldflags=[ '-Wl,macosx_version_min=10.8', '-stdlib=libc++' ]");
RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", "macosx", arch);

Просмотреть файл

@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
340AF2BA24B7CD3600DDD76D /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340AF2B924B7CD3600DDD76D /* Metal.framework */; };
340AF2BC24B7CEB800DDD76D /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340AF2BB24B7CEB800DDD76D /* MetalKit.framework */; };
343CCD2B1E75FF3E000EC0A6 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 343CCD2A1E75FF3E000EC0A6 /* CoreText.framework */; };
343CCD2D1E75FF47000EC0A6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 343CCD2C1E75FF47000EC0A6 /* CoreGraphics.framework */; };
343CCD2F1E75FF54000EC0A6 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 343CCD2E1E75FF54000EC0A6 /* CoreFoundation.framework */; };
@ -37,6 +39,8 @@
/* Begin PBXFileReference section */
21C951551C03D27A003A1E1D /* libSkiaSharp.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSkiaSharp.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
340AF2B924B7CD3600DDD76D /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
340AF2BB24B7CEB800DDD76D /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
343CCD261E75FD47000EC0A6 /* libskia.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libskia.a; path = ../../../externals/skia/out/macos/x64/libskia.a; sourceTree = "<group>"; };
343CCD281E75FF29000EC0A6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
343CCD2A1E75FF3E000EC0A6 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
@ -76,6 +80,8 @@
343CCD311E75FF71000EC0A6 /* Cocoa.framework in Frameworks */,
343CCD2F1E75FF54000EC0A6 /* CoreFoundation.framework in Frameworks */,
343CCD2D1E75FF47000EC0A6 /* CoreGraphics.framework in Frameworks */,
340AF2BA24B7CD3600DDD76D /* Metal.framework in Frameworks */,
340AF2BC24B7CEB800DDD76D /* MetalKit.framework in Frameworks */,
343CCD2B1E75FF3E000EC0A6 /* CoreText.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -103,6 +109,8 @@
343CCD251E75FD47000EC0A6 /* Frameworks */ = {
isa = PBXGroup;
children = (
340AF2BB24B7CEB800DDD76D /* MetalKit.framework */,
340AF2B924B7CD3600DDD76D /* Metal.framework */,
3477EF0C221654DE00527FC7 /* CoreServices.framework */,
343CCD301E75FF71000EC0A6 /* Cocoa.framework */,
343CCD2E1E75FF54000EC0A6 /* CoreFoundation.framework */,
@ -278,6 +286,7 @@
SK_CODEC_DECODES_RAW,
SK_HAS_WEBP_LIBRARY,
SK_XML,
SK_METAL,
);
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -335,6 +344,7 @@
SK_CODEC_DECODES_RAW,
SK_HAS_WEBP_LIBRARY,
SK_XML,
SK_METAL,
);
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -358,7 +368,7 @@
HEADER_SEARCH_PATHS = ../../../externals/skia;
INSTALL_PATH = "@rpath";
LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/macos/$(ARCHS)";
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.8;
OTHER_LDFLAGS = "-lskia";
PRODUCT_NAME = "$(TARGET_NAME)";
};
@ -375,7 +385,7 @@
HEADER_SEARCH_PATHS = ../../../externals/skia;
INSTALL_PATH = "@rpath";
LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/macos/$(ARCHS)";
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.8;
OTHER_LDFLAGS = "-lskia";
PRODUCT_NAME = "$(TARGET_NAME)";
};

Просмотреть файл

@ -10,76 +10,56 @@
<AssemblyName>SkiaSharpSample</AssemblyName>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<LangVersion>8.0</LangVersion>
<MtouchEnableSGenConc>true</MtouchEnableSGenConc>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<ProvisioningType>automatic</ProvisioningType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE;ENABLE_TEST_CLOUD;</DefineConstants>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchFastDev>true</MtouchFastDev>
<MtouchProfiling>true</MtouchProfiling>
<IOSDebuggerPort>41640</IOSDebuggerPort>
<MtouchLink>None</MtouchLink>
<MtouchArch>i386, x86_64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<DeviceSpecificBuild>false</DeviceSpecificBuild>
<MtouchVerbosity>
</MtouchVerbosity>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>portable</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchFloat32>true</MtouchFloat32>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>Full</MtouchLink>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchLink>None</MtouchLink>
<MtouchDebug>true</MtouchDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>portable</DebugType>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchLink>None</MtouchLink>
<MtouchArch>i386, x86_64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE;ENABLE_TEST_CLOUD;</DefineConstants>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<DeviceSpecificBuild>true</DeviceSpecificBuild>
<MtouchDebug>true</MtouchDebug>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchFastDev>true</MtouchFastDev>
<MtouchProfiling>true</MtouchProfiling>
<MtouchFloat32>true</MtouchFloat32>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<IOSDebuggerPort>59169</IOSDebuggerPort>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
<MtouchLink>SdkOnly</MtouchLink>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchLink>SdkOnly</MtouchLink>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />

Просмотреть файл

@ -0,0 +1,159 @@
#if __IOS__ || __MACOS__
using System;
using System.ComponentModel;
using System.Diagnostics;
using CoreGraphics;
using Foundation;
using Metal;
using MetalKit;
#if __IOS__
namespace SkiaSharp.Views.iOS
#elif __MACOS__
namespace SkiaSharp.Views.Mac
#endif
{
[Register(nameof(SKMetalView))]
[DesignTimeVisible(true)]
public class SKMetalView : MTKView, IMTKViewDelegate, IComponent
{
// for IComponent
#pragma warning disable 67
private event EventHandler DisposedInternal;
#pragma warning restore 67
ISite IComponent.Site { get; set; }
event EventHandler IComponent.Disposed
{
add { DisposedInternal += value; }
remove { DisposedInternal -= value; }
}
private bool designMode;
private IMTLCommandQueue commandQueue;
private GRContext context;
// created in code
public SKMetalView()
: this(CGRect.Empty)
{
Initialize();
}
// created in code
public SKMetalView(CGRect frame)
: base(frame, null)
{
Initialize();
}
// created in code
public SKMetalView(CGRect frame, IMTLDevice device)
: base(frame, device)
{
Initialize();
}
// created via designer
public SKMetalView(IntPtr p)
: base(p)
{
}
// created via designer
public override void AwakeFromNib()
{
Initialize();
}
private void Initialize()
{
designMode = ((IComponent)this).Site?.DesignMode == true || !Extensions.IsValidEnvironment;
if (designMode)
return;
var device = MTLDevice.SystemDefault;
if (device == null)
{
Console.WriteLine("Metal is not supported on this device.");
return;
}
ColorPixelFormat = MTLPixelFormat.BGRA8Unorm;
DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8;
SampleCount = 1;
Device = device;
commandQueue = device.CreateCommandQueue();
// hook up the drawing
Delegate = this;
}
public SKSize CanvasSize { get; private set; }
public GRContext GRContext => context;
void IMTKViewDelegate.DrawableSizeWillChange(MTKView view, CGSize size)
{
CanvasSize = size.ToSKSize();
if (Paused && EnableSetNeedsDisplay)
#if __IOS__
SetNeedsDisplay();
#elif __MACOS__
NeedsDisplay = true;
#endif
}
void IMTKViewDelegate.Draw(MTKView view)
{
if (designMode)
return;
if (Device == null || commandQueue == null || CurrentDrawable?.Texture == null)
return;
CanvasSize = DrawableSize.ToSKSize();
if (CanvasSize.Width <= 0 || CanvasSize.Height <= 0)
return;
// create the contexts if not done already
context ??= GRContext.CreateMetal(Device, commandQueue);
const SKColorType colorType = SKColorType.Bgra8888;
const GRSurfaceOrigin surfaceOrigin = GRSurfaceOrigin.TopLeft;
// create the render target
var metalInfo = new GRMetalTextureInfo(CurrentDrawable.Texture);
using var renderTarget = new GRBackendRenderTarget((int)CanvasSize.Width, (int)CanvasSize.Height, (int)SampleCount, metalInfo);
// create the surface
using var surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType);
using var canvas = surface.Canvas;
// start drawing
var e = new SKPaintMetalSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType);
OnPaintSurface(e);
// flush the SkiaSharp contents
canvas.Flush();
surface.Flush();
context.Flush();
// present
using var commandBuffer = commandQueue.CommandBuffer();
commandBuffer.PresentDrawable(CurrentDrawable);
commandBuffer.Commit();
}
public event EventHandler<SKPaintMetalSurfaceEventArgs> PaintSurface;
protected virtual void OnPaintSurface(SKPaintMetalSurfaceEventArgs e)
{
PaintSurface?.Invoke(this, e);
}
}
}
#endif

Просмотреть файл

@ -0,0 +1,34 @@
#if __IOS__ || __MACOS__
using System;
#if __IOS__
namespace SkiaSharp.Views.iOS
#elif __MACOS__
namespace SkiaSharp.Views.Mac
#endif
{
public class SKPaintMetalSurfaceEventArgs : EventArgs
{
public SKPaintMetalSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget)
: this(surface, renderTarget, GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888)
{
}
public SKPaintMetalSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType)
{
Surface = surface;
BackendRenderTarget = renderTarget;
ColorType = colorType;
Origin = origin;
}
public SKSurface Surface { get; private set; }
public GRBackendRenderTarget BackendRenderTarget { get; private set; }
public SKColorType ColorType { get; private set; }
public GRSurfaceOrigin Origin { get; private set; }
}
}
#endif