The next big change that’s in the works for the arcade app is an upgrade of the version of the Starling framework that we use. This has involved a complete overhaul of most of the menus and views in the app, and also to some of the background systems that are used. However, this work has been extremely beneficial to the overall quality of the app and its codebase.
There are a few main advantages to updating to Starling 2.0:
- Any new or updated libraries we use were beginning to drop support for older versions of starling, meaning we couldn’t keep up to date with bug fixes or new features we might want to use.
- Improved memory management with the introduction of an automatic pooling system for some of the more commonly used objects.
- The new Skip Unchanged Frames feature that was added into Starling 2.0.
Being able to upgrade to the latest version of any libraries we used is always a good idea, so I won’t stay on that subject. A greater benefit came from the object pooling system that was added. In the app we use a lot of Tweens and Points, the object pools mean that we can reuse these objects without having to constantly allocate and de-allocate new objects, which is a slow process, this also stops the ActionScript garbage collector from triggering too frequently, which is a big cause of stuttering or slowdown in our apps.
The single biggest reason we had for upgrading to the Starling 2.0 was the new feature that was added that allows the renderer to skip redrawing frames that haven’t changed. Given that parts of the app are almost always static, this is a feature that could deliver a huge improvement in performance.
Testing the benefits
To test the possible benefits of this frame skipping feature we built a test application that took one of the backgrounds from bubble and profiled the results with the new feature both enabled and disabled using Adobe’s profiler, Scout.
The device that we used was an older phone, the Galaxy Nexus, and the sea background from the bubble game. The phone was chosen because while it is an older phone it is still equivalent to a low budget device and this background because it has full screen animations and the billowing clouds are quite complex.
The scene was setup to match the target frame rate of the arcade app, which is 40fps; the animation was exported to target 24fps. This is what the scene looked like on the device:
The first test that we performed was a baseline, using the older version of Starling and the background animations playing and looping. This was the result, taken directly from Scout (The blue bars represent the amount of time spent processing each frame and the red line is the target to maintain a consistent 40 frames per second):
This shows that the average time to render the scene was just over 32 milliseconds this is almost twice the time that was have allocated for each frame at our desired frame rate.
I then updated the project to use Starling 2.0 and enabled the Skip Unchanged Frames feature. The scene and the device remained exactly the same. This is the result:
This shows a vast improvement in how long each frame was taking to render. Even the slowest frames are only taking 18 milliseconds. It also shows when the frames are skipped because there is no change between individual frames.
As a further test to see what the difference would be on a scene that was entirely static, I repeated the above tests with the animation paused. Old version on the top, Starling 2.0 on the bottom:
This is a fantastic difference, with frames taking less than 1 millisecond to render. This is quite a significant result in relation to the arcade app because there are a lot of times when we just display a static screen, especially on the home screen.
Of course these tests are purely focused on profiling the time it takes to render a frame, there is no background processing being performed outside of the animation system, but given that rendering now takes considerably less time there is a knock on effect for when we do have more processing to perform.
Updating the App
Updating the arcade app to take full advantage of these new features was a large task, despite our efforts to create all of the menus used in the app with Starling components alongside the feathers framework we still had some parts of the app that were built with traditional flash components. Given that skipping unchanged frames is not possible where there are objects on the native flash stage we had to start by converting these views over to starling.
The biggest of these was the in-app chat client. This has had a complete overhaul so that it takes full advantage of the hardware-accelerated rendering offered by using Starling. It also allows us to share fonts between the games and the chat client, reducing the overall memory footprint of the app and reducing the number of texture swaps that need to occur on the GPU.
While converting the flash-based views we found that some of the Starling-based views were resizing and refreshing constantly, even when stationary. This was something that stopped the frames from skipping, even though they looked like they hadn’t changed. Once this had been corrected we then made a pass of the other views in the game, to make sure there were no other occurrences of this.
During this upgrade we took the opportunity to strip out any old code or libraries that we are no longer using, this not only simplifies the code it also considerably reduces the time it takes to fully build the app and slightly reduced the size of the generated SWF file that gets packaged into the final app.
Results in the full app
After upgrading the arcade app to Starling 2.0 and updating the menus to fully support skipping unchanged frames I performed some more profiling to see what effect the upgrade had in the full app.
This test was performed on a OnePlus Three on the home screen of the app. This includes scrollable containers for the blog posts, game launcher and centre panel banners. The test included scrolling through the blog posts, swiping through the centre panels and game list and opening the navigation menu by tapping on the toolbar.
This is an example of what the scene would look like:
The first test was a baseline, using a version of the app built with the old version of Starling.
While on the home screen this is pretty much the pattern no matter what I do, its well within the target line, but is constantly processing in all frames.
The second test was just a static home screen in an app built using Starling 2.0
This is as we expected from the results of the initial tests that were performed on the bubble background earlier. Since nothing is changing there is very little processing that needs to be done on each frame.
The third test was to see what the performance looked like when scrolling through the blog posts and swiping through the game launcher.
This shows that between scrolls and swipes there is very little processing going on, but as soon as you start to scroll it jumps up to what it was in the initial baseline test, before dropping back down when the screen becomes static again.
The final test on the home screen was to open the navigation menu by tapping on the toolbar. This is an important test because this is one of the few components of the app that is still rendered using flash’s normal vector renderer, so it will show how skip unchanged frames works when paired with native stage objects.
You can see that as the menu opens it stops skipping frames, even though the starling scene hasn’t changed. This is because the native flash stage is always rendered on top of the starling stage, which means that it needs to be redrawn every frame to avoid any flash content leaving a trail wherever it moves on the screen.
The following image shows that the frames start to skip again once the navigation menu gets removed from the stage.
To see what difference these changes had made in the games tests were run in spin, on the same device as previously used. This was the result of the old version of starling:
And then the same test ran again with Starling 2.0:
This graph shows the frame time between spins, there is very little happening on screen so there are the frames that do nothing, with some redraws happening every other frame, these are likely caused by the chat client updating itself.
During a spin it looks exactly as we would expect, since there is a lot of movement on screen it needs to redraw itself constantly, once the spin completes it returns to the same pattern as the previous image.
While there has been a lot of work involved in this upgrade, it has been more than worth it. A lot of the internal systems and many of the menus have been updated or re-written, but there shouldn’t be a need for such a major update for a long time and anything new that we might need to use will be much easier to implement given that starling 2.0 now has more support than the older version we were using.
I have mainly focused on the skipping frames feature, but there have been other benefits as well. The blog view alone now uses an average of 10MB less memory thanks to the way textures are handled in Starling 2.0 and the new memory pooling features.
A side effect of upgrading has also been a boost to the time it takes to change orientation on Android devices. Orientation change on Android causes the render context to be lost, meaning that all textures need to be restored to the GPU, previously this has taken a long time to do, but the changes made in the latest versions of Adobe AIR (required for Starling 2.0) allow asynchronous texture uploading has reduced this time greatly.
The changes and refactoring that we made to the code has made it much easier to extend and improve, so any big changes like this upgrade will be easier to do in the future.
We’ve only really used a few of the new features that were added in this new version of starling. There are some other interesting new features, such as being able to add dynamic lights using bump-maps and more filters and masking options that could be used to make the clients look even more visually rich. But that’s all something for the future…