//----------------------------------------------------------------------- //----------------------------------------------------------------------- // file="GLhandle.cs" // Project: StgSharp // AuthorGroup: Nitload Space // Copyright (c) Nitload Space. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the “Software”), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and // this permission notice shall be included in all copies // or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED “AS IS”, // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //----------------------------------------------------------------------- //----------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.AccessControl; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace StgSharp.Graphics { /// /// A handle to an OpenGL object, /// must be indexed from a . /// Direct call will cause /// public unsafe class glHandle: IDisposable { private static uint* zeroHandle = (uint*)Marshal.AllocHGlobal(Marshal.SizeOf()); internal uint* source; internal uint* valuePtr; private glHandle(IntPtr handle) { this.valuePtr = (uint*)handle; source = (uint*)0; } private glHandle(uint value) { source = (uint*)0; valuePtr = (uint*)Marshal.AllocHGlobal(sizeof(uint)); *valuePtr = value; } internal glHandle(uint* val, glHandleSet set) { source = set!=null ? set!.handle:(uint*)0; valuePtr = val; } [Obsolete("Cannot init instance of this type", true)] public glHandle() { } public IntPtr Handle { get=> (IntPtr)valuePtr; } public bool IsIsolated { get => source == (uint*)0; } public uint Value { get => *valuePtr; set => *valuePtr = value; } public static glHandle ZeroHandle => FromPtr(IntPtr.Zero); public static glHandle Zero => Alloc(0); public static glHandle Alloc(uint value) { return new glHandle(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static glHandle FromPtr(IntPtr p) { return new glHandle(p); } ~glHandle() { if (valuePtr != zeroHandle && IsIsolated) { Marshal.FreeHGlobal((IntPtr)valuePtr); } } protected virtual void Dispose(bool disposing) { if (IsIsolated) { GCHandle.FromIntPtr((IntPtr)valuePtr).Free(); if (disposing) { } } } // // ~glHandle() // { // Dispose(disposing: false); // } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } } public unsafe class glSHandle { private static int* zeroHandle = (int*)Marshal.AllocHGlobal(Marshal.SizeOf()); internal int* source; internal int* valuePtr; private glSHandle(IntPtr handle) { this.valuePtr = (int*)handle; source = (int*)0; } private glSHandle(int value) { source = (int*)0; valuePtr = (int*)Marshal.AllocHGlobal(sizeof(int)); *valuePtr = value; } internal glSHandle(int* val, glHandleSet set) { source = set != null ? (int*)set!.handle : (int*)0; valuePtr = val; } [Obsolete("Cannot init instance of this type", true)] public glSHandle() { } public IntPtr Handle { get => (IntPtr)valuePtr; } public bool IsIsolated { get => source == (uint*)0; } public int Value { get => *valuePtr; set => *valuePtr = value; } public static glSHandle Zero => Alloc(0); public static glSHandle Alloc(int value) { return new glSHandle(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static glSHandle FromPtr(IntPtr p) { return new glSHandle(p); } ~glSHandle() { if (valuePtr != zeroHandle && IsIsolated) { Marshal.FreeHGlobal((IntPtr)valuePtr); } } } public unsafe class glArrayHandle { internal readonly Array a; internal GCHandle handle; private bool disposedValue; internal glArrayHandle(Array array) { this.a = array; handle = GCHandle.Alloc(array, GCHandleType.Pinned); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public IntPtr AddressOfArray() { if (handle != default) { return handle.AddrOfPinnedObject(); } else { throw new InvalidOperationException(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static glArrayHandle Alloc(T[] array) where T : struct { return new glArrayHandle(array); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static glArrayHandle CopyAlloc(T[] array) where T : struct { Array copy = new T[array.Length]; array.CopyTo(copy, 0); return new glArrayHandle(copy); } public void Release() { handle.Free(); handle = default; } } /// /// A handle to an OpenGL object. /// public unsafe class glHandleSet { private readonly uint[] _value; internal uint* handle; internal int length; public glHandleSet(int count) { _value = new uint[count]; length = count; handle = (uint*)GCHandle.Alloc(_value, GCHandleType.Pinned).AddrOfPinnedObject(); } public IntPtr Handle { get => (IntPtr)handle; } public glHandle this[int index] { get { if (index > length) { throw new IndexOutOfRangeException(); } return new glHandle(handle + index, this); } } public glSHandle this[uint index] { get { if (index > length) { throw new IndexOutOfRangeException(); } return new glSHandle(((int*)handle) + index, this); } } public static void Copy(in glHandleSet source, glHandleSet target) { if ((source == null) || (target == null)) { throw new NullReferenceException(); } if (source.length != target.length) { throw new Exception($"Lengths of {nameof(source)} and {nameof(target)} are not equal."); } for (int i = 0; i < source.length; i++) { target._value[i] = source._value[i]; } } public void Pin() { if (_value == null) { return; } handle = (uint*)GCHandle.Alloc(_value, GCHandleType.Pinned).AddrOfPinnedObject(); } /// /// Release all resource in this handle. /// This will release all resource in this . /// This will be not usable. /// public void Release() { if (_value == null) { return; } else { GCHandle.FromIntPtr((IntPtr)handle).Free(); handle = (uint*)IntPtr.Zero; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetValue(int index, uint value) { _value[index] = value; } ~glHandleSet() { } } }