diff options
| author | Devin J. Pohly <djpohly@gmail.com> | 2021-05-25 02:52:33 -0500 | 
|---|---|---|
| committer | Devin J. Pohly <djpohly@gmail.com> | 2021-05-25 02:52:33 -0500 | 
| commit | 823cefd2920085a0f74899fb679020005a1b6e0b (patch) | |
| tree | b6bf9c218278d5199e45bbc2d83e4828246d729e /dwl.c | |
| parent | 60c40c0989440fc54aa05b0e27cfbaad8c722fec (diff) | |
handle ephemeral pageflip failures
If a transient failure occurs in wlr_output_commit, re-render until it
doesn't happen.  This could possibly be removed if we decide to
implement damage tracking in the future.
Diffstat (limited to 'dwl.c')
| -rw-r--r-- | dwl.c | 58 | 
1 files changed, 31 insertions, 27 deletions
| @@ -1726,38 +1726,42 @@ rendermon(struct wl_listener *listener, void *data)  		}  	} -	/* wlr_output_attach_render makes the OpenGL context current. */ -	if (!wlr_output_attach_render(m->wlr_output, NULL)) -		return; +	/* HACK: This loop is the simplest way to handle ephemeral pageflip +	 * failures but probably not the best. Revisit if damage tracking is +	 * added. */ +	do { +		/* wlr_output_attach_render makes the OpenGL context current. */ +		if (!wlr_output_attach_render(m->wlr_output, NULL)) +			return; -	if (render) { -		/* Begin the renderer (calls glViewport and some other GL sanity checks) */ -		wlr_renderer_begin(drw, m->wlr_output->width, m->wlr_output->height); -		wlr_renderer_clear(drw, rootcolor); +		if (render) { +			/* Begin the renderer (calls glViewport and some other GL sanity checks) */ +			wlr_renderer_begin(drw, m->wlr_output->width, m->wlr_output->height); +			wlr_renderer_clear(drw, rootcolor); -		renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &now); -		renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &now); -		renderclients(m, &now); +			renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &now); +			renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &now); +			renderclients(m, &now);  #ifdef XWAYLAND -		renderindependents(m->wlr_output, &now); +			renderindependents(m->wlr_output, &now);  #endif -		renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &now); -		renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &now); - -		/* Hardware cursors are rendered by the GPU on a separate plane, and can be -		 * moved around without re-rendering what's beneath them - which is more -		 * efficient. However, not all hardware supports hardware cursors. For this -		 * reason, wlroots provides a software fallback, which we ask it to render -		 * here. wlr_cursor handles configuring hardware vs software cursors for you, -		 * and this function is a no-op when hardware cursors are in use. */ -		wlr_output_render_software_cursors(m->wlr_output, NULL); - -		/* Conclude rendering and swap the buffers, showing the final frame -		 * on-screen. */ -		wlr_renderer_end(drw); -	} +			renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &now); +			renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &now); + +			/* Hardware cursors are rendered by the GPU on a separate plane, and can be +			 * moved around without re-rendering what's beneath them - which is more +			 * efficient. However, not all hardware supports hardware cursors. For this +			 * reason, wlroots provides a software fallback, which we ask it to render +			 * here. wlr_cursor handles configuring hardware vs software cursors for you, +			 * and this function is a no-op when hardware cursors are in use. */ +			wlr_output_render_software_cursors(m->wlr_output, NULL); + +			/* Conclude rendering and swap the buffers, showing the final frame +			 * on-screen. */ +			wlr_renderer_end(drw); +		} -	wlr_output_commit(m->wlr_output); +	} while (!wlr_output_commit(m->wlr_output));  }  void | 
