Skip to content
Siarhei Siamashka edited this page Jul 31, 2013 · 8 revisions

This page tries to explain the DRI2 dialect used in Mali400 drivers and the deviations from http://www.x.org/releases/X11R7.7/doc/dri2proto/dri2proto.txt

DRI2BUFFER structure interpretation
attachment Always set to 1 (DRI2BufferBackLeft)
name UMP buffer secure id
pitch Row stride (must be a multiple of 8)
cpp Number of bytes per pixel (4 for 32bpp)
flags Starting offset inside of the UMP buffer

r3p0 and r3p1 blobs

The typical communication flow:

 DRI2GetBuffers A
 DRI2SwapBuffers (buffer A becomes visible)
 DRI2GetBuffers B
 DRI2SwapBuffers (buffer B becomes visible)
 DRI2SwapBuffers (buffer A becomes visible)
 DRI2SwapBuffers (buffer B becomes visible)
 ...
 DRI2SwapBuffers (buffer A becomes visible)
 DRI2SwapBuffers (buffer B becomes visible)
 ...

DRI2GetBuffers always requests for a single BackLeft buffer. The allocation of two UMP buffers (let's call them A and B) is done by the DDX driver in Xorg server (see the DRI2BUFFER structure). The Mali blob draws something in these buffers and calls DRI2SwapBuffers to get them visible on screen. Looks simple so far? Now the following communication happens to be also valid (and does occur in practice sometimes):

 DRI2GetBuffers A
 DRI2GetBuffers B
 DRI2SwapBuffers (buffer A becomes visible)
 DRI2SwapBuffers (buffer B becomes visible)
 DRI2SwapBuffers (buffer A becomes visible)
 DRI2SwapBuffers (buffer B becomes visible)
 ...

Now if we remember that the Mali blob only requests the BackLeft buffers, back to back requesting for the "same" buffer supposedly makes no sense. However in the Mali DRI2 dialect this has to be handled as depicted above (DRI2GetBuffers and DRI2SwapBuffers may be executed out of order relative to each other).

Also in X11 desktop system, windows may be resized at any time. DRI2 specification describes DRI2InvalidateBuffers event, which is used to notify the client about such changes, so supposedly the client may request the new buffers with the new size. But the Mali blob simply ignores this event. Instead it performs GetGeometry polling to detect the window size change. This implementation is also buggy, and we may easily end up with a size mismatch for buffers A and B (see https:/ssvb/xf86-video-sunxifb/commit/9e0a87319b90e3e364fde7cffd24662926f5a4fa). The following program can be used as a testcase: https:/ssvb/xf86-video-sunxifb/blob/master/test/gles-rgb-cycle-demo.c (if the bug manifests itself, the order of changing colors is going to be messed up).

About buffer swap throttling and vsync. Currently in xf86-video-sunxifb it is implemented by inserting FBIO_WAITFORVSYNC ioctl into DRI2 CopyRegion function. It gets called when taking care of the buffers swap (yeah, this is messy and maybe needs a cleanup). Whether the Mali blob waits for the DRI2BufferSwapComplete event or just happens to block on GetGeometry request is yet to be confirmed.

r3p2 blob

The typical communication flow becomes:

 DRI2GetBuffers A
 DRI2SwapBuffers (buffer A becomes visible)
 DRI2GetBuffers B
 DRI2SwapBuffers (buffer B becomes visible)
 DRI2GetBuffers C
 DRI2SwapBuffers (buffer C becomes visible)
 ...
 DRI2GetBuffers X
 DRI2SwapBuffers (buffer X becomes visible)

As every buffer is unconditionally requested every time, we automagically avoid the window resize bug. Yay?

Useful tools

http://xtrace.alioth.debian.org/

Clone this wiki locally