Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ComputeSharp.D2D1.Uwp/WinUI and PixelShaderEffect<T> #417

Closed
Sergio0694 opened this issue Oct 24, 2022 · 0 comments · Fixed by #451
Closed

ComputeSharp.D2D1.Uwp/WinUI and PixelShaderEffect<T> #417

Sergio0694 opened this issue Oct 24, 2022 · 0 comments · Fixed by #451
Labels
proposal 💡 A proposal for a new feature

Comments

@Sergio0694
Copy link
Owner

Sergio0694 commented Oct 24, 2022

Description

This issue tracks adding the new UWP and WinUI 3 package extensions for ComputeSharp.D2D1.
This also includes building a Win2D-compatible PixelShaderEffect<T> effect type.
For the related Win2D supporting work, see microsoft/Win2D#888.

Rationale

The goal of this new feature is allowing all UWP and WinUI 3 devs to easily plug ComputeSharp.D2D1 shaders into Win2D.

Proposed API

namespace ComputeSharp.D2D1.Uwp;

public sealed partial class PixelShaderEffect<T> : ICanvasEffect // ICanvasImageInterop
    where T : unmanaged, ID2D1PixelShader
{
    ~PixelShaderEffect();

    public Rect GetBounds(ICanvasResourceCreator resourceCreator);
    public Rect GetBounds(ICanvasResourceCreator resourceCreator, Matrix3x2 transform);
    public void Dispose();

    void ICanvasEffect.InvalidateSourceRectangle(ICanvasResourceCreatorWithDpi resourceCreator, uint sourceIndex, Rect invalidRectangle);
    Rect[] ICanvasEffect.GetInvalidRectangles(ICanvasResourceCreatorWithDpi resourceCreator);
    Rect ICanvasEffect.GetRequiredSourceRectangle(ICanvasResourceCreatorWithDpi resourceCreator, Rect outputRectangle, ICanvasEffect sourceEffect, uint sourceIndex, Rect sourceBounds);
    Rect[] ICanvasEffect.GetRequiredSourceRectangles(ICanvasResourceCreatorWithDpi resourceCreator, Rect outputRectangle, ICanvasEffect[] sourceEffects, uint[] sourceIndices, Rect[] sourceBounds);

    public T ConstantBuffer { get; set; }
    [DisallowNull] public D2D1TransformMapper<T>? TransformMapper { get; set; }
    public bool CacheOutput { get; set; }
    public CanvasBufferPrecision? BufferPrecision { get; set; }
    public string? Name { get; set; }
    public SourceCollection Sources { get; }
    public ResourceTextureManagerCollection ResourceTextureManagers { get; }

    public sealed class SourceCollection : IList<IGraphicsEffectSource?>, IReadOnlyList<IGraphicsEffectSource?>, IList
    {
        public int Count { get; }

        public IGraphicsEffectSource? this[int index] { get; set; }
        object? IList.this[int index] { get; set; }

        bool ICollection<IGraphicsEffectSource?>.IsReadOnly { get; }

        bool IList.IsReadOnly { get; }
        bool IList.IsFixedSize { get; }
        bool ICollection.IsSynchronized { get; }
        object ICollection.SyncRoot { get; }

        void ICollection<IGraphicsEffectSource?>.Add(IGraphicsEffectSource? item);
        int IList.Add(object value);
        void ICollection<IGraphicsEffectSource?>.Clear();
        void IList.Clear();
        bool ICollection<IGraphicsEffectSource?>.Contains(IGraphicsEffectSource? item);
        bool IList.Contains(object value);
        void ICollection<IGraphicsEffectSource?>.CopyTo(IGraphicsEffectSource?[] array, int arrayIndex);
        void ICollection.CopyTo(Array array, int index);
        IEnumerator<IGraphicsEffectSource?> IEnumerable<IGraphicsEffectSource?>.GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator();
        int IList<IGraphicsEffectSource?>.IndexOf(IGraphicsEffectSource? item);
        int IList.IndexOf(object value);
        void IList<IGraphicsEffectSource?>.Insert(int index, IGraphicsEffectSource? item);
        void IList.Insert(int index, object value);
        bool ICollection<IGraphicsEffectSource?>.Remove(IGraphicsEffectSource? item);
        void IList.Remove(object value);
        void IList<IGraphicsEffectSource?>.RemoveAt(int index);
        void IList.RemoveAt(int index);
    }

    public sealed class ResourceTextureManagerCollection : IList<D2D1ResourceTextureManager?>, IReadOnlyList<D2D1ResourceTextureManager?>, IList
    {
        public int Count { get; }

        [DisallowNull] public D2D1ResourceTextureManager? this[int index] { get; set; }
        object? IList.this[int index] { get; set; }

        bool ICollection<D2D1ResourceTextureManager?>.IsReadOnly { get; }

        bool IList.IsReadOnly { get; }
        bool IList.IsFixedSize { get; }
        bool ICollection.IsSynchronized { get; }
        object ICollection.SyncRoot { get; }

        void ICollection<D2D1ResourceTextureManager?>.Add(D2D1ResourceTextureManager? item);
        int IList.Add(object value);
        void ICollection<D2D1ResourceTextureManager?>.Clear();
        void IList.Clear();
        bool ICollection<D2D1ResourceTextureManager?>.Contains(D2D1ResourceTextureManager? item);
        bool IList.Contains(object value);
        void ICollection<D2D1ResourceTextureManager?>.CopyTo(D2D1ResourceTextureManager?[] array, int arrayIndex);
        void ICollection.CopyTo(Array array, int index);
        IEnumerator<D2D1ResourceTextureManager?> IEnumerable<D2D1ResourceTextureManager?>.GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator();
        int IList<D2D1ResourceTextureManager?>.IndexOf(D2D1ResourceTextureManager? item);
        int IList.IndexOf(object value);
        void IList<D2D1ResourceTextureManager?>.Insert(int index, D2D1ResourceTextureManager? item);
        void IList.Insert(int index, object value);
        bool ICollection<D2D1ResourceTextureManager?>.Remove(D2D1ResourceTextureManager? item);
        void IList.Remove(object value);
        void IList<D2D1ResourceTextureManager?>.RemoveAt(int index);
        void IList.RemoveAt(int index);
    }
}

Note: the API shape is still temporary and work in progress.

Example use

PixelShaderEffect<MyShader> effect = new()
{
    ConstantBuffer = new MyShader(...),
    Sources =
    {
        [0] = someCanvasBitmap,
        [1] = someOtherEffect,
        ...
    }
};

args.DrawingSession.DrawImage(effect); // Voilà! 🎉
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal 💡 A proposal for a new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant