Name ARM_implicit_external_sync Name Strings EGL_ARM_implicit_external_sync Contributors David Garbett Ray Smith Contacts David Garbett, ARM Ltd. (david 'dot' garbett 'at' arm 'dot' com) Status Draft Version Version 1, September 8, 2014 Number EGL Extension #103 Dependencies Requires EGL 1.1. This extension is written against the wording of the EGL 1.2 Specification. EGL_KHR_fence_sync is required. Overview This extension extends the "fence sync objects" defined in EGL_KHR_fence_sync. It allows the condition that triggers the associated fence command in the client API command stream to be explicitly specified on fence object creation. It introduces a new condition that can be used to ensure ordering between operations on buffers that may be accessed externally to the client API, when those operations use an implicit synchronization mechanism. Such a fence object will be signaled when all prior commands affecting such buffers are guaranteed to be executed before such external commands. Applications have limited control over when a native buffer is read or written by the GPU when imported as an EGLImageKHR or via eglCreatePixmapSurface, which is controlled by the EGL and client API implementations. While eglWaitClient or a client call such as glFinish could be called, this forces all rendering to complete, which can result in CPU/GPU serialization. Note this isn't an issue for window surfaces, where eglSwapBuffers ensures the rendering occurs in the correct order for the platform. Some platforms have an implicit synchronization mechanism associated with native resources, such as buffers. This means that accesses to the buffer have an implicit ordering imposed on them, without involvement from the application. However, this requires that an application that has imported an affected buffer into EGL has a mechanism to flush any drawing operations in flight such that they are waiting on the synchronization mechanism. Otherwise the application cannot guarantee that subsequent operations (such as displaying a rendered buffer) will occur after the commands performed by the client API (such as rendering the buffer). The mechanism to wait for the synchronization mechanism should not require the application to wait for all rendering to complete, so that it can continue preparing further commands asynchronously to the queued commands. This extension provides this functionality using the new condition type for fence sync objects, so the application only waits for the external synchronization. New Types None New Procedures and Functions None New Tokens Accepted as a value of the EGL_SYNC_CONDITION_KHR attribute passed in the list to eglCreateSyncKHR when is EGL_FENCE_SYNC_KHR, and can populate <*value> when eglGetSyncAttribKHR is called with set to EGL_SYNC_CONDITION_KHR: EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors) Add the following after the fifth paragraph of Section 3.8.1 (Sync Objects), added by KHR_fence_sync: "Typically client APIs are considered to execute commands in a linear queue, where a prior command is executed and completes before a later command is started. By default fence sync objects adhere to this model - a fence is signaled once prior commands have completed. However on some platforms a command in a client API may transition through multiple states before it completes, which may impact other components of the system. Therefore the condition that all prior commands must meet before the fence is triggered is configurable." Replace the sixth paragraph of Section 3.8.1 (Sync Objects), added by KHR_fence_sync: "If, is EGL_SYNC_FENCE_KHR, a fence sync object is created. In this case can be NULL or empty, or can specify the EGL_SYNC_CONDITION_KHR attribute. Attributes of the fence sync object have the following default values:" Replace the eighth paragraph of Section 3.8.1 (Sync Objects), added by KHR_fence_sync: "When the condition of the sync object is satisfied by the fence command, the sync is signaled by the associated client API context, causing any eglClientWaitSyncKHR commands (see below) blocking on to unblock. The condition is specified by the EGL_SYNC_CONDITION_KHR attribute passed to eglCreateSyncKHR. If the condition is specified as EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR, the fence sync object 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. If the condition is specified as EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, the fence sync object is satisfied by the completion of the fence command corresponding to the sync object, and the of all preceding commands in the associated client API context's command stream. defines the point in time when a command has been queued on any implicit synchronization mechanisms present on the platform which apply to any of the resources used by the command. This enforces an ordering, as defined by the synchronization mechanism, between the command and any other operations that also respect the synchronization mechanism(s)." Replace the second entry in the list of eglCreateSyncKHR errors in Section 3.8.1 (Sync Objects), added by KHR_fence_sync: " * If is EGL_SYNC_FENCE_KHR and contains an attribute other than EGL_SYNC_CONDITION_KHR, EGL_NO_SYNC_KHR is returned and an EGL_BAD_ATTRIBUTE error is generated. * If is EGL_SYNC_FENCE_KHR and the value specified for EGL_SYNC_CONDITION_KHR is not EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR or EGL_SYNC_PRIOR_COMMANDS_SUBMITTED_ARM, EGL_NO_SYNC_KHR is returned and an EGL_BAD_ATTRIBUTE error is generated." Issues 1. Could glFlush guarantee commands are submitted, making this extension unnecessary? RESOLVED: The Open GL ES 3.1 specification defines glFlush() as causing "all previously issued GL commands to complete in finite time". There is no requirement for the execution of commands to reach any specific point before it returns - a valid implementation of glFlush() could spawn a new thread that sleeps for a minute before submitting the pending commands. While an implementation could decide to ensure all commands are submitted within glFlush(), it could not be assumed to be the case across all implementations. In addition, there may be scenarios when submitting commands within glFlush() is harmful. Waiting for command submission may have a performance impact on some implementations that perform processing of commands asynchronously. In addition such a change may restrict what is possible in the future. For example if user events were introduced into OpenGL ES they have the potential of introducing deadlocks if submission in glFlush() is guaranteed. 2. Should a new entry point be defined that flushes commands synchronously, instead of the new fence type as defined by this extension? RESOLVED: While a synchronous "flush and submit" entrypoint would meet the requirements for this extension, there may be a small benefit in enabling the application to continue processing between flushing and waiting for submission. In addition, the semantics of the existing EGL_KHR_fence_sync extension closely match what is required for this extension, so defining the new functionality in terms of fences may enable simpler implementations. 3. Should OpenGL ES 3 glFenceSync be extended in preference to eglCreateSyncKHR? RESOLVED: Some platforms are yet to move to a OpenGL ES 3 implementation, or may be unwilling to expose OpenGL ES 3 entrypoints to applications. As EGL_KHR_fence_sync is older than OpenGL ES 3, and is comparatively a small change, it has a better chance of adoption in a platform. In addition this extension is based on the idea that there are platform-specific ways to interact with the client API command stream. As this is platform-specific, and does not fit with the existing model typically used by client APIs (such as Open GL ES) it is better placed in EGL. Finally extending EGL has the advantage that the extension applies to all client APIs. 4. Should a new parameter be defined, instead of extending the EGL_FENCE_SYNC_KHR fence sync objects defined by EGL_KHR_fence_sync? RESOLVED: Whether the new functionality is defined as an extension to the existing fence sync objects, or whether they are defined as a new type of sync object, we must acknowledge that the model of a client API processing commands serially (with prior commands completing before later commands are executed) is too simplistic for some platforms. Extending the existing fence sync objects allows us to use the existing concept of conditions that trigger the fences. It also allows the maximum amount of reuse of existing functionality, potentially simplifying the implementation and the use of the extension by applications. Revision History #1 (David Garbett, September 8, 2014) - Initial draft.