How to get 60 fps UI on mobile?
We have a big announcement to make – Project Colibri for Games is renamed to Hummingbird! Hummingbird is Coherent Labs’ new HTML5 rendering middleware which targets mobile and embedded devices. In a series of blog posts, I’ll describe the technical details of Hummingbird and what makes it times faster than any other solution on the market.
I’ll start with a general overview of the challenges that HTML5 rendering brings and follow up with the architecture we have put in place to overcome these challenges. In the post, I’ll be talking about HTML but I’m using it as an umbrella term that also includes CSS styling and JavaScript – everything necessary for a rich, animated page.
Rendering HTML user interface
The history of HTML (CSS and JavaScript) is quite long but from an engineering viewpoint, it has been a difficult field. The technology is ubiquitous and part of everybody’s everyday life but relatively few software solutions for rendering HTML have been developed over the years. The most recent browsers have at their core code that began it’s development more than 15 years ago.
There are very few attempts at creating an HTML renderer from scratch. Why?
- The HTML & CSS standard are complex and require significant engineering efforts even to show relatively simple pages.
- The standards are huge. To be standard-compliant you have to implement dozens of HTML tags, hundreds of CSS styles and thousands of JavaScript APIs in your solution.
- You have to support ill-formed and outdated pages. In order to be competitive, your web browser must support billions of pages that are old (with archaic standards) or badly written. The push of browsers to be standard-compliant is relatively recent, during the “browser wars” many software packages implemented their own proprietary extensions.
- Browsing security is paramount. It’s never fun to be hacked from your browser.
Browsers are not suitable for games
All the reasons above make “generic” web browsers unsuitable for video game UI. The browser core is a behemoth of code that is both slow for games and uses huge amounts of memory.
- All browsers use very deep hierarchies of polymorphic types.
- Per-frame memory allocations are abundant.
- String operations everywhere.
- Rendering is not always GPU accelerated.
- Dozens of layers of indirection (often cross-process communication).
This is not to claim that browsers are badly written – on the contrary, they are probably one of the best-engineered pieces of software that is available open source (WebKit, Blink, Gecko), but their runtime requirements are very different from what a game needs.
So how come we believe that HTML is the future of game UI?
We believe that if engineered smart, a UI middleware based on HTML could work really well for game UI. It needs the following features to be technically viable:
- High performance – take as little frame time as possible to let other systems do their work.
- Small memory footprint. The memory footprint of the library should be small and linearly increase with the complexity of the UI itself.
- Scalable. Modern processors have many cores and effectively making use of them is key.
- User control. Developers want to have maximum control over all aspects of the library – from memory allocations to the JavaScript garbage collector.
- Authoring tools. Authoring tools are key to empowering artists to make the best of the tools and iterate quickly.
The Hummingbird technology
Hummingbird is designed with the requirements of game UI in mind. It is engineered from scratch to work great on mobile and embedded devices. While it shares large amounts of code and paradigms with our desktop and console product – Coherent GT, it also has major differences. The library is an engineering effort that uses no existing open-source component in its core – DOM, styling, layout, rendering are all done with one goal in mind – performance.
Conceptually, we have built Hummingbird very similar to a game engine – this is a point where we differ significantly from other web renderers. If you think about it, there are many similarities between engines and an HTML renderer.
- There is a logical “scene” – in HTML this is the DOM
- There is a “rendering” scene – in HTML this is what will actually be drawn on-screen
- There are animations – often hundreds of them
- There is scripting – in HTML this is the exposure of the DOM to JavaScript
- There is complex rendering of hundreds of elements
Task system
Hummingbird employs a task-based (aka job-based) approach to the workloads and the data transformations it has to do. All operations are queued in task channels where they can be performed on a number of threads improving both performance and scalability. Hummingbird has a very rich system for tasks that is more complex than the similar infrastructure in most game engines. The reason is that while most games have a single “world”, the web engine has multiple – all currently active pages – we call them Views.
Memory footprint
Hummingbird allocates little to no memory per-frame, this brings very large benefits on mobile platforms where the memory allocators are slow. We employ a palette of different allocators and allocation strategies to make sure that memory is reused and we seldom have to reach the generic memory allocator.
Data-oriented design
The data layout and transformations in Hummingbird try to abide as much as possible to the data-oriented design paradigm. This is particularly challenging in HTML because the standard itself is very tree-centric. Everything in the DOM belongs to a tree structure which is difficult to adapt to the “flat” memory that gives the largest benefits during traversal and transformations. Hummingbird uses intermediate data representations where the structures are re-ordered in ways that will take the most out of the caching capabilities of the processor.
Animation system
All animations are kept in flat structures that minimize branching and maximize data locality. All animations are ticked together and the result later applied to animated nodes. This is similar to an Animation “component” – standard in many game engines. The alternative “object-oriented” approach would mandate every animation ticking by itself and modify the state of the DOM object. This would lead to poor cache utilization and heavy branching.
Rendering
On the rendering side, Hummingbird uses Renoir – the same graphics library we also use in our PC and console product – Coherent GT. Many modifications were however, introduced to Renoir to better fit mobile platforms. Renoir renders everything on the GPU and dynamically batches rendering commands to minimize draw calls.
Scripting
On the scripting side, Hummingbird uses lightweight “glue” methods that bridge between the C++ and JS world. A lot of the “garbage” values that are generated in JS during a typical game UI workload come from the modification of CSS styles with strings. The default styles in CSS make heavy use of strings. Hummingbird introduces extended styles that directly take numbers and objects and significantly improves the performance of style modifications from а script.
Visual authoring tool
A great UI middleware provider must empower all members of the development team. That is why in Hummingbird we have integrated our powerful visual editor. The Coherent Editor allows UI designers to create interactive, animated mobile user interface without the need to write any scripts. How cool is that?
This was a 10000-foot-long overview of some of the design decisions we made on Hummingbird and the rationale behind them. In following posts I’ll explain more about particular sub-systems and how they work. Are you interested in trying out Hummingbird? Sign up for the Beta here.
Follow Stoyan on Twitter: @stoyannk