/// <summary>Allocates memory for a <see cref="Guid"/> value and initializes it.</summary> /// <returns>A pointer to memory holding the <see cref="Guid"/> value for the current type.</returns> private static Guid *CreateRIID() { var p = (Guid *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(T), sizeof(Guid)); *p = typeof(T).GUID; return(p); }
/// <summary> /// Builds the custom method table pointer for <see cref="ID3DIncludeForD2DHelpers"/>. /// </summary> /// <returns>The method table pointer for <see cref="ID3DIncludeForD2DHelpers"/>.</returns> private static void **InitVtbl() { void **lpVtbl = (void **)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ID3DIncludeForD2DHelpers), sizeof(void *) * 2); #if NET6_0_OR_GREATER lpVtbl[0] = (delegate * unmanaged <ID3DIncludeForD2DHelpers *, D3D_INCLUDE_TYPE, sbyte *, void *, void **, uint *, int>) & Open; lpVtbl[1] = (delegate * unmanaged <ID3DIncludeForD2DHelpers *, void *, int>) & Close; #else lpVtbl[0] = (void *)Marshal.GetFunctionPointerForDelegate(OpenWrapper); lpVtbl[1] = (void *)Marshal.GetFunctionPointerForDelegate(CloseWrapper); #endif return(lpVtbl); }
/// <summary> /// Initializes the shared state for <see cref="PixelShaderEffect"/>. /// </summary> static PixelShaderEffect() { void **lpVtbl = (void **)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(PixelShaderEffect), sizeof(void *) * 14); // ID2D1EffectImpl #if NET6_0_OR_GREATER lpVtbl[0] = (delegate * unmanaged <PixelShaderEffect *, Guid *, void **, int>) & ID2D1EffectImplMethods.QueryInterface; lpVtbl[1] = (delegate * unmanaged <PixelShaderEffect *, uint>) & ID2D1EffectImplMethods.AddRef; lpVtbl[2] = (delegate * unmanaged <PixelShaderEffect *, uint>) & ID2D1EffectImplMethods.Release; lpVtbl[3] = (delegate * unmanaged <PixelShaderEffect *, ID2D1EffectContext *, ID2D1TransformGraph *, int>) & ID2D1EffectImplMethods.Initialize; lpVtbl[4] = (delegate * unmanaged <PixelShaderEffect *, D2D1_CHANGE_TYPE, int>) & ID2D1EffectImplMethods.PrepareForRender; lpVtbl[5] = (delegate * unmanaged <PixelShaderEffect *, ID2D1TransformGraph *, int>) & ID2D1EffectImplMethods.SetGraph; #else lpVtbl[0] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1EffectImplMethods.QueryInterfaceWrapper); lpVtbl[1] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1EffectImplMethods.AddRefWrapper); lpVtbl[2] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1EffectImplMethods.ReleaseWrapper); lpVtbl[3] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1EffectImplMethods.InitializeWrapper); lpVtbl[4] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1EffectImplMethods.PrepareForRenderWrapper); lpVtbl[5] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1EffectImplMethods.SetGraphWrapper); #endif // ID2D1DrawTransform #if NET6_0_OR_GREATER lpVtbl[6 + 0] = (delegate * unmanaged <PixelShaderEffect *, Guid *, void **, int>) & ID2D1DrawTransformMethods.QueryInterface; lpVtbl[6 + 1] = (delegate * unmanaged <PixelShaderEffect *, uint>) & ID2D1DrawTransformMethods.AddRef; lpVtbl[6 + 2] = (delegate * unmanaged <PixelShaderEffect *, uint>) & ID2D1DrawTransformMethods.Release; lpVtbl[6 + 3] = (delegate * unmanaged <PixelShaderEffect *, uint>) & ID2D1DrawTransformMethods.GetInputCount; lpVtbl[6 + 4] = (delegate * unmanaged <PixelShaderEffect *, RECT *, RECT *, uint, int>) & ID2D1DrawTransformMethods.MapOutputRectToInputRects; lpVtbl[6 + 5] = (delegate * unmanaged <PixelShaderEffect *, RECT *, RECT *, uint, RECT *, RECT *, int>) & ID2D1DrawTransformMethods.MapInputRectsToOutputRect; lpVtbl[6 + 6] = (delegate * unmanaged <PixelShaderEffect *, uint, RECT, RECT *, int>) & ID2D1DrawTransformMethods.MapInvalidRect; lpVtbl[6 + 7] = (delegate * unmanaged <PixelShaderEffect *, ID2D1DrawInfo *, int>) & ID2D1DrawTransformMethods.SetDrawInfo; #else lpVtbl[6 + 0] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1DrawTransformMethods.QueryInterfaceWrapper); lpVtbl[6 + 1] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1DrawTransformMethods.AddRefWrapper); lpVtbl[6 + 2] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1DrawTransformMethods.ReleaseWrapper); lpVtbl[6 + 3] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1DrawTransformMethods.GetInputCountWrapper); lpVtbl[6 + 4] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1DrawTransformMethods.MapOutputRectToInputRectsWrapper); lpVtbl[6 + 5] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1DrawTransformMethods.MapInputRectsToOutputRectWrapper); lpVtbl[6 + 6] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1DrawTransformMethods.MapInvalidRectWrapper); lpVtbl[6 + 7] = (void *)Marshal.GetFunctionPointerForDelegate(ID2D1DrawTransformMethods.SetDrawInfoWrapper); #endif VtblForID2D1EffectImpl = lpVtbl; VtblForID2D1DrawTransform = &lpVtbl[6]; }
/// <summary> /// Builds the custom method table pointer for <see cref="IDXGIFactory4As6Backcompat"/>. /// </summary> /// <returns>The method table pointer for <see cref="IDXGIFactory4As6Backcompat"/>.</returns> private static void **InitVtbl() { void **lpVtbl = (void **)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IDXGIFactory4As6Backcompat), sizeof(void *) * 30); new Span <IntPtr>(lpVtbl, 30).Clear(); #if NET6_0_OR_GREATER lpVtbl[2] = (delegate * unmanaged <IDXGIFactory4As6Backcompat *, uint>) & Release; lpVtbl[27] = (delegate * unmanaged <IDXGIFactory4As6Backcompat *, Guid *, void **, int>) & EnumWarpAdapter; lpVtbl[29] = (delegate * unmanaged <IDXGIFactory4As6Backcompat *, uint, DXGI_GPU_PREFERENCE, Guid *, void **, int>) & EnumAdapterByGpuPreference; #else lpVtbl[2] = (void *)Marshal.GetFunctionPointerForDelegate(ReleaseWrapper); lpVtbl[27] = (void *)Marshal.GetFunctionPointerForDelegate(EnumWarpAdapterWrapper); lpVtbl[29] = (void *)Marshal.GetFunctionPointerForDelegate(EnumAdapterByGpuPreferenceWrapper); #endif return(lpVtbl); }
/// <summary> /// Initializes the <see cref="For{T}"/> shared state. /// </summary> /// <param name="factory">The factory of <see cref="ID2D1TransformMapper{T}"/> instances to use for each created effect.</param> /// <exception cref="InvalidOperationException">Thrown if initialization is attempted with a mismatched transform factory.</exception> public static void Initialize(Func <ID2D1TransformMapper <T> >?factory) { // This conceptually acts as a static constructor, and this type is // internal, so in this very specific case locking on the type is fine. lock (typeof(For <T>)) { if (isInitialized) { // If the factory is already initialized, ensure the draw transform mapper is the same if (d2D1DrawTransformMapperFactory != factory) { ThrowHelper.ThrowInvalidOperationException( "Cannot initialize an ID2D1Effect factory for the same shader type with two different transform mappings. " + "Make sure to only ever register a pixel shader effect with either no transform, or the same transform type."); } } else { // Load all shader properties Guid guid = typeof(T).GUID; int inputCount = (int)D2D1InteropServices.GetPixelShaderInputCount <T>(); ReadOnlyMemory <byte> buffer = D2D1InteropServices.LoadPixelShaderBytecode <T>(); byte *typeAssociatedMemory = (byte *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(For <T>), buffer.Length); // Copy the bytecode to the target buffer buffer.Span.CopyTo(new Span <byte>(typeAssociatedMemory, buffer.Length)); // Set the shared state and mark the type as initialized shaderId = guid; numberOfInputs = inputCount; bytecode = typeAssociatedMemory; bytecodeSize = buffer.Length; d2D1DrawTransformMapperFactory = factory; isInitialized = true; } } }
/// <summary> /// Initializes the <see cref="For{T}"/> shared state. /// </summary> /// <param name="d2D1DrawTransformMapperFactory">The factory of <see cref="ID2D1TransformMapper{T}"/> instances to use for each created effect.</param> /// <exception cref="InvalidOperationException">Thrown if initialization is attempted with a mismatched transform factory.</exception> public static void Initialize(Func <ID2D1TransformMapper <T> >?d2D1DrawTransformMapperFactory) { // This conceptually acts as a static constructor, and this type is // internal, so in this very specific case locking on the type is fine. lock (typeof(For <T>)) { if (isInitialized) { // If the factory is already initialized, ensure the draw transform mapper is the same if (For <T> .d2D1DrawTransformMapperFactory != d2D1DrawTransformMapperFactory) { ThrowHelper.ThrowInvalidOperationException( "Cannot initialize an ID2D1Effect factory for the same shader type with two different transform mappings. " + "Make sure to only ever register a pixel shader effect with either no transform, or the same transform type."); } } else { // Load all shader properties Guid shaderId = typeof(T).GUID; ReadOnlyMemory <byte> bytecodeInfo = D2D1PixelShader.LoadBytecode <T>(); int bytecodeSize = bytecodeInfo.Length; byte *bytecode = (byte *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(For <T>), bytecodeSize); D2D1BufferPrecision bufferPrecision = D2D1PixelShader.GetOutputBufferPrecision <T>(); D2D1ChannelDepth channelDepth = D2D1PixelShader.GetOutputBufferChannelDepth <T>(); D2D1PixelOptions pixelOptions = D2D1PixelShader.GetPixelOptions <T>(); // Prepare the inputs info int inputCount = D2D1PixelShader.GetInputCount <T>(); D2D1PixelShaderInputType *inputTypes = (D2D1PixelShaderInputType *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(For <T>), sizeof(D2D1PixelShaderInputType) * inputCount); for (int i = 0; i < inputCount; i++) { inputTypes[i] = D2D1PixelShader.GetInputType <T>(i); } // Prepare the input descriptions ReadOnlyMemory <D2D1InputDescription> inputDescriptionsInfo = D2D1PixelShader.GetInputDescriptions <T>(); int inputDescriptionCount = inputDescriptionsInfo.Length; D2D1InputDescription *inputDescriptions = (D2D1InputDescription *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(For <T>), sizeof(D2D1InputDescription) * inputDescriptionCount); inputDescriptionsInfo.Span.CopyTo(new Span <D2D1InputDescription>(inputDescriptions, inputDescriptionCount)); // Copy the bytecode to the target buffer bytecodeInfo.Span.CopyTo(new Span <byte>(bytecode, bytecodeSize)); // Set the shared state and mark the type as initialized For <T> .shaderId = shaderId; For <T> .inputCount = inputCount; For <T> .inputTypes = inputTypes; For <T> .inputDescriptionCount = inputDescriptionCount; For <T> .inputDescriptions = inputDescriptions; For <T> .pixelOptions = pixelOptions; For <T> .bytecode = bytecode; For <T> .bytecodeSize = bytecodeSize; For <T> .bufferPrecision = bufferPrecision; For <T> .channelDepth = channelDepth; For <T> .d2D1DrawTransformMapperFactory = d2D1DrawTransformMapperFactory; isInitialized = true; } } }