* Improve the Vulkan APIs
  - removed the context argument as this is unused as well as an older C/C++ feature
  - added a SharpVk version of the GetProc property.
* Removed the context argument (this is more an older C/C++ feature/requirement)
* Expose the WebGL APIs
* Improve the GRGlInterface and GPU delegates
  - removing the object context for the GPU construction
    - obsoleted GRGlGetProcDelegate in favour of the better named GRGlGetProcedureAddressDelegate
    - renamed GRVkGetProcDelegate to GRVkGetProcedureAddressDelegate
    - use "ProcedureAddress" instead of "Proc" to show that it is the "address" not the actual procedure
  - reworked the GRGlInterface
    - use the new non-context delegates
    - use better naming: Create*
    - adding WebGL
  - created a SharpVk-specific delegate GRSharpVkGetProcedureAddressDelegate
    - use actual types instead of IntPtr
* Reduce the using obsolete warnings
  - still a few left, mainly the colorspace and text blob
* Switch the way GRGlInterface.Create() works
  - first try OpenGL as that is actually what is expected
  - don't explode on an error, return null, like the rest
* Update API usages
This commit is contained in:
Matthew Leibowitz 2020-05-17 22:11:59 +02:00 коммит произвёл GitHub
Родитель e30ebdec35
Коммит 98bfa94da7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
33 изменённых файлов: 269 добавлений и 152 удалений

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

@ -237,7 +237,9 @@ namespace SkiaSharp
Subset = null;
FrameIndex = 0;
PriorFrame = -1;
#pragma warning disable CS0612 // Type or member is obsolete
PremulBehavior = SKTransferFunctionBehavior.Respect;
#pragma warning restore CS0612 // Type or member is obsolete
}
public SKCodecOptions (SKZeroInitialized zeroInitialized, SKRectI subset)
{
@ -245,7 +247,9 @@ namespace SkiaSharp
Subset = subset;
FrameIndex = 0;
PriorFrame = -1;
#pragma warning disable CS0612 // Type or member is obsolete
PremulBehavior = SKTransferFunctionBehavior.Respect;
#pragma warning restore CS0612 // Type or member is obsolete
}
public SKCodecOptions (SKRectI subset)
{
@ -253,7 +257,9 @@ namespace SkiaSharp
Subset = subset;
FrameIndex = 0;
PriorFrame = -1;
#pragma warning disable CS0612 // Type or member is obsolete
PremulBehavior = SKTransferFunctionBehavior.Respect;
#pragma warning restore CS0612 // Type or member is obsolete
}
public SKCodecOptions (int frameIndex)
{
@ -261,7 +267,9 @@ namespace SkiaSharp
Subset = null;
FrameIndex = frameIndex;
PriorFrame = -1;
#pragma warning disable CS0612 // Type or member is obsolete
PremulBehavior = SKTransferFunctionBehavior.Respect;
#pragma warning restore CS0612 // Type or member is obsolete
}
public SKCodecOptions (int frameIndex, int priorFrame)
{
@ -269,7 +277,9 @@ namespace SkiaSharp
Subset = null;
FrameIndex = frameIndex;
PriorFrame = priorFrame;
#pragma warning disable CS0612 // Type or member is obsolete
PremulBehavior = SKTransferFunctionBehavior.Respect;
#pragma warning restore CS0612 // Type or member is obsolete
}
public SKZeroInitialized ZeroInitialized { get; set; }
@ -287,7 +297,9 @@ namespace SkiaSharp
Subset == obj.Subset &&
FrameIndex == obj.FrameIndex &&
PriorFrame == obj.PriorFrame &&
#pragma warning disable CS0612 // Type or member is obsolete
PremulBehavior == obj.PremulBehavior;
#pragma warning restore CS0612 // Type or member is obsolete
public readonly override bool Equals (object obj) =>
obj is SKCodecOptions f && Equals (f);
@ -305,7 +317,9 @@ namespace SkiaSharp
hash.Add (Subset);
hash.Add (FrameIndex);
hash.Add (PriorFrame);
#pragma warning disable CS0612 // Type or member is obsolete
hash.Add (PremulBehavior);
#pragma warning restore CS0612 // Type or member is obsolete
return hash.ToHashCode ();
}
}

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

@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace SkiaSharp
@ -15,11 +16,15 @@ namespace SkiaSharp
public delegate void SKSurfaceReleaseDelegate (IntPtr address, object context);
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use GRGlGetProcedureAddressDelegate instead.")]
public delegate IntPtr GRGlGetProcDelegate (object context, string name);
public delegate IntPtr GRVkGetProcDelegate (object context, string name, IntPtr instance, IntPtr device);
public delegate IntPtr GRGlGetProcedureAddressDelegate (string name);
public delegate void SKGlyphPathDelegate (SKPath path, SKMatrix matrix, object context);
public delegate IntPtr GRVkGetProcedureAddressDelegate (string name, IntPtr instance, IntPtr device);
public delegate void SKGlyphPathDelegate (SKPath path, SKMatrix matrix);
internal unsafe static partial class DelegateProxies
{
@ -100,16 +105,16 @@ namespace SkiaSharp
[MonoPInvokeCallback (typeof (GRGlGetProcProxyDelegate))]
private static IntPtr GRGlGetProcDelegateProxyImplementation (void* context, string name)
{
var del = Get<GRGlGetProcDelegate> ((IntPtr)context, out _);
return del.Invoke (null, name);
var del = Get<GRGlGetProcedureAddressDelegate> ((IntPtr)context, out _);
return del.Invoke (name);
}
[MonoPInvokeCallback (typeof (GRVkGetProcProxyDelegate))]
private static IntPtr GRVkGetProcDelegateProxyImplementation (void* context, string name, IntPtr instance, IntPtr device)
{
var del = Get<GRVkGetProcDelegate> ((IntPtr)context, out _);
var del = Get<GRVkGetProcedureAddressDelegate> ((IntPtr)context, out _);
return del.Invoke (null, name, instance, device);
return del.Invoke (name, instance, device);
}
[MonoPInvokeCallback (typeof (SKGlyphPathProxyDelegate))]
@ -117,7 +122,7 @@ namespace SkiaSharp
{
var del = Get<SKGlyphPathDelegate> ((IntPtr)context, out _);
var path = SKPath.GetObject (pathOrNull, false);
del.Invoke (path, *matrix, null);
del.Invoke (path, *matrix);
}
}
}

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

@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.ComponentModel;
using System.Runtime.InteropServices;
#if __TIZEN__
using System.Reflection;
#endif
namespace SkiaSharp
{
public unsafe class GRGlInterface : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
@ -15,58 +18,32 @@ namespace SkiaSharp
protected override void Dispose (bool disposing) =>
base.Dispose (disposing);
public static GRGlInterface CreateDefaultInterface ()
{
// first try ANGLE, then fall back to the OpenGL-based
return CreateNativeAngleInterface () ?? CreateNativeGlInterface ();
}
// Create* (defaults)
public static GRGlInterface CreateNativeGlInterface ()
public static GRGlInterface Create () =>
CreateGl () ?? CreateAngle ();
private static GRGlInterface CreateGl ()
{
// the native code will automatically return null on non-OpenGL platforms, such as UWP
return GetObject (SkiaApi.gr_glinterface_create_native_interface ());
}
public static GRGlInterface CreateNativeAngleInterface ()
private static GRGlInterface CreateAngle ()
{
if (PlatformConfiguration.IsWindows) {
return AssembleAngleInterface (AngleLoader.GetProc);
return CreateAngle (AngleLoader.GetProc);
} else {
// return null on non-DirectX platforms: everything except Windows
return null;
}
}
public static GRGlInterface CreateNativeEvasInterface (IntPtr evas)
{
#if __TIZEN__
var evasLoader = new EvasGlLoader (evas);
return AssembleGlesInterface ((ctx, name) => evasLoader.GetFunctionPointer (name));
#else
return null;
#endif
}
// Create* (assemble)
public static GRGlInterface AssembleInterface (GRGlGetProcDelegate get)
public static GRGlInterface Create (GRGlGetProcedureAddressDelegate get)
{
return AssembleInterface (null, get);
}
public static GRGlInterface AssembleInterface (object context, GRGlGetProcDelegate get)
{
// if on Windows, try ANGLE
if (PlatformConfiguration.IsWindows) {
var angle = AssembleAngleInterface (context, get);
if (angle != null) {
return angle;
}
}
// try the native default
var del = get != null && context != null
? new GRGlGetProcDelegate ((_, name) => get (context, name))
: get;
var proxy = DelegateProxies.Create (del, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx);
var proxy = DelegateProxies.Create (get, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx);
try {
return GetObject (SkiaApi.gr_glinterface_assemble_interface ((void*)ctx, proxy));
} finally {
@ -74,28 +51,12 @@ namespace SkiaSharp
}
}
public static GRGlInterface AssembleAngleInterface (GRGlGetProcDelegate get)
{
return AssembleAngleInterface (null, get);
}
public static GRGlInterface CreateAngle (GRGlGetProcedureAddressDelegate get) =>
CreateGles (get); // ANGLE is just a GLES v2 over DX v9+
public static GRGlInterface AssembleAngleInterface (object context, GRGlGetProcDelegate get)
public static GRGlInterface CreateOpenGl (GRGlGetProcedureAddressDelegate get)
{
// ANGLE is just a GLES v2 over DX v9+
return AssembleGlesInterface (context, get);
}
public static GRGlInterface AssembleGlInterface (GRGlGetProcDelegate get)
{
return AssembleGlInterface (null, get);
}
public static GRGlInterface AssembleGlInterface (object context, GRGlGetProcDelegate get)
{
var del = get != null && context != null
? new GRGlGetProcDelegate ((_, name) => get (context, name))
: get;
var proxy = DelegateProxies.Create (del, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx);
var proxy = DelegateProxies.Create (get, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx);
try {
return GetObject (SkiaApi.gr_glinterface_assemble_gl_interface ((void*)ctx, proxy));
} finally {
@ -103,17 +64,9 @@ namespace SkiaSharp
}
}
public static GRGlInterface AssembleGlesInterface (GRGlGetProcDelegate get)
public static GRGlInterface CreateGles (GRGlGetProcedureAddressDelegate get)
{
return AssembleGlesInterface (null, get);
}
public static GRGlInterface AssembleGlesInterface (object context, GRGlGetProcDelegate get)
{
var del = get != null && context != null
? new GRGlGetProcDelegate ((_, name) => get (context, name))
: get;
var proxy = DelegateProxies.Create (del, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx);
var proxy = DelegateProxies.Create (get, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx);
try {
return GetObject (SkiaApi.gr_glinterface_assemble_gles_interface ((void*)ctx, proxy));
} finally {
@ -121,19 +74,103 @@ namespace SkiaSharp
}
}
public bool Validate ()
public static GRGlInterface CreateWebGl (GRGlGetProcedureAddressDelegate get)
{
return SkiaApi.gr_glinterface_validate (Handle);
var proxy = DelegateProxies.Create (get, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx);
try {
return GetObject (SkiaApi.gr_glinterface_assemble_webgl_interface ((void*)ctx, proxy));
} finally {
gch.Free ();
}
}
public bool HasExtension (string extension)
public static GRGlInterface CreateEvas (IntPtr evas)
{
return SkiaApi.gr_glinterface_has_extension (Handle, extension);
#if __TIZEN__
var evasLoader = new EvasGlLoader (evas);
return CreateGles (name => evasLoader.GetFunctionPointer (name));
#else
return null;
#endif
}
// OBSOLETE CREATION
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use Create() instead.")]
public static GRGlInterface CreateDefaultInterface () =>
Create ();
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use Create() instead.")]
public static GRGlInterface CreateNativeGlInterface () =>
CreateGl ();
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use Create() instead.")]
public static GRGlInterface CreateNativeAngleInterface () =>
CreateAngle ();
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use CreateEvas(IntPtr) instead.")]
public static GRGlInterface CreateNativeEvasInterface (IntPtr evas) =>
CreateEvas (evas);
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use Create(GRGlGetProcedureAddressDelegate) instead.")]
public static GRGlInterface AssembleInterface (GRGlGetProcDelegate get) =>
Create (name => get (null, name));
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use Create(GRGlGetProcedureAddressDelegate) instead.")]
public static GRGlInterface AssembleInterface (object context, GRGlGetProcDelegate get) =>
Create (name => get (context, name));
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use CreateAngle(GRGlGetProcedureAddressDelegate) instead.")]
public static GRGlInterface AssembleAngleInterface (GRGlGetProcDelegate get) =>
CreateAngle (name => get (null, name));
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use CreateAngle(GRGlGetProcedureAddressDelegate) instead.")]
public static GRGlInterface AssembleAngleInterface (object context, GRGlGetProcDelegate get) =>
CreateAngle (name => get (context, name));
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use CreateOpenGl(GRGlGetProcedureAddressDelegate) instead.")]
public static GRGlInterface AssembleGlInterface (GRGlGetProcDelegate get) =>
CreateOpenGl (name => get (null, name));
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use CreateOpenGl(GRGlGetProcedureAddressDelegate) instead.")]
public static GRGlInterface AssembleGlInterface (object context, GRGlGetProcDelegate get) =>
CreateOpenGl (name => get (context, name));
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use CreateGles(GRGlGetProcedureAddressDelegate) instead.")]
public static GRGlInterface AssembleGlesInterface (GRGlGetProcDelegate get) =>
CreateGles (name => get (null, name));
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use CreateGles(GRGlGetProcedureAddressDelegate) instead.")]
public static GRGlInterface AssembleGlesInterface (object context, GRGlGetProcDelegate get) =>
CreateGles (name => get (context, name));
//
public bool Validate () =>
SkiaApi.gr_glinterface_validate (Handle);
public bool HasExtension (string extension) =>
SkiaApi.gr_glinterface_has_extension (Handle, extension);
//
internal static GRGlInterface GetObject (IntPtr handle) =>
handle == IntPtr.Zero ? null : new GRGlInterface (handle, true);
//
private static class AngleLoader
{
private static readonly IntPtr libEGL;
@ -168,22 +205,23 @@ namespace SkiaSharp
}
libEGL = LoadLibrary ("libEGL.dll");
if (Marshal.GetLastWin32Error () != 0 || libEGL == IntPtr.Zero)
throw new DllNotFoundException ("Unable to load libEGL.dll.");
libGLESv2 = LoadLibrary ("libGLESv2.dll");
if (Marshal.GetLastWin32Error () != 0 || libGLESv2 == IntPtr.Zero)
throw new DllNotFoundException ("Unable to load libGLESv2.dll.");
}
public static bool IsValid =>
libEGL != IntPtr.Zero && libGLESv2 != IntPtr.Zero;
// function to assemble the ANGLE interface
public static IntPtr GetProc (object context, string name)
public static IntPtr GetProc (string name)
{
// this is not supported at all on non-Windows platforms
if (!PlatformConfiguration.IsWindows) {
return IntPtr.Zero;
}
if (!IsValid)
return IntPtr.Zero;
IntPtr proc = GetProcAddress (libGLESv2, name);
if (proc == IntPtr.Zero)
{
@ -869,4 +907,3 @@ namespace SkiaSharp
#endif
}
}

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

@ -9,7 +9,7 @@ namespace SkiaSharp
public unsafe class GRVkBackendContext : IDisposable
{
private GRVkGetProcDelegate getProc;
private GRVkGetProcedureAddressDelegate getProc;
private GRVkGetProcProxyDelegate getProcProxy;
private GCHandle getProcHandle;
private void* getProcContext;
@ -48,7 +48,7 @@ namespace SkiaSharp
public IntPtr VkPhysicalDeviceFeatures2 { get; set; }
public GRVkGetProcDelegate GetProc {
public GRVkGetProcedureAddressDelegate GetProcedureAddress {
get => getProc;
set {
getProc = value;

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

@ -20,10 +20,10 @@ namespace SkiaSharp
public void HasExtension (string extension, int minVersion) =>
SkiaApi.gr_vk_extensions_has_extension (Handle, extension, (uint)minVersion);
public void Initialize (GRVkGetProcDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice) =>
public void Initialize (GRVkGetProcedureAddressDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice) =>
Initialize (getProc, vkInstance, vkPhysicalDevice, null, null);
public void Initialize (GRVkGetProcDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice, string[] instanceExtensions, string[] deviceExtensions)
public void Initialize (GRVkGetProcedureAddressDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice, string[] instanceExtensions, string[] deviceExtensions)
{
var proxy = DelegateProxies.Create (getProc, DelegateProxies.GRVkGetProcDelegateProxy, out var gch, out var ctx);
try {
@ -35,7 +35,7 @@ namespace SkiaSharp
}
}
public static GRVkExtensions Create (GRVkGetProcDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice, string[] instanceExtensions, string[] deviceExtensions)
public static GRVkExtensions Create (GRVkGetProcedureAddressDelegate getProc, IntPtr vkInstance, IntPtr vkPhysicalDevice, string[] instanceExtensions, string[] deviceExtensions)
{
var extensions = new GRVkExtensions ();
extensions.Initialize (getProc, vkInstance, vkPhysicalDevice, instanceExtensions, deviceExtensions);

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

@ -27,7 +27,7 @@ namespace SkiaSharp
public SKMatrix Matrix {
get {
var matrix = SKMatrix.MakeIdentity ();
var matrix = SKMatrix.Identity;
GetMatrix (ref matrix);
return matrix;
}

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

@ -436,7 +436,7 @@ namespace SkiaSharp
public void DrawPicture (SKPicture picture, float x, float y, SKPaint paint = null)
{
var matrix = SKMatrix.MakeTranslation (x, y);
var matrix = SKMatrix.CreateTranslation (x, y);
DrawPicture (picture, ref matrix, paint);
}
@ -476,7 +476,7 @@ namespace SkiaSharp
{
if (drawable == null)
throw new ArgumentNullException (nameof (drawable));
var matrix = SKMatrix.MakeTranslation (x, y);
var matrix = SKMatrix.CreateTranslation (x, y);
DrawDrawable (drawable, ref matrix);
}
@ -484,7 +484,7 @@ namespace SkiaSharp
{
if (drawable == null)
throw new ArgumentNullException (nameof (drawable));
var matrix = SKMatrix.MakeTranslation (p.X, p.Y);
var matrix = SKMatrix.CreateTranslation (p.X, p.Y);
DrawDrawable (drawable, ref matrix);
}

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

@ -71,7 +71,7 @@ namespace SkiaSharp
public void Draw (SKCanvas canvas, float x, float y)
{
var matrix = SKMatrix.MakeTranslation (x, y);
var matrix = SKMatrix.CreateTranslation (x, y);
Draw (canvas, ref matrix);
}

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

@ -758,15 +758,9 @@ namespace SkiaSharp
// GetGlyphPaths
public void GetGlyphPaths (ReadOnlySpan<ushort> glyphs, SKGlyphPathDelegate glyphPathDelegate) =>
GetGlyphPaths (glyphs, glyphPathDelegate, null);
public void GetGlyphPaths (ReadOnlySpan<ushort> glyphs, SKGlyphPathDelegate glyphPathDelegate, object context)
public void GetGlyphPaths (ReadOnlySpan<ushort> glyphs, SKGlyphPathDelegate glyphPathDelegate)
{
var del = glyphPathDelegate != null && context != null
? new SKGlyphPathDelegate ((p, m, _) => glyphPathDelegate (p, m, context))
: glyphPathDelegate;
var proxy = DelegateProxies.Create (del, DelegateProxies.SKGlyphPathDelegateProxy, out var gch, out var ctx);
var proxy = DelegateProxies.Create (glyphPathDelegate, DelegateProxies.SKGlyphPathDelegateProxy, out var gch, out var ctx);
try {
fixed (ushort* g = glyphs) {
SkiaApi.sk_font_get_paths (Handle, g, glyphs.Length, proxy, (void*)ctx);

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

@ -176,7 +176,7 @@ namespace SkiaSharp
Offset (offset.X, offset.Y);
public void Offset (float dx, float dy) =>
Transform (SKMatrix.MakeTranslation (dx, dy));
Transform (SKMatrix.CreateTranslation (dx, dy));
public void MoveTo (SKPoint point) =>
SkiaApi.sk_path_move_to (Handle, point.X, point.Y);

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

@ -230,6 +230,10 @@ namespace SkiaSharp
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_glinterface_t gr_glinterface_assemble_interface (void* ctx, GRGlGetProcProxyDelegate get);
// const gr_glinterface_t* gr_glinterface_assemble_webgl_interface(void* ctx, gr_gl_get_proc get)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_glinterface_t gr_glinterface_assemble_webgl_interface (void* ctx, GRGlGetProcProxyDelegate get);
// const gr_glinterface_t* gr_glinterface_create_native_interface()
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_glinterface_t gr_glinterface_create_native_interface ();

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

@ -1 +1 @@
Subproject commit 25edafc506731ebc66032b3e3376142395879dd4
Subproject commit 97e17c8badc8426842e517f87ac9c1679b18a7b6

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

@ -87,10 +87,12 @@ namespace SkiaSharp.Views.Android
{
colorType = SKColorType.Alpha8;
}
#pragma warning disable CS0618 // Type or member is obsolete
else if (config == Bitmap.Config.Argb4444)
{
colorType = SKColorType.Argb4444;
}
#pragma warning restore CS0618 // Type or member is obsolete
else if (config == Bitmap.Config.Rgb565)
{
colorType = SKColorType.Rgb565;
@ -157,10 +159,12 @@ namespace SkiaSharp.Views.Android
dstInfo.ColorType = SKColorType.Rgb565;
dstInfo.AlphaType = SKAlphaType.Opaque;
break;
#pragma warning disable CS0618 // Type or member is obsolete
case SKColorType.Argb4444:
config = Bitmap.Config.Argb4444;
dstInfo.ColorType = SKColorType.Argb4444;
break;
#pragma warning restore CS0618 // Type or member is obsolete
}
// destination bitmap

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

@ -42,8 +42,8 @@ namespace SkiaSharp.Views.Android
// create the contexts if not done already
if (context == null)
{
var glInterface = GRGlInterface.CreateNativeGlInterface();
context = GRContext.Create(GRBackend.OpenGL, glInterface);
var glInterface = GRGlInterface.Create();
context = GRContext.CreateGl(glInterface);
}
// manage the drawing surface

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

@ -42,8 +42,8 @@ namespace SkiaSharp.Views.Android
// create the contexts if not done already
if (context == null)
{
var glInterface = GRGlInterface.CreateNativeGlInterface();
context = GRContext.Create(GRBackend.OpenGL, glInterface);
var glInterface = GRGlInterface.Create();
context = GRContext.CreateGl(glInterface);
}
// manage the drawing surface

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

@ -139,9 +139,9 @@ namespace SkiaSharp.Views.Tizen
Gles.glViewport(0, 0, surfaceSize.Width, surfaceSize.Height);
// create the interface using the function pointers provided by the EFL
var glInterface = GRGlInterface.CreateNativeEvasInterface(glEvas);
var glInterface = GRGlInterface.CreateEvas(glEvas);
context?.Dispose();
context = GRContext.Create(GRBackend.OpenGL, glInterface);
context = GRContext.CreateGl(glInterface);
// create the render target
renderTarget?.Dispose();

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

@ -42,8 +42,8 @@ namespace SkiaSharp.Views.UWP
// create the SkiaSharp context
if (context == null)
{
glInterface = GRGlInterface.CreateNativeAngleInterface();
context = GRContext.Create(GRBackend.OpenGL, glInterface);
glInterface = GRGlInterface.Create();
context = GRContext.CreateGl(glInterface);
}
// get the new surface size

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

@ -79,8 +79,8 @@ namespace SkiaSharp.Views.Desktop
// create the contexts if not done already
if (grContext == null)
{
var glInterface = GRGlInterface.CreateNativeGlInterface();
grContext = GRContext.Create(GRBackend.OpenGL, glInterface);
var glInterface = GRGlInterface.Create();
grContext = GRContext.CreateGl(glInterface);
}
// get the new surface size

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

@ -6,6 +6,8 @@ using PhysicalDeviceFeaturesNative = SharpVk.Interop.PhysicalDeviceFeatures;
namespace SkiaSharp
{
public delegate IntPtr GRSharpVkGetProcedureAddressDelegate(string name, Instance instance, Device device);
public unsafe class GRSharpVkBackendContext : GRVkBackendContext
{
private Instance vkInstance;
@ -13,6 +15,7 @@ namespace SkiaSharp
private Device vkDevice;
private Queue vkQueue;
private PhysicalDeviceFeatures? vkPhysicalDeviceFeatures;
private GRSharpVkGetProcedureAddressDelegate getProc;
private PhysicalDeviceFeaturesNative devFeatures;
private GCHandle devFeaturesHandle;
@ -93,5 +96,32 @@ namespace SkiaSharp
}
}
}
public new GRSharpVkGetProcedureAddressDelegate GetProcedureAddress
{
get => getProc;
set
{
getProc = value;
base.GetProcedureAddress = null;
if (value is GRSharpVkGetProcedureAddressDelegate del)
{
base.GetProcedureAddress = (name, instance, device) =>
{
if (instance != IntPtr.Zero && vkInstance?.RawHandle.ToUInt64() != (ulong)instance.ToInt64())
throw new InvalidOperationException("Incorrect object for VkInstance.");
if (device != IntPtr.Zero && vkDevice?.RawHandle.ToUInt64() != (ulong)device.ToInt64())
throw new InvalidOperationException("Incorrect object for VkDevice.");
var i = instance != IntPtr.Zero ? vkInstance : null;
var d = device != IntPtr.Zero ? vkDevice : null;
return del?.Invoke(name, i, d) ?? IntPtr.Zero;
};
}
}
}
}
}

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

@ -5,10 +5,20 @@ namespace SkiaSharp
{
public static class GRVkExtensionsExtensions
{
public static void Initialize(this GRVkExtensions extensions, GRVkGetProcDelegate getProc, Instance instance, PhysicalDevice physicalDevice) =>
public static void Initialize(this GRVkExtensions extensions, GRSharpVkGetProcedureAddressDelegate getProc, Instance instance, PhysicalDevice physicalDevice) =>
extensions.Initialize(getProc, instance, physicalDevice, null, null);
public static void Initialize(this GRVkExtensions extensions, GRVkGetProcDelegate getProc, Instance instance, PhysicalDevice physicalDevice, string[] instanceExtensions, string[] deviceExtensions) =>
extensions.Initialize(getProc, (IntPtr)instance?.RawHandle.ToUInt64(), (IntPtr)physicalDevice?.RawHandle.ToUInt64(), instanceExtensions, deviceExtensions);
public static void Initialize(this GRVkExtensions extensions, GRSharpVkGetProcedureAddressDelegate getProc, Instance instance, PhysicalDevice physicalDevice, string[] instanceExtensions, string[] deviceExtensions)
{
GRVkGetProcedureAddressDelegate proc = (name, inst, _) =>
{
if (inst != IntPtr.Zero && instance?.RawHandle.ToUInt64() != (ulong)inst.ToInt64())
throw new InvalidOperationException("Incorrect object for VkInstance.");
return getProc?.Invoke(name, inst != IntPtr.Zero ? instance : null, null) ?? IntPtr.Zero;
};
extensions.Initialize(proc, (IntPtr)instance?.RawHandle.ToUInt64(), (IntPtr)physicalDevice?.RawHandle.ToUInt64(), instanceExtensions, deviceExtensions);
}
}
}

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

@ -41,7 +41,7 @@ namespace SkiaSharp.Tests
using (var ctx = CreateGlContext()) {
ctx.MakeCurrent();
var glInterface = GRGlInterface.CreateNativeGlInterface();
var glInterface = GRGlInterface.Create();
Assert.True(glInterface.Validate());

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

@ -14,7 +14,7 @@ namespace SkiaSharp.Tests
using (var ctx = CreateGlContext()) {
ctx.MakeCurrent();
var glInterface = GRGlInterface.CreateNativeGlInterface();
var glInterface = GRGlInterface.Create();
Assert.NotNull(glInterface);
Assert.True(glInterface.Validate());
@ -31,7 +31,7 @@ namespace SkiaSharp.Tests
if (IsMac) {
var lib = MacDynamicLibraries.dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", 1);
var glInterface = GRGlInterface.AssembleGlInterface((context, name) => {
var glInterface = GRGlInterface.Create(name => {
return MacDynamicLibraries.dlsym(lib, name);
});
@ -42,7 +42,7 @@ namespace SkiaSharp.Tests
} else if (IsWindows) {
var lib = WindowsDynamicLibraries.LoadLibrary("opengl32.dll");
var glInterface = GRGlInterface.AssembleGlInterface((context, name) => {
var glInterface = GRGlInterface.Create(name => {
var ptr = WindowsDynamicLibraries.GetProcAddress(lib, name);
if (ptr == IntPtr.Zero) {
ptr = wglGetProcAddress(name);
@ -55,7 +55,7 @@ namespace SkiaSharp.Tests
WindowsDynamicLibraries.FreeLibrary(lib);
} else if (IsLinux) {
var glInterface = GRGlInterface.AssembleGlInterface((context, name) => {
var glInterface = GRGlInterface.Create(name => {
return glXGetProcAddress(name);
});

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

@ -20,15 +20,15 @@ namespace SkiaSharp.Tests
{
var canvas = surface.Canvas;
Assert.Equal(SKMatrix.MakeIdentity(), canvas.TotalMatrix);
Assert.Equal(SKMatrix.Identity, canvas.TotalMatrix);
using (new SKAutoCanvasRestore(canvas))
{
canvas.Translate(10, 10);
Assert.Equal(SKMatrix.MakeTranslation(10, 10), canvas.TotalMatrix);
Assert.Equal(SKMatrix.CreateTranslation(10, 10), canvas.TotalMatrix);
}
Assert.Equal(SKMatrix.MakeIdentity(), canvas.TotalMatrix);
Assert.Equal(SKMatrix.Identity, canvas.TotalMatrix);
}
}
}
@ -188,6 +188,7 @@ namespace SkiaSharp.Tests
}
}
[Obsolete]
[SkippableFact]
public void CanDrawNullPointerZeroLengthText()
{
@ -199,6 +200,7 @@ namespace SkiaSharp.Tests
}
}
[Obsolete]
[SkippableFact]
public void ThrowsOnDrawNullPointerText()
{
@ -383,10 +385,10 @@ namespace SkiaSharp.Tests
using (var canvas = new SKCanvas(bitmap))
{
canvas.Translate(10, 20);
Assert.Equal(SKMatrix.MakeTranslation(10, 20).Values, canvas.TotalMatrix.Values);
Assert.Equal(SKMatrix.CreateTranslation(10, 20).Values, canvas.TotalMatrix.Values);
canvas.Translate(10, 20);
Assert.Equal(SKMatrix.MakeTranslation(20, 40).Values, canvas.TotalMatrix.Values);
Assert.Equal(SKMatrix.CreateTranslation(20, 40).Values, canvas.TotalMatrix.Values);
}
}

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

@ -276,7 +276,7 @@ namespace SkiaSharp.Tests
// only decode every second line
for (int y = 0; y < info.Height; y += 2) {
Assert.Equal (1, codec.GetScanlines (scanlineBitmap.GetAddr (0, y), 1, info.RowBytes));
Assert.Equal (1, codec.GetScanlines (scanlineBitmap.GetAddress (0, y), 1, info.RowBytes));
Assert.Equal (y + 1, codec.NextScanline);
if (codec.SkipScanlines (1))
Assert.Equal (y + 2, codec.NextScanline);

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

@ -10,42 +10,42 @@ namespace SkiaSharp.Tests
[SkippableFact]
public void MatrixCanInvert()
{
var m = SKMatrix.MakeTranslation(10, 20);
var m = SKMatrix.CreateTranslation(10, 20);
Assert.True(m.TryInvert(out var inverse));
Assert.Equal(SKMatrix.MakeTranslation(-10, -20).Values, inverse.Values);
Assert.Equal(SKMatrix.CreateTranslation(-10, -20).Values, inverse.Values);
}
[SkippableFact]
public void MatrixCanConcat()
{
var a = SKMatrix.MakeTranslation(10, 20);
var b = SKMatrix.MakeTranslation(5, 7);
var a = SKMatrix.CreateTranslation(10, 20);
var b = SKMatrix.CreateTranslation(5, 7);
var c = SKMatrix.Concat(a, b);
Assert.Equal(SKMatrix.MakeTranslation(15, 27).Values, c.Values);
Assert.Equal(SKMatrix.CreateTranslation(15, 27).Values, c.Values);
}
[SkippableFact]
public void MatrixCanPreConcat()
{
var a = SKMatrix.MakeTranslation(10, 20);
var b = SKMatrix.MakeTranslation(5, 7);
var a = SKMatrix.CreateTranslation(10, 20);
var b = SKMatrix.CreateTranslation(5, 7);
var c = a.PreConcat(b);
Assert.Equal(SKMatrix.MakeTranslation(15, 27).Values, c.Values);
Assert.Equal(SKMatrix.CreateTranslation(15, 27).Values, c.Values);
}
[SkippableFact]
public void MatrixCanPostConcat()
{
var a = SKMatrix.MakeTranslation(10, 20);
var b = SKMatrix.MakeTranslation(5, 7);
var a = SKMatrix.CreateTranslation(10, 20);
var b = SKMatrix.CreateTranslation(5, 7);
var c = a.PostConcat(b);
Assert.Equal(SKMatrix.MakeTranslation(15, 27).Values, c.Values);
Assert.Equal(SKMatrix.CreateTranslation(15, 27).Values, c.Values);
}
[SkippableFact]
@ -75,7 +75,7 @@ namespace SkiaSharp.Tests
new SKPoint(15, 15),
};
var matrix = SKMatrix.MakeTranslation(10, 10);
var matrix = SKMatrix.CreateTranslation(10, 10);
matrix.MapPoints(source, source);
Assert.Equal(expectedResult, source);

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

@ -228,7 +228,7 @@ namespace SkiaSharp.Tests
offset.Offset(2, 2);
var rrect = new SKRoundRect(rect, 5, 5);
var transformed = rrect.Transform(SKMatrix.MakeRotationDegrees(30));
var transformed = rrect.Transform(SKMatrix.CreateRotationDegrees(30));
Assert.Null(transformed);
}
@ -243,7 +243,7 @@ namespace SkiaSharp.Tests
offset.Offset(2, 2);
var rrect = new SKRoundRect(rect, 5, 5);
var transformed = rrect.Transform(SKMatrix.MakeTranslation(2, 2));
var transformed = rrect.Transform(SKMatrix.CreateTranslation(2, 2));
Assert.Equal(offset, transformed.Rect);
Assert.Equal(radii, transformed.Radii);

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

@ -175,7 +175,7 @@ namespace SkiaSharp.Tests
using var p = new SKPaint
{
Shader = SKShader.CreatePicture(picture, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, SKMatrix.MakeIdentity(), tile)
Shader = SKShader.CreatePicture(picture, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, SKMatrix.Identity, tile)
};
var r = SKRect.Create(bitmap.Width, bitmap.Height);
canvas.DrawRect(r, p);

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

@ -16,6 +16,7 @@ namespace SkiaSharp.Tests
Assert.Null(blob);
}
[Obsolete]
[SkippableFact]
public void NonGlyphTextEncodingDoesNotThrow()
{

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

@ -18,7 +18,7 @@ namespace SkiaSharp.Vulkan.Tests
VkDevice = (IntPtr)ctx.Device.RawHandle.ToUInt64(),
VkQueue = (IntPtr)ctx.GraphicsQueue.RawHandle.ToUInt64(),
GraphicsQueueIndex = ctx.GraphicsFamily,
GetProc = ctx.GetProc
GetProcedureAddress = ctx.GetProc
};
Assert.NotNull(grVkBackendContext);

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

@ -16,7 +16,7 @@ namespace SkiaSharp.Vulkan.Tests
VkDevice = ctx.Device,
VkQueue = ctx.GraphicsQueue,
GraphicsQueueIndex = ctx.GraphicsFamily,
GetProc = ctx.GetProc,
GetProcedureAddress = ctx.SharpVkGetProc,
VkPhysicalDeviceFeatures = ctx.PhysicalDevice.GetFeatures(),
};
Assert.NotNull(grVkBackendContext);

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

@ -18,7 +18,7 @@ namespace SkiaSharp.Vulkan.Tests
VkDevice = (IntPtr)ctx.Device.RawHandle.ToUInt64(),
VkQueue = (IntPtr)ctx.GraphicsQueue.RawHandle.ToUInt64(),
GraphicsQueueIndex = ctx.GraphicsFamily,
GetProc = ctx.GetProc
GetProcedureAddress = ctx.GetProc
};
Assert.NotNull(grVkBackendContext);
@ -50,7 +50,7 @@ namespace SkiaSharp.Vulkan.Tests
VkDevice = ctx.Device,
VkQueue = ctx.GraphicsQueue,
GraphicsQueueIndex = ctx.GraphicsFamily,
GetProc = ctx.GetProc
GetProcedureAddress = ctx.SharpVkGetProc
};
Assert.NotNull(grVkBackendContext);

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

@ -26,7 +26,9 @@ namespace SkiaSharp.Tests
public virtual uint PresentFamily { get; protected set; }
public virtual GRVkGetProcDelegate GetProc { get; protected set; }
public virtual GRVkGetProcedureAddressDelegate GetProc { get; protected set; }
public virtual GRSharpVkGetProcedureAddressDelegate SharpVkGetProc { get; protected set; }
public virtual void Dispose() =>
Instance?.Dispose();

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

@ -30,13 +30,27 @@ namespace SkiaSharp.Tests
PresentQueue = Device.GetQueue(PresentFamily, 0);
GetProc = (context, name, instanceHandle, deviceHandle) =>
GetProc = (name, instanceHandle, deviceHandle) =>
{
if (deviceHandle != IntPtr.Zero)
return Device.GetProcedureAddress(name);
return Instance.GetProcedureAddress(name);
};
SharpVkGetProc = (name, instance, device) =>
{
if (device != null)
return device.GetProcedureAddress(name);
if (instance != null)
return instance.GetProcedureAddress(name);
// SharpVk includes the static functions on Instance, but this is not actually correct
// since the functions are static, they are not tied to an instance. For example,
// VkCreateInstance is not found on an instance, it is creating said instance.
// Other libraries, such as VulkanCore, use another type to do this.
return Instance.GetProcedureAddress(name);
};
}
private (uint, uint) FindQueueFamilies()