[weston] simple-shm: explain two initial roundtrips

Submitted by Pekka Paalanen on Nov. 25, 2014, 7:58 a.m.

Details

Message ID 1416902337-11967-1-git-send-email-ppaalanen@gmail.com
State Superseded
Headers show

Not browsing as part of any series.

Commit Message

Pekka Paalanen Nov. 25, 2014, 7:58 a.m.
From: Pekka Paalanen <pekka.paalanen@collabora.co.uk>

Explain carefully why we need two roundtrips, not just one, not just
dispatch and roundtrip, but two roundtrips after creating the
wl_registry object.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
---
 clients/simple-shm.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Patch hide | download patch | download mbox

diff --git a/clients/simple-shm.c b/clients/simple-shm.c
index c1cb386..996a8a9 100644
--- a/clients/simple-shm.c
+++ b/clients/simple-shm.c
@@ -388,6 +388,36 @@  create_display(void)
 
 	wl_display_roundtrip(display->display);
 
+	/*
+	 * Why do we need two roundtrips here?
+	 *
+	 * wl_display_get_registry() sends a request to the server, to which
+	 * the server replies by emitting the wl_registry.global events.
+	 * The first wl_display_roundtrip() sends wl_display.sync. The server
+	 * first processes the wl_display.get_registry which includes sending
+	 * the global events, and then processes the sync. Therefore when the
+	 * sync (roundtrip) returns, we are guaranteed to have received and
+	 * processed all the global events.
+	 *
+	 * While we are inside the first wl_display_roundtrip(), incoming
+	 * events are dispatched, which causes registry_handle_global() to
+	 * be called for each global. One of these globals is wl_shm.
+	 * registry_handle_global() sends wl_registry.bind request for the
+	 * wl_shm global. However, wl_registry.bind request is sent only after
+	 * the first wl_display.sync, so the reply to the sync comes before
+	 * the initial events of the wl_shm object.
+	 *
+	 * When the reply to the first sync comes, the server may or may not
+	 * have sent initial wl_shm events. Therefore we need the second
+	 * wl_display_roundtrip() call here.
+	 *
+	 * The server processes the wl_registry.bind for wl_shm first, and
+	 * the second wl_display.sync next. During our second call to
+	 * wl_display_roundtrip() the initial wl_shm events are received and
+	 * processed. Finally, when the reply to the second wl_display.sync
+	 * arrives, it guarantees we have processed all wl_shm initial events.
+	 */
+
 	if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
 		fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
 		exit(1);

Comments

Can you add what wl_shm events it must get before continuing? (I guess 
it is the list of supported formats). This is not clear from this 
comment, which reads more like "bind won't work unless you do sync 
afterwards".

On 11/24/2014 11:58 PM, Pekka Paalanen wrote:
> From: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
>
> Explain carefully why we need two roundtrips, not just one, not just
> dispatch and roundtrip, but two roundtrips after creating the
> wl_registry object.
>
> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
> ---
>   clients/simple-shm.c | 30 ++++++++++++++++++++++++++++++
>   1 file changed, 30 insertions(+)
>
> diff --git a/clients/simple-shm.c b/clients/simple-shm.c
> index c1cb386..996a8a9 100644
> --- a/clients/simple-shm.c
> +++ b/clients/simple-shm.c
> @@ -388,6 +388,36 @@ create_display(void)
>
>   	wl_display_roundtrip(display->display);
>
> +	/*
> +	 * Why do we need two roundtrips here?
> +	 *
> +	 * wl_display_get_registry() sends a request to the server, to which
> +	 * the server replies by emitting the wl_registry.global events.
> +	 * The first wl_display_roundtrip() sends wl_display.sync. The server
> +	 * first processes the wl_display.get_registry which includes sending
> +	 * the global events, and then processes the sync. Therefore when the
> +	 * sync (roundtrip) returns, we are guaranteed to have received and
> +	 * processed all the global events.
> +	 *
> +	 * While we are inside the first wl_display_roundtrip(), incoming
> +	 * events are dispatched, which causes registry_handle_global() to
> +	 * be called for each global. One of these globals is wl_shm.
> +	 * registry_handle_global() sends wl_registry.bind request for the
> +	 * wl_shm global. However, wl_registry.bind request is sent only after
> +	 * the first wl_display.sync, so the reply to the sync comes before
> +	 * the initial events of the wl_shm object.
> +	 *
> +	 * When the reply to the first sync comes, the server may or may not
> +	 * have sent initial wl_shm events. Therefore we need the second
> +	 * wl_display_roundtrip() call here.
> +	 *
> +	 * The server processes the wl_registry.bind for wl_shm first, and
> +	 * the second wl_display.sync next. During our second call to
> +	 * wl_display_roundtrip() the initial wl_shm events are received and
> +	 * processed. Finally, when the reply to the second wl_display.sync
> +	 * arrives, it guarantees we have processed all wl_shm initial events.
> +	 */
> +
>   	if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
>   		fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
>   		exit(1);
>