A while back, I landed a change to update Cairo’s GL backend to support OpenGL ES version 3.0. In this blog post I’ll describe what this is, what makes it important, and what future steps can be taken.
What is Cairo?
Cairo is a drawing library that provides high quality 2D rendering of vector graphics. It’s claim to fame is a focus on making what you see on the screen identical to what gets printed on the printer. It’s raison d’être is to create SVG and PDF files with fancy graphics and nicely anti-aliased text. Cairo provides a stable, well-tested, well-documented API for applications to build against; historically, the list of applications and products using Cairo is impressively long.
Rendering performance is also important to Cairo, which it addresses by making provisions for ‘rendering backends.’ The backends tap into platform-specific underlying 2D graphics systems as output targets; the win32 backend ties into Window’s GDI services, xlib interfaces with the X window system’s windows and pixmaps, and so on.
However, computer hardware advancements have focused on optimization of 3D functionality and performance far more than 2D, to such a degree that it is faster to delegate 2D rendering to the 3D GPU. If nothing else, on most systems the GPU is quite powerful – essentially a whole secondary computer inside your computer – so offloading any computation to it can prove to be a win. Particularly if it can utilize the graphics optimization features, this is what the Cairo OpenGL backend aims to achieve.
What is OpenGL?
OpenGL, or the Open Graphics Library, is a high performance 3D vector graphics API for doing hardware-accelerated rendering. It’s been under constant development since 1991 and is an industry-wide standard. OpenGL ES is a variant of the OpenGL API, originally designed to be more suitable for embedded devices. OpenGL ES has evolved over time to approach feature parity with “regular” OpenGL and expanded to support a vast array of hardware, including the desktop platforms that OpenGL targets.
Cairo’s OpenGL backend (supporting GLX, WGL, and EGL) promises use of the underlying 3D tech for hardware-accelerating 2D drawings, although the efficiency of translating Cairo’s canvas model to the GPL has not always panned out as well as hoped. There is also an OpenVG backend, though it hasn’t received quite as much development attention. Cairo’s OpenGL implementation also includes support for OpenGL ES v2.
Say Hello to Cairo GL ES v3
The OpenGL ES 3.0 spec was released five years after ES 2.0 and packs quite a bit of new functionality. Numerous enhancements were made to the rendering pipeline that, if leveraged properly in Cairo, could provide much faster rendering performance. Texturing functionality was greatly enhanced, and while Cairo’s basic graphics operations aren’t heavy users of texturing, the enhancements could provide a significant functional and performance boon for more advanced drawing.
These new functions don’t come automatically though. The first step, which has landed in Cairo’s trunk, simply detects if GL ES 3.0 is available; if so, it creates a surface that’s able to talk with the GPU with this version of the protocol. Additional coding to leverage the new functionality will be introduced later as follow-on work.
This new GLESv3 support can be turned on at compile time via the –enable-glesv3 configure flag. A configure flag can also be used to select a particular GL variant. For instance, to use EGL with GL ES 3:
./configure --enable-egl --enable-glesv3
Samsung initially implemented the GLESv3 support for the Tizen platform, and it had been proposed for Cairo upstream in 2013, but this work was interleaved with a number of unrelated features and optimizations, so wasn’t in a directly-implementable state. I extracted the baseline GLESv3 support from this work and did the polishing needed to land it. The additional features and optimizations from that branch will leverage GL ES 3.0’s capabilities to provide improved performance over GL ES 2.0, but extracting them and rebasing them remains for future work.
Since the original (experimental) introduction of cairo-gl as a means to leverage the power of the GPU, graphics technology has increased its capabilities. The promise of 3D-hardware rendering to 2D drawing is even bigger than before; yet, to tap it Cairo must advance forward to adopt newer APIs, algorithms, and optimizations. Adopting GLESv3 support, while perhaps not exactly aggressive, is still necessary to keep the leading edge of technology within sight.
Much can be done to further leverage, optimize, and polish Cairo’s OpenGL ES 3.0 support, and we can also look to adopting even newer versions: OpenGL ES 3.1 was published in March 2014 to add compute shaders and independent vertex and fragment shaders; OpenGL ES 3.2 became available in August 2015, bringing functionality to support complex scenes and various optimizations for advanced usages.
Beyond OpenGL, there is also the new Vulkan 3D API to consider. This is not advertised as having any particular advantage for 2D rendering over what OpenGL can do, although it does include hardware management and parallelization advancements that theoretically could bring some benefit. However, since it’s a newer technology, support on older hardware may be an issue, at least for a while. Further, it remains to be seen if Cairo’s backend architecture would leverage or limit Vulkan’s capabilities.
If you use Cairo, take a look at what it can do with OpenGL ES v3 and let us know what you think!