Files
stgsharp/源代码/StgSharp/Graphics/GL/GLhandle.cs
T

362 lines
9.6 KiB
C#

//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// 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
{
/// <summary>
/// A handle to an OpenGL object,
/// must be indexed from a <see cref="glHandleSet"/>.
/// Direct call will cause <see langword="InvalidOperationException"/>
/// </summary>
public unsafe class glHandle: IDisposable
{
private static uint* zeroHandle = (uint*)Marshal.AllocHGlobal(Marshal.SizeOf<uint>());
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<int>());
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>(T[] array) where T : struct
{
return new glArrayHandle(array);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static glArrayHandle CopyAlloc<T>(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;
}
}
/// <summary>
/// A handle to an OpenGL object.
/// </summary>
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();
}
/// <summary>
/// Release all resource in this handle.
/// This will release all resource in this <see cref="glHandle"/>.
/// This <see langword="glHandle"/> will be not usable.
/// </summary>
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()
{
}
}
}