I looked through all modern skins from our add-ons catalog and picked several scenarios that had a negative impact on AIMP performance and UI response. I did my best to resolve them at the skin engine level.
I found that in most skins, blurring was the main source of interface lags. In 80% of cases blurring was applied to font shadows and in 15% – when an album cover was used as a background for some elements. Only 5% fell on the BlurredGlass feature for dynamic content.
I researched the most common scenarios. Aiming to resolve the most frequently encountered lags, I implemented several enhancements that then appeared in AIMP5:
- Instead of the Gaus blur algorithm, skins now use the stack-based blur algorithm. While it offers inferior quality at high blurring settings, it works two times faster.
- Small raster images now use the stack-based algorithm’s single-threaded version. The blurring effect is applied quicker, because there is no need for additional threads to be initialized.
- At the CoverArtDisplay control level, we introduced the BlurLevel property. It allows the engine to prepare an album cover’s blurred version beforehand. This is faster than the former mechanics – blurring the cover every time it renders like how it happens with BlurredGlass.
The algorithm for applying the mask to the layer now uses a table of pre-calculated values. This change slightly increased the amount of memory used (64 KB), but gave a 2-fold boost in performance.
We implemented shared access to temporary buffers and supported their caching. This sped up transition animation by up to five times.
We also redesigned the API used to transfer visualization data between the sound engine and the skin engine. For AIMP5 this meant a decrease in data conversion procedures and a 3.5-time productivity increase.
“Tile” Fill Mode
Fill speed grew significantly in scenarios when fill mode is set to “tile” and over 10 copies or the original texture are displayed.
Our skin statistics showed an interesting trend: album covers are usually displayed in four particular sizes. In previous versions, the data provider of the current track stored the original cover art and scaled it to the target size on rendering. In AIMP5, the provider has a small cache that stores the cover art’s last 4 sizes.
If the cache can accommodate all cover sizes a skin needs, AIMP renders covers 12 times faster than before. However, the rendering speed may drop down to 1 in skins that display more cover sizes.
High DPI Emulation
AIMP supports High DPI emulation mode. The skin engine uses anti-aliasing and stretches images and windows to fit the desired size. In AIMP5, we sped up this process by 1.5 times.
ACS5 is a new container for skin resources that outperforms its predecessors. It optimizes resource storage and helps the skin engine load resources:
- Instead of solid compression, the container compresses each resource individually. Although this change increased the skin size by 40%, it sped up loading time for large skins. This became possible after we eliminated the temporary buffer that was necessary for the solid container to unpack.
the Nagra SNST 4K skin took up 94 MB in the ASC4 container, and 102 MB in ACS5. However, when being loaded, its peak memory use was 1.8 GB, while with ACS5 it’s only 270 MB!
- Scripts and expressions in binding links are compiled before they are exported into ACS5. This leads to a 3-fold increase in script loading speed. Expressions are also calculated a few times faster, because they do not need to be parsed before each use anymore!
- Changes in storage mechanics affected textures as well. If a texture has a solid single-color fill, it is replaced with a simple color. This has a positive effect on storage use and rendering speed.
Since ACS5 implements file-by-file compression, the texture is unpacked only when AIMP accesses the texture for the first time. The skin engine also learned how to track which textures AIMP uses, and which ones it uses no more. The unused textures are archived and offloaded from memory. With this mechanism we significantly decreased the amount of memory that skins with high dpi support use – the engine simply does not unpack textures for unused scales.
When using old skin formats, the skin engine now projects the file into memory instead of loading it into memory directly. According to our data, the skins now load 20% slower, but consume half as much memory.
Note that for you to get all the benefits of the new format, old format skins will be repacked into the new format the first time you use them. Thus, the first time you use an old format skin in AIMP5 will be slower than even in AIMP4.
The skin information dialog now includes compatibility settings. They allow you to specify the skin engine for which the skin was developed. The information about skin engine differences is available in the new skin editor’s help documentation.
To draw menu items, you can now combine simple colors with textures or use simple colors alone.
ТThe context menu now supports scrollbars:
To replace buttons with a scrollbar, set scrollbar textures in the appropriate properties.
You can keep context menu icons in the resource repository that also stores other textures of that skin. This will allow you to add different icons for the skin’s different themes.
You can also apply automatic icon themes to you icons, so that they match the current font color of the menu item:
The setting is useful for modern single-color icons.
The OnClick event became available for user menu items. The event accepts handler scripts.
You can use the resource repository to set resources for other UI elements – the tray icon, context menu icons, tooltip colors.
You can now use a color resource from the repository as a font color.
You now have a capability to change the transparency of the inherited color – similar to how it was implemented in AIMP for Android v3.0.
You can now use scripts to open font and color settings dialogs.
Playlist entries can now have a background texture in addition to or instead of a color.
We introduced the SkinLayout property that defines a texture’s storyboard:
- States – a texture contains types of a “star” for different states. The control will draw five of such “stars”, and their state will be determined by the current rating value.
- StatesAndValues – a texture contains final types for different rating values and rating states. The control will use the texture frames “as is”.
The CopyToClipboard method is available from the scripts. It copies the current displayed value to the clipboard.
The CopyToClipboard method is available from the scripts for TASETextDisplayEx as well.
We introduced a new event – OnHyperlinkClick. It allows you to override a default action for hyperlinks.
Marque display mode that appealed so much to our users is now available for the Windows version. Marque mode allows the player to automatically scroll the displayed text back and forth if it does not fit inside the control that displays it.
This is a new control that is a simplified version of TASEAnimator. It displays frames that are switched manually and are programmed by means of a binding or a script. Frames are not switched by a timer.
This new control is a special variant of TASESlider, with the waveform visualization isolated. TASESeekBar also learned to visualize a repeat area in AB-repeat mode, for which we introduced additional color and texture properties:
This page selector is a simple control that came from mobile UI. The control shows how many pages there are and the user’s current location:
The element is bound to a “Tab Control” type access point and the element’s width is calculated automatically depending on the number of available tabs.
At the level of the docksite element we introduced a property that allows you to specify which windows it accepts as embedded. Thus, each docksite element can now contain different windows.
Auto and Enabled access points were added.
This new provider reports the user playback queue status.
A data provider for the playback queue.
This new data provider allows access to information about a playlist’s selected file.
A top-level context menu that lists all options for creating a new playlist.
A new data provider that allows access to the scrobbler’s state and advanced information about the currently played track. The provider only works when the “Scrobbler” plugin is connected and properly configured.
* * *
You can find a detailed list of changes in the skin editor’s help documentation.