Name EXT_sync_reuse Name Strings EGL_EXT_sync_reuse Contributors Daniel Kartch Jeff Vigil Ray Smith Contacts Daniel Kartch, NVIDIA Corporation (dkartch 'at' nvidia.com) Status Complete Version Version 4, May 16, 2018 Number EGL Extension #128 Extension type EGL display extension Dependencies Requires EGL 1.5 or EGL 1.4 with EGL_KHR_fence_sync Interacts with EGL_KHR_reusable_sync Interacts with EGL_ANDROID_native_fence_sync Interacts with EGL_NV_cuda_event This extension is written against the wording of the EGL 1.5 Specification. Overview The original EGLSync extensions separated sync objects into two types: fence sync objects signaled by one time events in an API command pipeline; and reusable sync objects signaled by commands which can be issued again and again. However, this conflates reusability of the event triggering a sync object with the EGLSync object itself. Although the event associated with a fence sync object will only occur once, there is no reason that it can't be replaced with a new event. Doing so would avoid unnecessary allocation and free operations in an application that repeatedly waits for events. With the current interfaces, such applications must constantly create and destroy new EGLSync objects. This extension allows all sync objects to be reusable. When a sync object is in the signaled state, it can be reset back to an unsignaled state, regenerating or reevaluating the events that trigger them. For fence sync objects, this means generating a new fence in the current API. For OpenCL event sync objects, this means waiting for a new OpenCL event handle. This mechanism also allows sync objects to be created in the signaled state with no associated fence/event, and have one applied later. Thus all EGLSyncs required by an application can be allocated up front, before any rendering operations have begun. New Types None New Tokens None New Procedures and Functions EGLBoolean eglUnsignalSyncEXT( EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); Replace text of subsections of 3.8.1 through 3.8.1.2 of EGL 1.5 Specification. Existing tables are preserved. 3.8.1 Sync Objects In addition to the aforementioned synchronization functions, which provide an efficient means of serializing client and native API operations within a thread, are provided to enable synchronization of client API operations between threads and/or between API contexts. Sync objects may be tested or waited upon by application threads. Sync objects have a status with two possible states: and , and may initially be in either state. EGL may be asked to wait for a sync object to become signaled, or a sync object’s status may be queried. Depending on the type of a sync object, its status may be changed either by an external event, or by explicitly signaling and/or unsignaling the sync. All sync objects are reusable. Once they enter the signaled state, they may be changed back to unsignaled, possibly replacing the associated external event that signals them. Sync objects are associated with an EGLDisplay when they are created, and have defining additional aspects of the sync object. All sync objects include attributes for their type and their status. Additional attributes are discussed below for different types of sync objects. If a sync object is created in the signaled state, its initial attribute list may be incomplete, with attributes necessary for its type provided when it is changed to unsignaled. have an associated fence command in a client API. A new fence command is generated whenever the sync object enters the unsignaled state. When the client API executes the fence command, an event is generated which signals the corresponding fence sync object. Fence sync objects may not be explicitly signaled. Fence sync objects may be used to wait for partial completion of a client API command stream, as a more flexible form of glFinish or vgFinish. An reflects the status of a corresponding OpenCL event object to which the sync object is linked. This provides another method of coordinating sharing of images between EGL and OpenCL (see Chapter 9 of the OpenCL 1.0 Specification and the cl_khr_egl_image extension). Waiting on such a sync object is equivalent to waiting for completion of the linked OpenCL event object. The command EGLSync eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); creates a sync object of the specified associated with the specified display , and returns a handle to the new object. is NULL or an attribute-value list specifying other attributes of the sync object, terminated by an attribute entry EGL_NONE. Attributes not specified in the list will be assigned their default values. The EGL_SYNC_STATUS attribute is defined for all sync types, but may only be specified explicitly at creation time for some types of sync objects, as discussed below. Other attributes are only allowed as indicated below for the sync type. Errors eglCreateSync returns EGL_NO_SYNC on failure. If is not the name of a valid, initialized EGLDisplay, an EGL_BAD_DISPLAY error is generated. If contains an attribute name not defined or not allowed for the type of sync object being created, an EGL_BAD_ATTRIBUTE error is generated. If is not a supported type of sync object, an EGL_BAD_PARAMETER error is generated. If is EGL_SYNC_FENCE, the EGL_SYNC_STATUS attribute is set to EGL_UNSIGNALED, and any of the following are true of the current context for the bound API (the context returned by eglGetCurrentContext), an EGL_BAD_MATCH error is generated: * There is no current context (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT). * does not match the EGLDisplay of the context (the EGLDisplay returned by eglGetCurrentDisplay). * The context does not support fence commands. While in the unsignaled state, the synchronization event associated with a sync object cannot be changed. When the of a sync object in the unsignaled state is satisfied, the sync is signaled, causing any eglClientWaitSync or eglWaitSync commands (see below) blocking on the sync to unblock. Once signaled, a sync object may be reused for a new synchronization event by switching it back to unsignaled. The command EGLBoolean eglUnsignalSyncEXT(EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); can be used to change the associated with display from the signaled state to the unsignaled state. The attribute list may be used to provide or replace attributes specific to the sync type as discussed below. The sync object's type and condition may not be changed. Errors eglUnsignalSyncEXT returns EGL_FALSE on failure, and has no effect on . If is not the name of a valid, initialized EGLDisplay, an EGL_BAD_DISPLAY error is generated. If is not a valid sync object associated with , an EGL_BAD_PARAMETER error is generated. If contains an attribute name not defined for the type of , an EGL_BAD_ATTRIBUTE error is generated. If is already in the unsignaled state, an EGL_BAD_ACCESS error is generated. If 's type is EGL_SYNC_FENCE and any of the following are true of the current context for the bound API (the context returned by eglGetCurrentContext), an EGL_BAD_MATCH error is generated: * There is no current context (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT). * does not match the EGLDisplay of the context (the EGLDisplay returned by eglGetCurrentDisplay). * The context does not support fence commands. If 's type is EGL_SYNC_CL_EVENT and EGL_CL_EVENT_HANDLE is not specified in , then an EGL_BAD_ATTRIBUTE error is generated. 3.8.1.1 Creating and Signaling Fence Sync Objects If type is EGL_SYNC_FENCE, a fence sync object is created. The EGL_SYNC_STATUS attribute may be specified as either EGL_UNSIGNALED or EGL_SIGNALED, and will default to EGL_UNSIGNALED. No other attributes may be specified for a fence sync object, either with eglCreateSync or eglUnsignalSyncEXT. Queriable attributes of the fence sync object are set as shown in table 3.7. When a fence sync object is created in the unsignaled state, or switched to that state with eglUnsignalSyncEXT, a fence command is inserted into the command stream of the bound client API’s current context (i.e., the context returned by eglGetCurrentContext), and is associated with the sync object. The only condition supported for fence sync objects is EGL_SYNC_PRIOR_COMMANDS_COMPLETE, which is satisfied by completion of the fence command corresponding to the sync object, and all preceding commands in the associated client API context’s command stream. The sync object will not be signaled until all effects from these commands on the client API’s internal and framebuffer state are fully realized. No other state is affected by execution of the fence command. Generation of fence commands for fence sync objects requires support from the bound client API, and will not succeed unless the client API satisfies one of the following properties. Note that eglWaitSync (see section 3.8.1.3) also requires satisfying these conditions. * client API is OpenGL, and either the OpenGL version is 3.2 or greater, or the GL_ARB_sync extension is supported. * client API is OpenGL ES, and either the OpenGL ES version is 3.0 or greater, or the GL_OES_EGL_sync extension is supported. * client API is OpenVG, and the VG_KHR_EGL_sync extension is supported. 3.8.1.2 Creating and Signaling OpenCL Event Sync Objects If type is EGL_SYNC_CL_EVENT, an OpenCL event sync object is created. The EGL_SYNC_STATUS attribute may not be explicitly specified during creation of this type of sync object. If no EGL_CL_EVENT_HANDLE attribute is specified at creation time, the sync object will be created in the signaled state. Otherwise its status will be determined by the provided OpenCL event, as described below. An EGL_CL_EVENT_HANDLE must always be specified for eglUnsignalSyncEXT. To use an OpenCL event sync object, the EGL_SYNC_CL_EVENT attribute must be set to a valid OpenCL handle returned by a call to clEnqueueReleaseGLObjects or clEnqueueReleaseEGLObjects; other types of OpenCL event handles are not supported. Implementations are not required to validate the OpenCL event, and passing an invalid event handle in may result in undefined behavior up to and including program termination. Note that EGL_CL_EVENT_HANDLE is not a queriable property of a sync object. Queriable attributes of the OpenCL event sync object are set as shown in table 3.8. The status of such a sync object depends on . When the status of is CL_QUEUED, CL_SUBMITTED, or CL_RUNNING, the status of the linked sync object will be EGL_UNSIGNALED. When the status of changes to CL_COMPLETE, the status of the linked sync object will become EGL_SIGNALED. The only condition supported for OpenCL event sync objects is EGL_SYNC_CL_EVENT_COMPLETE, which is satisfied when the status of the OpenCL event associated with the sync object changes to CL_COMPLETE. Associating an OpenCL event handle with a sync object places a reference on the linked OpenCL object. When the sync object is deleted or the event handle is replaced, the reference will be removed from the OpenCL object. If EGL_KHR_reusable_sync is present, then for sync objects of type EGL_SYNC_REUSABLE_KHR, the initial value of EGL_SYNC_STATUS may be set to either EGL_UNSIGNALED or EGL_SIGNALED, and will default to EGL_UNSIGNALED. If EGL_ANDROID_native_fence_sync is present, then for native fence sync objects, the EGL_SYNC_NATIVE_FENCE_FD_ANDROID attribute may be specified in eglUnsignalSyncEXT as well as eglCreateSync. If it is set to anything other than EGL_NO_NATIVE_FENCE_FD_ANDROID at creation time, then its initial EGL_SYNC_STATUS will reflect the current status of the provided fence FD, and it is an error to specifically set the status. If it is set to EGL_NO_NATIVE_FENCE_FD_ANDROID, then its EGL_SYNC_STATUS may be set to either EGL_UNSIGNALED (the default) or EGL_SIGNALED. If the status is signaled, then no native fence will be generated until after it is switched to unsignaled. If eglUnsignalSyncEXT is called for a native fence sync object with an FD of EGL_NO_NATIVE_FENCE_FD_ANDROID, then a new native fence will be generated at the next Flush(), as described for eglCreateSync. If EGL_NV_cuda_event is present, then for CUDA event sync objects, the EGL_CUDA_EVENT_HANDLE_NV may be specified in eglUnsignalSyncEXT as well as eglCreateSync. The current CUDA event handle is evaluated at the time the EGL sync object becomes unsignaled, and subsequent modification of the CUDA object with cudaEventRecord has no effect on the sync object until it is signaled. Subsequently restoring the sync object to unsignaled will cause the CUDA object to be reevaluated. Issues 1. Should a new attribute be required to specify a sync object as reusable? RESOLVED: No. The presence of this extension is sufficient to indicate reusability of all sync objects. This will not create any incompatibilities with existing applications that use sync objects only once. 2. Can we leverage the existing eglSignalSyncKHR function from EGL_KHR_reusable_sync for this extension? RESOLVED: No. Some types of sync objects require attributes which are themselves single-use objects, and must be replaced for the sync object to be reused. Therefore a new function which takes an attribute list is required. 3. Should the function for unsignaling be based on eglSignalSyncKHR from the KHR_reusable_sync extension, and take a mode parameter to distinguish signaling/unsignaling? RESOLVED: No. While all sync objects will support unsignaling, the reusable sync object is the only known one that supports direct signaling, rather than signaling through some condition being achieved. Therefore it is simplest to have the new function only support unsignaling, and continue to use the old extension for the one case where signaling is required. 4. If the initial attribute list is incomplete (e.g. an OpenCL event handle is not provided during creation of an OpenCL event sync object), should the EGL_SYNC_STATUS default to EGL_SIGNALED rather than generating an error if it is left unspecified? RESOLVED: Handling of allowed/default values for EGL_SYNC_STATUS is based on the sync type. For fence syncs, either value is allowed, defaulting to EGL_UNSIGNALED. For OpenCL event syncs, the value may not be specified, and instead is determined by whether an OpenCL event is provided at creation time, and if so by the status of that event. Revision History #4 (May 16, 2018) Daniel Kartch - Minor corrections to wording #3 (April 20, 2018) Daniel Kartch - Renamed to EXT - Fixed grammatical errors and prepared for publication #2 (January 23, 2018) Daniel Kartch - Rewrote some sections for clarity, and fixed typos - Changed default/allowed behavior for signal state at creation time to be determined by the sync type and other attributes. - Simplified interaction with EGL_KHR_reusable_sync. - Refined interaction with EGL_ANDROID_native_fence_sync to clarify allowed initial states for the sync status and fix the description of when new native fences are generated. #1 (January 16, 2018) Daniel Kartch - Initial draft as XXX