EGL_KHR_partial_update#

Supported Hardware#

Series6, Series6XE, Series6XT

Valid APIs#

EGL 1.4 or later is required.

Written based on the EGL 1.5 specification (March 12, 2014).

Description#

The aim of this extension is to allow efficient partial updates for postable surfaces. It allows implementations to completely avoid processing areas of the surface which have not changed between frames, allowing increased efficiency.

It does so by providing information and guarantees about the content of the current back buffer which allow the application to “repair” only areas that have become out of date since the particular back buffer was last used.

The information provided is in the form of the “age” of the buffer, that is, how many frames ago it was last used as the back buffer for the surface. If the application tracks what changes it has made to the surface since this back buffer was last used, it can bring the entire back buffer up to date by only re-rendering the areas it knows to be out of date.

Use of this extension provides a more efficient alternative to EGL_BUFFER_PRESERVED swap behaviour. EGL_BUFFER_PRESERVED typically implies an expensive full-frame copy at the beginning of the frame, as well as a dependency on the previous frame. Usage of this extension avoids both and requires only the necessary updates to a back buffer to be made.

Note#

The behavior of part of this extension is different depending on whether the EGL_EXT_buffer_age extension is also present. This extension trivially interacts with EGL_KHR_swap_buffers_with_damage and EGL_EXT_swap_buffers_with_damage. This extension is worded against the KHR version, but the interactions with the EXT version are identical.

Different with EGL_KHR_swap_buffers_with_damage. EGL_KHR_partial_update

concerns the area of a particular buffer that has changed since that same buffer was last used. As it only concerns changes to a single buffer, there is no dependency on the next or previous frames or any other buffer. It therefore cannot be used to infer anything about changes to the surface, which requires linking one frame or buffer to another. Buffer damage is therefore only useful to the producer.

Buffer damage example#

The buffer damage for a frame is the area changed since that same buffer was last used. If the buffer has not been used before, the buffer damage is the entire area of the buffer.

The buffer marked with an ‘X’ in the top left corner is the buffer that is being used for that frame. This is the buffer to which the buffer age and the buffer damage relate.

Note

This example shows a double buffered surface - the actual number of buffers could be different and variable throughout the lifetime of the surface. The age must therefore be queried for every frame.

  Frame 0     Frame 1     Frame 2     Frame 3     Frame 4
+---------+ +---------+ +---------+ +---------+ +---------+
|         | |#########| |#########| |#########| |#########|
|         | |         | |#########| |#########| |#########| Final surface
|         | |         | |         | |#########| |#########|   content
|         | |         | |         | |         | |#########|
+---------+ +---------+ +---------+ +---------+ +---------+
X---------+ +---------+ X---------+ +---------+ X---------+
|         | |         | |#########| |#########| |#########|
|         | |         | |#########| |#########| |#########| Buffer 1 content
|         | |         | |         | |         | |#########|
|         | |         | |         | |         | |#########|
+---------+ +---------+ +---------+ +---------+ +---------+
            X---------+ +---------+ X---------+ +---------+
            |#########| |#########| |#########| |#########|
            |         | |         | |#########| |#########| Buffer 2 content
            |         | |         | |#########| |#########|
            |         | |         | |         | |         |
            +---------+ +---------+ +---------+ +---------+
     0           0           2           2           2      Buffer age
+---------+ +---------+ +---------+ +---------+ +---------+
|@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |         | |         |
|@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |         | Buffer damage
|@@@@@@@@@| |@@@@@@@@@| |         | |@@@@@@@@@| |@@@@@@@@@|
|@@@@@@@@@| |@@@@@@@@@| |         | |         | |@@@@@@@@@|
+---------+ +---------+ +---------+ +---------+ +---------+

Example#

//The surface's swap behavior is EGL_BUFFER_DESTROYED
eglSurfaceAttrib(eglDisplay, eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
while(render_loop)
{
    EGLint rects[] = {100,  //start x position
                100,    //start y position
                100,    //width
                100}    //height
    //The damage region for <surface> is set to the area described by <n_rects> and
    //<rects> if all of the following conditions are met:
    //<surface> is the current draw surface of the calling thread
    //<surface> is a postable surface
    //There have been no client API commands which result with rendering to
    //<surface> since eglSwapBuffers was last called with <surface>, or since
    //<surface> was created in case eglSwapBuffers has not yet been called with
    //<surface>.
    eglSetDamageRegionKHR(eglDisplay, eglSurface, rects, 1); //before any render commands in this frame.
    //begin render
    //end render
    eglSwapBuffers(eglDisplay, eglSurface);
}