1Name 2 3 KHR_reusable_sync 4 5Name Strings 6 7 EGL_KHR_reusable_sync 8 9Contributors 10 11 Acorn Pooley 12 Gary King 13 Gregory Prisament 14 Jon Leech 15 Robert Palmer 16 17Contacts 18 19 Acorn Pooley, NVIDIA Corporation (apooley 'at' nvidia.com) 20 Gary King, NVIDIA Corporation (gking 'at' nvidia.com) 21 Gregory Prisament, NVIDIA Corporation (gprisament 'at' nvidia.com) 22 Jon Leech (jon 'at' alumni.caltech.edu) 23 Robert Palmer (robert.palmer 'at' nokia.com) 24 25Notice 26 27 Copyright (c) 2006-2013 The Khronos Group Inc. Copyright terms at 28 http://www.khronos.org/registry/speccopyright.html 29 30Status 31 32 Complete. 33 Approved by the Khronos Board of Promoters on August 28, 2009. 34 35Version 36 37 Version 22, January 31, 2014 38 39Number 40 41 EGL Extension #6 42 43Dependencies 44 45 Requires EGL 1.1 46 47 This extension is written against the wording of the EGL 1.2 48 Specification. 49 50Overview 51 52 This extension introduces the concept of "sync objects" into EGL. 53 Sync objects are a synchronization primitive, representing events 54 whose completion can be tested or waited upon. This extension 55 borrows from the GL_ARB_sync extension but introduces a type of sync 56 object known as "reusable sync object" comparable to an OS 57 semaphore. The specification is designed to allow additional types of 58 sync objects to be easily introduced in later extensions. 59 60 Reusable sync objects may be used to synchronize activity between 61 threads or between client APIs. Synchronization is accomplished by 62 explicitly changing the status of a reusable object using EGL API 63 commands. 64 65New Types 66 67 /* 68 * EGLSyncKHR is an opaque handle to an EGL sync object 69 */ 70 typedef void* EGLSyncKHR; 71 72 /* 73 * EGLTimeKHR is a 64-bit unsigned integer representing intervals 74 * in nanoseconds. 75 */ 76 #include <khrplatform.h> 77 typedef khronos_utime_nanoseconds_t EGLTimeKHR; 78 79 80New Procedures and Functions 81 82 EGLSyncKHR eglCreateSyncKHR( 83 EGLDisplay dpy, 84 EGLenum type, 85 const EGLint *attrib_list); 86 87 EGLBoolean eglDestroySyncKHR( 88 EGLDisplay dpy, 89 EGLSyncKHR sync); 90 91 EGLint eglClientWaitSyncKHR( 92 EGLDisplay dpy, 93 EGLSyncKHR sync, 94 EGLint flags, 95 EGLTimeKHR timeout); 96 97 EGLBoolean eglSignalSyncKHR( 98 EGLDisplay dpy, 99 EGLSyncKHR sync, 100 EGLenum mode); 101 102 EGLBoolean eglGetSyncAttribKHR( 103 EGLDisplay dpy, 104 EGLSyncKHR sync, 105 EGLint attribute, 106 EGLint *value); 107 108 109New Tokens 110 111 Accepted by the <type> parameter of eglCreateSyncKHR, and returned 112 in <value> when eglGetSyncAttribKHR is called with <attribute> 113 EGL_SYNC_TYPE_KHR: 114 115 EGL_SYNC_REUSABLE_KHR 0x30FA 116 117 Accepted by the <attribute> parameter of eglGetSyncAttribKHR: 118 119 EGL_SYNC_TYPE_KHR 0x30F7 120 EGL_SYNC_STATUS_KHR 0x30F1 121 122 Accepted by the <mode> parameter of eglSignalSyncKHR and returned in 123 <value> when eglGetSyncAttribKHR is called with <attribute> 124 EGL_SYNC_STATUS_KHR: 125 126 EGL_SIGNALED_KHR 0x30F2 127 EGL_UNSIGNALED_KHR 0x30F3 128 129 Accepted in the <flags> parameter of eglClientWaitSyncKHR: 130 131 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 132 133 Accepted in the <timeout> parameter of eglClientWaitSyncKHR: 134 135 EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull 136 137 Returned by eglClientWaitSyncKHR: 138 139 EGL_TIMEOUT_EXPIRED_KHR 0x30F5 140 EGL_CONDITION_SATISFIED_KHR 0x30F6 141 142 Returned by eglCreateSyncKHR in the event of an error: 143 144 EGL_NO_SYNC_KHR ((EGLSyncKHR)0) 145 146Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors) 147 148 Add a new subsection at the end of Section 3.8, page 43 149 (Synchronization Primitives) 150 151 "3.8.1 Sync Objects 152 153 In addition to the aforementioned synchronization functions, which 154 provide an efficient means of serializing client and native API 155 operations within a thread, <sync objects> are provided to enable 156 synchronization of client API operations between threads and/or 157 between API contexts. Sync objects may be tested or waited upon by 158 application threads. 159 160 Sync objects have a status with two possible states: <signaled> and 161 <unsignaled>. Initially, sync objects are unsignaled. EGL may be 162 asked to wait for a sync object to become signaled, or a sync 163 object's status may be queried. 164 165 Depending on the type of a sync object, its status may be changed 166 either by an external event, or by explicitly signaling and 167 unsignaling the sync. 168 169 Sync objects are associated with an EGLDisplay when they are 170 created, and have <attributes> defining additional aspects of the 171 sync object. All sync objects include attributes for their type and 172 their status. Additional attributes are discussed below 173 for different types of sync objects. 174 175 <Reusable sync objects> are created in the unsignaled state, and may 176 be signaled and/or unsignaled repeatedly. Every transition of a 177 reusable sync object's status from unsignaled to signaled will 178 release any threads waiting on that sync object. 179 180 The command 181 182 EGLSyncKHR eglCreateSyncKHR( 183 EGLDisplay dpy, 184 EGLenum type, 185 const EGLint *attrib_list); 186 187 creates a sync object of the specified <type> associated with the 188 specified display <dpy>, and returns a handle to the new object. 189 <attrib_list> is an attribute-value list specifying other attributes 190 of the sync object, terminated by an attribute entry EGL_NONE. 191 Attributes not specified in the list will be assigned their default 192 values. 193 194 If <type> is EGL_SYNC_REUSABLE_KHR, a reusable sync object is 195 created. In this case <attrib_list> must be NULL or empty 196 (containing only EGL_NONE). Attributes of the reusable sync object 197 are set as follows: 198 199 Attribute Name Initial Attribute Value(s) 200 --------------- -------------------------- 201 EGL_SYNC_TYPE_KHR EGL_SYNC_REUSABLE_KHR 202 EGL_SYNC_STATUS_KHR EGL_UNSIGNALED_KHR 203 204 Errors 205 ------ 206 207 * If <dpy> is not the name of a valid, initialized EGLDisplay, 208 EGL_NO_SYNC_KHR is returned and an EGL_BAD_DISPLAY error is 209 generated. 210 * If <attrib_list> is neither NULL nor empty (containing only 211 EGL_NONE), EGL_NO_SYNC_KHR is returned and an EGL_BAD_ATTRIBUTE 212 error is generated. 213 * If <type> is not a supported type of sync object, 214 EGL_NO_SYNC_KHR is returned and an EGL_BAD_ATTRIBUTE error is 215 generated. 216 217 The command 218 219 EGLint eglClientWaitSyncKHR( 220 EGLDisplay dpy, 221 EGLSyncKHR sync, 222 EGLint flags, 223 EGLTimeKHR timeout); 224 225 blocks the calling thread until the specified sync object <sync> is 226 signaled, or until <timeout> nanoseconds have passed. 227 228 More than one eglClientWaitSyncKHR may be outstanding on the same 229 <sync> at any given time. When there are multiple threads blocked on 230 the same <sync> and the sync object is signaled, all such threads 231 are released, but the order in which they are released is not 232 defined. 233 234 If the value of <timeout> is zero, then eglClientWaitSyncKHR simply 235 tests the current status of <sync>. If the value of <timeout> is the 236 special value EGL_FOREVER_KHR, then eglClientWaitSyncKHR does not 237 time out. For all other values, <timeout> is adjusted to the closest 238 value allowed by the implementation-dependent timeout accuracy, 239 which may be substantially longer than one nanosecond. 240 241 eglClientWaitSyncKHR returns one of three status values describing 242 the reason for returning. A return value of EGL_TIMEOUT_EXPIRED_KHR 243 indicates that the specified timeout period expired before <sync> 244 was signaled, or if <timeout> is zero, indicates that <sync> is 245 not signaled. A return value of EGL_CONDITION_SATISFIED_KHR 246 indicates that <sync> was signaled before the timeout expired, which 247 includes the case when <sync> was already signaled when 248 eglClientWaitSyncKHR was called. If an error occurs then an error is 249 generated and EGL_FALSE is returned. 250 251 If the EGL_SYNC_FLUSH_COMMANDS_BIT_KHR bit is set in 252 <flags>, and <sync> is unsignaled when eglClientWaitSyncKHR is 253 called, then the equivalent of Flush() will be performed for the 254 current API context (i.e., the context returned by 255 eglGetCurrentContext()) before blocking on <sync>. If no context is 256 current for the bound API, the EGL_SYNC_FLUSH_COMMANDS_BIT_KHR bit 257 is ignored. 258 259 If a sync object is destroyed while an eglClientWaitSyncKHR is 260 blocking on that object, eglClientWaitSyncKHR will unblock and 261 return immediately, just as if the sync object had been signaled 262 prior to being destroyed. 263 264 Errors 265 ------ 266 267 * If <sync> is not a valid sync object for <dpy>, EGL_FALSE is 268 returned and an EGL_BAD_PARAMETER error is generated. 269 * If <dpy> does not match the EGLDisplay passed to 270 eglCreateSyncKHR when <sync> was created, the behaviour is 271 undefined. 272 273 274 The command 275 276 EGLBoolean eglSignalSyncKHR( 277 EGLDisplay dpy, 278 EGLSyncKHR sync, 279 EGLenum mode); 280 281 signals or unsignals the reusable sync object <sync> by changing its 282 status to <mode>, which must be one of the values in table 3.bb. If 283 as a result of calling eglSignalSyncKHR the status of <sync> 284 transitions from unsignaled to signaled, any eglClientWaitSyncKHR 285 commands blocking on <sync> will unblock. 286 287 Assuming no errors are generated, EGL_TRUE is returned. 288 289 Mode Effect 290 ------------------ ------------- 291 EGL_SIGNALED_KHR Set the status of <sync> to signaled 292 EGL_UNSIGNALED_KHR Set the status of <sync> to unsignaled 293 294 Table 3.bb Modes Accepted by eglSignalSyncKHR Command 295 296 Errors 297 ------ 298 299 * If <sync> is not a valid sync object for <dpy>, EGL_FALSE is 300 returned and an EGL_BAD_PARAMETER error is generated. 301 * If the type of <sync> is not EGL_SYNC_REUSABLE_KHR, EGL_FALSE is 302 returned and an EGL_BAD_MATCH error is generated. 303 * If <dpy> does not match the EGLDisplay passed to 304 eglCreateSyncKHR when <sync> was created, the behaviour is 305 undefined. 306 307 308 The command 309 310 EGLBoolean eglGetSyncAttribKHR( 311 EGLDisplay dpy, 312 EGLSyncKHR sync, 313 EGLint attribute, 314 EGLint *value); 315 316 is used to query attributes of the sync object <sync>. Legal values 317 for <attribute> depend on the type of sync object, as shown in table 318 3.cc. Assuming no errors are generated, EGL_TRUE is returned and the 319 value of the queried attribute is returned in <value>. 320 321 Attribute Description Supported Sync Objects 322 ----------------- ----------------------- ---------------------- 323 EGL_SYNC_TYPE_KHR Type of the sync object All 324 EGL_SYNC_STATUS_KHR Status of the sync object All 325 326 Table 3.cc Attributes Accepted by eglGetSyncAttribKHR Command 327 328 Errors 329 ------ 330 331 * If <sync> is not a valid sync object for <dpy>, EGL_FALSE is 332 returned and an EGL_BAD_PARAMETER error is generated. 333 * If <dpy> does not match the display passed to eglCreateSyncKHR 334 when <sync> was created, the behaviour is undefined. 335 * If <attribute> is not one of the attributes in table 3.cc, 336 EGL_FALSE is returned and an EGL_BAD_ATTRIBUTE error is 337 generated. 338 * If <attribute> is not supported for the type of sync object 339 passed in <sync>, EGL_FALSE is returned and an EGL_BAD_MATCH 340 error is generated. 341 342 If any error occurs, <*value> is not modified. 343 344 The command 345 346 EGLBoolean eglDestroySyncKHR( 347 EGLDisplay dpy, 348 EGLSyncKHR sync); 349 350 is used to destroy an existing sync object. If any 351 eglClientWaitSyncKHR commands are blocking on <sync> when 352 eglDestroySyncKHR is called, they will be woken up, as if <sync> 353 were signaled. 354 355 If no errors are generated, EGL_TRUE is returned, and <sync> will no 356 longer be the handle of a valid sync object. 357 358 Errors 359 ------ 360 361 * If <sync> is not a valid sync object for <dpy>, EGL_FALSE is 362 returned and an EGL_BAD_PARAMETER error is generated. 363 * If <dpy> does not match the display passed to eglCreateSyncKHR 364 when <sync> was created, the behaviour is undefined." 365 366Issues 367 368 Note about the Issues 369 --------------------- 370 The wording for this extension was originally written as a single 371 extension defining two types of sync object; a "reusable sync 372 object" and a "fence sync object". That extension was split to 373 produce standalone extensions for each type of sync object, and 374 references to the other type removed from the specification 375 language. This issues list has been simplied to remove references to 376 fence sync objects but is otherwise very similar to the 377 EGL_KHR_fence_sync extension issues list. 378 379 1. Explain the key choices made in this extension. 380 381 RESPONSE: This extension has been written to enable adoption to be 382 as wide as possible, and to behave as similarly as possible to 383 synchronization primitives available in desktop OpenGL (e.g., 384 NV_fence, ARB_sync). 385 386 In the interest of enabling widespread adoption, this extension 387 (following the ARB_sync model) has foregone the inclusion of 388 synchronization primitives and synchronization tests which may be 389 performed entirely inside client API command streams, instead 390 performing synchronization tests (eglClientWaitSyncKHR) inside the 391 application & host CPU. 392 393 In the interest of maintaining similarity with previous 394 synchronization primitives, this extension attempts to copy the 395 ARB_sync specification wherever possible (both functionally and 396 stylistically), only making changes where needed to operate inside 397 EGL (rather than a client API context) and match EGL naming 398 conventions. 399 400 2. Why place this behavior in EGL, rather than in the client APIs? 401 402 RESPONSE: Ultimately, synchronization between multiple asynchronous 403 client API contexts (potentially executing in different threads) is 404 a problem which affects or will affect all EGL client APIs. Rather 405 than creating separate synchronization primitives in each of the 406 client APIs (and then wrapping them in an EGL container), in the 407 interest of developer simplicity & consistency this behavior is 408 being placed inside EGL. 409 410 3. What does this extension provide that can not be accomplished 411 with the existing, more efficient eglWaitClient and eglWaitNative 412 API functions? 413 414 RESPONSE: eglWaitClient and eglWaitNative may be implemented in 415 extremely lightweight manners, in some cases not blocking the 416 calling thread at all; however, they can not be used to synchronize 417 between client API contexts and native APIs executing in separate 418 threads (or simply between client API contexts executing in separate 419 threads), such as between a thread with an active OpenGL context and 420 a second thread performing video decode. 421 422 4. [REMOVED - found in the fence_sync extension.] 423 424 5. Should integration with native platform synchronization objects 425 be included in this extension, or reserved for future 426 (platform-specific) extensions? 427 428 RESOLVED: Integration with native platform synchronization objects 429 should not be part of this extension, but can be added as future 430 layered extensions if needed. These layered extensions can be 431 platform-specific, or perhaps OpenKODE based. 432 433 Originally, this extension included the ability to create native 434 platform synchronization objects from EGLSync objects. This feature 435 was removed for a few reasons: 436 437 i) The proposed mechanism suggested mapping EGLSync objects to 438 pthread conditional variables on platforms with pthread support. 439 However, pthread conditional variables require an associated 440 mutex and there was no mechanism to relay this associated mutex 441 to the application. 442 443 ii) On certain platforms support for converting to native 444 platform synchronization objects adds great complexity to the 445 implementation. 446 447 iii) Now that OpenKODE is more mature, it would be better to 448 allow conversion from EGLSyncKHR objects to OpenKODE 449 synchronization primitives rather than platform-specific ones. 450 We suggest that this functionality, if needed, be added as a 451 layered extension instead of being included here. This way, 452 EGL_KHR_sync remains minimal and easy to implement on a variety 453 of platforms. 454 455 6. Please provide a more detailed description of how 456 eglClientWaitSyncKHR behaves. 457 458 RESOLVED: eglClientWaitSyncKHR 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 may need to be imbedded into the actual 462 spec language): 463 464 * A reusable sync object has two possible status values: signaled 465 or unsignaled. 466 * When created, the status of the sync object is unsignaled by 467 default. 468 * A reusable sync can be set to signaled or unsignaled 469 status using eglSignalSyncKHR. 470 * A wait function called on a sync object in the unsignaled state 471 will block. It unblocks (note, not "returns to the application") 472 when the sync object transitions to the signaled state. 473 * A wait function called on a sync object in the signaled state 474 will return immediately. 475 476 7. Should the 'flags' argument to eglClientWaitSyncKHR be 477 EGLint or EGLuint? 478 479 RESOLVED: EGLint, setting a precedent for explicit bitmask types 480 in EGL going forward. We don't have an EGLuint type and it is 481 overkill for this purposes when other bitmasks (surface type 482 and api type) are already using EGLint attribute fields. 483 484 8. Can multiple WaitSyncs be placed on the same sync object? 485 486 RESOLVED: Yes. This has been allowed all along but we now state it 487 more clearly in the spec language. However, there is some concern 488 that this is hard to implement and of limited use, and we might 489 remove this capability before approving the extension. 490 491 One way to do this while allowing multiple waiters at some future 492 point is to expose it through the API to developers as either a sync 493 attribute allowing multiple waits (default not allowing it), or a 494 parameter to WaitSync, which initially must be something like 495 EGL_SINGLE_WAIT_ONLY. 496 497 9. Should eglDestroySyncKHR release all WaitSyncs placed on a 498 reusable sync object? 499 500 RESOLVED: Yes. It is safest to release all threads waiting on a 501 reusable object when the sync object is deleted so that waiting 502 threads do not wait forever. 503 504Revision History 505 506#22 (Jon Leech, January 31, 2014) 507 - Clarify return value of ClientWaitSyncKHR when called with <timeout> 508 of zero for an unsignaled <sync> (Bug 11576). 509#21 (Jon Leech, April 23, 2013) 510 - Simplify issues list to remove issues specific to fence sync 511 objects. 512#20 (Jon Leech, September 8, 2009) 513 - Change status to complete and note approval by the Promoters. 514 Minor formatting changes. 515#19 (Robert Palmer, July 14, 2009) 516 - Branch wording from draft KHR_sync specification. Remove ability 517 to create "fence sync objects and all tokens/wording specific to 518 them. 519#18 (Robert Palmer, July 8, 2009) 520 - Issues 8 and 9 declared resolved in EGL meeting 2009-07-08 521#17 (Robert Palmer, July 8, 2009) 522 - Update eglDestroySyncKHR to special-case deletion of fence sync 523 objects. This is explained in issue 9. 524 - Corrected EGL_REUSABLE_SYNC_KHR -> EGL_SYNC_REUSABLE_KHR 525 - Define value for EGL_SYNC_REUSABLE_KHR 526 - Fix typo and whitespace 527#16 (Jon Leech, July 7, 2009) 528 - Update description of new tokens to match changes to the 529 eglCreateSyncKHR entry point in revision 15. 530#15 (Jon Leech, June 16, 2009) 531 - Define separate one-time fence sync and reusable sync extensions 532 and corresponding extension strings. Remove AUTO_RESET and 533 eglFenceKHR. Rename eglCreateFenceSyncKHR to eglCreateSyncKHR and 534 change initial status of reusable syncs to unsignaled. Clarify 535 which functions apply to which types of sync objects. Update 536 issues list. 537#14 (Jon Leech, April 29, 2009) 538 - Clarify that all waiters are woken up on signalling a sync. 539 Remove tabs to cleanup some formatting issues. 540#13 (Acorn Pooley, April 2, 2009) 541 - Renamed 542 GL_OES_egl_sync -> GL_OES_EGL_sync 543 VG_KHR_egl_sync -> VG_KHR_EGL_sync 544#12 (Jon Leech, April 1, 2009) 545 - Changed sync flags type from EGLuint to EGLint and add issue 7. 546#11 (Acorn Pooley, February 4, 2009) 547 - add error case to eglGetSyncAttribKHR. 548 - fix year on rev 8-10 (2008->2009) 549#10 (Acorn Pooley, February 4, 2009) 550 - clarify some error message descriptions 551#9 (Greg Prisament, January 15, 2009) 552 - Destroy now wakes up all waits (eglClientWaitSyncKHR) 553 - Add EGLDisplay <dpy> as first parameter to all commands 554 - Split into 3 extension strings, EGL_KHR_sync, GL_OES_egl_sync, 555 VG_KHR_egl_sync, all described in this document. 556 - Add attribute AUTO_RESET_KHR 557 - Time type uses the type from khrplatform.h 558 - Remove EGL_ALREADY_SIGNALLED 559#8 (Jon Leech, November 11, 2009) 560 - Assign enum values 561#7 (Acorn Pooley, October 30, 2008) 562 - Fix typos 563 - remove obsolete wording about Native sync objects (see issue 5) 564 - formatting: remove tabs, 80 columns 565#6 (Acorn Pooley, October 27, 2008) 566 - Corrected 'enum' to 'EGLenum' in prototypes. 567#5 (Jon Leech, September 9, 2008) 568 - Removed native sync support (eglCreateNativeSyncKHR and 569 EGL_SYNC_NATIVE_SYNC_KHR), and re-flowed spec to fit in 80 columns. 570#4 (Jon Leech, November 20, 2007) 571 - Corrected 'enum' to 'EGLenum' in prototypes. 572#3 (Jon Leech, April 5, 2007) 573 - Added draft Status and TBD Number 574#2 (November 27, 2006) 575 - Changed OES token to KHR 576