microsoft / WindowsAppSDK

The Windows App SDK empowers all Windows desktop apps with modern Windows UI, APIs, and platform features, including back-compat support, shipped via NuGet.
https://docs.microsoft.com/windows/apps/windows-app-sdk/
MIT License
3.78k stars 319 forks source link

Proposal: Win2D Roadmap for the Windows App SDK #1150

Open duncanmacmichael opened 3 years ago

duncanmacmichael commented 3 years ago

Proposal - Win2D Roadmap for the Windows App SDK

Summary

This proposal describes our roadmap for shipping a version of Win2D that is compatible with WinUI 3 and the Windows App SDK into 2022. Because Win2D is an open source project and the Windows App SDK embodies transparent and open development, we'd love to hear your feedback which we will use to shape our decisions and priorities as we continue on the Win2D journey together. For the Windows App SDK versions 0.5 and 0.8, we released a fork of Win2D that was compatible with the SDK. In this proposal, we will refer to these two versions of Win2D as System Win2D and App SDK Win2D.

Win2D provides a mix of various components in a single longstanding GitHub repo, VS solution and NuGet package:

For more info about Win2D, see the Win2D documentation.

Staging plan

Win2D’s future with the Windows App SDK

The invariant work to include Win2D into the App SDK is as follows:

The larger concern is whether Win2D needs to be refactored. The current layering means that all projects that use Win2D have a hard dependency on WinUI 3 Xaml:

Current Win2D layering

image

Implications of Putting Win2D into App SDK without Refactoring

If we put Win2D into App SDK without refactoring the WinUI 3 dependency out, we would:

  1. Block anyone trying to get low-level graphics functionality without using WinUI 3.
  2. Be stuck with the layering until breaking changes are allowed again (App SDK 2.0).

If we chose this route and then attempted to fix the layering once we had breaking changes, we would be forcing you to deal with significant re-layering within the App SDK API from 1.0 to 2.0, which we would like to avoid.

Proposed architecture

To address the above issues, we propose that Win2D should be split before fully integrating into the App SDK:

  1. Higher level that becomes integrated of Microsoft.UI.Xaml.Controls:
    1. Xaml CanvasControl
    2. Printing functionality alongside WinUI Xaml printing functionality.
  2. Lower level, cross-framework at the platform level:
    1. Effect definitions for composition and rendering APIs, moved to the lifted platform
    2. WinRT wrappers for Direct2D, DirectWrite, WIC, composition interop, moved to the lifted platform

This would enforce separation of concerns between different components, remove confusing duplication between APIs, and avoid requiring apps to take a dependency on Xaml when they don’t use it.

image

Based on the concerns with layering and breaking changes, we are looking to continue shipping a companion Win2D until we can address the layering and have confidence enough in our open issues to avoid breaking changes. This would allow us to be in App SDK 1.X with a properly layered approach.

Open issues for community input

Since Win2D spans a lot of technology, we still have open issues that we're investigating to make sure our layering and approach is correct before we bring it into the App SDK and lock into an exposure. We invite you to give us your feedback on these issues!

Issue Description
Microsoft.UI.Composition support for Win2D in addition to Windows.UI.Composition Currently, Win2D has WUC interop. We want to make sure it has MUC interop and that it works well with both.
Support for DWriteCore Currently Win2D uses DWrite, while the text rendering technology for the Windows App SDK is DWriteCore. We want to rationalize around a single text stack to ensure users get a consistent experience, don't end up duplicating all their text resources, and have clean interop between higher-level Win2D and lower-level DWriteCore objects.
Memory and download impact of Win2D Today, the size of the System Win2D NuGet package is 2.98 MB and the App SDK Win2D NuGet package is 2.78 MB. In the future, when this functionality is available to the App SDK more broadly, we would like to download the components of Win2D piecemeal to avoid overhead.
Should App SDK Win2D support both system and lifted APIs, or only lifted APIs? This would enable App SDK Win2D to continue supporting both Windows.UI.Composition and Windows.UI.Xaml in addition to Microsoft.UI.Composition and Microsoft.UI.Xaml. It would enable new Win2D features to be available to System Xaml and WinUI 2 customers who might not be able to migrate to WinUI 3 Xaml at this time.
Redirect DWrite to go through DWriteCore Do we want to require all components to explicitly recompile to DWriteCore, or can we assist migration by (optionally) implicitly redirecting DWrite consumers to DWriteCore?
lukeblevins commented 3 years ago

@jtorjo FYI since you've been interested in this for years.

benstevens48 commented 3 years ago

I've been making heavy use of Win2D for a long time in a photo viewing/editing app. Here are my thoughts.

I think refactoring sounds like a good idea. I'm not sure how much you plan to change the code, but please keep the Direct2D interop capabilities as I use them heavily.

Higher level that becomes integrated of Microsoft.UI.Xaml.Controls: Xaml CanvasControl

I assume this will also include CanvasVirtualControl, CanvasAnimatedControl and CanvasSwapChainPanel. Please consider adding proper reference tracking to these controls, so we can remove the need for calling RemoveFromVisualTree - see https://microsoft.github.io/Win2D/WinUI2/html/RefCycles.htm.

Please also consider merging my 4 open pull requests - https://github.com/microsoft/Win2D/pulls, and please be careful about creating deadlocks between the Direct2D lock and Win2D locks, which is what 2 of these pull requests address.

Should App SDK Win2D support both system and lifted APIs, or only lifted APIs?

Ideally both, but I think it depends how quickly the new version of Win2D will be shipped. As far as I can see, it's going to be at least another year before I can migrate from system XAML to App SDK, or perhaps longer. So if the new Win2D will be available significantly before this then I would say target both. On the other hand if the new Win2D will only be available bug-free in a couple of years, then it might not be worth it.

I have to admit I haven't really been following DWrite vs DWriteCore, so I don't really understand the implications of this. I read somewhere that DWriteCore doesn't interop with Direct2D, but again I didn't understand the implications. I assume that we'll still be able to draw text etc onto a CanvasBitmap or CanvasSwapChain, or directly onto the underlying Direct2D bitmap types etc?

In terms of the size I'm mainly concerned about what effect it has on the size of my app, not on the dev dependencies, although it is nice not to have unnecessary dependencies. I'm also very concerned about start-up time, so wouldn't want Win2D runtime to be more than 1 DLL.

A final question - is the code going to be rewritten e.g. using C++/WinRT or will it stay using WRL? I don't have a strong opinion, I'm just interested. I imagine that integration/refactoring and future development might be easier if it was C++/WinRT, but on the other hand rewriting it is likely to introduce bugs.

jtorjo commented 3 years ago

@duke7553 Thanks for looping me in!

@duncanmacmichael

First of all, this may be a stupid question, but why can't you use https://github.com/microsoft/CsWin32/issues/327#issuecomment-878660224 ?

About it being refactored: I think I've stated this before, I do think the priority is in porting win2d, then do breaking changes (if needed). This library is beyond needed on WinUI Desktop -- it's been the only reason I converted my app to UWP.

This cost is much larger for "App SDK Win2D”, where projects expect pay-for-play of App SDK components and WinUI 3 Xaml is currently not used by many projects.

Once again, I'm totally fine with having this dependency at the beginning, in fact I don't care if it'll be here forever.

My biggest concern is for someone to just overthink this and then we'll end up with something ready years from now, instead of months. I've been half jokingly for quite a while now that it'll be easier to port my app to Mac than to port it to Windows (Desktop). Which is a really really sad state of events.

So to restate again, I'd rather have this dependency at start if this means having this earlier rather than having to wait yet another few years for this to be "properly" implemented.

Higher level that becomes integrated of Microsoft.UI.Xaml.Controls: Xaml CanvasControl Printing functionality alongside WinUI Xaml printing functionality.

And of course, CanvasAnimatedControl, and CanvasBitmap and so on.

About printing -- in my mind this is low priority. Sure you probably want it, but I'm guessing you want Direct2D for lightning fast UI drawing on the screen. Of course, I don't really know about how complex it is to implement printing, but to me this is definitely a low priority.

WinRT wrappers for Direct2D, DirectWrite, WIC, composition interop, moved to the lifted platform

As I've asked before, can we simply skip WinRT altogether (https://github.com/microsoft/CsWin32/issues/327#issuecomment-878660224)?

Open issues for community input

Microsoft.UI.Composition support for Win2D in addition to Windows.UI.Composition

I assume you mean https://docs.microsoft.com/en-us/uwp/api/windows.ui.composition?view=winrt-20348 and https://docs.microsoft.com/en-us/windows/winui/api/microsoft.ui.composition?view=winui-3.0

This is kinda' confusing to me, I've only used CanvasControl and CanvasAnimatedControl (and CanvasRenderTarget) to do my drawing.

To me, the CanvasControl, CanvasAnimatedControl, CanvasRenderTarget are of utmost importance when dealing with win2d.

Not sure internally how much they actually use Microsoft.UI.Composition.

So I guess to answer the question: CanvasControl, CanvasAnimatedControl, CanvasRenderTarget are needed. The rest can come later as an update.

Support for DWriteCore

This seems to make sense. Hope it won't mean a lot of development time.

Memory and download impact of Win2D

At a later time, I guess this is a nice to have. At this point, 6MB is pretty much 1-2 seconds of download time at decent speeds. Where I live, this is roughly 0.25s. I think this is a non-issue for now.

Should App SDK Win2D support both system and lifted APIs, or only lifted APIs?

I tend to say - just the lifted API, because I assume that's faster to do.

Redirect DWrite to go through DWriteCore

I'm not sure what this involves. If this is an implementation detail, then just do what you think is best. If this involves public API, please let me know what it involves, and I can offer an opinion :)

Final notes

My app uses win2d heavily. To quote from here: http://microsoft.github.io/Win2D/WinUI2/html/APIReference.htm, it will be easier to say what I'm not using:

Other than that, I'm using pretty much everything.

Another pet peeve of mine: CanvasBitmap.LoadAsync - I simply hate this function. And I hate it because it's async and it also has some weird reentry issues. To be clear, using it in several threads on the same canvas device will cause The component cannot be found. (Exception from HRESULT: 0x88982F50). Which almost makes me cry, I simply have to call this sequentially, and this is a huge bottleneck for me. I believe my app would be probably 40-50% faster when loading bitmaps if it weren't for this.

So can we have this function be sync, and not cause this?

Once again, IMO, please don't overthink this, I'd rather have something now (clearly, I'm dreaming now), rather than have to wait yet another few years for the "perfect solution".

ghost commented 3 years ago

As I've asked before, can we "simply skip" WinRT "altogether" ?

@jtorjo is it because of windows.storage.* performance issues or async variants ? what is it?

arcadiogarcia commented 3 years ago

Should App SDK Win2D support both system and lifted APIs, or only lifted APIs?

I think it is worth calling out that Windows App SDK doesn't support InkCanvas yet and AFAIK there are no plans to add support for the inking APIs until 2022 at least. That means there are whole categories of apps - inking/drawing/notetaking/... - that often rely heavily on Win2D but are unable to migrate to WinUI 3 anytime soon. I work/have worked in a couple of apps that would be affected by the loss of system Xaml support, happy to share more details offline if it helps. It would be really unfortunate if we were stuck in limbo and couldn't use any new features.

lhak commented 3 years ago

I would also prefer if the focus would first be on achieving parity with the current UWP win2d feature set (e.g. CanvasControl is currently unusable in the winui 3.0 version due to memory leaks) before starting refactoring efforts.

I think the current winui 3.0 branch of win2d already uses Microsoft.UI.Composition, doesn't it?

watsonwelch commented 3 years ago

+1 for achieving parity between Win2D for WinUI 3 and UWP (CanvasAnimatedControl, etc.) before focusing on refactoring/dependency reduction.

Aaron-Corp00 commented 3 years ago

@lhak Is there a link to an issue on these memory leaks? Thank you in advance.

lhak commented 3 years ago

@Aaron-Corp00 See https://github.com/microsoft/Win2D/issues/821 and https://github.com/microsoft/microsoft-ui-xaml/issues/3665

Aaron-Corp00 commented 3 years ago

@lhak Thank you. This was a great help to my team who is looking to port a Skia Control to Win2D for WinUI 3.

duncanmacmichael commented 3 years ago

Hi everyone, apologies for the delay in response. We're busily planning for the future of Windows right now, which of course includes Win2D! :-) The dev team and I have read all the responses so far and are really grateful for your input - at the moment, we're gathering feedback and thoughts from multiple sources including this proposal, so we'll respond soon for some of the specific questions and points. Thanks!

pjmlp commented 2 years ago

Even if I am already late for the party, my feedback regarding whatever form Win2D might take going forward, is that since GDI and GDI+, Windows has lacked developer friendly APIs for graphics programming.

Having to deal with COM boilerplate and low level C++ to compensate lack of higher level libraries, is quite far from what Qt, VCL, Android canvas, macOS/iOS Core Graphics offer in terms of productivity.

So basically for me, if I am using Win2D from .NET, having to keep my C++, DirectX and COM skills up to date shouldn't have to be an additional requirement.

brabebhin commented 2 years ago

Win2D should first be ported to desktop, and then any refactoring can be done upon it. Having it available in desktop would allow me to create a copy of MediaPlayerElement for windows app sdk, which seems to not be a priority for Microsoft. Without win2D it would be much harder to do it.

Thanks.

smj389 commented 1 year ago

It would be good to have an update for this?