Present extension changes needed for GL/Vulkan vblank modes

Keith Packard keithp at keithp.com
Tue Oct 17 04:52:15 UTC 2017


I know, Present was supposed to support all of the GL vblank modes, and
it mostly does, except for the most common case...

In any case, here's a summary of four presentation modes from Vulkan,
how you'd get that with GL and Present and what they mean:

Vulkan          GL                                      Present

IMMEDIATE       glXSwapIntervalEXT(dpy, draw, 0)        PresentPixmap(target-msc=0,
                glXSwapBuffers(dpy, draw)                 PresentOptionAsync)

                        Display the presented frame immediately, even if
                        that makes the screen tear.

MAILBOX         glXSwapBuffersMscOML(dpy, draw, 0,      PresentPixmap(target-msc=0)
                	    0, 0, NULL, NULL, NULL)

                        Display the presented frame at the next vblank
                        interval, replacing any frame already queued at
                        that time.

FIFO            glXSwapIntervalEXT(dpy, draw, 1)        PresentPixmap(target-msc=previous-msc+1)
                glXSwapBuffers(dpy, draw)
                
                        Place the frame to be presented at the end of a
                        queue. At each vblank interval, if the queue is
                        non-empty, display the first member of the
                        queue.


FIFO_RELAXED    glXSwapIntervalEXT(dpy, draw, -1)       PresentPixmap(target-msc=previous-msc+1,
                glXSwapBuffers(dpy, draw)                  PresentOptionAsync)

                        Place the frame to be presented at the end of a
                        queue. At each vblank interval, if the queue is
                        non-empty, display the first member of the
                        queue. Additionally, if the queue was empty and
                        no frame switch happened for this vblank
                        interval, immediately switch to the new frame

From the X protocol perspective, I think we're all set for IMMEDIATE and
MAILBOX. However, I think both FIFO and FIFO_RELAXED cannot be done
because they rely on the client knowing the previous MSC (Media Stream
Counter, or frame counter) value, which the client really isn't going to
know unless it's presenting every frame.

To fix them, I think we need to add relative MSC values to Present,
so we can ask that the X server do the right thing.

PresentOptionRelative

        If 'options' contains PresentOptionRelative, then the most
        recent actual MSC for a PresentPixmap request to the same
        drawable (i.e., the MSC value that would have been reported in
        the associated PresentCompleteNotify event) will be added to
MSC

0
        a Present(target-msc=1, PresentOptionRelative)
                target-msc = 1 + 0 (current drawable msc)
1 a present here
        b Present(target-msc=1, PresentOptionRelative)
                target-msc = 1 + 1 (previous Present actual MSC)
2 b present here
        Oops, we're late
3
        c Present(target-msc=1, PresentOptionRelative)
                target=msc = 1 + 2 (previous Present actual MSC)
        d Present(target-msc=1, PresentOptionRelative)
                target=msc = 1 + 4 (previous Present actual MSC)
4 c present here
5 d present here

        target-msc.

        If no PresentPixmap request has been made to this drawable, then
        the current MSC value for the drawable will be added to
        target-msc.

FIFO can be done by:

        PresentPixmap(target-msc=1, PresentOptionRelative)

FIFO_RELAXED can be done by:

        PresentPixmap(target-msc=1, PresentOptionRelative|PresentOptionAsync)

In addition, MAILBOX can be done more naturally by:

        PresentPixmap(target-msc=0, PresentOptionRelative)

Ok, so let's make sure it works on paper.

FIFO:


FIFO_RELAXED:

MSC

0
        a Present(target-msc=1, PresentOptionRelative|PresentOptionAsync)
                target-msc = 1 + 0 (current drawable msc)
1 a present here
        b Present(target-msc=1, PresentOptionRelative|PresentOptionAsync)
                target-msc = 1 + 1 (previous Present actual MSC)
2 b present here
        Oops, we're late
3
        c Present(target-msc=1, PresentOptionRelative|PresentOptionAsync)
                target=msc = 1 + 2 (previous Present actual MSC)
  c present here
        d Present(target-msc=1, PresentOptionRelative|PresentOptionAsync)
                target=msc = 1 + 3 (previous Present actual MSC)
4 d present here
5 

That looks like I want it to; the difference from the current code is
that the FIFO case doesn't skip a frame; with the current code, we'd
skip frame c:

MSC

0
        a Present(target-msc=1)
                target-msc = 1
1 a present here
        b Present(target-msc=2)
                target-msc = 2
2 b present here
        Oops, we're late
3
        c Present(target-msc=3)
                target=msc = 3
        d Present(target-msc=4)
                target=msc = 4
4 d present here
5 

Even in the FIFO_RELAXED case, if we miss more than one frame, we're
going to be skipping frames. Now, it's true that the current Mesa code
attempts to adjust the target-msc values based on the actual MSC values
it sees coming back in events, so the target-msc values it uses won't
get arbitrarily out of whack, they'll just get occasionally out of whack
by a frame or two.

Of course, one can argue that you really want the application to be
running in real time and that dropping frames is the correct thing to
do. If so, we already have OML_sync_control that does this; what this
message is about is respecting the semantics of the standard
glXSwapBuffers request.

Coding this up will take very little time; it's just a tiny bit of math
in the PresentPixmap request.

-- 
-keith
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <https://lists.x.org/archives/xorg-devel/attachments/20171016/b386bab3/attachment.sig>


More information about the xorg-devel mailing list