/// <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;
                }
            }
        }
Esempio n. 2
0
 public unsafe void GetInputCount()
 {
     Assert.AreEqual(D2D1InteropServices.GetPixelShaderInputCount <InvertEffect>(), 1u);
     Assert.AreEqual(D2D1InteropServices.GetPixelShaderInputCount <PixelateEffect.Shader>(), 1u);
     Assert.AreEqual(D2D1InteropServices.GetPixelShaderInputCount <ZonePlateEffect>(), 0u);
 }