/// <summary> /// Registers the specified instance with the dictionary. /// </summary> internal static void RegisterHandle(IntPtr handle, SKObject instance) { if (handle == IntPtr.Zero || instance == null) { return; } SKObject objectToDispose = null; instancesLock.EnterWriteLock(); try { if (instances.TryGetValue(handle, out var oldValue) && oldValue.Target is SKObject obj && !obj.IsDisposed) { #if THROW_OBJECT_EXCEPTIONS if (obj.OwnsHandle) { // a mostly recoverable error // if there is a managed object, then maybe something happened and the native object is dead throw new InvalidOperationException( $"A managed object already exists for the specified native object. " + $"H: {handle.ToString ("x")} Type: ({obj.GetType ()}, {instance.GetType ()})"); } #endif // this means the ownership was handed off to a native object, so clean up the managed side objectToDispose = obj; } instances[handle] = new WeakReference(instance); } finally { instancesLock.ExitWriteLock(); } // dispose the object we just replaced objectToDispose?.DisposeInternal(); }
internal static void RegisterHandle(IntPtr handle, SKObject instance) { if (handle == IntPtr.Zero) { return; } lock (instances) { // find old references WeakReference reference; if (instances.TryGetValue(handle, out reference)) { var shouldReplace = reference == null || reference.Target == null || ((SKObject)reference.Target).Handle == IntPtr.Zero; Debug.WriteLineIf(!shouldReplace, "Not replacing existing, living, managed instance with new object."); // replace the old one if it is dead instances[handle] = new WeakReference(instance); } else { // add a new reference instances.Add(handle, new WeakReference(instance)); } } }
public void Reset(SKImageInfo info, IntPtr addr, int rowBytes) { var cinfo = SKImageInfoNative.FromManaged(ref info); SkiaApi.sk_pixmap_reset_with_params(Handle, &cinfo, (void *)addr, (IntPtr)rowBytes); pixelSource = null; }
/// <summary> /// This object will take ownership of the specified object. /// </summary> /// <param name="obj">The object to own.</param> internal void TakeOwnership(SKObject obj) { lock (ownedObjects) { ownedObjects.Add(obj); } obj.RevokeOwnership(); }
internal void TakeOwnership(SKObject obj) { lock (ownedObjects) { ownedObjects.Add(obj); } obj.OwnsHandle = false; }
public static SKCanvas Create(SKRect bounds, SKWStream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } return(SKObject.Referenced(SKCanvas.GetObject(SkiaApi.sk_svgcanvas_create_with_stream(&bounds, stream.Handle)), stream)); }
public static SKCanvas Create(SKRect bounds, SKXmlWriter writer) { if (writer == null) { throw new ArgumentNullException(nameof(writer)); } return(SKObject.GetObject <SKCanvas> (SkiaApi.sk_svgcanvas_create(&bounds, writer.Handle))); }
public static SKImageInfo ToManaged(ref SKImageInfoNative native) => new SKImageInfo { ColorSpace = SKObject.GetObject <SKColorSpace> (native.colorspace), Width = native.width, Height = native.height, ColorType = native.colorType, AlphaType = native.alphaType, };
public bool UseEncodedData(IntPtr data, ulong length) { if (SKObject.SizeOf <IntPtr> () == 4 && length > UInt32.MaxValue) { throw new ArgumentOutOfRangeException(nameof(length), "The length exceeds the size of pointers."); } return(OnUseEncodedData(data, (IntPtr)length)); }
// Create public static SKCanvas Create(SKRect bounds, Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } var managed = new SKManagedWStream(stream); return(SKObject.Owned(Create(bounds, managed), managed)); }
/// <summary> /// This object will hand ownership over to the specified object. /// </summary> /// <param name="owner">The object to give ownership to.</param> internal void RevokeOwnership(SKObject owner = null) { if (owner != null) { owner.TakeOwnership(this); } else { OwnsHandle = false; } }
public static SKImageInfo ToManaged(ref SKImageInfoNative native) { return(new SKImageInfo { ColorSpace = SKObject.GetObject <SKColorSpace> (native.fColorSpace), Width = native.fWidth, Height = native.fHeight, ColorType = native.fColorType, AlphaType = native.fAlphaType, }); }
/// <summary> /// This object will hand ownership over to the specified object. /// </summary> /// <param name="owner">The object to give ownership to.</param> internal void RevokeOwnership(SKObject owner) { if (owner != null) { owner.TakeOwnership(this); } else { this.RevokeOwnership(); } }
public static SKCanvas Create(SKRect bounds, SKXmlWriter writer) { if (writer == null) { throw new ArgumentNullException(nameof(writer)); } var canvas = SKCanvas.GetObject(SkiaApi.sk_svgcanvas_create_with_writer(&bounds, writer.Handle)); writer.RevokeOwnership(canvas); return(SKObject.Referenced(canvas, writer)); }
public static SKCanvas Create(SKRect bounds, SKWStream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } // TODO: there seems to be a memory issue with things getting destroyed in the incorrect order //return SKObject.Referenced (SKObject.GetObject<SKCanvas> (SkiaApi.sk_svgcanvas_create_with_stream (&bounds, stream.Handle)), stream); var writer = new SKXmlStreamWriter(stream); return(SKObject.Owned(SKCanvas.GetObject(SkiaApi.sk_svgcanvas_create_with_writer(&bounds, writer.Handle)), writer)); }
internal static void DeregisterHandle(IntPtr handle, SKObject instance) { if (handle == IntPtr.Zero) { return; } lock (instances) { // find any references WeakReference reference; if (instances.TryGetValue(handle, out reference)) { // remove it if it is dead or the correct object instances.Remove(handle); } } }
internal static bool DeregisterHandle(IntPtr handle, SKObject instance) { if (handle == IntPtr.Zero) { return(false); } lock (instances) { // find any references if (Interlocked.Decrement(ref instance.referenceCount) <= 0 && instances.TryGetValue(handle, out var reference)) { // remove it if it is dead or the correct object instances.Remove(handle); return(true); } } return(false); }
// Reset public void Reset() { SkiaApi.sk_pixmap_reset(Handle); pixelSource = null; }
/// <summary> /// This object will dispose the specific child object which disposed. /// </summary> /// <param name="child">The child object to dispose when the parent is disposed.</param> internal void SetDisposeChild(SKObject child) { lock (ownedObjects) { ownedObjects.Add(child); } }
/// <summary> /// This object will take ownership of the specified object. /// </summary> /// <param name="obj">The object to own.</param> private void TakeOwnership(SKObject obj) { SetDisposeChild(obj); obj.RevokeOwnership(); }
/// <summary> /// Removes the registered instance from the dictionary. /// </summary> internal static void DeregisterHandle(IntPtr handle, SKObject instance) { if (handle == IntPtr.Zero) { return; } if (instance is ISKSkipObjectRegistration) { return; } instancesLock.EnterWriteLock(); try { var existed = instances.TryGetValue(handle, out var weak); if (existed && (!weak.IsAlive || weak.Target == instance)) { instances.Remove(handle); } else { #if THROW_OBJECT_EXCEPTIONS InvalidOperationException ex = null; if (!existed) { // the object may have been replaced if (!instance.IsDisposed) { // recoverable error // there was no object there, but we are still alive ex = new InvalidOperationException( $"A managed object did not exist for the specified native object. " + $"H: {handle.ToString ("x")} Type: {instance.GetType ()}"); } } else if (weak.Target is SKObject o && o != instance) { // there was an object in the dictionary, but it was NOT this object if (!instance.IsDisposed) { // recoverable error // there was a new living object there, but we are still alive ex = new InvalidOperationException( $"Trying to remove a different object with the same native handle. " + $"H: {handle.ToString ("x")} Type: ({o.GetType ()}, {instance.GetType ()})"); } } if (ex != null) { if (instance.fromFinalizer) { exceptions.Add(ex); } else { throw ex; } } #endif } } finally { instancesLock.ExitWriteLock(); } }
protected override void DisposeManaged() { base.DisposeManaged(); pixelSource = null; }