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
This commit is contained in:
parent
d3bd5f2a7b
commit
507d9bc19e
|
@ -574,6 +574,11 @@ static bool drm_connector_commit(struct wlr_output *output) {
|
||||||
return true;
|
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,
|
static void fill_empty_gamma_table(size_t size,
|
||||||
uint16_t *r, uint16_t *g, uint16_t *b) {
|
uint16_t *r, uint16_t *g, uint16_t *b) {
|
||||||
assert(0xFFFF < UINT64_MAX / (size - 1));
|
assert(0xFFFF < UINT64_MAX / (size - 1));
|
||||||
|
@ -1094,6 +1099,7 @@ static const struct wlr_output_impl output_impl = {
|
||||||
.attach_render = drm_connector_attach_render,
|
.attach_render = drm_connector_attach_render,
|
||||||
.test = drm_connector_test,
|
.test = drm_connector_test,
|
||||||
.commit = drm_connector_commit,
|
.commit = drm_connector_commit,
|
||||||
|
.rollback = drm_connector_rollback,
|
||||||
.set_gamma = set_drm_connector_gamma,
|
.set_gamma = set_drm_connector_gamma,
|
||||||
.get_gamma_size = drm_connector_get_gamma_size,
|
.get_gamma_size = drm_connector_get_gamma_size,
|
||||||
.export_dmabuf = drm_connector_export_dmabuf,
|
.export_dmabuf = drm_connector_export_dmabuf,
|
||||||
|
|
|
@ -97,6 +97,12 @@ static bool output_commit(struct wlr_output *wlr_output) {
|
||||||
return true;
|
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) {
|
static void output_destroy(struct wlr_output *wlr_output) {
|
||||||
struct wlr_headless_output *output =
|
struct wlr_headless_output *output =
|
||||||
headless_output_from_output(wlr_output);
|
headless_output_from_output(wlr_output);
|
||||||
|
@ -113,6 +119,7 @@ static const struct wlr_output_impl output_impl = {
|
||||||
.destroy = output_destroy,
|
.destroy = output_destroy,
|
||||||
.attach_render = output_attach_render,
|
.attach_render = output_attach_render,
|
||||||
.commit = output_commit,
|
.commit = output_commit,
|
||||||
|
.rollback = output_rollback,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool wlr_output_is_headless(struct wlr_output *wlr_output) {
|
bool wlr_output_is_headless(struct wlr_output *wlr_output) {
|
||||||
|
|
|
@ -302,6 +302,12 @@ static bool output_commit(struct wlr_output *wlr_output) {
|
||||||
return true;
|
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,
|
static bool output_set_cursor(struct wlr_output *wlr_output,
|
||||||
struct wlr_texture *texture, int32_t scale,
|
struct wlr_texture *texture, int32_t scale,
|
||||||
enum wl_output_transform transform,
|
enum wl_output_transform transform,
|
||||||
|
@ -431,6 +437,7 @@ static const struct wlr_output_impl output_impl = {
|
||||||
.attach_render = output_attach_render,
|
.attach_render = output_attach_render,
|
||||||
.test = output_test,
|
.test = output_test,
|
||||||
.commit = output_commit,
|
.commit = output_commit,
|
||||||
|
.rollback = output_rollback,
|
||||||
.set_cursor = output_set_cursor,
|
.set_cursor = output_set_cursor,
|
||||||
.move_cursor = output_move_cursor,
|
.move_cursor = output_move_cursor,
|
||||||
};
|
};
|
||||||
|
|
|
@ -162,11 +162,17 @@ static bool output_commit(struct wlr_output *wlr_output) {
|
||||||
return true;
|
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 = {
|
static const struct wlr_output_impl output_impl = {
|
||||||
.destroy = output_destroy,
|
.destroy = output_destroy,
|
||||||
.attach_render = output_attach_render,
|
.attach_render = output_attach_render,
|
||||||
.test = output_test,
|
.test = output_test,
|
||||||
.commit = output_commit,
|
.commit = output_commit,
|
||||||
|
.rollback = output_rollback,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
|
struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct wlr_output_impl {
|
||||||
bool (*attach_render)(struct wlr_output *output, int *buffer_age);
|
bool (*attach_render)(struct wlr_output *output, int *buffer_age);
|
||||||
bool (*test)(struct wlr_output *output);
|
bool (*test)(struct wlr_output *output);
|
||||||
bool (*commit)(struct wlr_output *output);
|
bool (*commit)(struct wlr_output *output);
|
||||||
|
void (*rollback)(struct wlr_output *output);
|
||||||
bool (*set_gamma)(struct wlr_output *output, size_t size,
|
bool (*set_gamma)(struct wlr_output *output, size_t size,
|
||||||
const uint16_t *r, const uint16_t *g, const uint16_t *b);
|
const uint16_t *r, const uint16_t *g, const uint16_t *b);
|
||||||
size_t (*get_gamma_size)(struct wlr_output *output);
|
size_t (*get_gamma_size)(struct wlr_output *output);
|
||||||
|
|
|
@ -606,6 +606,10 @@ bool wlr_output_commit(struct wlr_output *output) {
|
||||||
|
|
||||||
void wlr_output_rollback(struct wlr_output *output) {
|
void wlr_output_rollback(struct wlr_output *output) {
|
||||||
output_state_clear(&output->pending);
|
output_state_clear(&output->pending);
|
||||||
|
|
||||||
|
if (output->impl->rollback) {
|
||||||
|
output->impl->rollback(output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_output_attach_buffer(struct wlr_output *output,
|
void wlr_output_attach_buffer(struct wlr_output *output,
|
||||||
|
|
Loading…
Reference in New Issue