aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevin J. Pohly <djpohly@gmail.com>2021-05-25 02:52:33 -0500
committerDevin J. Pohly <djpohly@gmail.com>2021-05-25 02:52:33 -0500
commit823cefd2920085a0f74899fb679020005a1b6e0b (patch)
treeb6bf9c218278d5199e45bbc2d83e4828246d729e
parent60c40c0989440fc54aa05b0e27cfbaad8c722fec (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.
-rw-r--r--dwl.c58
1 files changed, 31 insertions, 27 deletions
diff --git a/dwl.c b/dwl.c
index e0b404e..a38f452 100644
--- a/dwl.c
+++ b/dwl.c
@@ -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