• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    NV_sync
4
5Name Strings
6
7    EGL_NV_sync
8
9Contributors
10
11    Gary King
12    Gregory Prisament
13    Acorn Pooley
14    Jon Leech
15
16Contacts
17
18    Acorn Pooley, NVIDIA Corporation (apooley 'at' nvidia.com)
19    Gary King, NVIDIA Corporation (gking 'at' nvidia.com)
20
21Status
22
23    Complete
24
25Version
26
27    Version 7, July 27, 2010
28
29Number
30
31    EGL Extension #19
32
33Dependencies
34
35    Requires EGL 1.1
36
37    This extension is written against the wording of the EGL 1.2
38    Specification.
39
40Overview
41
42    This extension introduces the concept of "sync objects" into EGL.
43    Sync objects are a synchronization primitive, representing events
44    whose completion can be tested or waited upon.  This extension
45    borrows heavily from the GL_ARB_sync extension, and like that
46    extension, introduces only a single type of sync object, the
47    "fence sync object."  Additional types of sync objects may be
48    introduced in later extensions.
49
50    Fence sync objects have corresponding fences, which are inserted
51    into client API command streams.  A sync object can be queried
52    for a given condition, such as completion of the corresponding
53    fence.  Fence completion allows applications to request a partial
54    Finish of an API command stream, wherein all commands issued in
55    a particular client API context will be forced to complete before
56    control is returned to the calling thread.
57
58    This extension is nearly identical to NVIDIA's original proposal for the
59    EGL_KHR_sync extension, which some minor differences outlined in Issue 7
60    below.
61
62New Types
63
64    /*
65     * EGLSyncNV is an opaque handle to an EGL sync object
66     */
67    typedef void* EGLSyncNV;
68
69    /*
70     * EGLTimeNV is a 64-bit unsigned integer representing intervals in
71     * nanoseconds (unadjusted standard time). A type defined in the
72     * standard Khronos <KHR/khrplatform.h> header is used instead of
73     * a less-portable native C type.
74     */
75    #include <KHR/khrplatform.h>
76    typedef khronos_utime_nanoseconds_t EGLTimeNV;
77
78New Procedures and Functions
79
80    EGLSyncNV eglCreateFenceSyncNV( EGLDisplay dpy,
81                                    EGLenum condition,
82                                    const EGLint *attrib_list );
83
84    EGLBoolean eglDestroySyncNV( EGLSyncNV sync );
85
86    EGLBoolean eglFenceNV( EGLSyncNV sync );
87
88    EGLint eglClientWaitSyncNV( EGLSyncNV sync,
89                               EGLint flags, EGLTimeNV timeout );
90
91    EGLBoolean eglSignalSyncNV( EGLSyncNV sync, EGLenum mode );
92
93    EGLBoolean eglGetSyncAttribNV( EGLSyncNV sync, EGLint attribute,
94                                   EGLint *value );
95
96
97New Tokens
98
99    Accepted in the <condition> parameter of eglCreateFenceSyncNV, and
100    returned in <value> when eglGetSyncAttribNV is called with <attribute>
101    EGL_SYNC_CONDITION_NV:
102
103        EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV     0x30E6
104
105    Accepted as an attribute name in the <attrib_list> parameter of
106    eglCreateFenceSyncNV, and by the <attribute> parameter of
107    eglGetSyncAttribNV:
108
109        EGL_SYNC_STATUS_NV                      0x30E7
110
111    Accepted as an attribute value in the <attrib_list> parameter of
112    eglCreateFenceSyncNV for the EGL_SYNC_STATUS_NV attribute, by
113    the <mode> parameter of eglSignalSyncNV and returned in <value>
114    when eglGetSyncAttribNV is called with <attribute>
115    EGL_SYNC_STATUS_NV:
116
117        EGL_SIGNALED_NV                         0x30E8
118        EGL_UNSIGNALED_NV                       0x30E9
119
120    Accepted in the <flags> parameter of eglClientWaitSyncNV:
121
122        EGL_SYNC_FLUSH_COMMANDS_BIT_NV          0x0001
123
124    Accepted in the <timeout> parameter of eglClientWaitSyncNV:
125
126        EGL_FOREVER_NV                          0xFFFFFFFFFFFFFFFFull
127
128    Returned by eglClientWaitSyncNV:
129
130        EGL_ALREADY_SIGNALED_NV                 0x30EA
131        EGL_TIMEOUT_EXPIRED_NV                  0x30EB
132        EGL_CONDITION_SATISFIED_NV              0x30EC
133
134    Accepted in the <attribute> parameter of eglGetSyncAttribNV:
135
136        EGL_SYNC_TYPE_NV                        0x30ED
137        EGL_SYNC_CONDITION_NV                   0x30EE
138
139    Returned in <value> when eglGetSyncAttribNV is called with
140    <attribute> EGL_SYNC_TYPE_NV:
141
142        EGL_SYNC_FENCE_NV                       0x30EF
143
144    Returned by eglCreateFenceSyncNV in the event of an error:
145
146        EGL_NO_SYNC_NV                          ((EGLSyncNV)0)
147
148
149
150Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
151
152    Add a new subsection at the end of Section 3.8, page 43
153    (Synchronization Primitives)
154
155    "3.8.1  Sync Objects
156    In addition to the aforementioned synchronization functions, which
157    provide an efficient means of serializing client and native API
158    operations within a thread, "Sync Objects" are provided to enable
159    synchronization of client API operations between threads and/or between
160    API contexts.  Sync objects may be tested or waited upon by application
161    threads.
162
163    Sync objects have a status with two possible states: <signaled> and
164    <unsignaled>.  Events may be associated with a sync object.  When an
165    event is initially associated with a sync object, the object is
166    unsignaled (its status is set to unsignaled).  Once a sync object has
167    been created, EGL may be asked to wait for a sync object to become
168    signaled.  Sync objects may also be signaled or unsignaled explicitly.
169    Sync objects are associated with an EGLDisplay; this association
170    is made when the sync object is created.
171
172    Only one type of sync object is defined, the fence sync object, whose
173    associated events are triggered by fence commands which are inserted
174    into the command streams of client API contexts.  Fence sync objects may
175    be used to wait for partial completion of a client API command stream,
176    as a more flexible form of glFinish / vgFinish.
177
178    The command
179
180        EGLSyncNV eglCreateFenceSyncNV( EGLDisplay dpy,
181                                        enum condition,
182                                        EGLint *attrib_list );
183
184    creates a fence sync object for the specified display <dpy> and returns
185    a handle to the new object.  The sync object is assigned a type of
186    EGL_SYNC_FENCE_NV.  <condition> must be
187    EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV.  <attrib_list> is an attribute-value
188    list specifying other attributes of the sync object, terminated by an
189    attribute entry EGL_NONE.  Attributes not specified in the list will be
190    assigned their default values.  Attributes accepted by fence sync objects
191    are listed in table 3.aa
192
193      Attribute Name            Attribute Value(s)                     Default Value
194      ---------------           ------------------------------------   --------------
195      EGL_SYNC_STATUS_NV         EGL_SIGNALED_NV, EGL_UNSIGNALED_NV    EGL_SIGNALED_NV
196
197      Table 3.aa  Fence Sync Object Attributes
198
199    * If <dpy> is not the name of a valid, initialized EGLDisplay,
200    EGL_NO_SYNC_NV is returned and an EGL_BAD_DISPLAY error is generated.
201
202    * If <condition> is not EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV,
203    EGL_NO_SYNC_NV is returned and an EGL_BAD_PARAMETER error is generated.
204
205    * If any attribute not appearing in table 3.?? is specified in
206    <attrib_list>, EGL_NO_SYNC_NV is returned and an EGL_BAD_ATTRIBUTE error is
207    generated.
208
209
210    The command
211
212        EGLBoolean eglFenceNV( EGLSyncNV sync );
213
214    inserts a fence command into the command stream of the bound API's current
215    context (i.e., the context returned by eglGetCurrentContext), and
216    assoicates it with sync object <sync>.  <sync> must be a sync object
217    created with eglCreateFenceSyncNV, and the display associated with <sync>
218    must match the current display (i.e., the display returned by
219    eglGetCurrentDisplay).  Calling eglFenceNV unsignals <sync>.
220
221    When the condition of <sync> is satisfied by the fence command, <sync> is
222    signaled by the associated client API context, causing any
223    eglClientWaitSyncNV commands (see below) blocking on <sync> to unblock.
224    The condition EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV is satisfied by completion
225    of the fence command corresponding to the sync object, and all preceding
226    commands in the associated client API context's command stream.  <sync>
227    will not be signaled until all effects from these commands on the client
228    API's internal and framebuffer state are fully realized.  No other state
229    is affected by execution of the fence command.
230
231    Multiple fence commands may be inserted in any client API command stream
232    for a single sync object.  The sync object is unsignaled every time a new
233    fence command is issued, and signaled every time a previous fence command
234    completes, so its status is indeterminate until all fence commands
235    associated with the sync object have completed.  However, each time a fence
236    command completes (signaling the sync object), at least one
237    eglClientWaitSyncNV command blocking on that sync object will unblock.
238
239    EGL_TRUE is returned upon successful insertion of the fence command.
240
241    * If <sync> is not a valid sync object with a type of EGL_SYNC_FENCE_NV,
242    EGL_FALSE is returned and an EGL_BAD_PARAMETER error is generated.
243
244    * If the display associated with <sync> does not match the current
245    display, EGL_FALSE is returned and an EGL_BAD_MATCH error is generated.
246
247    * If no context is current for the bound API (i.e., eglGetCurrentContext
248    returns EGL_NO_CONTEXT), EGL_FALSE is returned and an EGL_BAD_MATCH error
249    is generated.
250
251    The command
252
253        EGLint eglClientWaitSyncNV( EGLSyncNV sync, uint flags,
254                                     EGLTimeNV timeout );
255
256    blocks the calling thread until the specified sync object <sync> is
257    signaled, or until a specified timeout value expires.  If <sync> is
258    signaled at the time eglClientWaitSyncNV is called then eglClientWaitSyncNV
259    will not block.  If <sync> is unsignaled at the time eglClientWaitSyncNV is
260    called then eglClientWaitSyncNV will wait up to <timeout> nanoseconds for
261    <sync> to become signaled.
262
263    If the value of <timeout> is zero, then eglClientWaitSyncNV will never
264    block and simply tests the current status of <sync>.  If the value of
265    <timeout> is the special value EGL_FOREVER_NV then eglClientWaitSyncNV
266    does not time out.
267
268    eglClientWaitSyncNV returns one of three status values describing the
269    reason for returning.  A return value of EGL_ALREADY_SIGNALED_NV will
270    always be returned if <sync> was signaled when eglClientWaitSyncNV was
271    called, even if <timeout> is zero.  A return value of
272    EGL_TIMEOUT_EXPIRED_NV indicates that indicates that the specified
273    timeout period expired before <sync> was signaled.  A return value of
274    EGL_CONDITION_SATISFIED_NV indicates that <sync> was signaled before
275    the timeout expired.
276
277    Note that a fence sync object can be in the signaled state because one of
278    three events has occured:
279
280    1. A previously inserte fence has completed and has signaled the sync
281       object.
282    2. The sync object was created.  Creation of a sync object sets it in the
283       signaled state by default, unless the attribute EGL_SYNC_STATUS_NV
284       is set to EGL_UNSIGNALED_NV in the attribute list.
285    3. The sync object was signaled by a previously issued
286       eglSignalSyncNV(sync, EGL_SIGNALED_NV) command.
287
288    If the sync object being blocked upon will not be signaled in finite time
289    (for example, by an associated fence command issued previously, but not
290    yet flushed to the graphics pipeline), then eglClientWaitSyncNV may
291    wait forever.  To help prevent this behavior (footnote1), if the
292    EGL_SYNC_FLUSH_COMMANDS_BIT_NV bit is set in <flags>, and <sync> is
293    unsignaled when eglClientWaitSyncNV is called, then the equivalent of
294    Flush() will be performed for the current API context (i.e., the context
295    returned by eglGetCurrentContext()) before blocking on <sync>.  If no
296    context is current for the bound API, the EGL_SYNC_FLUSH_COMMANDS_BIT_NV
297    bit is ignored.
298
299        (footnote 1): The simple Flush behavior defined by
300        EGL_SYNC_FLUSH_COMMANDS_BIT_NV will not help when waiting for a fence
301        command issued in a different context's command stream.  Applications
302        which block on a fence sync object must take additional steps to ensure
303        that the context from which the associated fence command was issued
304        has flushed that command to the graphics pipeline.
305
306    If a sync object is deleted when an eglClientWaitSyncNV is blocking on
307    that object, the behavior of eglClientWaitSyncNV is undefined.  Some
308    possible behaviors are to return immediately, to wait for fence commands
309    associated with the deleted sync to complete, or to not return until the
310    timeout period expires.
311
312    * If <sync> is not a valid sync object, EGL_FALSE is returned and an
313      EGL_BAD_PARAMETER error is generated.
314
315
316    The command
317
318        EGLBoolean eglSignalSyncNV( EGLSyncNV sync, enum mode );
319
320    signals or unsignals the sync object <sync> by changing its status to
321    <mode>, which must be one of the values in table 3.bb.  If, as a
322    result of calling eglSignalSyncNV, the status of <sync> transitions
323    from unsignaled to signaled, then at least one eglClientWaitSyncNV
324    commands blocking on <sync> will unblock.
325
326    Assuming no errors are generated, EGL_TRUE is returned.
327
328        Mode                   Effect
329        ------------------     -------------
330        EGL_SIGNALED_NV       Set the status of <sync> to signaled
331        EGL_UNSIGNALED_NV     Set the status of <sync> to unsignaled
332
333        Table 3.bb  Modes Accepted by eglSignalSyncNV Command
334
335    * If <sync> is not a valid sync object, EGL_FALSE is returned and an
336      EGL_BAD_PARAMETER error is generated.
337
338
339    The command
340
341        EGLBoolean eglGetSyncAttribNV( EGLSyncNV sync, EGLint attribute,
342                                       EGLint *value );
343
344    is used to query attributes of the sync object <sync>.  Legal values for
345    <attribute> depend on the type of sync object; these are listed in table 3.cc.
346    Assuming no errors are generated, EGL_TRUE is returned and the value of
347    the queried attribute is returned in <value>.
348
349        Attribute               Description                  Supported Sync Objects
350        -----------------       -----------------------      ---------------------
351        EGL_SYNC_TYPE_NV        Type of the sync object      All
352        EGL_SYNC_STATUS_NV      Status of the sync object    All
353        EGL_SYNC_CONDITION_NV   Signaling condition          EGL_SYNC_FENCE_NV
354
355    * If <sync> is not a valid sync object, EGL_FALSE is returned and an
356      EGL_BAD_PARAMETER error is generated.
357
358    The command
359
360        EGLBoolean eglDestroySyncNV( EGLSyncNV sync );
361
362    is used to destroy an existing sync object.  If any eglClientWaitSyncNV
363    commands are blocking on <sync> when eglDestroySyncNV is called, their
364    behavior is undefined.  After calling eglDestroySyncNV, <sync> is no
365    longer a valid sync object.  Assuming no errors are generated, EGL_TRUE
366    is returned.
367
368    * If <sync> is not a valid sync object, EGL_FALSE is returned and an
369      EGL_BAD_PARAMETER error is generated.
370
371Issues
372
373    1.  Explain the key choices made in this extension.
374
375    RESPONSE:  This extension has been written to enable adoption to be as wide
376    as possible, and to behave as similarly as possible to synchronization
377    primitives available in desktop OpenGL (e.g., NV_fence, ARB_sync).
378
379    In the interest of enabling widespread adoption, this extension (following
380    the ARB_sync model) has foregone the inclusion of synchronization primitives
381    and synchronization tests which may be performed entirely inside client
382    API command streams, instead performing synchronization tests
383    (eglClientWaitSyncNV) inside the application & host CPU.
384
385    In the interest of maintaining similarity with previous synchronization
386    primitives, this extension attempts to copy the ARB_sync specification
387    wherever possible (both functionally and stylistically), only making
388    changes where needed to operate inside EGL (rather than a client API
389    context) and match EGL naming conventions.
390
391    2.  Why place this behavior in EGL, rather than in the client APIs?
392
393    RESPONSE:  Ultimately, synchronization between multiple asynchronous client
394    API contexts (potentially executing in different threads) is a problem
395    which affects or will affect all EGL client APIs.  Rather than creating
396    separate synchronization primitives in each of the client APIs (and then
397    wrapping them in an EGL container), in the interest of developer simplicity
398    & consistency this behavior is being placed inside EGL.
399
400    3.  What does this extension provide that can not be accomplished with the
401    existing, more efficient eglWaitClient and eglWaitNative API functions?
402
403    RESPONSE:  eglWaitClient and eglWaitNative may be implemented in extremely
404    lightweight manners, in some cases not blocking the calling thread at
405    all; however, they can not be used to synchronize between client API
406    contexts and native APIs executing in separate threads (or simply between
407    client API contexts executing in separate threads), such as between a
408    thread with an active OpenGL context and a second thread performing
409    video decode.
410
411    4.  What does this extension provide that could not be accomplished with
412    native platform synchronization primitives and the existing client API
413    Finish commands?
414
415    RESPONSE:  This extension provides a lighter-weight mechanism for
416    synchronizing an application with client API command streams than the
417    all-or-nothing Finish commands, enabling applications to block until
418    a subset of issued client API commands have completed.
419
420    5.  Should integration with native platform synchronization objects be
421    included in this extension, or reserved for future (platform-specific)
422    extensions?
423
424    RESOLVED: Integration with native platform synchronization objects should
425    not be part of this extension, but can be added as future layered
426    extensions if needed.  These layered extensions can be platform-specific,
427    or perhaps OpenKODE based.
428
429    Originally, this extension included the ability to create native platform
430    synchronization objects from EGLSync objects.  This feature was removed
431    for a few reasons:
432
433        i) The proposed mechanism suggested mapping EGLSync objects to pthread
434        conditional variables on platforms with pthread support.  However,
435        pthread conditional variables require an associated mutex and there
436        was no mechanism to relay this associated mutex to the application.
437
438        ii) On certain platforms support for converting to native platform
439        synchronization objects adds great complexity to the implementation.
440
441        iii) Now that OpenKODE is more mature, it would be better to allow
442        conversion from EGLSyncNV objects to OpenKODE synchronization
443        primitives rather than platform-specific ones.  We suggest that this
444        functionality, if needed, be added as a layered extension instead of
445        being included here.  This way, EGL_NV_sync remains minimal and easy
446        to implement on a variety of platforms.
447
448    6.  Please provide a more detailed description of how ClientWaitSyncNV
449    behaves.
450
451    RESPONSE:  Issue 18 in the ARB_sync specification includes a very
452    detailed description of ClientWaitSyncARB (the ARB_sync equivalent of
453    ClientWaitSyncNV).  This is provided (unmodified) below:
454
455      Does ClientWaitSyncARB wait on an event, or on sync object
456    status? What is the meaning of sync object status?
457
458    RESOLVED: ClientWaitSyncARB blocks until the status of the sync
459    object transitions to the signaled state. Sync object status is
460    either signaled or unsignaled. More detailed rules describing
461    signalling follow (these need to be imbedded into the actual
462    spec language):
463
464    R1) A sync object has two possible status values: signaled or
465        unsignaled (corresponding to SYNC_STATUS_ARB values of
466        SIGNALED_ARB or UNSIGNALED_ARB, respectively).
467
468    R2) When created, the state of the sync object is signaled by
469        default, but may be explicitly set to unsignaled.
470
471    R3) A fence command is inserted into a command stream. A sync
472        object is not.
473
474    R4) When a fence command is inserted into a command stream using
475        FenceARB(), the status of the sync object associated with
476        that fence command is set to the unsignaled state.
477
478    R5) Multiple fence commands can be associated with the same sync
479        object.
480
481    R6) A fence command, once its condition has been met, will set
482        its associated sync object to the signaled state. The only
483        condition currently supported is
484        SYNC_PRIOR_COMMANDS_COMPLETE_ARB.
485
486    R7) A wait function, such as ClientWaitSyncARB, waits on a sync
487        object, not on a fence.
488
489    R8) A wait function, such as ClientWaitSyncARB, called on a sync
490        object in the unsignaled state will block. It unblocks
491        (note, not "returns to the application") when the sync
492        object transitions to the signaled state.
493
494    Some of the behaviors resulting from these rules are:
495
496    B1) Calling ClientWaitSyncARB with a timeout of 0 will return
497        TRUE if the sync object is in the signaled state. Note that
498        calling ClientWaitSyncARB with a timeout of 0 in a loop can
499        miss state transitions.
500    B2) Stacking fences is allowed. Each fence, once its condition
501        has been met, will set its associated sync object to the
502        signaled state. If the sync object is already in the
503        signaled state, it stays in that state.
504    B3) ClientWaitSyncARB could take a timeout parameter and return
505        a boolean. If the timeout period has expired,
506        ClientWaitSyncARB will unblock and return FALSE to the
507        caller. If ClientWaitSyncARB unblocks because the sync
508        object it was waiting on is in the signaled state, it will
509        return TRUE.
510    B4) We could define a FinishMultipleSync() command that will
511        unblock once all (or any) of the sync objects passed to it
512        are in the signaled state (also see issue 12).
513    B5) We could define a set/resetSyncObject function to manually
514        set the sync object in the signaled or unsignaled state.
515        This makes it easy for apps to reuse a sync object in the
516        multi-context case, so the sync object can be blocked upon
517        before a fence command is associated with it in the command
518        stream.
519    B6) We could define an API to convert a sync object into an OS
520        specific synchronization primitive (Events on Windows, file
521        descriptors or X-events or semaphores on Unix?)
522
523    7) How does this extension differ from (relate to) EGL_KHR_sync:
524
525    RESPONSE:
526    As of the time of writing this, the EGL_KHR_sync specification has not
527    been finalized by Khronos and continues to undergo revision.  However,
528    NVIDIA has the functionality outlined in this specification implemented
529    and has decided to make it available to developers immediately.
530
531    For the most part, EGL_KHR_sync is identical to revision 5 of EGL_KHR_sync
532    with the following changes:
533
534        a) Enum values are different
535        b) EGLTimeNV is unsigned long long instead of uint64_t.
536        c) Behaviour when there are multiple waiting threads is undefined.
537
538Revision History
539
540#7   (Jon Leech, July 27, 2010)
541    - Redefine EGLTimeNV type to use a typedef from the standard
542      Khronos headers instead of a native C type, for portability.
543#6   (Greg Prisament, May 28, 2009)
544    - Branch spec & turn it into an _NV extension.
545#5   (Greg Prisament, July 22, 2008)
546    - Removed NativeSyncKHR,  CreateNativeSyncKHR, and corresponding wording.
547    - Correct EGLuint to EGLint (EGLuint doesn't exist).
548#4   (Jon Leech, November 20, 2007)
549   - Corrected 'enum' to 'EGLenum' in prototypes.
550#3   (Jon Leech, April 5, 2007)
551   - Added draft Status and TBD Number
552#2   (November 27, 2006)
553   - Changed OES token to KHR
554
555