From 091eed2e6fe361973f0a43b786085c67b3a269af Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Fri, 27 Mar 2020 12:57:29 +0100 Subject: [PATCH 1/3] Remove reflection usage for most SKObject --- binding/Binding/GRContext.cs | 22 ++++++- binding/Binding/GRGlInterface.cs | 26 +++++++-- binding/Binding/SKCanvas.cs | 18 ++++++ binding/Binding/SKCodec.cs | 22 ++++++- binding/Binding/SKColorFilter.cs | 34 ++++++++--- binding/Binding/SKColorSpace.cs | 40 +++++++++---- binding/Binding/SKData.cs | 38 ++++++++---- binding/Binding/SKDocument.cs | 27 +++++++-- binding/Binding/SKDrawable.cs | 22 ++++++- binding/Binding/SKFontManager.cs | 36 +++++++++--- binding/Binding/SKFontStyle.cs | 18 ++++++ binding/Binding/SKFontStyleSet.cs | 24 +++++++- binding/Binding/SKImage.cs | 64 ++++++++++++-------- binding/Binding/SKImageFilter.cs | 72 ++++++++++++++--------- binding/Binding/SKImageInfo.cs | 2 +- binding/Binding/SKMaskFilter.cs | 28 +++++++-- binding/Binding/SKMatrix44.cs | 18 ++++++ binding/Binding/SKObject.cs | 10 +--- binding/Binding/SKPaint.cs | 36 +++++++++--- binding/Binding/SKPath.cs | 18 ++++++ binding/Binding/SKPathEffect.cs | 36 +++++++++--- binding/Binding/SKPicture.cs | 18 ++++++ binding/Binding/SKPictureRecorder.cs | 8 +-- binding/Binding/SKSVG.cs | 2 +- binding/Binding/SKShader.cs | 81 ++++++++++++++++---------- binding/Binding/SKStream.cs | 20 ++++++- binding/Binding/SKString.cs | 18 ++++++ binding/Binding/SKSurface.cs | 38 ++++++++---- binding/Binding/SKSurfaceProperties.cs | 18 ++++++ binding/Binding/SKTextBlob.cs | 19 +++++- binding/Binding/SKTypeface.cs | 32 +++++++--- binding/Binding/SKVertices.cs | 20 ++++++- 32 files changed, 691 insertions(+), 194 deletions(-) diff --git a/binding/Binding/GRContext.cs b/binding/Binding/GRContext.cs index 34393bae76..5fb1e7714d 100644 --- a/binding/Binding/GRContext.cs +++ b/binding/Binding/GRContext.cs @@ -38,7 +38,7 @@ public static GRContext Create (GRBackend backend, IntPtr backendContext) => backend switch { GRBackend.Metal => throw new NotSupportedException (), - GRBackend.OpenGL => GetObject (SkiaApi.gr_context_make_gl (backendContext)), + GRBackend.OpenGL => GRContext.GetObject (SkiaApi.gr_context_make_gl (backendContext)), GRBackend.Vulkan => throw new NotSupportedException (), _ => throw new ArgumentOutOfRangeException (nameof (backend)), }; @@ -47,7 +47,7 @@ public static GRContext CreateGl () => CreateGl (null); public static GRContext CreateGl (GRGlInterface backendContext) => - GetObject (SkiaApi.gr_context_make_gl (backendContext == null ? IntPtr.Zero : backendContext.Handle)); + GetObject (SkiaApi.gr_context_make_gl (backendContext == null ? IntPtr.Zero : backendContext.Handle)); public GRBackend Backend => SkiaApi.gr_context_get_backend (Handle); @@ -98,5 +98,23 @@ public int GetMaxSurfaceSampleCount (SKColorType colorType) => [EditorBrowsable (EditorBrowsableState.Never)] [Obsolete ("Use GetMaxSurfaceSampleCount(SKColorType) instead.")] public int GetRecommendedSampleCount (GRPixelConfig config, float dpi) => 0; + + internal static GRContext GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new GRContext (ptr, owns); + } } } diff --git a/binding/Binding/GRGlInterface.cs b/binding/Binding/GRGlInterface.cs index 0da306dd67..8ee4184335 100644 --- a/binding/Binding/GRGlInterface.cs +++ b/binding/Binding/GRGlInterface.cs @@ -25,7 +25,7 @@ public static GRGlInterface CreateDefaultInterface () public static GRGlInterface CreateNativeGlInterface () { // the native code will automatically return null on non-OpenGL platforms, such as UWP - return GetObject (SkiaApi.gr_glinterface_create_native_interface ()); + return GetObject (SkiaApi.gr_glinterface_create_native_interface ()); } public static GRGlInterface CreateNativeAngleInterface () @@ -69,7 +69,7 @@ public static GRGlInterface AssembleInterface (object context, GRGlGetProcDelega : get; var proxy = DelegateProxies.Create (del, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx); try { - return GetObject (SkiaApi.gr_glinterface_assemble_interface ((void*)ctx, proxy)); + return GetObject (SkiaApi.gr_glinterface_assemble_interface ((void*)ctx, proxy)); } finally { gch.Free (); } @@ -98,7 +98,7 @@ public static GRGlInterface AssembleGlInterface (object context, GRGlGetProcDele : get; var proxy = DelegateProxies.Create (del, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx); try { - return GetObject (SkiaApi.gr_glinterface_assemble_gl_interface ((void*)ctx, proxy)); + return GetObject (SkiaApi.gr_glinterface_assemble_gl_interface ((void*)ctx, proxy)); } finally { gch.Free (); } @@ -116,7 +116,7 @@ public static GRGlInterface AssembleGlesInterface (object context, GRGlGetProcDe : get; var proxy = DelegateProxies.Create (del, DelegateProxies.GRGlGetProcDelegateProxy, out var gch, out var ctx); try { - return GetObject (SkiaApi.gr_glinterface_assemble_gles_interface ((void*)ctx, proxy)); + return GetObject (SkiaApi.gr_glinterface_assemble_gles_interface ((void*)ctx, proxy)); } finally { gch.Free (); } @@ -132,6 +132,24 @@ public bool HasExtension (string extension) return SkiaApi.gr_glinterface_has_extension (Handle, extension); } + internal static GRGlInterface GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new GRGlInterface (ptr, owns); + } + private static class AngleLoader { private static readonly IntPtr libEGL; diff --git a/binding/Binding/SKCanvas.cs b/binding/Binding/SKCanvas.cs index cbfc449673..9edc35162e 100644 --- a/binding/Binding/SKCanvas.cs +++ b/binding/Binding/SKCanvas.cs @@ -906,6 +906,24 @@ public void DrawPatch (SKPoint[] cubics, SKColor[] colors, SKPoint[] texCoords, SkiaApi.sk_canvas_draw_patch (Handle, cubes, (uint*)cols, coords, mode, paint.Handle); } } + + internal static SKCanvas GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKCanvas (ptr, owns); + } } public class SKAutoCanvasRestore : IDisposable diff --git a/binding/Binding/SKCodec.cs b/binding/Binding/SKCodec.cs index 13610ea5f6..d9e5ad34a7 100644 --- a/binding/Binding/SKCodec.cs +++ b/binding/Binding/SKCodec.cs @@ -312,7 +312,7 @@ public static SKCodec Create (SKStream stream, out SKCodecResult result) throw new ArgumentNullException (nameof (stream)); fixed (SKCodecResult* r = &result) { - var codec = GetObject (SkiaApi.sk_codec_new_from_stream (stream.Handle, r)); + var codec = GetObject (SkiaApi.sk_codec_new_from_stream (stream.Handle, r)); stream.RevokeOwnership (codec); return codec; } @@ -325,7 +325,7 @@ public static SKCodec Create (SKData data) if (data == null) throw new ArgumentNullException (nameof (data)); - return GetObject (SkiaApi.sk_codec_new_from_data (data.Handle)); + return GetObject(SkiaApi.sk_codec_new_from_data (data.Handle)); } // utils @@ -343,5 +343,23 @@ internal static SKStream WrapManagedStream (Stream stream) return new SKFrontBufferedManagedStream (stream, MinBufferedBytesNeeded, true); } } + + internal static SKCodec GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKCodec (ptr, owns); + } } } diff --git a/binding/Binding/SKColorFilter.cs b/binding/Binding/SKColorFilter.cs index 02da7715b2..203f1743d3 100644 --- a/binding/Binding/SKColorFilter.cs +++ b/binding/Binding/SKColorFilter.cs @@ -20,12 +20,12 @@ protected override void Dispose (bool disposing) => public static SKColorFilter CreateBlendMode(SKColor c, SKBlendMode mode) { - return GetObject(SkiaApi.sk_colorfilter_new_mode((uint)c, mode)); + return GetObject(SkiaApi.sk_colorfilter_new_mode((uint)c, mode)); } public static SKColorFilter CreateLighting(SKColor mul, SKColor add) { - return GetObject(SkiaApi.sk_colorfilter_new_lighting((uint)mul, (uint)add)); + return GetObject(SkiaApi.sk_colorfilter_new_lighting((uint)mul, (uint)add)); } public static SKColorFilter CreateCompose(SKColorFilter outer, SKColorFilter inner) @@ -34,7 +34,7 @@ public static SKColorFilter CreateCompose(SKColorFilter outer, SKColorFilter inn throw new ArgumentNullException(nameof(outer)); if (inner == null) throw new ArgumentNullException(nameof(inner)); - return GetObject(SkiaApi.sk_colorfilter_new_compose(outer.Handle, inner.Handle)); + return GetObject(SkiaApi.sk_colorfilter_new_compose(outer.Handle, inner.Handle)); } public static SKColorFilter CreateColorMatrix(float[] matrix) @@ -44,13 +44,13 @@ public static SKColorFilter CreateColorMatrix(float[] matrix) if (matrix.Length != 20) throw new ArgumentException("Matrix must have a length of 20.", nameof(matrix)); fixed (float* m = matrix) { - return GetObject (SkiaApi.sk_colorfilter_new_color_matrix (m)); + return GetObject (SkiaApi.sk_colorfilter_new_color_matrix (m)); } } public static SKColorFilter CreateLumaColor() { - return GetObject(SkiaApi.sk_colorfilter_new_luma_color()); + return GetObject(SkiaApi.sk_colorfilter_new_luma_color()); } public static SKColorFilter CreateTable(byte[] table) @@ -60,7 +60,7 @@ public static SKColorFilter CreateTable(byte[] table) if (table.Length != TableMaxLength) throw new ArgumentException($"Table must have a length of {TableMaxLength}.", nameof(table)); fixed (byte* t = table) { - return GetObject (SkiaApi.sk_colorfilter_new_table (t)); + return GetObject (SkiaApi.sk_colorfilter_new_table (t)); } } @@ -79,18 +79,36 @@ public static SKColorFilter CreateTable(byte[] tableA, byte[] tableR, byte[] tab fixed (byte* r = tableR) fixed (byte* g = tableG) fixed (byte* b = tableB) { - return GetObject (SkiaApi.sk_colorfilter_new_table_argb (a, r, g, b)); + return GetObject (SkiaApi.sk_colorfilter_new_table_argb (a, r, g, b)); } } public static SKColorFilter CreateHighContrast(SKHighContrastConfig config) { - return GetObject(SkiaApi.sk_colorfilter_new_high_contrast(&config)); + return GetObject (SkiaApi.sk_colorfilter_new_high_contrast(&config)); } public static SKColorFilter CreateHighContrast(bool grayscale, SKHighContrastConfigInvertStyle invertStyle, float contrast) { return CreateHighContrast(new SKHighContrastConfig(grayscale, invertStyle, contrast)); } + + internal static SKColorFilter GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKColorFilter (ptr, owns); + } } } diff --git a/binding/Binding/SKColorSpace.cs b/binding/Binding/SKColorSpace.cs index d15768d50d..1b003dda9f 100644 --- a/binding/Binding/SKColorSpace.cs +++ b/binding/Binding/SKColorSpace.cs @@ -66,7 +66,7 @@ public static SKColorSpace CreateIcc (IntPtr input, long length) if (input == IntPtr.Zero) throw new ArgumentNullException (nameof (input)); - return GetObject (SkiaApi.sk_colorspace_new_icc ((void*)input, (IntPtr)length)); + return GetObject (SkiaApi.sk_colorspace_new_icc ((void*)input, (IntPtr)length)); } public static SKColorSpace CreateIcc (byte[] input, long length) @@ -75,7 +75,7 @@ public static SKColorSpace CreateIcc (byte[] input, long length) throw new ArgumentNullException (nameof (input)); fixed (byte* i = input) { - return GetObject (SkiaApi.sk_colorspace_new_icc (i, (IntPtr)length)); + return GetObject (SkiaApi.sk_colorspace_new_icc (i, (IntPtr)length)); } } @@ -85,7 +85,7 @@ public static SKColorSpace CreateIcc (byte[] input) throw new ArgumentNullException (nameof (input)); fixed (byte* i = input) { - return GetObject (SkiaApi.sk_colorspace_new_icc (i, (IntPtr)input.Length)); + return GetObject (SkiaApi.sk_colorspace_new_icc (i, (IntPtr)input.Length)); } } @@ -114,33 +114,33 @@ public static SKColorSpace CreateRgb (SKColorSpaceRenderTargetGamma gamma, SKMat if (toXyzD50 == null) throw new ArgumentNullException (nameof (toXyzD50)); - return GetObject (SkiaApi.sk_colorspace_new_rgb_with_gamma (gamma, toXyzD50.Handle)); + return GetObject (SkiaApi.sk_colorspace_new_rgb_with_gamma (gamma, toXyzD50.Handle)); } public static SKColorSpace CreateRgb (SKColorSpaceRenderTargetGamma gamma, SKColorSpaceGamut gamut) => - GetObject (SkiaApi.sk_colorspace_new_rgb_with_gamma_and_gamut (gamma, gamut)); + GetObject (SkiaApi.sk_colorspace_new_rgb_with_gamma_and_gamut (gamma, gamut)); public static SKColorSpace CreateRgb (SKColorSpaceTransferFn coeffs, SKMatrix44 toXyzD50) { if (toXyzD50 == null) throw new ArgumentNullException (nameof (toXyzD50)); - return GetObject (SkiaApi.sk_colorspace_new_rgb_with_coeffs (&coeffs, toXyzD50.Handle)); + return GetObject (SkiaApi.sk_colorspace_new_rgb_with_coeffs (&coeffs, toXyzD50.Handle)); } public static SKColorSpace CreateRgb (SKColorSpaceTransferFn coeffs, SKColorSpaceGamut gamut) => - GetObject (SkiaApi.sk_colorspace_new_rgb_with_coeffs_and_gamut (&coeffs, gamut)); + GetObject (SkiaApi.sk_colorspace_new_rgb_with_coeffs_and_gamut (&coeffs, gamut)); public static SKColorSpace CreateRgb (SKNamedGamma gamma, SKMatrix44 toXyzD50) { if (toXyzD50 == null) throw new ArgumentNullException (nameof (toXyzD50)); - return GetObject (SkiaApi.sk_colorspace_new_rgb_with_gamma_named (gamma, toXyzD50.Handle)); + return GetObject (SkiaApi.sk_colorspace_new_rgb_with_gamma_named (gamma, toXyzD50.Handle)); } public static SKColorSpace CreateRgb (SKNamedGamma gamma, SKColorSpaceGamut gamut) => - GetObject (SkiaApi.sk_colorspace_new_rgb_with_gamma_named_and_gamut (gamma, gamut)); + GetObject (SkiaApi.sk_colorspace_new_rgb_with_gamma_named_and_gamut (gamma, gamut)); public bool ToXyzD50 (SKMatrix44 toXyzD50) { @@ -158,10 +158,28 @@ public bool GetNumericalTransferFunction (out SKColorSpaceTransferFn fn) } public SKMatrix44 ToXyzD50 () => - GetObject (SkiaApi.sk_colorspace_as_to_xyzd50 (Handle), false); + SKMatrix44.GetObject (SkiaApi.sk_colorspace_as_to_xyzd50 (Handle), false); public SKMatrix44 FromXyzD50 () => - GetObject (SkiaApi.sk_colorspace_as_from_xyzd50 (Handle), false); + SKMatrix44.GetObject (SkiaApi.sk_colorspace_as_from_xyzd50 (Handle), false); + + internal static SKColorSpace GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKColorSpace (ptr, owns); + } private sealed class SKColorSpaceStatic : SKColorSpace { diff --git a/binding/Binding/SKData.cs b/binding/Binding/SKData.cs index c0c4e57ee5..42ebb7c656 100644 --- a/binding/Binding/SKData.cs +++ b/binding/Binding/SKData.cs @@ -45,7 +45,7 @@ public static SKData CreateCopy (IntPtr bytes, ulong length) { if (SizeOf () == 4 && length > UInt32.MaxValue) throw new ArgumentOutOfRangeException (nameof (length), "The length exceeds the size of pointers."); - return GetObject (SkiaApi.sk_data_new_with_copy ((void*)bytes, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_with_copy ((void*)bytes, (IntPtr) length)); } public static SKData CreateCopy (byte[] bytes) => @@ -54,7 +54,7 @@ public static SKData CreateCopy (byte[] bytes) => public static SKData CreateCopy (byte[] bytes, ulong length) { fixed (byte* b = bytes) { - return GetObject (SkiaApi.sk_data_new_with_copy (b, (IntPtr)length)); + return GetObject (SkiaApi.sk_data_new_with_copy (b, (IntPtr)length)); } } @@ -67,7 +67,7 @@ public static SKData CreateCopy (ReadOnlySpan bytes) public static SKData Create (int size) { - return GetObject (SkiaApi.sk_data_new_uninitialized ((IntPtr) size)); + return GetObject (SkiaApi.sk_data_new_uninitialized ((IntPtr) size)); } public static SKData Create (ulong size) @@ -75,7 +75,7 @@ public static SKData Create (ulong size) if (SizeOf () == 4 && size > UInt32.MaxValue) throw new ArgumentOutOfRangeException (nameof (size), "The size exceeds the size of pointers."); - return GetObject (SkiaApi.sk_data_new_uninitialized ((IntPtr) size)); + return GetObject (SkiaApi.sk_data_new_uninitialized ((IntPtr) size)); } public static SKData Create (string filename) @@ -85,7 +85,7 @@ public static SKData Create (string filename) var utf8path = StringUtilities.GetEncodedText (filename, SKEncoding.Utf8); fixed (byte* u = utf8path) { - return GetObject (SkiaApi.sk_data_new_from_file (u)); + return GetObject (SkiaApi.sk_data_new_from_file (u)); } } @@ -136,7 +136,7 @@ public static SKData Create (SKStream stream, int length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); } public static SKData Create (SKStream stream, ulong length) @@ -144,7 +144,7 @@ public static SKData Create (SKStream stream, ulong length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); } public static SKData Create (SKStream stream, long length) @@ -152,7 +152,7 @@ public static SKData Create (SKStream stream, long length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); } public static SKData Create (IntPtr address, int length) @@ -171,7 +171,7 @@ public static SKData Create (IntPtr address, int length, SKDataReleaseDelegate r ? new SKDataReleaseDelegate ((addr, _) => releaseProc (addr, context)) : releaseProc; var proxy = DelegateProxies.Create (del, DelegateProxies.SKDataReleaseDelegateProxy, out _, out var ctx); - return GetObject (SkiaApi.sk_data_new_with_proc ((void*)address, (IntPtr)length, proxy, (void*)ctx)); + return GetObject (SkiaApi.sk_data_new_with_proc ((void*)address, (IntPtr)length, proxy, (void*)ctx)); } internal static SKData FromCString (string str) @@ -188,7 +188,7 @@ public SKData Subset (ulong offset, ulong length) if (offset > UInt32.MaxValue) throw new ArgumentOutOfRangeException (nameof (offset), "The offset exceeds the size of pointers."); } - return GetObject (SkiaApi.sk_data_new_subset (Handle, (IntPtr) offset, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_subset (Handle, (IntPtr) offset, (IntPtr) length)); } public byte[] ToArray () @@ -233,6 +233,24 @@ public void SaveTo (Stream target) } } + internal static SKData GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKData (ptr, owns); + } + private class SKDataStream : UnmanagedMemoryStream { private SKData host; diff --git a/binding/Binding/SKDocument.cs b/binding/Binding/SKDocument.cs index 9ad41e47f8..d08fb90f71 100644 --- a/binding/Binding/SKDocument.cs +++ b/binding/Binding/SKDocument.cs @@ -24,10 +24,10 @@ public void Abort () => SkiaApi.sk_document_abort (Handle); public SKCanvas BeginPage (float width, float height) => - GetObject (SkiaApi.sk_document_begin_page (Handle, width, height, null), false); + SKCanvas.GetObject (SkiaApi.sk_document_begin_page (Handle, width, height, null), false); public SKCanvas BeginPage (float width, float height, SKRect content) => - GetObject (SkiaApi.sk_document_begin_page (Handle, width, height, &content), false); + SKCanvas.GetObject (SkiaApi.sk_document_begin_page (Handle, width, height, &content), false); public void EndPage () => SkiaApi.sk_document_end_page (Handle); @@ -72,7 +72,7 @@ public static SKDocument CreateXps (SKWStream stream, float dpi) throw new ArgumentNullException (nameof (stream)); } - return Referenced (GetObject (SkiaApi.sk_document_create_xps_from_stream (stream.Handle, dpi)), stream); + return Referenced (GetObject (SkiaApi.sk_document_create_xps_from_stream (stream.Handle, dpi)), stream); } // CreatePdf @@ -111,7 +111,7 @@ public static SKDocument CreatePdf (SKWStream stream) throw new ArgumentNullException (nameof (stream)); } - return GetObject (SkiaApi.sk_document_create_pdf_from_stream (stream.Handle)); + return GetObject (SkiaApi.sk_document_create_pdf_from_stream (stream.Handle)); } public static SKDocument CreatePdf (string path, float dpi) => @@ -176,7 +176,7 @@ public static SKDocument CreatePdf (SKWStream stream, SKDocumentPdfMetadata meta cmetadata.fModified = &modified; } - return Referenced (GetObject (SkiaApi.sk_document_create_pdf_from_stream_with_metadata (stream.Handle, &cmetadata)), stream); + return Referenced (GetObject (SkiaApi.sk_document_create_pdf_from_stream_with_metadata (stream.Handle, &cmetadata)), stream); } } @@ -199,5 +199,22 @@ private static SKDocument Referenced (SKDocument doc, SKWStream stream) return doc; } + internal static SKDocument GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKDocument (ptr, owns); + } } } diff --git a/binding/Binding/SKDrawable.cs b/binding/Binding/SKDrawable.cs index 5fc68af81f..cab7e6fcb8 100644 --- a/binding/Binding/SKDrawable.cs +++ b/binding/Binding/SKDrawable.cs @@ -78,7 +78,7 @@ public void Draw (SKCanvas canvas, float x, float y) // do not unref as this is a plain pointer return, not a reference counted pointer public SKPicture Snapshot () => - GetObject (SkiaApi.sk_drawable_new_picture_snapshot (Handle), unrefExisting: false); + SKPicture.GetObject (SkiaApi.sk_drawable_new_picture_snapshot (Handle), unrefExisting: false); public void NotifyDrawingChanged () => SkiaApi.sk_drawable_notify_drawing_changed (Handle); @@ -102,7 +102,7 @@ protected virtual SKPicture OnSnapshot () private static void DrawInternal (IntPtr d, void* context, IntPtr canvas) { var drawable = DelegateProxies.GetUserData ((IntPtr)context, out _); - drawable.OnDraw (GetObject (canvas, false)); + drawable.OnDraw (SKCanvas.GetObject (canvas, false)); } [MonoPInvokeCallback (typeof (SKManagedDrawableGetBoundsProxyDelegate))] @@ -130,5 +130,23 @@ private static void DestroyInternal (IntPtr d, void* context) } gch.Free (); } + + internal static SKDrawable GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKDrawable (ptr, owns); + } } } diff --git a/binding/Binding/SKFontManager.cs b/binding/Binding/SKFontManager.cs index 62289c829c..0ce34bef6a 100644 --- a/binding/Binding/SKFontManager.cs +++ b/binding/Binding/SKFontManager.cs @@ -54,12 +54,12 @@ public string GetFamilyName (int index) public SKFontStyleSet GetFontStyles (int index) { - return GetObject (SkiaApi.sk_fontmgr_create_styleset (Handle, index)); + return SKFontStyleSet.GetObject (SkiaApi.sk_fontmgr_create_styleset (Handle, index)); } public SKFontStyleSet GetFontStyles (string familyName) { - return GetObject (SkiaApi.sk_fontmgr_match_family (Handle, familyName)); + return SKFontStyleSet.GetObject (SkiaApi.sk_fontmgr_match_family (Handle, familyName)); } public SKTypeface MatchFamily (string familyName, SKFontStyle style) @@ -67,7 +67,7 @@ public SKTypeface MatchFamily (string familyName, SKFontStyle style) if (style == null) throw new ArgumentNullException (nameof (style)); - return GetObject (SkiaApi.sk_fontmgr_match_family_style (Handle, familyName, style.Handle)); + return SKTypeface.GetObject (SkiaApi.sk_fontmgr_match_family_style (Handle, familyName, style.Handle)); } public SKTypeface MatchTypeface (SKTypeface face, SKFontStyle style) @@ -77,7 +77,7 @@ public SKTypeface MatchTypeface (SKTypeface face, SKFontStyle style) if (style == null) throw new ArgumentNullException (nameof (style)); - return GetObject (SkiaApi.sk_fontmgr_match_face_style (Handle, face.Handle, style.Handle)); + return SKTypeface.GetObject (SkiaApi.sk_fontmgr_match_face_style (Handle, face.Handle, style.Handle)); } public SKTypeface CreateTypeface (string path, int index = 0) @@ -87,7 +87,7 @@ public SKTypeface CreateTypeface (string path, int index = 0) var utf8path = StringUtilities.GetEncodedText (path, SKEncoding.Utf8); fixed (byte* u = utf8path) { - return GetObject (SkiaApi.sk_fontmgr_create_from_file (Handle, u, index)); + return SKTypeface.GetObject (SkiaApi.sk_fontmgr_create_from_file (Handle, u, index)); } } @@ -109,7 +109,7 @@ public SKTypeface CreateTypeface (SKStreamAsset stream, int index = 0) managed.Dispose (); } - var typeface = GetObject (SkiaApi.sk_fontmgr_create_from_stream (Handle, stream.Handle, index)); + var typeface = SKTypeface.GetObject (SkiaApi.sk_fontmgr_create_from_stream (Handle, stream.Handle, index)); stream.RevokeOwnership (typeface); return typeface; } @@ -119,7 +119,7 @@ public SKTypeface CreateTypeface (SKData data, int index = 0) if (data == null) throw new ArgumentNullException (nameof (data)); - return GetObject (SkiaApi.sk_fontmgr_create_from_data (Handle, data.Handle, index)); + return SKTypeface.GetObject (SkiaApi.sk_fontmgr_create_from_data (Handle, data.Handle, index)); } public SKTypeface MatchCharacter (char character) @@ -176,12 +176,30 @@ public SKTypeface MatchCharacter (string familyName, SKFontStyle style, string[] if (familyName == null) familyName = string.Empty; - return GetObject (SkiaApi.sk_fontmgr_match_family_style_character (Handle, familyName, style.Handle, bcp47, bcp47?.Length ?? 0, character)); + return SKTypeface.GetObject (SkiaApi.sk_fontmgr_match_family_style_character (Handle, familyName, style.Handle, bcp47, bcp47?.Length ?? 0, character)); } public static SKFontManager CreateDefault () { - return GetObject (SkiaApi.sk_fontmgr_create_default ()); + return SKFontManager.GetObject (SkiaApi.sk_fontmgr_create_default ()); + } + + internal static SKFontManager GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKFontManager (ptr, owns); } private sealed class SKFontManagerStatic : SKFontManager diff --git a/binding/Binding/SKFontStyle.cs b/binding/Binding/SKFontStyle.cs index 8b553d3685..63ff4da486 100644 --- a/binding/Binding/SKFontStyle.cs +++ b/binding/Binding/SKFontStyle.cs @@ -44,5 +44,23 @@ protected override void DisposeNative () => public static SKFontStyle Italic => new SKFontStyle (SKFontStyleWeight.Normal, SKFontStyleWidth.Normal, SKFontStyleSlant.Italic); public static SKFontStyle BoldItalic => new SKFontStyle (SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Italic); + + internal static SKFontStyle GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKFontStyle (ptr, owns); + } } } diff --git a/binding/Binding/SKFontStyleSet.cs b/binding/Binding/SKFontStyleSet.cs index c666328ef7..4d98769fce 100644 --- a/binding/Binding/SKFontStyleSet.cs +++ b/binding/Binding/SKFontStyleSet.cs @@ -37,7 +37,7 @@ public SKTypeface CreateTypeface (int index) if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException ($"Index was out of range. Must be non-negative and less than the size of the set.", nameof (index)); - return GetObject (SkiaApi.sk_fontstyleset_create_typeface (Handle, index)); + return SKTypeface.GetObject (SkiaApi.sk_fontstyleset_create_typeface (Handle, index)); } public SKTypeface CreateTypeface (SKFontStyle style) @@ -45,7 +45,7 @@ public SKTypeface CreateTypeface (SKFontStyle style) if (style == null) throw new ArgumentNullException (nameof (style)); - return GetObject (SkiaApi.sk_fontstyleset_match_style (Handle, style.Handle)); + return SKTypeface.GetObject (SkiaApi.sk_fontstyleset_match_style (Handle, style.Handle)); } public IEnumerator GetEnumerator () => GetStyles ().GetEnumerator (); @@ -66,5 +66,25 @@ private SKFontStyle GetStyle (int index) SkiaApi.sk_fontstyleset_get_style (Handle, index, fontStyle.Handle, IntPtr.Zero); return fontStyle; } + + internal static SKFontStyleSet GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + + return instance; + } + + return new SKFontStyleSet (ptr, owns); + } } } diff --git a/binding/Binding/SKImage.cs b/binding/Binding/SKImage.cs index 242e3118e9..84a52e949a 100644 --- a/binding/Binding/SKImage.cs +++ b/binding/Binding/SKImage.cs @@ -29,7 +29,7 @@ public static SKImage Create (SKImageInfo info) var pixels = Marshal.AllocCoTaskMem (info.BytesSize); using (var pixmap = new SKPixmap (info, pixels)) { // don't use the managed version as that is just extra overhead which isn't necessary - return GetObject (SkiaApi.sk_image_new_raster (pixmap.Handle, DelegateProxies.SKImageRasterReleaseDelegateProxyForCoTaskMem, null)); + return GetObject (SkiaApi.sk_image_new_raster (pixmap.Handle, DelegateProxies.SKImageRasterReleaseDelegateProxyForCoTaskMem, null)); } } @@ -80,7 +80,7 @@ public static SKImage FromPixelCopy (SKImageInfo info, IntPtr pixels, int rowByt throw new ArgumentNullException (nameof (pixels)); var nInfo = SKImageInfoNative.FromManaged (ref info); - return GetObject (SkiaApi.sk_image_new_raster_copy (&nInfo, (void*)pixels, (IntPtr)rowBytes)); + return GetObject (SkiaApi.sk_image_new_raster_copy (&nInfo, (void*)pixels, (IntPtr)rowBytes)); } [EditorBrowsable (EditorBrowsableState.Never)] @@ -92,7 +92,7 @@ public static SKImage FromPixelCopy (SKPixmap pixmap) { if (pixmap == null) throw new ArgumentNullException (nameof (pixmap)); - return GetObject (SkiaApi.sk_image_new_raster_copy_with_pixmap (pixmap.Handle)); + return GetObject (SkiaApi.sk_image_new_raster_copy_with_pixmap (pixmap.Handle)); } public static SKImage FromPixelCopy (SKImageInfo info, ReadOnlySpan pixels) => @@ -114,7 +114,7 @@ public static SKImage FromPixelData (SKImageInfo info, SKData data, int rowBytes if (data == null) throw new ArgumentNullException (nameof (data)); var cinfo = SKImageInfoNative.FromManaged (ref info); - return GetObject (SkiaApi.sk_image_new_raster_data (&cinfo, data.Handle, (IntPtr)rowBytes)); + return GetObject (SkiaApi.sk_image_new_raster_data (&cinfo, data.Handle, (IntPtr)rowBytes)); } public static SKImage FromPixels (SKImageInfo info, SKData data, int rowBytes) @@ -122,7 +122,7 @@ public static SKImage FromPixels (SKImageInfo info, SKData data, int rowBytes) if (data == null) throw new ArgumentNullException (nameof (data)); var cinfo = SKImageInfoNative.FromManaged (ref info); - return GetObject (SkiaApi.sk_image_new_raster_data (&cinfo, data.Handle, (IntPtr)rowBytes)); + return GetObject (SkiaApi.sk_image_new_raster_data (&cinfo, data.Handle, (IntPtr)rowBytes)); } public static SKImage FromPixels (SKImageInfo info, IntPtr pixels) @@ -158,7 +158,7 @@ public static SKImage FromPixels (SKPixmap pixmap, SKImageRasterReleaseDelegate ? new SKImageRasterReleaseDelegate ((addr, _) => releaseProc (addr, releaseContext)) : releaseProc; var proxy = DelegateProxies.Create (del, DelegateProxies.SKImageRasterReleaseDelegateProxy, out _, out var ctx); - return GetObject (SkiaApi.sk_image_new_raster (pixmap.Handle, proxy, (void*)ctx)); + return GetObject (SkiaApi.sk_image_new_raster (pixmap.Handle, proxy, (void*)ctx)); } // create a new image from encoded data @@ -169,7 +169,7 @@ public static SKImage FromEncodedData (SKData data, SKRectI subset) throw new ArgumentNullException (nameof (data)); var handle = SkiaApi.sk_image_new_from_encoded (data.Handle, &subset); - return GetObject (handle); + return GetObject (handle); } public static SKImage FromEncodedData (SKData data) @@ -178,7 +178,7 @@ public static SKImage FromEncodedData (SKData data) throw new ArgumentNullException (nameof (data)); var handle = SkiaApi.sk_image_new_from_encoded (data.Handle, null); - return GetObject (handle); + return GetObject (handle); } public static SKImage FromEncodedData (ReadOnlySpan data) @@ -249,7 +249,7 @@ public static SKImage FromBitmap (SKBitmap bitmap) throw new ArgumentNullException (nameof (bitmap)); var handle = SkiaApi.sk_image_new_from_bitmap (bitmap.Handle); - return GetObject (handle); + return GetObject (handle); } // create a new image from a GPU texture @@ -352,7 +352,7 @@ public static SKImage FromTexture (GRContext context, GRBackendTexture texture, ? new SKImageTextureReleaseDelegate ((_) => releaseProc (releaseContext)) : releaseProc; var proxy = DelegateProxies.Create (del, DelegateProxies.SKImageTextureReleaseDelegateProxy, out _, out var ctx); - return GetObject (SkiaApi.sk_image_new_from_texture (context.Handle, texture.Handle, origin, colorType, alpha, cs, proxy, (void*)ctx)); + return GetObject (SkiaApi.sk_image_new_from_texture (context.Handle, texture.Handle, origin, colorType, alpha, cs, proxy, (void*)ctx)); } [EditorBrowsable (EditorBrowsableState.Never)] @@ -408,7 +408,7 @@ public static SKImage FromAdoptedTexture (GRContext context, GRBackendTexture te throw new ArgumentNullException (nameof (texture)); var cs = colorspace == null ? IntPtr.Zero : colorspace.Handle; - return GetObject (SkiaApi.sk_image_new_from_adopted_texture (context.Handle, texture.Handle, origin, colorType, alpha, cs)); + return GetObject (SkiaApi.sk_image_new_from_adopted_texture (context.Handle, texture.Handle, origin, colorType, alpha, cs)); } // create a new image from a picture @@ -431,11 +431,11 @@ private static SKImage FromPicture (SKPicture picture, SKSizeI dimensions, SKMat throw new ArgumentNullException (nameof (picture)); var p = paint?.Handle ?? IntPtr.Zero; - return GetObject (SkiaApi.sk_image_new_from_picture (picture.Handle, &dimensions, matrix, p)); + return GetObject (SkiaApi.sk_image_new_from_picture (picture.Handle, &dimensions, matrix, p)); } public SKData Encode () => - GetObject (SkiaApi.sk_image_encode (Handle)); + SKData.GetObject (SkiaApi.sk_image_encode (Handle)); [EditorBrowsable (EditorBrowsableState.Never)] [Obsolete] @@ -480,7 +480,7 @@ public SKData Encode (SKPixelSerializer serializer) public SKData Encode (SKEncodedImageFormat format, int quality) { - return GetObject (SkiaApi.sk_image_encode_specific (Handle, format, quality)); + return SKData.GetObject (SkiaApi.sk_image_encode_specific (Handle, format, quality)); } public int Width => @@ -499,13 +499,13 @@ public SKData Encode (SKEncodedImageFormat format, int quality) SkiaApi.sk_image_get_color_type (Handle); public SKColorSpace ColorSpace => - GetObject (SkiaApi.sk_image_get_colorspace (Handle)); + SKColorSpace.GetObject (SkiaApi.sk_image_get_colorspace (Handle)); public bool IsAlphaOnly => SkiaApi.sk_image_is_alpha_only (Handle); public SKData EncodedData => - GetObject (SkiaApi.sk_image_ref_encoded (Handle)); + SKData.GetObject (SkiaApi.sk_image_ref_encoded (Handle)); // ToShader @@ -513,10 +513,10 @@ public SKShader ToShader () => ToShader (SKShaderTileMode.Clamp, SKShaderTileMode.Clamp); public SKShader ToShader (SKShaderTileMode tileX, SKShaderTileMode tileY) => - GetObject (SkiaApi.sk_image_make_shader (Handle, tileX, tileY, null)); + SKShader.GetObject (SkiaApi.sk_image_make_shader (Handle, tileX, tileY, null)); public SKShader ToShader (SKShaderTileMode tileX, SKShaderTileMode tileY, SKMatrix localMatrix) => - GetObject (SkiaApi.sk_image_make_shader (Handle, tileX, tileY, &localMatrix)); + SKShader.GetObject (SkiaApi.sk_image_make_shader (Handle, tileX, tileY, &localMatrix)); // PeekPixels @@ -595,7 +595,7 @@ public bool ScalePixels (SKPixmap dst, SKFilterQuality quality, SKImageCachingHi public SKImage Subset (SKRectI subset) { - return GetObject (SkiaApi.sk_image_make_subset (Handle, &subset)); + return GetObject (SkiaApi.sk_image_make_subset (Handle, &subset)); } // ToRasterImage @@ -605,8 +605,8 @@ public SKImage ToRasterImage () => public SKImage ToRasterImage (bool ensurePixelData) => ensurePixelData - ? GetObject (SkiaApi.sk_image_make_raster_image (Handle)) - : GetObject (SkiaApi.sk_image_make_non_texture_image (Handle)); + ? GetObject (SkiaApi.sk_image_make_raster_image (Handle)) + : GetObject (SkiaApi.sk_image_make_non_texture_image (Handle)); // ToTextureImage @@ -618,7 +618,7 @@ public SKImage ToTextureImage (GRContext context, SKColorSpace colorspace) if (context == null) throw new ArgumentNullException (nameof (context)); - return GetObject (SkiaApi.sk_image_make_texture_image (Handle, context.Handle, colorspace?.Handle ?? IntPtr.Zero)); + return GetObject (SkiaApi.sk_image_make_texture_image (Handle, context.Handle, colorspace?.Handle ?? IntPtr.Zero)); } // ApplyImageFilter @@ -637,8 +637,26 @@ public SKImage ApplyImageFilter (SKImageFilter filter, SKRectI subset, SKRectI c fixed (SKRectI* os = &outSubset) fixed (SKPointI* oo = &outOffset) { - return GetObject (SkiaApi.sk_image_make_with_filter (Handle, filter.Handle, &subset, &clipBounds, os, oo)); + return GetObject (SkiaApi.sk_image_make_with_filter (Handle, filter.Handle, &subset, &clipBounds, os, oo)); } } + + internal static SKImage GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKImage (ptr, owns); + } } } diff --git a/binding/Binding/SKImageFilter.cs b/binding/Binding/SKImageFilter.cs index 1d493f4cf6..7eeebf6c7a 100644 --- a/binding/Binding/SKImageFilter.cs +++ b/binding/Binding/SKImageFilter.cs @@ -21,7 +21,7 @@ protected override void Dispose (bool disposing) => public static SKImageFilter CreateMatrix(SKMatrix matrix, SKFilterQuality quality, SKImageFilter input = null) { - return GetObject(SkiaApi.sk_imagefilter_new_matrix(&matrix, quality, input == null ? IntPtr.Zero : input.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_matrix(&matrix, quality, input == null ? IntPtr.Zero : input.Handle)); } public static SKImageFilter CreateAlphaThreshold(SKRectI region, float innerThreshold, float outerThreshold, SKImageFilter input = null) @@ -36,19 +36,19 @@ public static SKImageFilter CreateAlphaThreshold(SKRegion region, float innerThr { if (region == null) throw new ArgumentNullException (nameof (region)); - return GetObject(SkiaApi.sk_imagefilter_new_alpha_threshold(region.Handle, innerThreshold, outerThreshold, input == null ? IntPtr.Zero : input.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_alpha_threshold(region.Handle, innerThreshold, outerThreshold, input == null ? IntPtr.Zero : input.Handle)); } public static SKImageFilter CreateBlur(float sigmaX, float sigmaY, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_blur(sigmaX, sigmaY, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_blur(sigmaX, sigmaY, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateColorFilter(SKColorFilter cf, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { if (cf == null) throw new ArgumentNullException(nameof(cf)); - return GetObject(SkiaApi.sk_imagefilter_new_color_filter(cf.Handle, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_color_filter(cf.Handle, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateCompose(SKImageFilter outer, SKImageFilter inner) @@ -57,54 +57,54 @@ public static SKImageFilter CreateCompose(SKImageFilter outer, SKImageFilter inn throw new ArgumentNullException(nameof(outer)); if (inner == null) throw new ArgumentNullException(nameof(inner)); - return GetObject(SkiaApi.sk_imagefilter_new_compose(outer.Handle, inner.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_compose(outer.Handle, inner.Handle)); } public static SKImageFilter CreateDisplacementMapEffect(SKDisplacementMapEffectChannelSelectorType xChannelSelector, SKDisplacementMapEffectChannelSelectorType yChannelSelector, float scale, SKImageFilter displacement, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { if (displacement == null) throw new ArgumentNullException(nameof(displacement)); - return GetObject(SkiaApi.sk_imagefilter_new_displacement_map_effect(xChannelSelector, yChannelSelector, scale, displacement.Handle, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_displacement_map_effect(xChannelSelector, yChannelSelector, scale, displacement.Handle, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateDropShadow(float dx, float dy, float sigmaX, float sigmaY, SKColor color, SKDropShadowImageFilterShadowMode shadowMode, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_drop_shadow(dx, dy, sigmaX, sigmaY, (uint)color, shadowMode, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_drop_shadow(dx, dy, sigmaX, sigmaY, (uint)color, shadowMode, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateDistantLitDiffuse(SKPoint3 direction, SKColor lightColor, float surfaceScale, float kd, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_distant_lit_diffuse(&direction, (uint)lightColor, surfaceScale, kd, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_distant_lit_diffuse(&direction, (uint)lightColor, surfaceScale, kd, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreatePointLitDiffuse(SKPoint3 location, SKColor lightColor, float surfaceScale, float kd, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_point_lit_diffuse(&location, (uint)lightColor, surfaceScale, kd, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_point_lit_diffuse(&location, (uint)lightColor, surfaceScale, kd, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateSpotLitDiffuse(SKPoint3 location, SKPoint3 target, float specularExponent, float cutoffAngle, SKColor lightColor, float surfaceScale, float kd, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_spot_lit_diffuse(&location, &target, specularExponent, cutoffAngle, (uint)lightColor, surfaceScale, kd, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_spot_lit_diffuse(&location, &target, specularExponent, cutoffAngle, (uint)lightColor, surfaceScale, kd, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateDistantLitSpecular(SKPoint3 direction, SKColor lightColor, float surfaceScale, float ks, float shininess, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_distant_lit_specular(&direction, (uint)lightColor, surfaceScale, ks, shininess, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_distant_lit_specular(&direction, (uint)lightColor, surfaceScale, ks, shininess, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreatePointLitSpecular(SKPoint3 location, SKColor lightColor, float surfaceScale, float ks, float shininess, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_point_lit_specular(&location, (uint)lightColor, surfaceScale, ks, shininess, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_point_lit_specular(&location, (uint)lightColor, surfaceScale, ks, shininess, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateSpotLitSpecular(SKPoint3 location, SKPoint3 target, float specularExponent, float cutoffAngle, SKColor lightColor, float surfaceScale, float ks, float shininess, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_spot_lit_specular(&location, &target, specularExponent, cutoffAngle, (uint)lightColor, surfaceScale, ks, shininess, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_spot_lit_specular(&location, &target, specularExponent, cutoffAngle, (uint)lightColor, surfaceScale, ks, shininess, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateMagnifier(SKRect src, float inset, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_magnifier(&src, inset, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_magnifier(&src, inset, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateMatrixConvolution(SKSizeI kernelSize, float[] kernel, float gain, float bias, SKPointI kernelOffset, SKMatrixConvolutionTileMode tileMode, bool convolveAlpha, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) @@ -114,7 +114,7 @@ public static SKImageFilter CreateMatrixConvolution(SKSizeI kernelSize, float[] if (kernel.Length != kernelSize.Width * kernelSize.Height) throw new ArgumentException("Kernel length must match the dimensions of the kernel size (Width * Height).", nameof(kernel)); fixed (float* k = kernel) { - return GetObject (SkiaApi.sk_imagefilter_new_matrix_convolution (&kernelSize, k, gain, bias, &kernelOffset, tileMode, convolveAlpha, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject (SkiaApi.sk_imagefilter_new_matrix_convolution (&kernelSize, k, gain, bias, &kernelOffset, tileMode, convolveAlpha, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } } @@ -147,79 +147,97 @@ public static SKImageFilter CreateMerge(SKImageFilter[] filters, SKImageFilter.C handles[i] = filters[i].Handle; } fixed (IntPtr* h = handles) { - return GetObject (SkiaApi.sk_imagefilter_new_merge (h, filters.Length, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject (SkiaApi.sk_imagefilter_new_merge (h, filters.Length, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } } public static SKImageFilter CreateDilate(int radiusX, int radiusY, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_dilate(radiusX, radiusY, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_dilate(radiusX, radiusY, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateErode(int radiusX, int radiusY, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_erode(radiusX, radiusY, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_erode(radiusX, radiusY, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateOffset(float dx, float dy, SKImageFilter input = null, SKImageFilter.CropRect cropRect = null) { - return GetObject(SkiaApi.sk_imagefilter_new_offset(dx, dy, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_offset(dx, dy, input == null ? IntPtr.Zero : input.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreatePicture(SKPicture picture) { if (picture == null) throw new ArgumentNullException(nameof(picture)); - return GetObject(SkiaApi.sk_imagefilter_new_picture(picture.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_picture(picture.Handle)); } public static SKImageFilter CreatePicture(SKPicture picture, SKRect cropRect) { if (picture == null) throw new ArgumentNullException(nameof(picture)); - return GetObject(SkiaApi.sk_imagefilter_new_picture_with_croprect(picture.Handle, &cropRect)); + return GetObject(SkiaApi.sk_imagefilter_new_picture_with_croprect(picture.Handle, &cropRect)); } public static SKImageFilter CreateTile(SKRect src, SKRect dst, SKImageFilter input) { if (input == null) throw new ArgumentNullException(nameof(input)); - return GetObject(SkiaApi.sk_imagefilter_new_tile(&src, &dst, input.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_tile(&src, &dst, input.Handle)); } public static SKImageFilter CreateBlendMode(SKBlendMode mode, SKImageFilter background, SKImageFilter foreground = null, SKImageFilter.CropRect cropRect = null) { if (background == null) throw new ArgumentNullException(nameof(background)); - return GetObject(SkiaApi.sk_imagefilter_new_xfermode(mode, background.Handle, foreground == null ? IntPtr.Zero : foreground.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_xfermode(mode, background.Handle, foreground == null ? IntPtr.Zero : foreground.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateArithmetic(float k1, float k2, float k3, float k4, bool enforcePMColor, SKImageFilter background, SKImageFilter foreground = null, SKImageFilter.CropRect cropRect = null) { if (background == null) throw new ArgumentNullException(nameof(background)); - return GetObject(SkiaApi.sk_imagefilter_new_arithmetic(k1, k2, k3, k4, enforcePMColor, background.Handle, foreground == null ? IntPtr.Zero : foreground.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_arithmetic(k1, k2, k3, k4, enforcePMColor, background.Handle, foreground == null ? IntPtr.Zero : foreground.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); } public static SKImageFilter CreateImage(SKImage image) { if (image == null) throw new ArgumentNullException(nameof(image)); - return GetObject(SkiaApi.sk_imagefilter_new_image_source_default(image.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_image_source_default(image.Handle)); } public static SKImageFilter CreateImage(SKImage image, SKRect src, SKRect dst, SKFilterQuality filterQuality) { if (image == null) throw new ArgumentNullException(nameof(image)); - return GetObject(SkiaApi.sk_imagefilter_new_image_source(image.Handle, &src, &dst, filterQuality)); + return GetObject(SkiaApi.sk_imagefilter_new_image_source(image.Handle, &src, &dst, filterQuality)); } public static SKImageFilter CreatePaint(SKPaint paint, SKImageFilter.CropRect cropRect = null) { if (paint == null) throw new ArgumentNullException(nameof(paint)); - return GetObject(SkiaApi.sk_imagefilter_new_paint(paint.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + return GetObject(SkiaApi.sk_imagefilter_new_paint(paint.Handle, cropRect == null ? IntPtr.Zero : cropRect.Handle)); + } + + internal static SKImageFilter GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKImageFilter (ptr, owns); } public class CropRect : SKObject diff --git a/binding/Binding/SKImageInfo.cs b/binding/Binding/SKImageInfo.cs index 1566468349..e7e1e21d4f 100644 --- a/binding/Binding/SKImageInfo.cs +++ b/binding/Binding/SKImageInfo.cs @@ -24,7 +24,7 @@ public static SKImageInfoNative FromManaged (ref SKImageInfo managed) => public static SKImageInfo ToManaged (ref SKImageInfoNative native) => new SKImageInfo { - ColorSpace = SKObject.GetObject (native.colorspace), + ColorSpace = SKColorSpace.GetObject (native.colorspace), Width = native.width, Height = native.height, ColorType = native.colorType, diff --git a/binding/Binding/SKMaskFilter.cs b/binding/Binding/SKMaskFilter.cs index d3e425587d..dd09d4006a 100644 --- a/binding/Binding/SKMaskFilter.cs +++ b/binding/Binding/SKMaskFilter.cs @@ -44,7 +44,7 @@ public static float ConvertSigmaToRadius (float sigma) public static SKMaskFilter CreateBlur (SKBlurStyle blurStyle, float sigma) { - return GetObject (SkiaApi.sk_maskfilter_new_blur (blurStyle, sigma)); + return SKMaskFilter.GetObject (SkiaApi.sk_maskfilter_new_blur (blurStyle, sigma)); } [EditorBrowsable (EditorBrowsableState.Never)] @@ -68,7 +68,7 @@ public static SKMaskFilter CreateBlur (SKBlurStyle blurStyle, float sigma, SKRec public static SKMaskFilter CreateBlur (SKBlurStyle blurStyle, float sigma, SKRect occluder, bool respectCTM) { - return GetObject (SkiaApi.sk_maskfilter_new_blur_with_flags (blurStyle, sigma, &occluder, respectCTM)); + return GetObject (SkiaApi.sk_maskfilter_new_blur_with_flags (blurStyle, sigma, &occluder, respectCTM)); } public static SKMaskFilter CreateTable (byte[] table) @@ -78,18 +78,36 @@ public static SKMaskFilter CreateTable (byte[] table) if (table.Length != TableMaxLength) throw new ArgumentException ("Table must have a length of {SKColorTable.MaxLength}.", nameof (table)); fixed (byte* t = table) { - return GetObject (SkiaApi.sk_maskfilter_new_table (t)); + return GetObject (SkiaApi.sk_maskfilter_new_table (t)); } } public static SKMaskFilter CreateGamma (float gamma) { - return GetObject (SkiaApi.sk_maskfilter_new_gamma (gamma)); + return GetObject (SkiaApi.sk_maskfilter_new_gamma (gamma)); } public static SKMaskFilter CreateClip (byte min, byte max) { - return GetObject (SkiaApi.sk_maskfilter_new_clip (min, max)); + return GetObject (SkiaApi.sk_maskfilter_new_clip (min, max)); + } + + internal static SKMaskFilter GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKMaskFilter (ptr, owns); } } } diff --git a/binding/Binding/SKMatrix44.cs b/binding/Binding/SKMatrix44.cs index 8d20494893..3f1fb8e194 100644 --- a/binding/Binding/SKMatrix44.cs +++ b/binding/Binding/SKMatrix44.cs @@ -415,5 +415,23 @@ public double Determinant () => public static implicit operator SKMatrix44 (SKMatrix matrix) => new SKMatrix44 (matrix); + + internal static SKMatrix44 GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKMatrix44 (ptr, owns); + } } } diff --git a/binding/Binding/SKObject.cs b/binding/Binding/SKObject.cs index 0cd55566d9..c8c101902d 100644 --- a/binding/Binding/SKObject.cs +++ b/binding/Binding/SKObject.cs @@ -66,12 +66,6 @@ protected override void DisposeNative () refcnt.SafeUnRef (); } - internal static TSkiaObject GetObject (IntPtr handle, bool owns = true, bool unrefExisting = true, bool refNew = false) - where TSkiaObject : SKObject - { - return GetObject (handle, owns, unrefExisting, refNew); - } - internal static TSkiaObject GetObject (IntPtr handle, bool owns = true, bool unrefExisting = true, bool refNew = false) where TSkiaObject : SKObject where TSkiaImplementation : SKObject, TSkiaObject @@ -223,14 +217,14 @@ internal void RevokeOwnership (SKObject newOwner) internal static int SizeOf () => #if WINDOWS_UWP || NET_STANDARD - Marshal.SizeOf (); + Marshal.SizeOf (); #else Marshal.SizeOf (typeof (T)); #endif internal static T PtrToStructure (IntPtr intPtr) => #if WINDOWS_UWP || NET_STANDARD - Marshal.PtrToStructure (intPtr); + Marshal.PtrToStructure (intPtr); #else (T)Marshal.PtrToStructure (intPtr, typeof (T)); #endif diff --git a/binding/Binding/SKPaint.cs b/binding/Binding/SKPaint.cs index 288ad16a72..3bc40927ce 100644 --- a/binding/Binding/SKPaint.cs +++ b/binding/Binding/SKPaint.cs @@ -120,22 +120,22 @@ public SKStrokeJoin StrokeJoin { } public SKShader Shader { - get => GetObject (SkiaApi.sk_paint_get_shader (Handle)); + get => SKShader.GetObject (SkiaApi.sk_paint_get_shader (Handle)); set => SkiaApi.sk_paint_set_shader (Handle, value == null ? IntPtr.Zero : value.Handle); } public SKMaskFilter MaskFilter { - get => GetObject (SkiaApi.sk_paint_get_maskfilter (Handle)); + get => SKMaskFilter.GetObject (SkiaApi.sk_paint_get_maskfilter (Handle)); set => SkiaApi.sk_paint_set_maskfilter (Handle, value == null ? IntPtr.Zero : value.Handle); } public SKColorFilter ColorFilter { - get => GetObject (SkiaApi.sk_paint_get_colorfilter (Handle)); + get => SKColorFilter.GetObject (SkiaApi.sk_paint_get_colorfilter (Handle)); set => SkiaApi.sk_paint_set_colorfilter (Handle, value == null ? IntPtr.Zero : value.Handle); } public SKImageFilter ImageFilter { - get => GetObject (SkiaApi.sk_paint_get_imagefilter (Handle)); + get => SKImageFilter.GetObject (SkiaApi.sk_paint_get_imagefilter (Handle)); set => SkiaApi.sk_paint_set_imagefilter (Handle, value == null ? IntPtr.Zero : value.Handle); } @@ -150,7 +150,7 @@ public SKFilterQuality FilterQuality { } public SKTypeface Typeface { - get => GetObject (SkiaApi.sk_paint_get_typeface (Handle)); + get => SKTypeface.GetObject (SkiaApi.sk_paint_get_typeface (Handle)); set => SkiaApi.sk_paint_set_typeface (Handle, value == null ? IntPtr.Zero : value.Handle); } @@ -180,7 +180,7 @@ public float TextSkewX { } public SKPathEffect PathEffect { - get => GetObject (SkiaApi.sk_paint_get_path_effect (Handle)); + get => SKPathEffect.GetObject (SkiaApi.sk_paint_get_path_effect (Handle)); set => SkiaApi.sk_paint_set_path_effect (Handle, value == null ? IntPtr.Zero : value.Handle); } @@ -202,7 +202,7 @@ public float GetFontMetrics (out SKFontMetrics metrics, float scale = 0f) } public SKPaint Clone () => - GetObject (SkiaApi.sk_paint_clone (Handle)); + GetObject (SkiaApi.sk_paint_clone (Handle)); // MeasureText @@ -356,7 +356,7 @@ public SKPath GetTextPath (IntPtr buffer, IntPtr length, float x, float y) if (buffer == IntPtr.Zero && length != IntPtr.Zero) throw new ArgumentNullException (nameof (buffer)); - return GetObject (SkiaApi.sk_paint_get_text_path (Handle, (void*)buffer, length, x, y)); + return SKPath.GetObject (SkiaApi.sk_paint_get_text_path (Handle, (void*)buffer, length, x, y)); } public SKPath GetTextPath (string text, SKPoint[] points) @@ -387,7 +387,7 @@ public SKPath GetTextPath (IntPtr buffer, IntPtr length, SKPoint[] points) throw new ArgumentNullException (nameof (buffer)); fixed (SKPoint* p = points) { - return GetObject (SkiaApi.sk_paint_get_pos_text_path (Handle, (void*)buffer, length, p)); + return SKPath.GetObject (SkiaApi.sk_paint_get_pos_text_path (Handle, (void*)buffer, length, p)); } } @@ -805,5 +805,23 @@ public float[] GetHorizontalTextIntercepts (IntPtr text, IntPtr length, float[] return intervals; } } + + internal static SKPaint GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKPaint (ptr, owns); + } } } diff --git a/binding/Binding/SKPath.cs b/binding/Binding/SKPath.cs index 40a629ae1e..b93986e066 100644 --- a/binding/Binding/SKPath.cs +++ b/binding/Binding/SKPath.cs @@ -472,6 +472,24 @@ public static int ConvertConicToQuads (SKPoint p0, SKPoint p1, SKPoint p2, float } } + internal static SKPath GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKPath (ptr, owns); + } + public class Iterator : SKObject { private readonly SKPath path; diff --git a/binding/Binding/SKPathEffect.cs b/binding/Binding/SKPathEffect.cs index b087b66371..717f9a09a9 100644 --- a/binding/Binding/SKPathEffect.cs +++ b/binding/Binding/SKPathEffect.cs @@ -19,7 +19,7 @@ public static SKPathEffect CreateCompose(SKPathEffect outer, SKPathEffect inner) throw new ArgumentNullException(nameof(outer)); if (inner == null) throw new ArgumentNullException(nameof(inner)); - return GetObject(SkiaApi.sk_path_effect_create_compose(outer.Handle, inner.Handle)); + return GetObject (SkiaApi.sk_path_effect_create_compose(outer.Handle, inner.Handle)); } public static SKPathEffect CreateSum(SKPathEffect first, SKPathEffect second) @@ -28,36 +28,36 @@ public static SKPathEffect CreateSum(SKPathEffect first, SKPathEffect second) throw new ArgumentNullException(nameof(first)); if (second == null) throw new ArgumentNullException(nameof(second)); - return GetObject(SkiaApi.sk_path_effect_create_sum(first.Handle, second.Handle)); + return GetObject (SkiaApi.sk_path_effect_create_sum(first.Handle, second.Handle)); } public static SKPathEffect CreateDiscrete(float segLength, float deviation, UInt32 seedAssist = 0) { - return GetObject(SkiaApi.sk_path_effect_create_discrete(segLength, deviation, seedAssist)); + return GetObject (SkiaApi.sk_path_effect_create_discrete(segLength, deviation, seedAssist)); } public static SKPathEffect CreateCorner(float radius) { - return GetObject(SkiaApi.sk_path_effect_create_corner(radius)); + return GetObject (SkiaApi.sk_path_effect_create_corner(radius)); } public static SKPathEffect Create1DPath(SKPath path, float advance, float phase, SKPath1DPathEffectStyle style) { if (path == null) throw new ArgumentNullException(nameof(path)); - return GetObject(SkiaApi.sk_path_effect_create_1d_path(path.Handle, advance, phase, style)); + return GetObject (SkiaApi.sk_path_effect_create_1d_path(path.Handle, advance, phase, style)); } public static SKPathEffect Create2DLine(float width, SKMatrix matrix) { - return GetObject(SkiaApi.sk_path_effect_create_2d_line(width, &matrix)); + return GetObject (SkiaApi.sk_path_effect_create_2d_line(width, &matrix)); } public static SKPathEffect Create2DPath(SKMatrix matrix, SKPath path) { if (path == null) throw new ArgumentNullException(nameof(path)); - return GetObject(SkiaApi.sk_path_effect_create_2d_path(&matrix, path.Handle)); + return GetObject (SkiaApi.sk_path_effect_create_2d_path(&matrix, path.Handle)); } public static SKPathEffect CreateDash(float[] intervals, float phase) @@ -67,7 +67,7 @@ public static SKPathEffect CreateDash(float[] intervals, float phase) if (intervals.Length % 2 != 0) throw new ArgumentException("The intervals must have an even number of entries.", nameof(intervals)); fixed (float* i = intervals) { - return GetObject (SkiaApi.sk_path_effect_create_dash (i, intervals.Length, phase)); + return GetObject (SkiaApi.sk_path_effect_create_dash (i, intervals.Length, phase)); } } @@ -78,7 +78,25 @@ public static SKPathEffect CreateTrim(float start, float stop) public static SKPathEffect CreateTrim(float start, float stop, SKTrimPathEffectMode mode) { - return GetObject(SkiaApi.sk_path_effect_create_trim(start, stop, mode)); + return GetObject (SkiaApi.sk_path_effect_create_trim(start, stop, mode)); + } + + internal static SKPathEffect GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKPathEffect (ptr, owns); } } } diff --git a/binding/Binding/SKPicture.cs b/binding/Binding/SKPicture.cs index 17bd0c0ed4..6560aec3ec 100644 --- a/binding/Binding/SKPicture.cs +++ b/binding/Binding/SKPicture.cs @@ -37,5 +37,23 @@ public SKShader ToShader (SKShaderTileMode tmx, SKShaderTileMode tmy, SKRect til public SKShader ToShader (SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix, SKRect tile) => SKShader.CreatePicture (this, tmx, tmy, localMatrix, tile); + + internal static SKPicture GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKPicture (ptr, owns); + } } } diff --git a/binding/Binding/SKPictureRecorder.cs b/binding/Binding/SKPictureRecorder.cs index f2f3662633..a810ca2908 100644 --- a/binding/Binding/SKPictureRecorder.cs +++ b/binding/Binding/SKPictureRecorder.cs @@ -26,19 +26,19 @@ protected override void DisposeNative () => public SKCanvas BeginRecording (SKRect cullRect) { - return GetObject (SkiaApi.sk_picture_recorder_begin_recording (Handle, &cullRect), false); + return SKCanvas.GetObject (SkiaApi.sk_picture_recorder_begin_recording (Handle, &cullRect), false); } public SKPicture EndRecording () { - return GetObject (SkiaApi.sk_picture_recorder_end_recording (Handle)); + return SKPicture.GetObject (SkiaApi.sk_picture_recorder_end_recording (Handle)); } public SKDrawable EndRecordingAsDrawable () { - return GetObject (SkiaApi.sk_picture_recorder_end_recording_as_drawable (Handle)); + return SKDrawable.GetObject (SkiaApi.sk_picture_recorder_end_recording_as_drawable (Handle)); } - public SKCanvas RecordingCanvas => GetObject (SkiaApi.sk_picture_get_recording_canvas (Handle), false); + public SKCanvas RecordingCanvas => SKCanvas.GetObject (SkiaApi.sk_picture_get_recording_canvas (Handle), false); } } diff --git a/binding/Binding/SKSVG.cs b/binding/Binding/SKSVG.cs index 746edb03d1..d89c32287b 100644 --- a/binding/Binding/SKSVG.cs +++ b/binding/Binding/SKSVG.cs @@ -14,7 +14,7 @@ public static SKCanvas Create (SKRect bounds, SKXmlWriter writer) throw new ArgumentNullException (nameof (writer)); } - return SKObject.GetObject (SkiaApi.sk_svgcanvas_create (&bounds, writer.Handle)); + return SKCanvas.GetObject (SkiaApi.sk_svgcanvas_create (&bounds, writer.Handle)); } } } diff --git a/binding/Binding/SKShader.cs b/binding/Binding/SKShader.cs index 0df58c0af7..e0de19953b 100644 --- a/binding/Binding/SKShader.cs +++ b/binding/Binding/SKShader.cs @@ -20,30 +20,30 @@ public SKShader WithColorFilter (SKColorFilter filter) if (filter == null) throw new ArgumentNullException (nameof (filter)); - return GetObject (SkiaApi.sk_shader_with_color_filter (Handle, filter.Handle)); + return GetObject (SkiaApi.sk_shader_with_color_filter (Handle, filter.Handle)); } // WithLocalMatrix public SKShader WithLocalMatrix (SKMatrix localMatrix) => - GetObject (SkiaApi.sk_shader_with_local_matrix (Handle, &localMatrix)); + GetObject (SkiaApi.sk_shader_with_local_matrix (Handle, &localMatrix)); // CreateEmpty public static SKShader CreateEmpty () => - GetObject (SkiaApi.sk_shader_new_empty ()); + GetObject (SkiaApi.sk_shader_new_empty ()); // CreateColor public static SKShader CreateColor (SKColor color) => - GetObject (SkiaApi.sk_shader_new_color ((uint)color)); + GetObject (SkiaApi.sk_shader_new_color ((uint)color)); public static SKShader CreateColor (SKColorF color, SKColorSpace colorspace) { if (colorspace == null) throw new ArgumentNullException (nameof (colorspace)); - return GetObject (SkiaApi.sk_shader_new_color4f (&color, colorspace.Handle)); + return GetObject (SkiaApi.sk_shader_new_color4f (&color, colorspace.Handle)); } // CreateBitmap @@ -56,7 +56,7 @@ public static SKShader CreateBitmap (SKBitmap src, SKShaderTileMode tmx, SKShade if (src == null) throw new ArgumentNullException (nameof (src)); - return GetObject (SkiaApi.sk_shader_new_bitmap (src.Handle, tmx, tmy, null)); + return GetObject (SkiaApi.sk_shader_new_bitmap (src.Handle, tmx, tmy, null)); } public static SKShader CreateBitmap (SKBitmap src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix) @@ -64,7 +64,7 @@ public static SKShader CreateBitmap (SKBitmap src, SKShaderTileMode tmx, SKShade if (src == null) throw new ArgumentNullException (nameof (src)); - return GetObject (SkiaApi.sk_shader_new_bitmap (src.Handle, tmx, tmy, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_bitmap (src.Handle, tmx, tmy, &localMatrix)); } // CreateImage @@ -98,7 +98,7 @@ public static SKShader CreatePicture (SKPicture src, SKShaderTileMode tmx, SKSha if (src == null) throw new ArgumentNullException (nameof (src)); - return GetObject (SkiaApi.sk_shader_new_picture (src.Handle, tmx, tmy, null, null)); + return GetObject (SkiaApi.sk_shader_new_picture (src.Handle, tmx, tmy, null, null)); } public static SKShader CreatePicture (SKPicture src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKRect tile) @@ -106,7 +106,7 @@ public static SKShader CreatePicture (SKPicture src, SKShaderTileMode tmx, SKSha if (src == null) throw new ArgumentNullException (nameof (src)); - return GetObject (SkiaApi.sk_shader_new_picture (src.Handle, tmx, tmy, null, &tile)); + return GetObject (SkiaApi.sk_shader_new_picture (src.Handle, tmx, tmy, null, &tile)); } public static SKShader CreatePicture (SKPicture src, SKShaderTileMode tmx, SKShaderTileMode tmy, SKMatrix localMatrix, SKRect tile) @@ -114,7 +114,7 @@ public static SKShader CreatePicture (SKPicture src, SKShaderTileMode tmx, SKSha if (src == null) throw new ArgumentNullException (nameof (src)); - return GetObject (SkiaApi.sk_shader_new_picture (src.Handle, tmx, tmy, &localMatrix, &tile)); + return GetObject (SkiaApi.sk_shader_new_picture (src.Handle, tmx, tmy, &localMatrix, &tile)); } // CreateLinearGradient @@ -132,7 +132,7 @@ public static SKShader CreateLinearGradient (SKPoint start, SKPoint end, SKColor var points = stackalloc SKPoint[] { start, end }; fixed (SKColor* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_linear_gradient (points, (uint*)c, cp, colors.Length, mode, null)); + return GetObject (SkiaApi.sk_shader_new_linear_gradient (points, (uint*)c, cp, colors.Length, mode, null)); } } @@ -146,7 +146,7 @@ public static SKShader CreateLinearGradient (SKPoint start, SKPoint end, SKColor var points = stackalloc SKPoint[] { start, end }; fixed (SKColor* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_linear_gradient (points, (uint*)c, cp, colors.Length, mode, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_linear_gradient (points, (uint*)c, cp, colors.Length, mode, &localMatrix)); } } @@ -163,7 +163,7 @@ public static SKShader CreateLinearGradient (SKPoint start, SKPoint end, SKColor var points = stackalloc SKPoint[] { start, end }; fixed (SKColorF* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_linear_gradient_color4f (points, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, null)); + return GetObject (SkiaApi.sk_shader_new_linear_gradient_color4f (points, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, null)); } } @@ -177,7 +177,7 @@ public static SKShader CreateLinearGradient (SKPoint start, SKPoint end, SKColor var points = stackalloc SKPoint[] { start, end }; fixed (SKColorF* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_linear_gradient_color4f (points, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_linear_gradient_color4f (points, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, &localMatrix)); } } @@ -195,7 +195,7 @@ public static SKShader CreateRadialGradient (SKPoint center, float radius, SKCol fixed (SKColor* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_radial_gradient (¢er, radius, (uint*)c, cp, colors.Length, mode, null)); + return GetObject (SkiaApi.sk_shader_new_radial_gradient (¢er, radius, (uint*)c, cp, colors.Length, mode, null)); } } @@ -208,7 +208,7 @@ public static SKShader CreateRadialGradient (SKPoint center, float radius, SKCol fixed (SKColor* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_radial_gradient (¢er, radius, (uint*)c, cp, colors.Length, mode, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_radial_gradient (¢er, radius, (uint*)c, cp, colors.Length, mode, &localMatrix)); } } @@ -224,7 +224,7 @@ public static SKShader CreateRadialGradient (SKPoint center, float radius, SKCol fixed (SKColorF* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_radial_gradient_color4f (¢er, radius, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, null)); + return GetObject (SkiaApi.sk_shader_new_radial_gradient_color4f (¢er, radius, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, null)); } } @@ -237,7 +237,7 @@ public static SKShader CreateRadialGradient (SKPoint center, float radius, SKCol fixed (SKColorF* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_radial_gradient_color4f (¢er, radius, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_radial_gradient_color4f (¢er, radius, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, &localMatrix)); } } @@ -264,7 +264,7 @@ public static SKShader CreateSweepGradient (SKPoint center, SKColor[] colors, fl fixed (SKColor* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_sweep_gradient (¢er, (uint*)c, cp, colors.Length, tileMode, startAngle, endAngle, null)); + return GetObject (SkiaApi.sk_shader_new_sweep_gradient (¢er, (uint*)c, cp, colors.Length, tileMode, startAngle, endAngle, null)); } } @@ -277,7 +277,7 @@ public static SKShader CreateSweepGradient (SKPoint center, SKColor[] colors, fl fixed (SKColor* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_sweep_gradient (¢er, (uint*)c, cp, colors.Length, tileMode, startAngle, endAngle, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_sweep_gradient (¢er, (uint*)c, cp, colors.Length, tileMode, startAngle, endAngle, &localMatrix)); } } @@ -302,7 +302,7 @@ public static SKShader CreateSweepGradient (SKPoint center, SKColorF[] colors, S fixed (SKColorF* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_sweep_gradient_color4f (¢er, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, tileMode, startAngle, endAngle, null)); + return GetObject (SkiaApi.sk_shader_new_sweep_gradient_color4f (¢er, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, tileMode, startAngle, endAngle, null)); } } @@ -315,7 +315,7 @@ public static SKShader CreateSweepGradient (SKPoint center, SKColorF[] colors, S fixed (SKColorF* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_sweep_gradient_color4f (¢er, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, tileMode, startAngle, endAngle, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_sweep_gradient_color4f (¢er, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, tileMode, startAngle, endAngle, &localMatrix)); } } @@ -333,7 +333,7 @@ public static SKShader CreateTwoPointConicalGradient (SKPoint start, float start fixed (SKColor* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_two_point_conical_gradient (&start, startRadius, &end, endRadius, (uint*)c, cp, colors.Length, mode, null)); + return GetObject (SkiaApi.sk_shader_new_two_point_conical_gradient (&start, startRadius, &end, endRadius, (uint*)c, cp, colors.Length, mode, null)); } } @@ -346,7 +346,7 @@ public static SKShader CreateTwoPointConicalGradient (SKPoint start, float start fixed (SKColor* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_two_point_conical_gradient (&start, startRadius, &end, endRadius, (uint*)c, cp, colors.Length, mode, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_two_point_conical_gradient (&start, startRadius, &end, endRadius, (uint*)c, cp, colors.Length, mode, &localMatrix)); } } @@ -362,7 +362,7 @@ public static SKShader CreateTwoPointConicalGradient (SKPoint start, float start fixed (SKColorF* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_two_point_conical_gradient_color4f (&start, startRadius, &end, endRadius, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, null)); + return GetObject (SkiaApi.sk_shader_new_two_point_conical_gradient_color4f (&start, startRadius, &end, endRadius, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, null)); } } @@ -375,36 +375,36 @@ public static SKShader CreateTwoPointConicalGradient (SKPoint start, float start fixed (SKColorF* c = colors) fixed (float* cp = colorPos) { - return GetObject (SkiaApi.sk_shader_new_two_point_conical_gradient_color4f (&start, startRadius, &end, endRadius, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, &localMatrix)); + return GetObject (SkiaApi.sk_shader_new_two_point_conical_gradient_color4f (&start, startRadius, &end, endRadius, c, colorspace?.Handle ?? IntPtr.Zero, cp, colors.Length, mode, &localMatrix)); } } // CreatePerlinNoiseFractalNoise public static SKShader CreatePerlinNoiseFractalNoise (float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed) => - GetObject (SkiaApi.sk_shader_new_perlin_noise_fractal_noise (baseFrequencyX, baseFrequencyY, numOctaves, seed, null)); + GetObject (SkiaApi.sk_shader_new_perlin_noise_fractal_noise (baseFrequencyX, baseFrequencyY, numOctaves, seed, null)); public static SKShader CreatePerlinNoiseFractalNoise (float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKPointI tileSize) => CreatePerlinNoiseFractalNoise (baseFrequencyX, baseFrequencyY, numOctaves, seed, (SKSizeI)tileSize); public static SKShader CreatePerlinNoiseFractalNoise (float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKSizeI tileSize) => - GetObject (SkiaApi.sk_shader_new_perlin_noise_fractal_noise (baseFrequencyX, baseFrequencyY, numOctaves, seed, &tileSize)); + GetObject (SkiaApi.sk_shader_new_perlin_noise_fractal_noise (baseFrequencyX, baseFrequencyY, numOctaves, seed, &tileSize)); // CreatePerlinNoiseImprovedNoise public static SKShader CreatePerlinNoiseImprovedNoise (float baseFrequencyX, float baseFrequencyY, int numOctaves, float z) => - GetObject (SkiaApi.sk_shader_new_perlin_noise_improved_noise (baseFrequencyX, baseFrequencyY, numOctaves, z)); + GetObject (SkiaApi.sk_shader_new_perlin_noise_improved_noise (baseFrequencyX, baseFrequencyY, numOctaves, z)); // CreatePerlinNoiseTurbulence public static SKShader CreatePerlinNoiseTurbulence (float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed) => - GetObject (SkiaApi.sk_shader_new_perlin_noise_turbulence (baseFrequencyX, baseFrequencyY, numOctaves, seed, null)); + GetObject (SkiaApi.sk_shader_new_perlin_noise_turbulence (baseFrequencyX, baseFrequencyY, numOctaves, seed, null)); public static SKShader CreatePerlinNoiseTurbulence (float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKPointI tileSize) => CreatePerlinNoiseTurbulence (baseFrequencyX, baseFrequencyY, numOctaves, seed, (SKSizeI)tileSize); public static SKShader CreatePerlinNoiseTurbulence (float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, SKSizeI tileSize) => - GetObject (SkiaApi.sk_shader_new_perlin_noise_turbulence (baseFrequencyX, baseFrequencyY, numOctaves, seed, &tileSize)); + GetObject (SkiaApi.sk_shader_new_perlin_noise_turbulence (baseFrequencyX, baseFrequencyY, numOctaves, seed, &tileSize)); // CreateCompose @@ -418,7 +418,7 @@ public static SKShader CreateCompose (SKShader shaderA, SKShader shaderB, SKBlen if (shaderB == null) throw new ArgumentNullException (nameof (shaderB)); - return GetObject (SkiaApi.sk_shader_new_compose (shaderA.Handle, shaderB.Handle, mode)); + return GetObject (SkiaApi.sk_shader_new_compose (shaderA.Handle, shaderB.Handle, mode)); } // CreateColorFilter @@ -442,5 +442,22 @@ public static SKShader CreateLocalMatrix (SKShader shader, SKMatrix localMatrix) return shader.WithLocalMatrix (localMatrix); } + internal static SKShader GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKShader (ptr, owns); + } } } diff --git a/binding/Binding/SKStream.cs b/binding/Binding/SKStream.cs index 0e61031dec..06ce97d076 100644 --- a/binding/Binding/SKStream.cs +++ b/binding/Binding/SKStream.cs @@ -245,6 +245,24 @@ protected override void Dispose (bool disposing) => protected override void DisposeNative () => SkiaApi.sk_stream_asset_destroy (Handle); + + internal static SKStreamAssetImplementation GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKStreamAssetImplementation (ptr, owns); + } } public abstract class SKStreamMemory : SKStreamAsset @@ -545,7 +563,7 @@ public SKStreamAsset DetachAsStream () public SKData DetachAsData () { - return GetObject (SkiaApi.sk_dynamicmemorywstream_detach_as_data (Handle)); + return SKData.GetObject (SkiaApi.sk_dynamicmemorywstream_detach_as_data (Handle)); } public void CopyTo (IntPtr data) diff --git a/binding/Binding/SKString.cs b/binding/Binding/SKString.cs index 8f819e7d58..1b6340623f 100644 --- a/binding/Binding/SKString.cs +++ b/binding/Binding/SKString.cs @@ -69,6 +69,24 @@ protected override void Dispose (bool disposing) => protected override void DisposeNative () => SkiaApi.sk_string_destructor (Handle); + + internal static SKString GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKString (ptr, owns); + } } } diff --git a/binding/Binding/SKSurface.cs b/binding/Binding/SKSurface.cs index bc5682a091..c93d085f8d 100644 --- a/binding/Binding/SKSurface.cs +++ b/binding/Binding/SKSurface.cs @@ -46,7 +46,7 @@ public static SKSurface Create (SKImageInfo info, SKSurfaceProperties props) => public static SKSurface Create (SKImageInfo info, int rowBytes, SKSurfaceProperties props) { var cinfo = SKImageInfoNative.FromManaged (ref info); - return GetObject (SkiaApi.sk_surface_new_raster (&cinfo, (IntPtr)rowBytes, props?.Handle ?? IntPtr.Zero)); + return GetObject (SkiaApi.sk_surface_new_raster (&cinfo, (IntPtr)rowBytes, props?.Handle ?? IntPtr.Zero)); } // convenience RASTER DIRECT to use a SKPixmap instead of SKImageInfo and IntPtr @@ -96,7 +96,7 @@ public static SKSurface Create (SKImageInfo info, IntPtr pixels, int rowBytes, S ? new SKSurfaceReleaseDelegate ((addr, _) => releaseProc (addr, context)) : releaseProc; var proxy = DelegateProxies.Create (del, DelegateProxies.SKSurfaceReleaseDelegateProxy, out _, out var ctx); - return GetObject (SkiaApi.sk_surface_new_raster_direct (&cinfo, (void*)pixels, (IntPtr)rowBytes, proxy, (void*)ctx, props?.Handle ?? IntPtr.Zero)); + return GetObject (SkiaApi.sk_surface_new_raster_direct (&cinfo, (void*)pixels, (IntPtr)rowBytes, proxy, (void*)ctx, props?.Handle ?? IntPtr.Zero)); } // GPU BACKEND RENDER TARGET surface @@ -145,7 +145,7 @@ public static SKSurface Create (GRContext context, GRBackendRenderTarget renderT if (renderTarget == null) throw new ArgumentNullException (nameof (renderTarget)); - return GetObject (SkiaApi.sk_surface_new_backend_render_target (context.Handle, renderTarget.Handle, origin, colorType, colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero)); + return GetObject (SkiaApi.sk_surface_new_backend_render_target (context.Handle, renderTarget.Handle, origin, colorType, colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero)); } // GPU BACKEND TEXTURE surface @@ -198,7 +198,7 @@ public static SKSurface Create (GRContext context, GRBackendTexture texture, GRS if (texture == null) throw new ArgumentNullException (nameof (texture)); - return GetObject (SkiaApi.sk_surface_new_backend_texture (context.Handle, texture.Handle, origin, sampleCount, colorType, colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero)); + return GetObject (SkiaApi.sk_surface_new_backend_texture (context.Handle, texture.Handle, origin, sampleCount, colorType, colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero)); } // GPU BACKEND TEXTURE AS RENDER TARGET surface @@ -251,7 +251,7 @@ public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTextur if (texture == null) throw new ArgumentNullException (nameof (texture)); - return GetObject (SkiaApi.sk_surface_new_backend_texture_as_render_target (context.Handle, texture.Handle, origin, sampleCount, colorType, colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero)); + return GetObject (SkiaApi.sk_surface_new_backend_texture_as_render_target (context.Handle, texture.Handle, origin, sampleCount, colorType, colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero)); } // GPU NEW surface @@ -282,18 +282,18 @@ public static SKSurface Create (GRContext context, bool budgeted, SKImageInfo in throw new ArgumentNullException (nameof (context)); var cinfo = SKImageInfoNative.FromManaged (ref info); - return GetObject (SkiaApi.sk_surface_new_render_target (context.Handle, budgeted, &cinfo, sampleCount, origin, props?.Handle ?? IntPtr.Zero, shouldCreateWithMips)); + return GetObject (SkiaApi.sk_surface_new_render_target (context.Handle, budgeted, &cinfo, sampleCount, origin, props?.Handle ?? IntPtr.Zero, shouldCreateWithMips)); } // NULL surface public static SKSurface CreateNull (int width, int height) => - GetObject (SkiaApi.sk_surface_new_null (width, height)); + GetObject (SkiaApi.sk_surface_new_null (width, height)); // public SKCanvas Canvas => - GetObject (SkiaApi.sk_surface_get_canvas (Handle), false); + SKCanvas.GetObject (SkiaApi.sk_surface_get_canvas (Handle), false); [EditorBrowsable (EditorBrowsableState.Never)] [Obsolete ("Use SurfaceProperties instead.")] @@ -308,10 +308,10 @@ public SKSurfaceProps SurfaceProps { } public SKSurfaceProperties SurfaceProperties => - GetObject (SkiaApi.sk_surface_get_props (Handle), false); + SKSurfaceProperties.GetObject (SkiaApi.sk_surface_get_props (Handle), false); public SKImage Snapshot () => - GetObject (SkiaApi.sk_surface_new_image_snapshot (Handle)); + SKImage.GetObject (SkiaApi.sk_surface_new_image_snapshot (Handle)); public void Draw (SKCanvas canvas, float x, float y, SKPaint paint) { @@ -346,5 +346,23 @@ public bool ReadPixels (SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, var cinfo = SKImageInfoNative.FromManaged (ref dstInfo); return SkiaApi.sk_surface_read_pixels (Handle, &cinfo, (void*)dstPixels, (IntPtr)dstRowBytes, srcX, srcY); } + + internal static SKSurface GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKSurface (ptr, owns); + } } } diff --git a/binding/Binding/SKSurfaceProperties.cs b/binding/Binding/SKSurfaceProperties.cs index 6ec25cf057..fab6f0d059 100644 --- a/binding/Binding/SKSurfaceProperties.cs +++ b/binding/Binding/SKSurfaceProperties.cs @@ -47,5 +47,23 @@ protected override void DisposeNative () => public bool IsUseDeviceIndependentFonts => Flags.HasFlag (SKSurfacePropsFlags.UseDeviceIndependentFonts); + + internal static SKSurfaceProperties GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKSurfaceProperties (ptr, owns); + } } } diff --git a/binding/Binding/SKTextBlob.cs b/binding/Binding/SKTextBlob.cs index adbbcb09c0..00f332eaac 100644 --- a/binding/Binding/SKTextBlob.cs +++ b/binding/Binding/SKTextBlob.cs @@ -26,6 +26,23 @@ public SKRect Bounds { } public uint UniqueId => SkiaApi.sk_textblob_get_unique_id (Handle); + internal static SKTextBlob GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKTextBlob(ptr, owns); + } } public unsafe class SKTextBlobBuilder : SKObject @@ -50,7 +67,7 @@ protected override void DisposeNative () => // Build public SKTextBlob Build () => - GetObject (SkiaApi.sk_textblob_builder_make (Handle)); + SKTextBlob.GetObject (SkiaApi.sk_textblob_builder_make (Handle)); // AddRun diff --git a/binding/Binding/SKTypeface.cs b/binding/Binding/SKTypeface.cs index 0eb8b883ce..c973781487 100644 --- a/binding/Binding/SKTypeface.cs +++ b/binding/Binding/SKTypeface.cs @@ -43,7 +43,7 @@ protected override void Dispose (bool disposing) => public static SKTypeface CreateDefault () { - return GetObject (SkiaApi.sk_typeface_create_default ()); + return GetObject (SkiaApi.sk_typeface_create_default ()); } [EditorBrowsable (EditorBrowsableState.Never)] @@ -71,7 +71,7 @@ public static SKTypeface FromFamilyName (string familyName, SKFontStyle style) if (style == null) throw new ArgumentNullException (nameof (style)); - return GetObject (SkiaApi.sk_typeface_create_from_name_with_font_style (familyName, style.Handle)); + return GetObject (SkiaApi.sk_typeface_create_from_name_with_font_style (familyName, style.Handle)); } public static SKTypeface FromFamilyName (string familyName, SKFontStyleWeight weight, SKFontStyleWidth width, SKFontStyleSlant slant) @@ -100,7 +100,7 @@ public static SKTypeface FromFile (string path, int index = 0) var utf8path = StringUtilities.GetEncodedText (path, SKEncoding.Utf8); fixed (byte* u = utf8path) { - return GetObject (SkiaApi.sk_typeface_create_from_file (u, index)); + return GetObject (SkiaApi.sk_typeface_create_from_file (u, index)); } } @@ -122,7 +122,7 @@ public static SKTypeface FromStream (SKStreamAsset stream, int index = 0) managed.Dispose (); } - var typeface = GetObject (SkiaApi.sk_typeface_create_from_stream (stream.Handle, index)); + var typeface = GetObject (SkiaApi.sk_typeface_create_from_stream (stream.Handle, index)); stream.RevokeOwnership (typeface); return typeface; } @@ -142,9 +142,9 @@ public int CharsToGlyphs (string chars, out ushort[] glyphs) public int CharsToGlyphs (IntPtr str, int strlen, SKEncoding encoding, out ushort[] glyphs) => GetGlyphs (str, strlen, encoding, out glyphs); - public string FamilyName => (string)GetObject (SkiaApi.sk_typeface_get_family_name (Handle)); + public string FamilyName => (string)SKString.GetObject (SkiaApi.sk_typeface_get_family_name (Handle)); - public SKFontStyle FontStyle => GetObject (SkiaApi.sk_typeface_get_fontstyle (Handle)); + public SKFontStyle FontStyle => SKFontStyle.GetObject (SkiaApi.sk_typeface_get_fontstyle (Handle)); public int FontWeight => SkiaApi.sk_typeface_get_font_weight (Handle); @@ -330,10 +330,28 @@ public SKStreamAsset OpenStream () => public SKStreamAsset OpenStream (out int ttcIndex) { fixed (int* ttc = &ttcIndex) { - return GetObject (SkiaApi.sk_typeface_open_stream (Handle, ttc)); + return SKStreamAssetImplementation.GetObject (SkiaApi.sk_typeface_open_stream (Handle, ttc)); } } + internal static SKTypeface GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKTypeface (ptr, owns); + } + private sealed class SKTypefaceStatic : SKTypeface { internal SKTypefaceStatic (IntPtr x) diff --git a/binding/Binding/SKVertices.cs b/binding/Binding/SKVertices.cs index 7d73aecc22..e98f322ab3 100644 --- a/binding/Binding/SKVertices.cs +++ b/binding/Binding/SKVertices.cs @@ -48,8 +48,26 @@ public static SKVertices CreateCopy (SKVertexMode vmode, SKPoint[] positions, SK fixed (SKPoint* t = texs) fixed (SKColor* c = colors) fixed (UInt16* i = indices) { - return GetObject (SkiaApi.sk_vertices_make_copy (vmode, vertexCount, p, t, (uint*)c, indexCount, i)); + return GetObject (SkiaApi.sk_vertices_make_copy (vmode, vertexCount, p, t, (uint*)c, indexCount, i)); } } + + internal static SKVertices GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKVertices (ptr, owns); + } } } From 64cfa4bb6d1ed30e7d55eed18ad57f95ea595a80 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Fri, 27 Mar 2020 13:13:01 +0100 Subject: [PATCH 2/3] Merge --- binding/Binding/SKData.cs | 38 ++++++++++++++++++++++++++--------- binding/Binding/SKTypeface.cs | 2 ++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/binding/Binding/SKData.cs b/binding/Binding/SKData.cs index 422de86d64..2f658010fa 100644 --- a/binding/Binding/SKData.cs +++ b/binding/Binding/SKData.cs @@ -48,7 +48,7 @@ public static SKData CreateCopy (IntPtr bytes, ulong length) { if (SizeOf () == 4 && length > UInt32.MaxValue) throw new ArgumentOutOfRangeException (nameof (length), "The length exceeds the size of pointers."); - return GetObject (SkiaApi.sk_data_new_with_copy ((void*)bytes, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_with_copy ((void*)bytes, (IntPtr) length)); } public static SKData CreateCopy (byte[] bytes) => @@ -57,7 +57,7 @@ public static SKData CreateCopy (byte[] bytes) => public static SKData CreateCopy (byte[] bytes, ulong length) { fixed (byte* b = bytes) { - return GetObject (SkiaApi.sk_data_new_with_copy (b, (IntPtr)length)); + return GetObject (SkiaApi.sk_data_new_with_copy (b, (IntPtr)length)); } } @@ -72,7 +72,7 @@ public static SKData CreateCopy (ReadOnlySpan bytes) public static SKData Create (int size) { - return GetObject (SkiaApi.sk_data_new_uninitialized ((IntPtr) size)); + return GetObject (SkiaApi.sk_data_new_uninitialized ((IntPtr) size)); } public static SKData Create (ulong size) @@ -80,7 +80,7 @@ public static SKData Create (ulong size) if (SizeOf () == 4 && size > UInt32.MaxValue) throw new ArgumentOutOfRangeException (nameof (size), "The size exceeds the size of pointers."); - return GetObject (SkiaApi.sk_data_new_uninitialized ((IntPtr) size)); + return GetObject (SkiaApi.sk_data_new_uninitialized ((IntPtr) size)); } public static SKData Create (string filename) @@ -90,7 +90,7 @@ public static SKData Create (string filename) var utf8path = StringUtilities.GetEncodedText (filename, SKTextEncoding.Utf8); fixed (byte* u = utf8path) { - return GetObject (SkiaApi.sk_data_new_from_file (u)); + return GetObject (SkiaApi.sk_data_new_from_file (u)); } } @@ -141,7 +141,7 @@ public static SKData Create (SKStream stream, int length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); } public static SKData Create (SKStream stream, ulong length) @@ -149,7 +149,7 @@ public static SKData Create (SKStream stream, ulong length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); } public static SKData Create (SKStream stream, long length) @@ -157,7 +157,7 @@ public static SKData Create (SKStream stream, long length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr) length)); } public static SKData Create (IntPtr address, int length) @@ -176,7 +176,7 @@ public static SKData Create (IntPtr address, int length, SKDataReleaseDelegate r ? new SKDataReleaseDelegate ((addr, _) => releaseProc (addr, context)) : releaseProc; var proxy = DelegateProxies.Create (del, DelegateProxies.SKDataReleaseDelegateProxy, out _, out var ctx); - return GetObject (SkiaApi.sk_data_new_with_proc ((void*)address, (IntPtr)length, proxy, (void*)ctx)); + return GetObject (SkiaApi.sk_data_new_with_proc ((void*)address, (IntPtr)length, proxy, (void*)ctx)); } internal static SKData FromCString (string str) @@ -195,7 +195,7 @@ public SKData Subset (ulong offset, ulong length) if (offset > UInt32.MaxValue) throw new ArgumentOutOfRangeException (nameof (offset), "The offset exceeds the size of pointers."); } - return GetObject (SkiaApi.sk_data_new_subset (Handle, (IntPtr) offset, (IntPtr) length)); + return GetObject (SkiaApi.sk_data_new_subset (Handle, (IntPtr) offset, (IntPtr) length)); } // ToArray @@ -253,6 +253,24 @@ public void SaveTo (Stream target) } } + internal static SKData GetObject (IntPtr ptr, bool owns = true, bool unrefExisting = true) + { + if (GetInstance (ptr, out var instance)) { + if (unrefExisting && instance is ISKReferenceCounted refcnt) { +#if THROW_OBJECT_EXCEPTIONS + if (refcnt.GetReferenceCount () == 1) + throw new InvalidOperationException ( + $"About to unreference an object that has no references. " + + $"H: {ptr:x} Type: {instance.GetType ()}"); +#endif + refcnt.SafeUnRef (); + } + return instance; + } + + return new SKData (ptr, owns); + } + // private class SKDataStream : UnmanagedMemoryStream diff --git a/binding/Binding/SKTypeface.cs b/binding/Binding/SKTypeface.cs index edac3b7c55..94cb856913 100644 --- a/binding/Binding/SKTypeface.cs +++ b/binding/Binding/SKTypeface.cs @@ -456,6 +456,8 @@ internal static SKTypeface GetObject(IntPtr ptr, bool owns = true, bool unrefExi } return instance; } + + return new SKTypeface (ptr, owns); } // From e822a9fe838a66bd0e2c456762faf826b634794a Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Fri, 27 Mar 2020 17:19:41 +0100 Subject: [PATCH 3/3] Minor fixes --- binding/Binding/SKSVG.cs | 2 +- binding/Binding/SKSurface.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/binding/Binding/SKSVG.cs b/binding/Binding/SKSVG.cs index 6dd49ca3b7..271d226722 100644 --- a/binding/Binding/SKSVG.cs +++ b/binding/Binding/SKSVG.cs @@ -30,7 +30,7 @@ public static SKCanvas Create (SKRect bounds, SKWStream stream) //return SKObject.Referenced (SKObject.GetObject (SkiaApi.sk_svgcanvas_create_with_stream (&bounds, stream.Handle)), stream); var writer = new SKXmlStreamWriter (stream); - return SKObject.Owned (SKObject.GetObject (SkiaApi.sk_svgcanvas_create_with_writer (&bounds, writer.Handle)), writer); + return SKObject.Owned (SKCanvas.GetObject (SkiaApi.sk_svgcanvas_create_with_writer (&bounds, writer.Handle)), writer); } [EditorBrowsable (EditorBrowsableState.Never)] diff --git a/binding/Binding/SKSurface.cs b/binding/Binding/SKSurface.cs index f625535b3a..9093ba822e 100644 --- a/binding/Binding/SKSurface.cs +++ b/binding/Binding/SKSurface.cs @@ -293,7 +293,7 @@ public static SKSurface CreateNull (int width, int height) => // public SKCanvas Canvas => - GetObject (SkiaApi.sk_surface_get_canvas (Handle), false, unrefExisting: false); + SKCanvas.GetObject (SkiaApi.sk_surface_get_canvas (Handle), false, unrefExisting: false); [EditorBrowsable (EditorBrowsableState.Never)] [Obsolete ("Use SurfaceProperties instead.")]