As a name suggests glClientWaitSync is aimed on clients. Here client is simply an actor who issues OpenGL commands and wants to get notified when they are executed. In most cases a client is simply one of your application’s threads. Demonstration of glClientWaitSync is below:
Here we see that some thread issues OpenGL commands: A7, A6, A5, A4, A3, A2. After A2 thread inserts a fence F using glFenceSync into OpenGL queue and also inserts a last command A1. After this thread continues its normal execution while GPU processes issued commands. At some point of time our thread can call glClientWaitSync over a created fence F – this will make it to wait until F is executed by GPU. This way a thread (a client) can ensure that previous commands are executed by GPU.
An example of glClientWaitSync is the following. Suppose that a thread has scheduled commands to render a texture X and afterwards it must hand over this texture to another thread for further processing. Without the knowledge of when commands are executed a texture X can be passed in a semi-ready state. Using glClientWaitSync this issue is solved easily.
On the other side as documentation says glWaitSync is aimed on server. Here server is a generalization of OpenGL subsystem itself. This call is used to synchronize two flows of OpenGL commands. Demonstration of glWaitSync is below:
Here we see two OpenGL queues: one is just populated with commands by Thread 1 and second one is just populated with commands by Thread 2. Thread 1 has inserted a fence object F into its queue using glFenceSync, while the second thread inserted a WAIT – W(F) – on this fence in its queue using glWaitSync. A net effect of this is the following. Commands of both threads are executed by GPU in parallel but suppose that commands from the second queue are executed faster. Soon GPU meet a W(F) and ceases further execution of commands from this queue until a referencing fence F from the first queue is executed. After a referencing fence from the first queue is swallowed by GPU commands from the second queue are unleashed.
glWaitSync is handy when commands from the second thread (e.g. B1, B2 & B3) depend on results of commands from the first queue. E.g. suppose that Thread 1 with commands A1 – A7 has programmed GPU to execute some shader program over a texture X. At the same time Thread 2 wants to display this texture X (using commands B1 – B3) however it must known when shader is finished (otherwise it would expose semi-ready texture). Using fence objects and glWaitSync Thread 2 could instruct GPU to wait until shader program is finished before executing commands B1 – B3.
More information on these calls could be found here: https://www.opengl.org/wiki/Sync_Object.