| Name | |
| APPLE_sync | |
| Name Strings | |
| GL_APPLE_sync | |
| Contributors | |
| Contributors to ARB_sync desktop OpenGL extension from which this | |
| extension borrows heavily | |
| Contact | |
| Benj Lipchak (lipchak 'at' apple 'dot' com) | |
| Status | |
| Complete | |
| Version | |
| Last Modified Date: July 10, 2012 | |
| Author Revision: 3 | |
| Number | |
| OpenGL ES Extension #124 | |
| Dependencies | |
| OpenGL ES 1.1 or OpenGL ES 2.0 is required. | |
| This specification is written against the OpenGL ES 2.0.25 specification. | |
| EXT_debug_label affects the definition of this extension. | |
| Overview | |
| This extension introduces the concept of "sync objects". Sync | |
| objects are a synchronization primitive - a representation of events | |
| whose completion status can be tested or waited upon. One specific | |
| type of sync object, the "fence sync object", is supported in this | |
| extension, and additional types can easily be added in the future. | |
| Fence sync objects have corresponding fences, which are inserted | |
| into the OpenGL command stream at the time the sync object is | |
| created. A sync object can be queried for a given condition. The | |
| only condition supported for fence sync objects is completion of the | |
| corresponding fence command. Fence completion allows applications to | |
| request a partial Finish, wherein all commands prior to the fence | |
| will be forced to complete before control is returned to the calling | |
| process. | |
| These new mechanisms allow for synchronization between the host CPU | |
| and the GPU, which may be accessing the same resources (typically | |
| memory), as well as between multiple GL contexts bound to multiple | |
| threads in the host CPU. | |
| New Types | |
| (Implementer's Note: GLint64 and GLuint64 are defined as appropriate | |
| for an ISO C 99 compiler. Other language bindings, or non-ISO | |
| compilers, may need to use a different approach). | |
| #include <inttypes.h> | |
| typedef int64_t GLint64; | |
| typedef uint64_t GLuint64; | |
| typedef struct __GLsync *GLsync; | |
| New Procedures and Functions | |
| sync FenceSyncAPPLE(enum condition, bitfield flags); | |
| boolean IsSyncAPPLE(sync sync); | |
| void DeleteSyncAPPLE(sync sync); | |
| enum ClientWaitSyncAPPLE(sync sync, bitfield flags, uint64 timeout); | |
| void WaitSyncAPPLE(sync sync, bitfield flags, uint64 timeout); | |
| void GetInteger64vAPPLE(enum pname, int64 *params); | |
| void GetSyncivAPPLE(sync sync, enum pname, sizei bufSize, sizei *length, | |
| int *values); | |
| New Tokens | |
| Accepted as the <pname> parameter of GetInteger64vAPPLE: | |
| MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 | |
| Accepted as the <pname> parameter of GetSyncivAPPLE: | |
| OBJECT_TYPE_APPLE 0x9112 | |
| SYNC_CONDITION_APPLE 0x9113 | |
| SYNC_STATUS_APPLE 0x9114 | |
| SYNC_FLAGS_APPLE 0x9115 | |
| Returned in <values> for GetSynciv <pname> OBJECT_TYPE_APPLE: | |
| SYNC_FENCE_APPLE 0x9116 | |
| Returned in <values> for GetSyncivAPPLE <pname> SYNC_CONDITION_APPLE: | |
| SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 | |
| Returned in <values> for GetSyncivAPPLE <pname> SYNC_STATUS_APPLE: | |
| UNSIGNALED_APPLE 0x9118 | |
| SIGNALED_APPLE 0x9119 | |
| Accepted in the <flags> parameter of ClientWaitSyncAPPLE: | |
| SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 | |
| Accepted in the <timeout> parameter of WaitSyncAPPLE: | |
| TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull | |
| Returned by ClientWaitSyncAPPLE: | |
| ALREADY_SIGNALED_APPLE 0x911A | |
| TIMEOUT_EXPIRED_APPLE 0x911B | |
| CONDITION_SATISFIED_APPLE 0x911C | |
| WAIT_FAILED_APPLE 0x911D | |
| Accepted by the <type> parameter of LabelObjectEXT and | |
| GetObjectLabelEXT: | |
| SYNC_OBJECT_APPLE 0x8A53 | |
| Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation) | |
| Add to Table 2.2, GL data types: | |
| "GL Type Minimum Description | |
| Bit Width | |
| ------- --------- ---------------------------------------------- | |
| int64 64 Signed 2's complement binary integer | |
| uint64 64 Unsigned binary integer | |
| sync <ptrbits> Sync object handle (see section 5.2)" | |
| Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) | |
| Insert a new section following "Flush and Finish" (Section 5.1) | |
| describing sync objects and fence operation. Renumber existing | |
| section 5.2 "Hints" and all following 5.* sections. | |
| "5.2 Sync Objects and Fences | |
| --------------------------- | |
| Sync objects act as a <synchronization primitive> - a representation | |
| of events whose completion status can be tested or waited upon. Sync | |
| objects may be used for synchronization with operations occuring in | |
| the GL state machine or in the graphics pipeline, and for | |
| synchronizing between multiple graphics contexts, among other | |
| purposes. | |
| Sync objects have a status value with two possible states: | |
| <signaled> and <unsignaled>. Events are associated with a sync | |
| object. When a sync object is created, its status is set to | |
| unsignaled. When the associated event occurs, the sync object is | |
| signaled (its status is set to signaled). The GL may be asked to | |
| wait for a sync object to become signaled. | |
| Initially, only one specific type of sync object is defined: the | |
| fence sync object, whose associated event is triggered by a fence | |
| command placed in the GL command stream. Fence sync objects are used | |
| to wait for partial completion of the GL command stream, as a more | |
| flexible form of Finish. | |
| The command | |
| sync FenceSyncAPPLE(enum condition, bitfield flags); | |
| creates a new fence sync object, inserts a fence command in the GL | |
| command stream and associates it with that sync object, and returns | |
| a non-zero name corresponding to the sync object. | |
| When the specified <condition> of the sync object is satisfied by | |
| the fence command, the sync object is signaled by the GL, causing | |
| any ClientWaitSyncAPPLE or WaitSyncAPPLE commands (see below) blocking | |
| on <sync> to <unblock>. No other state is affected by FenceSyncAPPLE | |
| or by execution of the associated fence command. | |
| <condition> must be SYNC_GPU_COMMANDS_COMPLETE_APPLE. This condition | |
| is satisfied by completion of the fence command corresponding to the | |
| sync object and all preceding commands in the same command stream. | |
| The sync object will not be signaled until all effects from these | |
| commands on GL client and server state and the framebuffer are fully | |
| realized. Note that completion of the fence command occurs once the | |
| state of the corresponding sync object has been changed, but | |
| commands waiting on that sync object may not be unblocked until | |
| some time after the fence command completes. | |
| <flags> must be 0[fn1]. | |
| [fn1: <flags> is a placeholder for anticipated future extensions | |
| of fence sync object capabilities.] | |
| Each sync object contains a number of <properties> which determine | |
| the state of the object and the behavior of any commands associated | |
| with it. Each property has a <property name> and <property value>. | |
| The initial property values for a sync object created by FenceSyncAPPLE | |
| are shown in table 5.props: | |
| Property Name Property Value | |
| -------------------- ---------------- | |
| OBJECT_TYPE_APPLE SYNC_FENCE_APPLE | |
| SYNC_CONDITION_APPLE <condition> | |
| SYNC_STATUS_APPLE UNSIGNALED_APPLE | |
| SYNC_FLAGS_APPLE <flags> | |
| -------------------------------------- | |
| Table 5.props: Initial properties of a | |
| sync object created with FenceSyncAPPLE. | |
| Properties of a sync object may be queried with GetSyncivAPPLE (see | |
| section 6.1.6). The SYNC_STATUS_APPLE property will be changed to | |
| SIGNALED_APPLE when <condition> is satisfied. | |
| If FenceSyncAPPLE fails to create a sync object, zero will be returned | |
| and a GL error will be generated as described. An INVALID_ENUM error | |
| is generated if <condition> is not SYNC_GPU_COMMANDS_COMPLETE_APPLE. If | |
| <flags> is not zero, an INVALID_VALUE error is generated. | |
| A sync object can be deleted by passing its name to the command | |
| void DeleteSyncAPPLE(sync sync); | |
| If the fence command corresponding to the specified sync object has | |
| completed, or if no ClientWaitSyncAPPLE or WaitSyncAPPLE commands are | |
| blocking on <sync>, the object is deleted immediately. Otherwise, <sync> | |
| is flagged for deletion and will be deleted when it is no longer | |
| associated with any fence command and is no longer blocking any | |
| ClientWaitSyncAPPLE or WaitSyncAPPLE command. In either case, after | |
| returning from DeleteSyncAPPLE the <sync> name is invalid and can no | |
| longer be used to refer to the sync object. | |
| DeleteSyncAPPLE will silently ignore a <sync> value of zero. An | |
| INVALID_VALUE error is generated if <sync> is neither zero nor the | |
| name of a sync object. | |
| 5.2.1 Waiting for Sync Objects | |
| ------------------------------ | |
| The command | |
| enum ClientWaitSyncAPPLE(sync sync, bitfield flags, uint64 timeout); | |
| causes the GL to block, and will not return until the sync object | |
| <sync> is signaled, or until the specified <timeout> period expires. | |
| <timeout> is in units of nanoseconds. <timeout> is adjusted to the | |
| closest value allowed by the implementation-dependent timeout | |
| accuracy, which may be substantially longer than one nanosecond, and | |
| may be longer than the requested period. | |
| If <sync> is signaled at the time ClientWaitSyncAPPLE is called | |
| then ClientWaitSyncAPPLE returns immediately. If <sync> is unsignaled | |
| at the time ClientWaitSyncAPPLE is called then ClientWaitSyncAPPLE will | |
| block and will wait up to <timeout> nanoseconds for <sync> to become | |
| signaled. <flags> controls command flushing behavior, and may be | |
| SYNC_FLUSH_COMMANDS_BIT_APPLE, as discussed in section 5.2.2. | |
| ClientWaitSyncAPPLE returns one of four status values. A return value of | |
| ALREADY_SIGNALED_APPLE indicates that <sync> was signaled at the time | |
| ClientWaitSyncAPPLE was called. ALREADY_SIGNALED_APPLE will always be | |
| returned if <sync> was signaled, even if the value of <timeout> is zero. | |
| A return value of TIMEOUT_EXPIRED_APPLE indicates that the specified | |
| timeout period expired before <sync> was signaled. A return value of | |
| CONDITION_SATISFIED_APPLE indicates that <sync> was signaled before the | |
| timeout expired. Finally, if an error occurs, in addition to | |
| generating a GL error as specified below, ClientWaitSyncAPPLE immediately | |
| returns WAIT_FAILED_APPLE without blocking. | |
| If the value of <timeout> is zero, then ClientWaitSyncAPPLE does not | |
| block, but simply tests the current state of <sync>. | |
| TIMEOUT_EXPIRED_APPLE will be returned in this case if <sync> is not | |
| signaled, even though no actual wait was performed. | |
| If <sync> is not the name of a sync object, an INVALID_VALUE error | |
| is generated. If <flags> contains any bits other than | |
| SYNC_FLUSH_COMMANDS_BIT_APPLE, an INVALID_VALUE error is generated. | |
| The command | |
| void WaitSyncAPPLE(sync sync, bitfield flags, uint64 timeout); | |
| is similar to ClientWaitSyncAPPLE, but instead of blocking and not | |
| returning to the application until <sync> is signaled, WaitSyncAPPLE | |
| returns immediately, instead causing the GL server [fn2] to block | |
| until <sync> is signaled [fn3]. | |
| [fn2 - the GL server may choose to wait either in the CPU | |
| executing server-side code, or in the GPU hardware if it | |
| supports this operation.] | |
| [fn3 - WaitSyncAPPLE allows applications to continue to queue commands | |
| from the client in anticipation of the sync being signalled, | |
| increasing client-server parallelism.] | |
| <sync> has the same meaning as for ClientWaitSyncAPPLE. | |
| <timeout> must currently be the special value TIMEOUT_IGNORED_APPLE, and | |
| is not used. Instead, WaitSyncAPPLE will always wait no longer than an | |
| implementation-dependent timeout. The duration of this timeout in | |
| nanoseconds may be queried by calling GetInteger64vAPPLE with <value> | |
| MAX_SERVER_WAIT_TIMEOUT_APPLE. There is currently no way to determine | |
| whether WaitSyncAPPLE unblocked because the timeout expired or because | |
| the sync object being waited on was signaled. | |
| <flags> must be 0. | |
| If an error occurs, WaitSyncAPPLE generates a GL error as specified | |
| below, and does not cause the GL server to block. | |
| If <sync> is not the name of a sync object, an INVALID_VALUE error | |
| is generated. If <timeout> is not TIMEOUT_IGNORED_APPLE, or <flags> | |
| is not zero, an INVALID_VALUE error is generated [fn4]. | |
| [fn4 - <flags> and <timeout> are placeholders for anticipated future | |
| extensions of sync object capabilities. They must have these reserved | |
| values in order that existing code calling WaitSyncAPPLE operate properly | |
| in the presence of such extensions.] | |
| Multiple Waiters | |
| ---------------- | |
| It is possible for both the GL client to be blocked on a sync object | |
| in a ClientWaitSyncAPPLE command, the GL server to be blocked as the | |
| result of a previous WaitSyncAPPLE command, and for additional | |
| WaitSyncAPPLE commands to be queued in the GL server, all for a single | |
| sync object. When such a sync object is signaled in this situation, the | |
| client will be unblocked, the server will be unblocked, and all such | |
| queued WaitSyncAPPLE commands will continue immediately when they are | |
| reached. | |
| See appendix C.2 for more information about blocking on a sync | |
| object in multiple GL contexts. | |
| 5.2.2 Signalling | |
| ---------------- | |
| A fence sync object can be in the signaled state only once the | |
| corresponding fence command has completed and signaled the sync | |
| object. | |
| If the sync object being blocked upon will not be signaled in finite | |
| time (for example, by an associated fence command issued previously, | |
| but not yet flushed to the graphics pipeline), then ClientWaitSyncAPPLE | |
| may hang forever. To help prevent this behavior [fn5], if the | |
| SYNC_FLUSH_COMMANDS_BIT_APPLE bit is set in <flags>, and <sync> is | |
| unsignaled when ClientWaitSyncAPPLE is called, then the equivalent of | |
| Flush will be performed before blocking on <sync>. | |
| [fn5 - The simple flushing behavior defined by | |
| SYNC_FLUSH_COMMANDS_BIT_APPLE will not help when waiting for a fence | |
| command issued in another context's command stream to complete. | |
| Applications which block on a fence sync object must take | |
| additional steps to assure that the context from which the | |
| corresponding fence command was issued has flushed that command | |
| to the graphics pipeline.] | |
| If a sync object is marked for deletion while a client is blocking | |
| on that object in a ClientWaitSyncAPPLE command, or a GL server is | |
| blocking on that object as a result of a prior WaitSyncAPPLE command, | |
| deletion is deferred until the sync object is signaled and all | |
| blocked GL clients and servers are unblocked. | |
| Additional constraints on the use of sync objects are discussed in | |
| appendix C. | |
| State must be maintained to indicate which sync object names are | |
| currently in use. The state require for each sync object in use is | |
| an integer for the specific type, an integer for the condition, an | |
| integer for the flags, and a bit indicating whether the object is | |
| signaled or unsignaled. The initial values of sync object state are | |
| defined as specified by FenceSyncAPPLE." | |
| Update the Debug Labels section's last sentence to include | |
| SYNC_OBJECT_APPLE as a value supported for the <type> passed to | |
| LabelObjectEXT. | |
| Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State | |
| Requests) | |
| Add GetInteger64vAPPLE to the first list of commands in section 6.1.1 | |
| "Simple Queries", and change the next sentence to mention the query: | |
| "There are four commands for obtaining simple state variables: | |
| ... | |
| void GetInteger64vAPPLE(enum value, int64 *data); | |
| ... | |
| The commands obtain boolean, integer, 64-bit integer, or | |
| floating-point..." | |
| Modify the third sentence of section 6.1.2 "Data Conversions": | |
| "If any of the other simple queries are called, a boolean value of | |
| TRUE or FALSE is interpreted as 1 or 0, respectively. If GetIntegerv | |
| or GetInteger64vAPPLE are called, a floating-point value is rounded to | |
| the nearest integer, unless the value is an RGBA color component..." | |
| Insert a new subsection following "String Queries" (subsection | |
| 6.1.5) describing sync object queries. Renumber existing subsection | |
| 6.1.6 "Buffer Object Queries" and all following 6.1.* subsections. | |
| "6.1.6 Sync Object Queries | |
| Properties of sync objects may be queried using the command | |
| void GetSyncivAPPLE(sync sync, enum pname, sizei bufSize, | |
| sizei *length, int *values); | |
| The value or values being queried are returned in the parameters | |
| <length> and <values>. | |
| On success, GetSyncivAPPLE replaces up to <bufSize> integers in <values> | |
| with the corresponding property values of the object being queried. | |
| The actual number of integers replaced is returned in *<length>. If | |
| <length> is NULL, no length is returned. | |
| If <pname> is OBJECT_TYPE_APPLE, a single value representing the specific | |
| type of the sync object is placed in <values>. The only type | |
| supported is SYNC_FENCE_APPLE. | |
| If <pname> is SYNC_STATUS_APPLE, a single value representing the status of | |
| the sync object (SIGNALED_APPLE or UNSIGNALED_APPLE) is placed in <values>. | |
| If <pname> is SYNC_CONDITION_APPLE, a single value representing the | |
| condition of the sync object is placed in <values>. The only | |
| condition supported is SYNC_GPU_COMMANDS_COMPLETE_APPLE. | |
| If <pname> is SYNC_FLAGS_APPLE, a single value representing the flags with | |
| which the sync object was created is placed in <values>. No flags | |
| are currently supported. | |
| If <sync> is not the name of a sync object, an INVALID_VALUE error | |
| is generated. If <pname> is not one of the values described above, | |
| an INVALID_ENUM error is generated. If an error occurs, | |
| nothing will be written to <values> or <length>. | |
| The command | |
| boolean IsSyncAPPLE(sync sync); | |
| returns TRUE if <sync> is the name of a sync object. If <sync> is | |
| not the name of a sync object, or if an error condition occurs, | |
| IsSyncAPPLE returns FALSE (note that zero is not the name of a sync | |
| object). | |
| Sync object names immediately become invalid after calling | |
| DeleteSyncAPPLE, as discussed in sections 5.2 and D.2, but the underlying | |
| sync object will not be deleted until it is no longer associated | |
| with any fence command and no longer blocking any *WaitSyncAPPLE command." | |
| Update the Debug Labels section's last sentence to include | |
| SYNC_OBJECT_APPLE as a value supported for the <type> passed to | |
| GetObjectLabelEXT. | |
| Additions to Appendix C (Shared Objects and Multiple Contexts) | |
| In the third paragraph of the appendix, add "sync objects" to the | |
| list of shared state. | |
| Add "sync objects" to the list of objects in the first sentence of | |
| C.1.3. Append the following to the first paragraph of C.1.3: | |
| "A sync object is in use while there is a corresponding fence command | |
| which has not yet completed and signaled the sync object, or while | |
| there are any GL clients and/or servers blocked on the sync object as | |
| a result of ClientWaitSyncAPPLE or WaitSyncAPPLE commands." | |
| "C.1.3 Deleted Object and Object Name Lifetimes | |
| Insert a new section following "Object Deletion Behavior" (section | |
| C.1) describing sync object multicontext behavior. Renumber existing | |
| section C.2 "Propagating State Changes..." and all following C.* | |
| sections. | |
| "C.2 Sync Objects and Multiple Contexts | |
| -------------------------------------- | |
| When multiple GL clients and/or servers are blocked on a single sync | |
| object and that sync object is signalled, all such blocks are released. | |
| The order in which blocks are released is implementation-dependent." | |
| Edit the former C.2.1 to read as follows: | |
| "C.3.1 Determining Completion of Changes to an object | |
| ---------------------------------------------------- | |
| The contents of an object T are considered to have been changed once | |
| a command such as described in section C.2 has completed. Completion | |
| of a command [fn6] may be determined either by calling Finish, or by | |
| calling FenceSyncAPPLE and executing a WaitSyncAPPLE command on the | |
| associated sync object. The second method does not require a round trip | |
| to the GL server and may be more efficient, particularly when changes to | |
| T in one context must be known to have completed before executing | |
| commands dependent on those changes in another context. | |
| [fn6: The GL already specifies that a single context processes | |
| commands in the order they are received. This means that a change to | |
| an object in a context at time <t> must be completed by the time a | |
| command issued in the same context at time <t+1> uses the result of that | |
| change.]" | |
| Dependencies on EXT_debug_label | |
| If EXT_debug_label is not available, omit the updates to Debug label | |
| sections of chapters 5 and 6, and omit SYNC_OBJECT_APPLE from Table 6.X. | |
| Errors | |
| INVALID_VALUE is generated if the <sync> parameter of | |
| ClientWaitSyncAPPLE, WaitSyncAPPLE, or GetSyncivAPPLE is not the name | |
| of a sync object. | |
| INVALID_VALUE is generated if the <sync> parameter of DeleteSyncAPPLE | |
| is neither zero nor the name of a sync object. | |
| INVALID_ENUM is generated if the <condition> parameter of FenceSyncAPPLE | |
| is not SYNC_GPU_COMMANDS_COMPLETE_APPLE. | |
| INVALID_VALUE is generated if the <flags> parameter of | |
| ClientWaitSyncAPPLE contains bits other than SYNC_FLUSH_COMMANDS_BIT_APPLE, | |
| or if the <flags> parameter of WaitSyncAPPLE is nonzero. | |
| INVALID_ENUM is generated if the <pname> parameter of GetSyncivAPPLE is | |
| neither OBJECT_TYPE_APPLE, SYNC_CONDITION_APPLE, SYNC_FLAGS_APPLE, nor | |
| SYNC_STATUS_APPLE. | |
| New State | |
| Table 6.X. Sync Objects. | |
| Get value Type Get command Initial value Description Section | |
| -------------------- ---- ----------------- -------------------------------- --------------------- ------- | |
| OBJECT_TYPE_APPLE Z_1 GetSyncivAPPLE SYNC_FENCE_APPLE Type of sync object 5.2 | |
| SYNC_STATUS_APPLE Z_2 GetSyncivAPPLE UNSIGNALED_APPLE Sync object status 5.2 | |
| SYNC_CONDITION_APPLE Z_1 GetSyncivAPPLE SYNC_GPU_COMMANDS_COMPLETE_APPLE Sync object condition 5.2 | |
| SYNC_FLAGS_APPLE Z GetSyncivAPPLE SYNC_FLAGS_APPLE Sync object flags 5.2 | |
| SYNC_OBJECT_APPLE 0*xc GetObjectLabelEXT empty Debug label 5.X | |
| New Implementation Dependent State | |
| Table 40. Implementation Dependent Values (cont.) | |
| Get value Type Get command Min. value Description Section | |
| ------------------ ---- ------------- ---------- ---------------- ------- | |
| MAX_SERVER_WAIT_ Z^+ GetInteger64v 0 Maximum WaitSync 5.2 | |
| TIMEOUT_APPLE timeout interval | |
| Sample Code | |
| ... kick off a lengthy GL operation | |
| /* Place a fence and associate a fence sync object */ | |
| GLsyncAPPLE sync = glFenceSyncAPPLE(GLSYNC_GPU_COMMANDS_COMPLETE_APPLE, 0); | |
| /* Elsewhere, wait for the sync to be signaled */ | |
| /* To wait a specified amount of time (possibly clamped), do | |
| * this to convert a time in seconds into nanoseconds: | |
| */ | |
| GLuint64APPLE timeout = num_seconds * ((GLuint64)1000 * 1000 * 1000); | |
| glWaitSyncAPPLE(sync, 0, timeout); | |
| /* Or to determine the maximum possible wait interval and wait | |
| * that long, do this instead: | |
| */ | |
| GLuint64APPLE max_timeout; | |
| glGetInteger64vAPPLE(GL_MAX_SERVER_WAIT_TIMEOUT_APPLE, &max_timeout); | |
| glWaitSyncAPPLE(sync, 0, max_timeout); | |
| Issues | |
| See ARB_sync issues list: http://www.opengl.org/registry/specs/ARB/sync.txt | |
| Revision History | |
| Version 3, 2012/07/10 - Add support for debug label extension. | |
| Version 2, 2012/06/18 - Correct spec to indicate ES 1.1 may also be okay. | |
| Version 1, 2012/06/01 - Conversion from ARB_sync to APPLE_sync for ES. |