Windows on Arm has really gathered momentum and the ecosystem is continuing to grow. It now has the supporting tools to make it easy to port Windows apps to run natively.
And it is worth it – the increase in speed and battery life over emulation of Win32 apps is significant, if hard to quantify.
With Universal Windows Platform (UWP), there are a few simple steps to get your code running natively. UWP is Microsoft’s modern framework designed to make cross-platform development easy. And, as ever more libraries, open-source software projects and other dependencies move over to Arm64, the last hurdle is now more achievable than ever.
Let us look at a case study of how a developer ported their UWP app to native Arm64.
StaffPad is an award-winning music notation app built for composers. You can write music with a pen on screen, edit it and hear it played back. There is some complicated mathematics behind it, which will be explained shortly, but first let us look at the application’s setup.
StaffPad is built by an international team of developer-musicians, from various backgrounds. The app is UWP-based. This decision was made due to the team’s want to be cross-platform, along with the ease of creating a friendly portable device user experience.
The StaffPad developers use Visual Studio Enterprise. The app is split in two layers: 1) a pure-C++ core, and 2) a “native experience” layer handling the User Interface and interaction, which is C#/XAML.
When porting, the biggest issue is likely to be third-party dependencies, especially with UWP solving most other cross-platform issues. For StaffPad, this was true as well.
There was one main blocker here – third-party libraries with vector intrinsics designed for intel-specific hardware acceleration. These were used mainly for FFT (Fast Fourier Transform) processes in the audio engine.
StaffPad’s solution was to build their own optimized FFT code. There were alternative third party library options available which would have given the solution quicker. However, by writing just what StaffPad needed, it was able to keep it lean and fast and in-house.
No other dependencies caused StaffPad any trouble.
Local libraries were easy. StaffPad just needed to set its target to Arm64 and rebuild, and make sure that the main project was pointing at the native Arm library. Despite having a few internal libraries of audio codecs and other things, this was done within a couple of hours.
StaffPad uses plenty of UWP features like Win2D – and they ported without any issue. So, like local dependencies, this was just a matter of targeting Arm64 and building. Having sorted the dependencies, both the C++ core and the C#/XAML UI layer compiled just fine.
Testing was crucial, but straightforward. It is vital to see the app on a device to show what it looks like in a new environment. In StaffPad’s case, there were just a few small mistakes that were quickly fixed once the app was looked on a Microsoft Surface Pro X.
Visual Studio 2019 comes with Windows on Arm debugging, which is also available in Visual Studio 2017 if the 15.9 update is applied and the Arm64 toolset is then downloaded. It only supports Remote Debugging, and there are a couple of steps to get set up for it. The device must accept Remote Debugging. This is achieved through going to the Settings window, choosing Windows Update > For Developer and turning on Developer Mode and Device Discovery. When turning on Device Discovery, you will be able to pair your Windows on Arm device with the machine you are developing on.
Visual Studio Code has local debugging, but the libraries and compilers are still being ported, so it may not be possible depending on the language you are developing in.
For their Continuous Integration (CI) pipeline, StaffPad use Azure DevOps. Windows on Arm just slotted in without any difficulties, to be permanently tested like everything else.
With a well-tested app ready the next question is how to deploy.
Rather than going for an installer, StaffPad deploys to customers through the Windows Store. The Store works well with UWP, allowing easy options across a range of platforms – you can even get StaffPad for the Microsoft HoloLens. To deploy, the new platform version was just uploaded and then was available straight away.
The difference between emulation and native was striking for StaffPad. The app does push devices with graphics, audio, touch, machine learning (ML) and networking all needing processing. In particular, the audio engine failed to perform under emulation, with the start up slow and memory usage high.
Natively, the UI is snappy, loading is fast, pen usage is lag-free – overall it is a joy to use.
It is hard to compare machines as they all have different specifications, but native Arm64 StaffPad’s start up time on the Microsoft Surface Pro X is much faster. The feel of the app in use is also smoother than on similar x64 devices. For StaffPad, the speed, all-day battery life, instant-on and continuous connectivity were all reasons why it wanted to be using Windows on Arm. You can read more from StaffPad in this case study.
As you have seen through this example, porting your UWP app to Windows on Arm is generally easy. There can be some issues with dependencies and libraries, but more and more of them are producing Windows on Arm versions. Many Open Source projects are already compatible or may not require much effort to get them going, if they are a dependency.
And once the dependencies are sorted, it is easy from there. Target Arm64, build, and deploy.
It is do-able and worth it for the performance improvements.
The following resources provide more Windows on Arm and UWP information:
Learn more about Windows on Arm