dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.18k stars 1.74k forks source link

[regression/8.0.0] Clipping not working on Windows #18430

Open davidbritch opened 12 months ago

davidbritch commented 12 months ago

Description

I just updated my GraphicsViewDemos project to .NET 8 and used PlatformImage.FromStream to load images on all platforms. Very nice!

In doing so I discovered a crash on Windows when you try and clip an image. It's this issue again. When you try to run clipping code you get an unhandled exception on Windows, with the message: "After calling CanvasDrawingSession.CreateLayer, you must close the resulting CanvasActiveLayer before ending the CanvasDrawingSession"

Capture

Both of the following code blocks cause the exception:

            IImage image;
            var assembly = GetType().GetTypeInfo().Assembly;
            using (var stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
            {
                image = PlatformImage.FromStream(stream);
            }

            if (image != null)
            {
                PathF path = new PathF();
                path.AppendCircle(100, 90, 80);
                canvas.ClipPath(path);  // Must be called before DrawImage
                canvas.DrawImage(image, 10, 10, image.Width, image.Height);
            }
            IImage image;
            var assembly = GetType().GetTypeInfo().Assembly;
            using (var stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
            {
                image = PlatformImage.FromStream(stream);
            }

            if (image != null)
            {
                canvas.SubtractFromClip(60, 60, 90, 90);
                canvas.DrawImage(image, 10, 10, image.Width, image.Height);
            }

Steps to Reproduce

  1. Run the attached sample on Windows.

Link to public reproduction project repository

https://github.com/davidbritch/dotnet-maui-issues/tree/main/GraphicsViewClipping

Version with bug

8.0.0-rc.2.9373

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

Unknown/Other

Affected platforms

Windows

Affected platform versions

No response

Did you find any workaround?

No response

Relevant log output

No response

XamlTest commented 12 months ago

Verified this on Visual Studio Enterprise 17.8.0 Preview 5.0(8.0.0-rc.2.9373). Repro on Windows 11, not repro on Android 14.0-API34 and iOS 16.4 with below Project: GraphicsViewDemos.zip

FaithfulDev commented 1 month ago

In case someone was wondering: The bug is still present (as described above) ☹️

Visual Studio Community Version 17.12.0 Preview .NET 9 Preview (9.0.100-preview.7.24407.12 )

FaithfulDev commented 1 month ago

In Microsoft.Maui.Graphics.Win2D.W2DCanvasState.ClipPath and Microsoft.Maui.Graphics.Win2D.W2DCanvasState.SubtractFromClip are calls to CreateLayer. That one returns the CanvasActiveLayer that isn't closed at the end of the session (the cause of the exception). The class does implement a dispose for it, but the problem is, that the exception occurs before that happens. I don't know when and where this active layer should be disposed.

I added a call to dispose the W2DCanvas at the end of OnDraw in W2DGraphicsView (experimenting). That actually makes it work, but it also causes W2DGraphicsView.Invalidate to trigger a different exception (since I disposed of something it needs).

Maybe someone can do something with this little bit of context information 😄