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.
This commit is contained in:
Devin J. Pohly 2021-05-25 02:52:33 -05:00
parent 60c40c0989
commit 823cefd292
1 changed files with 29 additions and 25 deletions

54
dwl.c
View File

@ -1726,38 +1726,42 @@ rendermon(struct wl_listener *listener, void *data)
} }
} }
/* wlr_output_attach_render makes the OpenGL context current. */ /* HACK: This loop is the simplest way to handle ephemeral pageflip
if (!wlr_output_attach_render(m->wlr_output, NULL)) * failures but probably not the best. Revisit if damage tracking is
return; * added. */
do {
/* wlr_output_attach_render makes the OpenGL context current. */
if (!wlr_output_attach_render(m->wlr_output, NULL))
return;
if (render) { if (render) {
/* Begin the renderer (calls glViewport and some other GL sanity checks) */ /* 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_begin(drw, m->wlr_output->width, m->wlr_output->height);
wlr_renderer_clear(drw, rootcolor); wlr_renderer_clear(drw, rootcolor);
renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &now); renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &now);
renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &now); renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &now);
renderclients(m, &now); renderclients(m, &now);
#ifdef XWAYLAND #ifdef XWAYLAND
renderindependents(m->wlr_output, &now); renderindependents(m->wlr_output, &now);
#endif #endif
renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &now); renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &now);
renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &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 /* 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 * moved around without re-rendering what's beneath them - which is more
* efficient. However, not all hardware supports hardware cursors. For this * efficient. However, not all hardware supports hardware cursors. For this
* reason, wlroots provides a software fallback, which we ask it to render * reason, wlroots provides a software fallback, which we ask it to render
* here. wlr_cursor handles configuring hardware vs software cursors for you, * here. wlr_cursor handles configuring hardware vs software cursors for you,
* and this function is a no-op when hardware cursors are in use. */ * and this function is a no-op when hardware cursors are in use. */
wlr_output_render_software_cursors(m->wlr_output, NULL); wlr_output_render_software_cursors(m->wlr_output, NULL);
/* Conclude rendering and swap the buffers, showing the final frame /* Conclude rendering and swap the buffers, showing the final frame
* on-screen. */ * on-screen. */
wlr_renderer_end(drw); wlr_renderer_end(drw);
} }
wlr_output_commit(m->wlr_output); } while (!wlr_output_commit(m->wlr_output));
} }
void void