SkiaSharp icon indicating copy to clipboard operation
SkiaSharp copied to clipboard

[FEATURE] Support for GPU Acceleration for WinUI3

Open gmurray81 opened this issue 2 years ago • 4 comments

GPU Acceleration is important in SkiaSharp for scenarios where you have large fill areas on high dpi monitors, as well as just general performance maximization. It's important that GPU acceleration is also supported for the WinUI3 platform.

It seems the challenge was lack of support for Angle. Is this still valid? Are there alternatives?

gmurray81 avatar Dec 16 '21 22:12 gmurray81

We are running into the same issue, our application is really struggling when drawing real time plots on high dpi monitors.

rick-palmsens avatar Dec 21 '21 12:12 rick-palmsens

We are very interested in the GPU acceleration as well using Uno Platform with WinUI 3 main head.

3D-aero-sbahr avatar Jan 14 '22 07:01 3D-aero-sbahr

This is especially important because I recently evaluated Win2D in WinUI3 and was very disappointed with the performance compared to SkiaSharp in SOFTWARE mode. Perhaps I was doing something wrong, But ATM it seems like SkiaSharp is the right answer for high performance 2D rendering in WinUI3

gmurray81 avatar Mar 11 '22 14:03 gmurray81

Any updates on this?

gmurray81 avatar Jul 09 '22 16:07 gmurray81

Bump, any updates on this one? Running into WinUI performance issues too.

p2pbsh avatar Jan 17 '23 20:01 p2pbsh

ANGLE needs to be patched to be used in WinUI 3, I have a sample project which uses a patched version of ANGLE in WinUI 3. https://github.com/levinli303/WinUIANGLE, the detail of the patch is in https://github.com/levinli303/vcpkg/tree/angle-winui, hopefully someone will find it useful.

levinli303 avatar Feb 16 '23 05:02 levinli303

Just for my understanding: SKXamlCanvas does not use GPU-Acceleration right now, correct? What needs to be done on your/my side to enable GPU-acceleration? I don't understand the comment from @levinli303 above and if this could help me. Do I need to compile ANGLE myself?

TopperDEL avatar Sep 22 '23 12:09 TopperDEL

The current issue is that we require ANGLE to be rebuilt using the new WinUI types. The current implementation is just for UWP and the ANGLE team is not really interested in adding another Windows platform.

Since we are already using all the Google build tools such as gn/ninja, we can build it as part of the SkiaSharp build. However, someone needs to do the bit of work to update the type references and somehow (I am not sure yet) reference all the correct files in the WindowsAppSDK nuget package.

Once we get a build of ANGLE for WinUI 3, then I can uncomment the code that we already have for the SkiaSharp GL view.

As of today, none of the work is really SkiaSharp or native skia work.

All the work needs to be done is to fork (and hopefully PR back) the Google ANGLE code and make the required modifications: https://chromium.googlesource.com/angle/angle

The required code is probably all here: https://github.com/levinli303/vcpkg/tree/angle-winui

But instead of SkiaSharp depending on layers of patches and then using vcpkg to build those patches, we should just make those modifications in a normal way and upstream. Google is open to a nice PR and I am sure if we just get the code changes to them they will accept it. They are probably not really interested in building and testing the new platform - not sure they do that for UWP anyways.

I see the forked vcpkg does a lot of things to extract and generate files - and we can do that too in the ANGLE code using some python scripts. All doable, just I do not have the time to work on that.

mattleibow avatar Sep 22 '23 14:09 mattleibow

Making this work will also help the Uno Platform apps ;) So if anyone who is a big Uno fan...

mattleibow avatar Sep 22 '23 14:09 mattleibow

there's a slightly updated version of the patch for ANGLE on WinUI here (that should work with WinAppSDK 1.4.1) https://github.com/celestiamobile/vcpkg/commit/abac0a9a434f0b91b836c3ee6456f18aaa9f21c3

levinli303 avatar Sep 23 '23 04:09 levinli303

Can you work @levinli303 converted into a PR? It seems you know what you are doing - I don't understand whats Happening in your Patch and how all stitches together. Thank you!

TopperDEL avatar Sep 23 '23 07:09 TopperDEL

i'm not familiar with SkiaSharp but i'm happy to provide more info and assist if anyone wants to make it work.

levinli303 avatar Sep 26 '23 05:09 levinli303

From my understanding Skiasharp does not have to be changed that much - am I right @mattleibow? As long as ANGLE gets support for WinUI it should be ok. So getting a PR done for ANGLE should mostly be it.

TopperDEL avatar Sep 26 '23 05:09 TopperDEL

i don't think my patch can be upstreamed to Google's ANGLE easily. In addition to the patch being dirty (enabling the UWP path on Win32 in order to use the SwapChainPanel), https://github.com/celestiamobile/vcpkg/blob/56dcda1c419e9efefa36454f15e291a6ff9f558f/ports/angle/portfile.cmake#L155 makes the generated libs tied to the version of WindowsAppSDK specified. Some time ago I tried using the ANGLE built against WindowsAppSDK 1.2 in a WindowsAppSDK 1.3 project with SwapChainPanel, it does not work.

I would suggest keep a separate fork of google/angle

levinli303 avatar Sep 26 '23 12:09 levinli303

I've added a 50$ bounty on Gitpay for this issue to be solved - I hope that is at least a start. I digged into ANGLE for a moment but I am completely lost.

TopperDEL avatar Sep 26 '23 13:09 TopperDEL

I suppose theoretically a new backend for Skia could be made that uses D3D11 or D3D12 directly instead of using ANGLE.

That sounds like perhaps more work than modifying ANGLE to work with the WinUI3 types.

ShadowMarker789 avatar Oct 04 '23 12:10 ShadowMarker789

Are you capable of doing this? :)

TopperDEL avatar Oct 04 '23 12:10 TopperDEL

"I recently evaluated Win2D in WinUI3 and was very disappointed with the performance compared to SkiaSharp in SOFTWARE mode. Perhaps I was doing something wrong"

@gmurray81 you were most definitely doing something wrong. There is absolutely no way whatsoever that can be true. Win2D is a very thin wrapper over D2D, which is extremely fast. You'd need to elaborate further (in some other issue) for others to understand what was going on there.

Sergio0694 avatar Oct 04 '23 13:10 Sergio0694

Are you capable of doing this? :)

I doubt it.

Have you considered taking a look at how Avalonia uses ANGLE?

I vaguely recall them mentioning that they maintain their own fork of ANGLE. They use it for their Skia implementation on Windows, as they find its performance is better than WGL.

ShadowMarker789 avatar Oct 04 '23 13:10 ShadowMarker789

@Sergio0694 unfortunately, It's a bit hard to decompose what I'm doing into individual areas that can be analyzed, since I'm attempting to implement a layer for our charting product that targets Win2d, and the framerates were just not acceptable compared to Skia. This may have been self inflicted, for example, perhaps I was creating and destroying resources that need to be cached.

BUT, I heavily suspect based on my past interactions with Direct2D both directly and via WPF that there are some inefficiencies how Direct2D tessellates a complex polyline to render it on the GPU. Perhaps this has been fixed in later versions of Direct2D, though.

Try this as an example. Create a polyline that oscillates up and down in the y direction entirely randomly and with high frequency. Render this in WPF and modify it with a high framerate. This will bring WPF to its knees. Again, could be fixed in later Direct2d (doesn't help WPF) but may help Win2d.

Anyhow, I don't know if it was scenarios like that which were causing the performance to be worse than software based Skia. But that's one of the scenarios I've experienced in the past that Skia handles much more gracefully than WPF (old Direct2d)

Funny story actually. The Chromium/Skia team actually broke this scneario when they first enabled the GPU support in Chrome, and I needed to report a bug, which they then fixed (not sure how, maybe they adjusted the way the prepped the lines for the GPU, or maybe they detect the scenario with heuristics and use a raster fallback)

https://bugs.chromium.org/p/chromium/issues/detail?id=102165&can=1&q=reporter%3Agmurray%40gmail.com

Anyhow, may not be that scenario, since I don't think I was testing anything related to that. But this is an example of the fact that what I'm testing is non-trivial polyline and polygon rendering. So perhaps Win2D is not optimized enough for certain types of shapes, etc, because traditionally Direct2D has definitely had some issues in this regard. To this day, you can feed a shape like this to WPF and it will just refuse to process it well.

gmurray81 avatar Oct 04 '23 13:10 gmurray81

Also note though, I've definitely had some issues from WinUI in the past also where it just seemed like there was too much tax being paid to bridge between managed/native. E.g. it seemed like all the data binding/dep prop stuff was pretty slow, presumably from being pretty chatty over that seam. The nature of my interaction with Win2D is also pretty chatty and from C# so there could be too much tax being paid to just funnel the information to Win2D for rendering. If managed/native bridging from WinUI to native libraries has been improved over time, then perhaps that will help also.

I haven't had the opportunity to test out the behavior of the Win2D layer I built against newer WinUI/Win2D versions in a while.

gmurray81 avatar Oct 04 '23 13:10 gmurray81

@gmurray81 Can you mock up a Skia drawing routine that you find performs poorly when not accelerated, and performs well when accelerated?

A method that takes in as a parameter SKPaintSurfaceEventArgs would do.

ShadowMarker789 avatar Oct 05 '23 05:10 ShadowMarker789

Are you capable of doing this? :)

Would you know where to start doing that?

I have no familiarity with Skia's codebase and am a bit lost delving into the repository so far.

ShadowMarker789 avatar Oct 09 '23 12:10 ShadowMarker789

"BUT, I heavily suspect based on my past interactions with Direct2D both directly and via WPF that there are some inefficiencies how Direct2D tessellates a complex polyline to render it on the GPU. Perhaps this has been fixed in later versions of Direct2D, though."

@gmurray81 I'm not entirely sure I'm following, are you sure we're talking about the same things here? You mention WPF, but that has its own DX9 renderer. I'm talking about Win2D, which runs on top of D2D, which uses DX11 behind the scenes. WPF does not use D2D in its renderer. Unless you specifically used Win2D (or D2D directly) from WPF (ie. you either referenced Win2D and used its canvas control via a XAML Island, or manually setup the Win32 interop to manage an HWND-based swapchain, or something else), then chances are you didn't actually use D2D at all. Is it possible there's a misunderstanding there about the various technologies? And if you did in fact use D2D, then yeah you most definitely just did something wrong, because as I said I just don't see how it could possibly be slower than Skia in software mode (or even if it was hardware accelerated), that just doesn't really make sense to me 😅

Eg. you talked about "creating a polyline". If this is the PolyLine you mean, yeah that's not Win2D/D2D at all.

Sergio0694 avatar Oct 09 '23 12:10 Sergio0694

This topic is quite important for my use-case - so I would love to see this tackled by anyone with knowledge in this space. I unfortunately do not have any clue what needs to be done.

But I raise the bounty for solving this issue to 500$.

TopperDEL avatar Nov 09 '23 13:11 TopperDEL

I might take a look and see if I can build a demo when I have time. Assuming the work here required would be just building ANGLE for WinUI (which is already done sometime ago) and switch SkiaSharp to Microsoft.UI.Xaml.Controls.SwapChainPanel from Windows.UI.Xaml.Controls.SwapChainPanel

levinli303 avatar Nov 09 '23 14:11 levinli303

That would be awesome! 🎉

TopperDEL avatar Nov 09 '23 15:11 TopperDEL

i've built the latest ANGLE against the latest WindowsAppSDK 1.4.231008000 here angle.zip

however i am struggling to make SkiaSharp compile (i have not made changes yet):

Error occurred while restoring NuGet packages: Invalid restore input. The original target frameworks value must match the aliases. Original target frameworks: netstandard2.0;netstandard2.1;net462;net7.0;net462;net7.0-windows10.0.19041.0, aliases: netstandard2.0;netstandard2.1;net462;net7.0;net7.0-windows10.0.19041.0. Input files: REDACTED\SkiaSharp\source\SkiaSharp.Views\SkiaSharp.Views.Desktop.Common\SkiaSharp.Views.Desktop.Common.csproj.

levinli303 avatar Nov 10 '23 04:11 levinli303

i've built the latest ANGLE against the latest WindowsAppSDK 1.4.231008000 here angle.zip

however i am struggling to make SkiaSharp compile (i have not made changes yet):

Error occurred while restoring NuGet packages: Invalid restore input. The original target frameworks value must match the aliases. Original target frameworks: netstandard2.0;netstandard2.1;net462;net7.0;net462;net7.0-windows10.0.19041.0, aliases: netstandard2.0;netstandard2.1;net462;net7.0;net7.0-windows10.0.19041.0. Input files: REDACTED\SkiaSharp\source\SkiaSharp.Views\SkiaSharp.Views.Desktop.Common\SkiaSharp.Views.Desktop.Common.csproj.

Maybe @mattleibow knows something about this?

TopperDEL avatar Nov 10 '23 09:11 TopperDEL

Any news on this one?

TopperDEL avatar Nov 27 '23 12:11 TopperDEL