Name

    NV_delay_before_swap

Name Strings

    GLX_NV_delay_before_swap

Contributors

    Miguel Angel Vico, NVIDIA
    Jeannot Breton, NVIDIA
    Eric Werness, NVIDIA
    Andy Ritger, NVIDIA
    James Jones, NVIDIA
    Cass Everitt, NVIDIA
    John Carmack, id Software

Contact

    Miguel Angel Vico, NVIDIA Corporation (mvicomoya 'at' nvidia.com)

Status

    Complete.

Version

    Last Modified Date:         11/08/2013
    Revision:                   1

Number

    OpenGL Extension #445

Dependencies

    Requires GLX 1.1

    Requires EXT_swap_control

    Interacts with EXT_swap_control_tear

    This specification is written against the wording of the GLX 1.4 and
    is based on the WGL_NV_delay_before_swap specifications

Overview

    For most interactive applications, the standard rendering loop responding
    to input events on a frame granularity is sufficient.  Some more demanding
    applications may want to exchange performance for the ability to sample
    input closer to the final frame swap and adjust rendering accordingly.
    This extension adds functionality to allow the application to wait until a
    specified time before a swapbuffers command would be able to execute.


New Procedures and Functions

    Bool glXDelayBeforeSwapNV(Display *dpy, GLXDrawable drawable, GLfloat seconds)


New Tokens

    None

Additions to the GLX 1.4 Specification

    [Add the following to Section 3.3.10 of the GLX specification
    (Double Buffering)]

    glXDelayBeforeSwapNV blocks the CPU until <seconds> seconds before a
    synchronized swap would occur on a particular GLX window drawable.  It
    also returns a boolean value equal to True when the implementation had
    to wait for the synchronized swap and False otherwise.

    The parameter <seconds> accepts positive floating point values not larger
    than the length in seconds of the swap period on the associated drawable.
    When buffer swaps are synchronized, the swap period is composed of one or
    multiple video frame periods.  A video frame period is the time required by
    the monitor to display a full frame of video data.  A swap interval set to
    a value of 2 means that the color buffers will be swapped at most every
    other video frame.  If <seconds> is smaller than 0, glXDelayBeforeSwapNV
    will return False and will not wait for the end of the swap period.  If
    <seconds> is greater than a swap period, glXDelayBeforeSwapNV will return
    immediately without generating any error and the return value will be False.

    The application should use a <seconds> delay large enough to have time to
    complete its work before the end of the swap period.  If <seconds> is close
    to 0.0, the application may miss the end of the swap period and it will
    have to wait an additional swap period before it can swap.

    If glXDelayBeforeSwapNV detects that there is less than <seconds> seconds
    before the end of the swap period, it will return immediately and the
    return value will be False. The implementation will not wait an additional
    video frame period to have an exact delay of <seconds> seconds.

    If buffer swaps are unsynchronized, glXDelayBeforeSwapNV will return
    immediately and the return value will be False.  It could happen for
    multiple reasons, for example if the swap interval is equal to 0, if the
    window is in a mode switch or if no monitors are active.

GLX Protocol

    One new GLX protocol command is added.

    DelayBeforeSwapNV
        1       CARD8                   opcode (X assigned)
        1       17                      GLX opcode (glXVendorPrivateWithReply)
        2       4                       request length
        4       1341                    vendor specific opcode
        4       GLX_DRAWABLE            drawable
        4       FLOAT32                 seconds
      =>
        1       CARD8                   reply
        1                               unused
        2       CARD16                  sequence number
        4       0                       reply length
        1       BOOL                    waited
        23                              unused

Errors

    glXDelayBeforeSwapNV generates BadValue if parameter <seconds> is
    less than zero.

    glXDelayBeforeSwapNV generates GLXBadWindow if parameter <drawable> is
    not a GLXWindow or Window XID.

Usage Examples

    Here is a simple example that shows how an application can use
    GLX_NV_delay_before_swap to lower input latency when rendering its frames.

    void DrawFrame(Display *dpy, GLXDrawable drawable)
    {
        // Render the slowest part of the frame
        DrawScene();
        // Make sure there's no remaining work on the GPU
        glFinish();
        // Wait for the end of the swap period
        glXDelayBeforeSwapNV(dpy, drawable, 0.0015);

        // Sample inputs and adjust the image before the SwapBuffer

        glXSwapBuffers(dpy, drawable);
    }

Issues

    (1) What happens if glXDelayBeforeSwapNV is called and the <seconds> delay
        is larger than the time left until the end of the swap period?

        RESOLVED.  The function returns immediately.  We also added a return
        value to glXDelayBeforeSwapNV to help the application detects this
        situation.  When glXDelayBeforeSwapNV returns False, but didn't
        generate any error, it means that it didn't have to wait because it got
        called less than <seconds> seconds before the end of the swap period.

    (2) Should we add a function that return the amount of time until the end
        of the swap period?

        RESOLVED.  It would be nice to know exactly when the current swap
        period is going to end, but in some configurations it's not possible
        to return a value that we can guarantee will always be accurate.

    (3) How does glXDelayBeforeSwapNV interact with GLX_EXT_swap_control_tear?

        RESOLVED. glXDelayBeforeSwapNV always attempts to stall until the
        specified time before the SwapBuffers command could complete. With
        swap_control_tear, the swap will wait until a fixed swap period if
        possible, but perform an unsynchronized swap otherwise. If the
        swapbuffers would wait, then glXDelayBeforeSwapNV will wait similarly if
        required, but if the swap period is already past and the swapbuffers
        would execute unsynchronized, then glXDelayBeforeSwapNV would return
        immediately.

    (4) Why does this extension delay before execution of SwapBuffers rather
        than on a potential swap period?

	RESOLVED. Given that the expected use case is to wait until before the
	SwapBuffers would execute to sample input, having any cases where the
	behavior of the delay mismatches the behavior of the swap (such as
	swap_control_tear or swap_interval!=1) can cause significant issues in
	when the input is sampled.

Revision History

    Rev.    Date    Author    Changes
    ----  --------  --------  -----------------------------------------
     1    10/22/13  mvicomoya Internal revisions.
