Uno Platform 4.4 – Wasm Threading+Exception Handling, Rich Animations, GamePad APIs and more

Over 90 improvements in this release!

Uno Platform 4.4 is our 4th release in 2022, keeping us on a once-in-six-weeks rapid release schedule we aim for. The release packs numerous UI and performance improvements across all target platforms. First, on the UI side you’ll be able to produce beautiful fluid animations on .NET Android, .NET iOS and Skia-based targets, as well as increase high-fidelity renderings of all your texts on Skia-based targets. Second, on the performance side we are including support for the most recent WebAssembly advances available in .NET 7 – Wasm Threading and Exception handling. Lastly, we also enabled new input scenarios via GamePad API support and improved the default project templates.

In total we have implemented and resolved over 90 new feature requests and issues. Let’s unpack it together.

About Uno Platform

For those new to Uno Platform – it allows for creation of pixel-perfect, single-source C# and XAML apps which run natively on Windows, iOS, Android, macOS, Linux and Web via WebAssembly. It offers Figma integration for design-development handoff, and a set of extensions to bootstrap your projects. Uno Platform is free and Open Source (Apache 2.0) and available on GitHub.

Fluid Animations via Skottie Integration

We already blogged about our contribution to SkiaSharp for Skottie open source project, providing fundamentals for playing Lottie files and thus enabling fluid animations for all frameworks and libraries taking a dependency on Skottie.

Today we are announcing support for AnimatedVisualPlayer for Skia and .NET 6 Mobile targets, leveraging the very work we contributed to SkiaSharp.Skottie. OSS FTW!

This feature enables scenarios for playing Lottie files on all Uno-supported platforms, but it also enables support for the WinUI 3 ProgressRing and its Material variant.

High-fidelity rendering via TextBlock for Skia Rewrite

TextBlock has received a large overhaul, providing the ability to display a TextBlock in all its richness, with wrapping, coloring, line height and more.

The high-fidelity rendering of text was a highly requested feature. We’ve decided the best approach was to not reinvent the wheel, as is our philosophy, and in this scenario use HarfBuzz, an open-source text rendering implementation used in many large projects. Once again, OSS FTW!

Here are some samples of before-and-after look and feel you can expect.

Many more updates are coming in this space, stay tuned!

Uno Platform Project default template updates

Starting from this release, the `dotnet new unoapp` uses WinUI 3 and .NET 6 as the default template, migrating from the older UWP-based template. Those UWP+Xamarin based templates have been renamed to be “dotnet new unoapp-uwp”, in case you need to use them.

Additionally, we’ve updated the Skia+WPF target support to remove the second “Skia.Wpf.Host” project and at the same time ensure that .NET 6 and C# 10 were supported for Skia+WPF target. As of 4.4 release authoring the Skia+WPF head will not be confusing as it is now similar to the other project heads.

If you want to upgrade your existing project to this new project format, you can follow this guide.

WebAssembly Performance Updates

Exciting new updates are coming to WebAssembly, and the .NET team has been very busy to get performance updates ready for .NET 7. We’re able to activate some WebAssembly-related features in Uno Platform ahead of the official .NET 7 support, so that you can experiment with it, or as some of our clients do – use it in production as we will be there to support you if needed.

In particular, the biggest improvements are in the area of WebAssembly Exceptions and Threading support.

1. WebAssembly Exceptions support

Enabling WebAssembly exceptions in your projects allows for your code to stay entirely in WebAssembly for exception handling, improving the performance as a result. In addition, the generated code size is smaller too.

Support for this feature has been added in .NET 7 previews, and it is now included in Uno Platform Wasm projects and so your Uno-Wasm projects now automatically benefit from performance improvement and file size reduction that this feature brings. All you need to do is upgrade to the latest 4.4 bits and update Uno.Wasm.Bootstrap to the latest preview.  This new feature is enabled by default in Uno.Wasm.Bootstrap 4.0-dev builds, and makes use of the WebAssembly specifications for Exceptions handling.

Since WebAssembly was introduced, exceptions had to be emulated by Emscripten, causing each try/catch/finally block to force the “decoration” of invocations through JavaScript. This had a significant performance impact, as JavaScript/Wasm boundaries crossing is expensive.

For example, here’s a before-and-after comparison of call stacks, captured using the Chromium profiler:

You’ll notice that the “invoke_viiii” and “js-to-wasm:iiii:” frames have been removed, causing this synthetic benchmark to be 1.75x faster.

Because the Exception Handling feature has been available for a while in major browsers, starting from the Uno Bootstrapper 4.0 previews which use this feature, older browsers versions are not supported anymore. If an app needs to be compatible with earlier browsers, it is best to use the Uno Wasm Bootstrapper 3.x builds.

2. WebAssembly Threading support

Another exciting update is experimental Threading support in .NET 7. Our team has been working with the .NET team on providing early feedback for the hard work they’ve been putting into enabling Wasm threading for the past few months. This is another great open source win for everyone, as ultimately both .NET and Uno Platform communities will benefit from this feature.  We are glad to be able to contribute to this journey by being one of the first to take Wasm threading to our community.

Both Uno.UI and the Uno Bootstrapper have been updated to include threading support. On the Uno.UI side, this means that you can create Threads or Tasks and use the CoreDispatcher or DispatcherQueue to come back to the main thread. This is enables Web Apps to perform expensive tasks off the UI thread and avoid freezing the UI.

If you have been following us for a while, you may remember that we experimented with threads two years ago with the mono runtime. We’ve been able to reactivate the code we developed back then to enable threads very quickly as a result.

Getting Started with WebAssembly Threads

The .NET team is eager to get feedback for developers needing the support for threads, and so are we!

If you want to experiment with threads in your app, it’s quite easy:

  1.  Update both “Uno.Wasm.Bootstrap” and “Uno.Wasm.Bootstrap.DevServer” to the preview version 4.0.0-dev.174 or later.
  2. Add the following to your `.Wasm.csproj` :
				
					<PropertyGroup>
	<WasmShellEnableThreads>true</WasmShellEnableThreads>
</PropertyGroup>

				
			

You should now be able to use threads through Task and Thread, as well as synchronization primitives like Event, Monitor, etc.

Now, there will be dragons and make sure to open issues with logs and repros if you find scenarios that don’t work properly.

New Scenarios via new GamePad APIs support

We have added initial support for the Windows.Gaming.Input APIs including Gamepad which allows you to get real-time input readings from game controllers (like Xbox controllers) connected to your device – running fully cross-platform on Android, iOS, macOS, Windows and even WebAssembly! This is also an important building block for support of remote controllers for TV-based scenarios. And we made sure to test it on Tesla web browser – because why not 🙂 ?

 

Many Small Performance Improvements for all platforms...

..and over time they add to a lot. As for every release, we’re making performance updates across the board to improve startup time or specific runtime scenarios:

  • We’ve made some changes to the way android drawables are resolved. This time, on net6.0 and later, we’re generating the table of drawables instead of relying on reflection. This makes for a zero-cost startup for this part and saves about 40ms.

  • On iOS and macOS, we’ve made numerous changes to interop costs, such as converting Color to CGColor without an intermediate, avoiding calling specific methods that could re-create managed objects during disposition to release pressure on the GC

  • On Android, we’ve moved the TextBlock Paint creation to Java to avoid invoking many small methods from C#, and do one big JavaScript call, saving 10% during text color creation.

  • We’ve changed how SelectorItem handles selection animations to avoid using DateTime.Now as the source of time. In .NET 6 and later, such calls must go through libICU for localization, making it more expensive than a simple Stopwatch use.

Thanks to our Community Contributors

  • Pre-Android 23 fix (@queequac)
  • Docs updates (@aki32, @mmarinchenko, @workgroupengineering)

Next Steps

To upgrade to latest release of Uno Platform, please update your packages to 4.4 via your Visual Studio NuGet package manager! If you are new to Uno Platform, the best way to get started is to follow our official getting started guide. (5 min to complete)

Share this post:
Tune in Today at 12 PM EST for our free Uno Platform 5.0 Live Webinar
Watch Here