Improving ARM® Mali™ drivers on fbdev

This blog post refers to the public ARM Mali Midgard r6p0 user-space binary drivers for GNU/Linux which are now available for download.  The "fbdev" variant now has support for dma-buf using a standard ioctl, which is explained in detail here.

What is wrong with fbdev?

The Linux kernel defines a user-space API that lets applications control displays via frame buffer drivers, also known as "fbdev" drivers.  This is achieved via a set of file operations on "/dev/fb*" devices such as ioctl or mmap, which allows direct access to the pixel data of a display.  While this is a simple, widespread, lightweight and powerful interface, it is no longer suitable in the world of modern embedded graphics computing.

For example, it does not provide any means to share the frame buffer directly with another kernel driver such as a GPU driver.  When running an application that renders graphics with a GPU, each frame contains pixels that the GPU generated within its own buffers.  The display controller is a separate entity with its own frame buffer located elsewhere in memory.  So the standard way of displaying the GPU frames in fbdev mode is for the user-space (EGL part of the driver) to copy the data from a GPU buffer to the display controller's frame buffer.  This is done on the CPU, typically by calling memcpy.  This works, but can easily become the biggest bottleneck in the system and is therefore not acceptable in a real product.

There are many other limitations to "fbdev" which are not covered in this blog post, such as managing layers, synchronising applications with the display controller or performing 2D composition in hardware.

What can we do to fix it?

All new display controller drivers should be implementing the Direct Rendering Manager (DRM) API instead of fbdev.  DRM offers a much more modern set of features and solves many of the problems seen with fbdev.  However, there are still a lot of GPU-accelerated products that control their display using an fbdev Linux driver.  Work needs to be done on each of these to avoid the unacceptably inefficient CPU memcpy and to let the GPU directly write into the frame buffer.

A typical way of achieving this is by using the dma-buf framework in the Linux kernel.  Typically, the frame buffer driver registers itself as a dma-buf exporter and implements a way for user-space to get a file descriptor for this frame buffer (an ioctl).  The user-space driver then passes the dma-buf file descriptor to the GPU kernel driver to import and use.  When rendering happens, the GPU pixels are directly written into the frame buffer using a hardware DMA operation - this is also referred to as "zero-copy" and is much faster than calling memcpy.  However, there is no standard ioctl in the fbdev API to export the frame buffer with dma-buf so each fbdev driver has a slightly different one.  This means the user-space needs to be modified to work with each fbdev driver, which is not compatible with the public standard Mali binary drivers as they must not depend on platform specific display drivers.

FBIOGET_DMABUF

This is why, starting with r6p0, we are adding a more generic ioctl implementation to export the dma-buf file descriptor defined as a custom extension to the standard fbdev API in supported kernels: the FBIOGET_DMABUF ioctl.  This way, no extra dependency is being added on the user-space binary.  If the ioctl is not available on a given kernel, then the user-space will revert to memcpy.  We have already enabled this in our ODROID-XU3 Linux kernel branch on Github.

We should keep this added functionality in all our new fbdev Mali Midgard binary drivers and Linux kernels for supported platforms, such as ODROID-XU3, Chromebook devices with an ARM Mali GPU, Firefly...

  • First thanks to al of you solving the bottleneck, this is really great news!

    Do I understand this article right that the new driver could support DRM?

    Currently I'm trying to get Chrome / Ozone with the gdm platform running on an odroid-xu3.

    So far it fails on creating the window surface.

    mn on the binary blob shows that there is now a local eglCreatePlatformWindowSurfaceEXT imlementation in the r6p0 driver.

    From definition this one should be used to pass an gdm surface instead of a native window, is it just a fake implementation?

    Or is it somehow adressable using flags in eglCreateWindowSurface?

    Thanks!

  • Thanks for your feedback.

    The Chrome OS Mali drivers are produced by Google to work with the Chrome OS windowing system, so we don't have control over these drivers.  Sorry I can't answer your question due to this.  Also the fbdev binary drivers mentioned in this blog post do not use DRM or GBM but only the classic frame buffer API.  I can see there is some public interest in a standard Mali driver with GBM/DRM back-end, we'll see whether we can do this and if so then we'll make a new blog post.

    Guillaume

  • Thanks for making this clear, Guillaume.

    I took the last time to go a little bit deeper into the Chromium / Ozone-gbm internals and opened a ticket for this:

    Re: Is it possible to benefit from DMA in r6p0 using DRM + GPU?

    I think its a better place to continue discussion as this blog hiere, isn't it?

    Markus

  • Is there any news on when updated Firefly binary drivers will be available?

    I realise it will require an updated kernel but we're prepared to make any necessary kernel changes if it means we can get decent graphics performance without having to rely on shimming Android binaries with libhybris.

    Thanks,

    John