• Siarhei Siamashka's avatar
    DRI2: Workaround window resize bug in Mali r3p0 blob · 9e0a8731
    Siarhei Siamashka authored
    The Mali blob is doing something like this:
    
     1. Request BackLeft DRI2 buffer (buffer A) and render to it
     2. Swap buffers
     3. Request BackLeft DRI2 buffer (buffer B)
     4. Check window size, and if it has changed - go back to step 1.
     5. Render to the current back buffer (either buffer A or B)
     6. Swap buffers
     7. Go back to step 4
    
    A very serious show stopper problem is that the Mali blob ignores
    DRI2-InvalidateBuffers events and just uses GetGeometry polling
    to check whether the window size has changed. Unfortunately this
    is racy and we may end up with a size mismatch between buffer A
    and buffer B. This is particularly easy to trigger when the window
    size changes exactly between steps 1 and 3.
    
    See test/gles-yellow-blue-flip.c program which demonstrates this.
    Qt5 applications also trigger this bug.
    
    We workaround the issue by explicitly tracking the requests for
    BackLeft buffers and checking whether the sizes of these buffers
    match at step 1 and step 3. However the real challenge here is
    notifying the client application that these buffers are no good,
    so that it can request them again. As DRI2-InvalidateBuffers
    events are ignored, we are in a pretty difficult situation.
    Fortunately I remembered a weird behaviour observed earlier:
    
        https://groups.google.com/forum/#!msg/linux-sunxi/qnxpVaqp1Ys/aVTq09DVih0J
    
    
    
    Actually if we return UMP secure ID value 1 for the second DRI2
    buffer request, the blob responds to this by spitting out the
    following error message:
    
        [EGL-X11] [2274] DETECTED ONLY ONE FRAMEBUFFER - FORCING A RESIZE
        [EGL-X11] [2274] DRI2 UMP ID 0x3 retrieved
        [EGL-X11] [2274] DRI2 WINDOW UMP SECURE ID CHANGED (0x3 -> 0x3)
    
    And then it proceeds by re-trying to request a pair of DRI2 buffers.
    But that's exactly the behaviour we want! As a down side, some ugly
    flashing can be seen on screen at the time when this workaround kicks
    in, but then everything normalizes. And unfortunately, the race
    condition is still not totally eliminated because the blob is
    apparently getting DRI2 buffer sizes from the separate GetGeometry
    requests instead of using the information provided by DRI2GetBuffers.
    But now the problem is at least very hard to trigger.
    Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
    9e0a8731
sunxi_mali_ump_dri2.c 29 KB