meta data for this page
  •  

Graphics Hardware

The PinePhone has a Mali graphics chipset. Although there is a proprietary graphics driver for the chip it is strongly recommended that the “Lima” driver that is in the latest 5.x kernel and in Mesa is used instead. To make use of the available graphics hardware there is OpenGL 2.1 and Open GL ES 2.0. Here is an example output from glxinfo.

Mobian uses the Wayland compositor instead of X11, which makes it rather unique and leading edge in the Linux world. This also means that it hits a number of corner cases with applications especially because it supports only a much older OpenGL version or the less supported OpenGL ES specification. Note that some people refer to OpenGL as “desktop” and OpenGL ES (GLES) as “mobile.” This gives you a sense of the fact that GLES is much less feature rich.

Note that there are a number of applications already using the graphics hardware in Mobian. For example, phosh's compositor phoc makes heavy use of GLES for certain graphics intensive tasks. Also, the Mpv movie player uses either GL or GLES to make video playback smooth. You can force mpv to use GLES using the “–opengl-es=yes” command-line parameter, otherwise it uses GL. Both are working well and you can get more verbose information with the “-v” parameter.

$ mpv -v --opengl-es=yes <path_to_some_video_file>
...
[vo/gpu/wayland] GL_VERSION='OpenGL ES 2.0 Mesa 20.1.5'
[vo/gpu/wayland] Detected GLES 2.0.
[vo/gpu/wayland] GL_VENDOR='lima'
[vo/gpu/wayland] GL_RENDERER='Mali400'
[vo/gpu/wayland] GL_SHADING_LANGUAGE_VERSION='OpenGL ES GLSL ES 1.0.16'
...

There is strong evidence that using OpenGL 2.1 or GLES 2.0 with Wayland is a configuration that does work well in practice. However, applications that use widget toolkits like GTK 3.x or Qt in this same configuration currently have some problems. Celluloid is a very thin wrapper around the mpv video player above. It literally shares most of its bits with mpv. First of all, like all GTK apps they will not auto-detect that they must use GLES. Instead, you need to provide the environment variable “GDK_GL=gles” so that it will initialize the app with GLES. Otherwise there is a general “Unable to create GL context” error.

$ GDK_GL=gles celluloid <path_to_some_video>

Somewhere in GTK 3.x with the GLES there is a colour channel issue with red and blue. Skin tones look blue. You can see the problem is the gtk3-demo. If you run this and go to the “OpenGL Area” demo you'll see a triangle that is blue, but is really supposed to be a yellow gradient.

$ sudo apt install gtk-3-examples
$ GDK_GL=gles gtk3-demo
... go to the OpenGL Area and click Run

Beyond the colour map issue there is also some frame repetition problems as you can see in this video and is also visible in the Epiphany webkit browser if you run it with the environment variable on a graphics intensive website. Epiphany also exhibits a problem where it only renders a single line of a web page that is one pixel in height, but it is unclear yet what the cause could be. Scrolling with your finger sometimes reveals the whole webpage along with the issues of the colour channel mentioned above.

Qt applications, such as PureMaps, uses GLES for graphical acceleration. In this specific case there are certain objects, such as the bullseye (current location) and pins that are missing from the maps. There are workarounds, which involves either picking another map provider or forcing Qt to fall back to software rendering. These are described in the PureMaps wiki page.

So, while it is much more problematic to use GL or GLES with Qt/GTK it is commonly thought that the problems are probably somewhat easily fixed with the right knowledge an persistence. The original author of the GLES support in GTK3 pointed to this experimental branch with some examples of what is being done to improve GLES support with X11, which may give some idea of what's needed to get things working better with Wayland. https://gitlab.gnome.org/GNOME/gtk/-/commits/wip/ebassi/gdk-egl-x11/

GTK4 is reported to be working much better with GLES on Wayland because it uses less CPU-based rendering and focuses more on the hardware. The celluloid author has said that the colour map issue is fixed when he tried it with GTK4. https://github.com/celluloid-player/celluloid/issues/580

Tracing OpenGL using apitrace

When debugging OpenGL problems the mesa teams recommends using a tool called “apitrace,” which will intercept all of the different GL* API interactions the program makes during its execution. This is also useful to see whether a program actually uses the graphics hardware or not, which isn't always obvious. It's also easily installed using the Debian package.

$ sudo apt install apitrace
$ apitrace trace -a egl -o output_trace_file.trace mpv <my_program> <arg1> <arg2> ...
apitrace: loaded into /usr/bin/apitrace
apitrace: unloaded from /usr/bin/apitrace
apitrace: loaded into /usr/bin/my_prgram
apitrace: tracing to output_trace_file.trace
apitrace: attempting to read configuration file: /home/mobian/.config/apitrace/gltrace.conf
... program runs until you exit it...
apitrace: unloaded from /usr/bin/mpv

If there is no trace generated then the program didn't use any graphical acceleration at all when it ran. Note that some programs only use GL or GLES depending on the workload. Epiphany is a great example since it won't use GLES on the mobile wikipedia site, but it will for one that has more advertisements and animation. If you forgot to add the GDK_GL=gles environment variable on a GTK application it might fall back to using software rendering.

After you have extracted a trace you can dump human readable information from it.

$ apitrace dump output_trace_file.trace
3 eglGetPlatformDisplay(platform = EGL_PLATFORM_WAYLAND_KHR, native_display = 0xffff900013e0, attrib_list = {}) = 0xffff9000fb20
4 eglInitialize(dpy = 0xffff9000fb20, major = NULL, minor = NULL) = EGL_TRUE
8 eglBindAPI(api = EGL_OPENGL_API) = EGL_TRUE
9 eglChooseConfig(dpy = 0xffff9000fb20, attrib_list = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE}, configs = NULL, config_size = 0, num_config = &12) = EGL_TRUE
10 eglChooseConfig(dpy = 0xffff9000fb20, attrib_list = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE}, configs = {0xffff90075610, 0xffff900756e0, 0xffff900757b0, 0xffff90075880, 0xffff90075950, 0xffff90075a20, 0xffff90075130, 0xffff90075200, 0xffff900752d0, 0xffff900753a0, 0xffff90075470, 0xffff90075540}, config_size = 12, num_config = &12) = EGL_TRUE
...
# Here you can often see the negotiation of what sort of OpenGL the program can use and what the system supports
...
115 eglCreateContext(dpy = 0xffff9000fb20, config = 0xffff90075610, share_context = NULL, attrib_list = {EGL_CON
TEXT_MAJOR_VERSION, 4, EGL_CONTEXT_MINOR_VERSION, 4, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PR
OFILE_BIT, EGL_NONE}) = NULL
# The above line checked if OpenGL 4.4 can be used
116 eglCreateContext(dpy = 0xffff9000fb20, config = 0xffff90075610, share_context = NULL, attrib_list = {EGL_CON
TEXT_MAJOR_VERSION, 4, EGL_CONTEXT_MINOR_VERSION, 3, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PR
OFILE_BIT, EGL_NONE}) = NULL
# It tries again with OpenGL 4.3 and so on until the last eglCreateContext
...
122 eglCreateContext(dpy = 0xffff9000fb20, config = 0xffff90075610, share_context = NULL, attrib_list = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 1, EGL_CONTEXT_OPENGL_PROFILE_MASK, 0x0, EGL_NONE}) = 0xffff90075fe0
# It finally settled on OpenGL 2.1 (desktop) in this case, not GLES 2.0
...