Name

    KHR_mutable_render_buffer

Name Strings

    EGL_KHR_mutable_render_buffer

Contributors

    Alon Or-bach
    John Carmack
    Cass Everitt
    Michael Gold
    James Jones
    Jesse Hall
    Ray Smith

Contact

    Alon Or-bach, Samsung Electronics (alon.orbach 'at' samsung.com)

IP Status

    No known claims.

Notice

    Copyright (c) 2016 The Khronos Group Inc. Copyright terms at
        http://www.khronos.org/registry/speccopyright.html

Status

    Approved by the EGL Working Group on January 28, 2016
    Ratified by the Khronos Board of Promoters on March 11, 2016

Version

    Version 12, January 29, 2016

Number

    EGL Extension #96

Extension Type

    EGL display extension

Dependencies

    EGL 1.2 or later is required.

    Written based on the EGL 1.5 specification (August 27, 2014).

New Types

    None

New Procedures and Functions

    None

New Tokens

    Accepted as a new value for the EGL_SURFACE_TYPE EGLConfig attribute:

        EGL_MUTABLE_RENDER_BUFFER_BIT_KHR           0x00001000

Overview

    The aim of this extension is to allow toggling of front-buffer rendering
    for window surfaces after their initial creation.

    This allows for implementations to switch between back-buffered and single-
    buffered rendering without requiring re-creation of the surface. It is not
    expected for toggling to be a frequent event.

    This extension does not guarantee when rendering results appear on-screen.
    To avoid incorrect results, applications will need to use mechanisms not
    included in this extension to synchronize rendering with the display. This
    functionality is not covered by this extension, and vendors are encouraged
    to provide guidelines on how this is achieved on their implementation.

Add to the list of supported tokens for EGL_SURFACE_TYPE in section 3.4
"Configuration Management", page 23:

    If EGL_MUTABLE_RENDER_BUFFER_BIT_KHR is set in EGL_SURFACE_TYPE, then the
    EGL_RENDER_BUFFER attribute of a surface can be toggled between front
    buffer and back buffer rendering using eglSurfaceAttrib (see section
    3.5.6).

Add to the list of supported tokens for eglSurfaceAttrib in section 3.5.6
"Surface Attributes", page 43:

    If attribute is EGL_RENDER_BUFFER, then value specifies whether to render
    to a back buffer by specifying EGL_BACK_BUFFER, or directly to the front
    buffer by specifying EGL_SINGLE_BUFFER. The change to which buffer is
    rendered to takes effect at the subsequent eglSwapBuffers call, as
    described in section 3.10.1.2, and changes are considered pending up until
    that point.

    If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE attribute of
    the EGLConfig used to create surface does not contain
    EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, or the windowing system is unable to
    support the requested rendering mode, an EGL_BAD_MATCH error is generated
    and the EGL_RENDER_BUFFER state is left unchanged.

Modify the following sentence in section 3.5.6 "Surface Attributes", page 45:

    Querying EGL_RENDER_BUFFER returns the buffer which client API rendering
    is requested to use. For a window surface, this is the attribute value
    specified when the surface was created or last set via eglSurfaceAttrib.

Modify the third bullet describing eglQueryContext in section 3.7.4, page 63:

    If the context is bound to a window surface, then either EGL_BACK_BUFFER
    or EGL_SINGLE_BUFFER may be returned. The value returned depends on
    both the buffer requested by the setting of the EGL_RENDER_BUFFER property
    of the surface (which may be queried by calling eglQuerySurface - see
    section 3.5.6), and on the client API (not all client APIs support
    single-buffer rendering to window surfaces). Some client APIs allow control
    of whether rendering goes to the front or back buffer for back buffered
    surfaces. This client API-specific choice is not reflected in the returned
    value, which only describes the buffer that will be rendered to by default
    if not overridden by the client API. If the EGL_RENDER_BUFFER attribute of
    a surface is changed by calling eglSurfaceAttrib, the value returned by
    eglQueryContext will change once eglSwapBuffers is called, as described in
    section 3.10.1.2.

Modify the following sentence in section 3.10.1 "Posting to a Window", page 79:

    If surface is a single-buffered window, pixmap, or pbuffer surface for which
    there is a pending change to the EGL_RENDER_BUFFER attribute, eglSwapBuffers
    performs an implicit flush operation on the context and effects the
    attribute change. If surface is a single-buffered window, pixmap, or pbuffer
    surface for which there is no pending change to the EGL_RENDER_BUFFER
    attribute, eglSwapBuffers has no effect.

Add a new section 3.10.1.2 "Handling of render buffer attribute changes"

    If there is a pending change to the EGL_RENDER_BUFFER attribute of a
    surface, as described in section 3.5.6, the change to which buffer is
    rendered to takes effect at the subsequent eglSwapBuffers call.

    When switching to single-buffered from back-buffered rendering and the
    surface's EGL_SWAP_BEHAVIOR attribute is set to EGL_BUFFER_DESTROYED, the
    back buffers are considered to be undefined after calling eglSurfaceAttrib.
    Only draw calls after this eglSurfaceAttrib call are guaranteed to affect
    the back buffer content. If it is set to EGL_BUFFER_PRESERVED, the back
    buffer contents are unaffected. At the next eglSwapBuffers call, the back
    buffer is posted as the front buffer. After this, any draw calls take
    effect on the front buffer.

    When switching to back-buffered from single-buffered rendering, any draw
    calls up until the next eglSwapBuffers call continues to affect the front
    buffer, and this initial eglSwapBuffers call does not affect the window
    content. The back buffer is considered to be undefined at this point, no
    matter what the EGL_SWAP_BEHAVIOR attribute of the surface is set to. Once
    the pending change has taken place during this initial eglSwapBuffers call,
    further rendering affects the back buffer.

    If the EGL_RENDER_BUFFER attribute is changed twice or more in succession
    without new content rendered to the surface as described above, undefined
    content may appear on-screen.


Issues

 1) When should the switch between rendering modes occur?

    RESOLVED: The switch should take effect after the subsequent eglSwapBuffers
    call. The operation of the subsequent eglSwapBuffers call is according to
    the current state (i.e the state before the eglSurfaceAttrib call), not the
    pending state.

    When switching to EGL_SINGLE_BUFFER, the current state is EGL_BACK_BUFFER
    and therefore eglSwapBuffers posts the current back buffer. After this any
    rendering takes effect on the front buffer.

    When switching to EGL_BACK_BUFFER, the current state is EGL_SINGLE_BUFFER
    and therefore eglSwapBuffers only flushes the current context. After this
    any rendering takes effect on the back buffer.

 2) If this extension is advertised, should all surface configurations with
    EGL_WINDOW_BIT in EGL_SURFACE_TYPE be required to support it?

    RESOLVED: No. Add a config bit to indicate support for EGL_RENDER_BUFFER
    toggling. If toggle performed when not supported, EGL_BAD_MATCH error is
    generated.

 3) How often do we expect the switch between single and back buffering to
    occur?

    RESOLVED: It is not expected for the toggle to be a frequent call. For
    example, we expect it to be called once when enabling a VR accessory and
    once when disabling it.

 4) Do we need to reword section 3.7.4 (page 63)?

    RESOLVED: Yes. Modified to explain how some client APIs can still override
    the behavior and what value eglQueryContext is expected to return for
    EGL_RENDER_BUFFER.

 5) Why not enable this via the client API, like OpenGL does via glDrawBuffer?

    RESOLVED: This would not be possible on some platforms, where the swap chain
    is controlled via EGL.

 6) Is this extension a client or display extension?

    RESOLVED: This is a display extension.

 7) What state are back buffers after switching between single and back buffered
    rendering?

    RESOLVED: This is as set out in section 3.10.1.2.

 8) What guarantees of an onscreen update does this extension make?

    RESOLVED: This extension does not make any additional guarantees to the
    equivalent behavior of a window surface with EGL_RENDER_BUFFER set to the
    same value at creation of the surface. When a surface is single-buffered,
    any API call which is specified to explicitly or implicitly flush is
    expected to affect the on-screen content in finite time, but no timing
    guarantees are provided.

    It is recommended that if ancillary buffers are not required, they are
    invalidated before flushing to reduce unnecessary memory transfers on some
    implementations (e.g. by calling glInvalidateFramebuffer for OpenGL ES).

 9) Should an implicit flush occur when eglSwapBuffers is called on a
    single-buffered surface?

    RESOLVED: Only when there is a pending EGL_RENDER_BUFFER change which will
    be affected by this eglSwapBuffers call. Contexts must be flushed when
    changing render targets.

 10) How does toggling EGL_RENDER_BUFFER affect client APIs?

    RESOLVED: Changing the value of EGL_RENDER_BUFFER should result in the same
    behavior in client APIs as binding a window surface with that mode to the
    current context.  For example, in OpenGL, it is akin to switching from a
    drawable with a back buffer and front buffer to a drawable with only a
    front buffer, or vice versa.

    Note the effect of such an operation on the draw buffer and framebuffer
    completeness, if applicable, is client API specific. OpenGL ES applications
    will see no change and will be able to continue rendering without updating
    the draw buffer, as OpenGL ES exposes only one renderable surface,
    regardless of single or back-buffered drawables. OpenGL applications should
    update the current draw buffer using glDrawBuffers() or similar commands to
    ensure rendering targets the correct buffer after toggling
    EGL_RENDER_BUFFER.

 11) How should interaction between multiple window surfaces be handled?

    RESOLVED: This is left to platform vendors to define. Implementations may
    choose to restrict use of front buffer rendering to forbid interaction
    between multiple windows, or provide a buffer that is read by the display
    or compositing hardware but not the final composited results to prevent
    security concerns or undefined content.

 12) How should the name of the extension be?

    RESOLVED: EGL_KHR_mutable_render_buffer


Revision History

#12 (Jon Leech, January 29, 2016)
   - Assign enumerant value
   - Update Status block

#11 (Alon Or-bach, January 28, 2016)
   - Updated issue 1 to be consistent with new resolution to issue 9
   - Marked issues 7, 8 and 10 as resolved

#10 (Alon Or-bach, January 28, 2016)
   - Renamed extension to EGL_KHR_mutable_render_buffer, resolving issue 12
   - Updates issue 7 resolution to just refer to spec
   - Cleaned up section 3.10.1.2 wording
   - Added wording to overview on lack of guarantee of rendering results

#9 (Alon Or-bach, January 22, 2016)
   - Marked issues 1, 9 and 11 as resolved
   - Updated issue 4 to reflect previously agreed wording for section 3.7.4
   - Updated issue 8 to indicate no new flush guarantees made by this extension
   - New proposed resolution to issue 7 and modified section 3.10.1.2 to vary
     whether back buffer content are undefined based on swap behavior
   - Updated issue 10 with wording to explain differing client API behaviors
   - Added error condition for windowing systems unable to support a requested
     rendering mode in section 3.5.6
   - New proposed resolution to issue 12 for extension naming
   - Minor updates to wording (attribute instead of mode, overview phrasing)

#8 (Ray Smith, January 5, 2016)
   - Revert issue 1 resolution to that in revision 6, adding wording to section
     3.10.1 to make eglSwapBuffers effect pending state changes even for single
     buffered surfaces.

#7 (Alon Or-bach, December 17, 2015)
   - New proposed resolution to issue 1 (explicit flush as update boundary),
     updating the wording of 3.5.6, 3.7.4 3.10.1.2 to reflect this
   - Added new issue 11 to reflect concerns about interactions between multiple
     windows
   - Added new issue 12 to determine extension name

#6 (Alon Or-bach, November 11, 2015)
   - Resolved issue 6 and proposed resolution to issue 4 (section 3.7.4)
   - Added new issue 10 with proposed resolution

#5 (Alon Or-bach, May 12, 2015)
   - Updated section 3.10.1.2, changed resolution to issue 9

#4 (Alon Or-bach, April 15, 2015)
   - Added issue 9 and a typo fix

#3 (Alon Or-bach, April 09, 2015)
   - Added issue 7 and 8, wording on what content expected during mode switch

#2 (Alon Or-bach, March 09, 2015)
   - Cleanup, rename to XXX_set_render_buffer_mode

#1 (Alon Or-bach, March 04, 2015)
   - Initial draft
