GL_OES_EGL_sync#

Supported Hardware#

Series5, Series5XT, Series6, Series6XE, Series6XT

Valid APIs#

OpenGL ES 1.x, 2.0, 3.x

Description#

This extension enables the use of EGLSync objects in an OpenGL ES command stream. EGLSync objects are defined in separate extensions, such as EGL_KHR_fence_sync.

Note#

This functionality is superseded by GLSync objects in OpenGL ES 3.0, but is still useful for cross-API communication.

Example#

// Disclaimer: None of this is good thread-safe code, it's pseudo-code for illustration. The exact CPU-side synchronisation mechanism will depend on your code.
// A fence sync handle accessible from both threads.
EGLSyncKHR g_eglFenceSync = 0;
// Pseudo-Function representing operations on a thread, in particular this thread is acting as
// a data producer.
void Thread1()
{
    // Render something
    glDraw(...);
    // Create a fence sync object in the command stream after the draw call, so a second
    // thread knows when the render operation is completed.
    g_eglFenceSync = eglCreateSyncKHR(eglDisplay, EGL_SYNC_FENCE_KHR, NULL);
    /*  Call eglClientWaitSync to flush the context, so that it's guaranteed to finish at
        some point. It only flushes the current context for the thread, hence calling it
        here - Flushing from the thread which actually needs to wait on this sync object
        would not flush the previous draw operations. By setting the timeout to 0 we've
        effectively called "glFlush" but a little more precisely, and it must work on all
        drivers.
    */
    EGLint waitResult = eglClientWaitSyncKHR(eglDisplay, eglFenceSync,
                            EGL_SYNCH_FLUSH_COMMANDS_BIT_KHR, 0);
}
// Pseudo-Function representing operations on a second thread. This thread acts as a data consumer.
void Thread2()
{
    while(g_eglFenceSync == 0)
    {
        // Do some other work, the first thread isn't ready.
    }
    // Wait for the synchronisation object
    EGLint waitResult = eglClientWaitSyncKHR(eglDisplay, eglFenceSync,
                            EGL_SYNCH_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR);
    // Destroy the fence sync object once we're done with it.
    EGLBoolean success = eglDestroySyncKHR(eglDisplay, eglFenceSync);
    // Now that the first thread's rendering has completed, do something with the result.
    // For example, composite the result of the draw into a windowing system.
    glDraw(...);
}