From 507d9bc19e05d3fd4378063ad87f4a74b3dfcfca Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 6 Apr 2020 11:53:20 +0200 Subject: Add wlr_output_impl.rollback Most of the pending output state is not forwarded to the backend prior to an output commit. For instance, wlr_output_set_mode just stashes the mode without calling any wlr_output_impl function. wlr_output_impl.commit is responsible for applying the pending mode. However, there are exceptions to this rule. The first one is wlr_output_attach_render. It won't go away before renderer v6 is complete, because it needs to set the current EGL surface. The second one is wlr_output_attach_buffer. wlr_output_impl.attach_buffer is removed in [1]. When wlr_output_rollback is called, all pending state is supposed to be cleared. This works for all the state except the two exceptions mentionned above. To fix this, introduce wlr_output_impl.rollback. Right now, the backend resets the current EGL surface. This prevents GL commands from affecting the output after wlr_output_rollback. This patch is required for FBO-based outputs to work properly. The compositor might be using FBOs for its own purposes [2], having leftover FBO state can have bad consequences. [1]: https://github.com/swaywm/wlroots/pull/2097 [2]: https://github.com/swaywm/wlroots/pull/2063#issuecomment-597614312 --- backend/drm/drm.c | 6 ++++++ backend/headless/output.c | 7 +++++++ backend/wayland/output.c | 7 +++++++ backend/x11/output.c | 6 ++++++ 4 files changed, 26 insertions(+) (limited to 'backend') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 3bdb288e..55760015 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -574,6 +574,11 @@ static bool drm_connector_commit(struct wlr_output *output) { return true; } +static void drm_connector_rollback(struct wlr_output *output) { + struct wlr_drm_backend *drm = get_drm_backend_from_backend(output->backend); + wlr_egl_make_current(&drm->renderer.egl, EGL_NO_SURFACE, NULL); +} + static void fill_empty_gamma_table(size_t size, uint16_t *r, uint16_t *g, uint16_t *b) { assert(0xFFFF < UINT64_MAX / (size - 1)); @@ -1094,6 +1099,7 @@ static const struct wlr_output_impl output_impl = { .attach_render = drm_connector_attach_render, .test = drm_connector_test, .commit = drm_connector_commit, + .rollback = drm_connector_rollback, .set_gamma = set_drm_connector_gamma, .get_gamma_size = drm_connector_get_gamma_size, .export_dmabuf = drm_connector_export_dmabuf, diff --git a/backend/headless/output.c b/backend/headless/output.c index 18847af0..918581f5 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -97,6 +97,12 @@ static bool output_commit(struct wlr_output *wlr_output) { return true; } +static void output_rollback(struct wlr_output *wlr_output) { + struct wlr_headless_output *output = + headless_output_from_output(wlr_output); + wlr_egl_make_current(&output->backend->egl, EGL_NO_SURFACE, NULL); +} + static void output_destroy(struct wlr_output *wlr_output) { struct wlr_headless_output *output = headless_output_from_output(wlr_output); @@ -113,6 +119,7 @@ static const struct wlr_output_impl output_impl = { .destroy = output_destroy, .attach_render = output_attach_render, .commit = output_commit, + .rollback = output_rollback, }; bool wlr_output_is_headless(struct wlr_output *wlr_output) { diff --git a/backend/wayland/output.c b/backend/wayland/output.c index ae58b584..07c5ec8d 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -302,6 +302,12 @@ static bool output_commit(struct wlr_output *wlr_output) { return true; } +static void output_rollback(struct wlr_output *wlr_output) { + struct wlr_wl_output *output = + get_wl_output_from_output(wlr_output); + wlr_egl_make_current(&output->backend->egl, EGL_NO_SURFACE, NULL); +} + static bool output_set_cursor(struct wlr_output *wlr_output, struct wlr_texture *texture, int32_t scale, enum wl_output_transform transform, @@ -431,6 +437,7 @@ static const struct wlr_output_impl output_impl = { .attach_render = output_attach_render, .test = output_test, .commit = output_commit, + .rollback = output_rollback, .set_cursor = output_set_cursor, .move_cursor = output_move_cursor, }; diff --git a/backend/x11/output.c b/backend/x11/output.c index 4e016afe..f2b90cd3 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -162,11 +162,17 @@ static bool output_commit(struct wlr_output *wlr_output) { return true; } +static void output_rollback(struct wlr_output *wlr_output) { + struct wlr_x11_output *output = get_x11_output_from_output(wlr_output); + wlr_egl_make_current(&output->x11->egl, EGL_NO_SURFACE, NULL); +} + static const struct wlr_output_impl output_impl = { .destroy = output_destroy, .attach_render = output_attach_render, .test = output_test, .commit = output_commit, + .rollback = output_rollback, }; struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) { -- cgit v1.2.3