From ec837e3c9e08a8334fa7093d7f39af2a2f11e122 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 11 Feb 2018 12:49:30 +0100 Subject: Introduce wlr_output_damage --- include/rootston/output.h | 16 ++----------- include/wlr/types/wlr_output_damage.h | 45 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 include/wlr/types/wlr_output_damage.h (limited to 'include') diff --git a/include/rootston/output.h b/include/rootston/output.h index 3a6d3cc7..7f42904f 100644 --- a/include/rootston/output.h +++ b/include/rootston/output.h @@ -4,13 +4,7 @@ #include #include #include - -/** - * Damage tracking requires to keep track of previous frames' damage. To allow - * damage tracking to work with triple buffering, a history of two frames is - * required. - */ -#define ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN 2 +#include struct roots_desktop; @@ -22,15 +16,9 @@ struct roots_output { struct roots_view *fullscreen_view; struct timespec last_frame; - pixman_region32_t damage; // in ouput-local coordinates - - // circular queue for previous damage - pixman_region32_t previous_damage[ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN]; - size_t previous_damage_idx; + struct wlr_output_damage *damage; struct wl_listener frame; - struct wl_listener mode; - struct wl_listener needs_swap; }; void output_add_notify(struct wl_listener *listener, void *data); diff --git a/include/wlr/types/wlr_output_damage.h b/include/wlr/types/wlr_output_damage.h new file mode 100644 index 00000000..eadbff29 --- /dev/null +++ b/include/wlr/types/wlr_output_damage.h @@ -0,0 +1,45 @@ +#ifndef WLR_TYPES_WLR_OUTPUT_DAMAGE_H +#define WLR_TYPES_WLR_OUTPUT_DAMAGE_H + +#include + +/** + * Damage tracking requires to keep track of previous frames' damage. To allow + * damage tracking to work with triple buffering, a history of two frames is + * required. + */ +#define WLR_OUTPUT_DAMAGE_PREVIOUS_LEN 2 + +struct wlr_output_damage { + struct wlr_output *output; + + pixman_region32_t current; // in output-local coordinates + + // circular queue for previous damage + pixman_region32_t previous[WLR_OUTPUT_DAMAGE_PREVIOUS_LEN]; + size_t previous_idx; + + struct { + struct wl_signal frame; + struct wl_signal destroy; + } events; + + struct wl_listener output_destroy; + struct wl_listener output_mode; + struct wl_listener output_needs_swap; + struct wl_listener output_frame; +}; + +struct wlr_output_damage *wlr_output_damage_create(struct wlr_output *output); +void wlr_output_damage_destroy(struct wlr_output_damage *output_damage); +bool wlr_output_damage_make_current(struct wlr_output_damage *output_damage, + bool *needs_swap, pixman_region32_t *damage); +bool wlr_output_damage_swap_buffers(struct wlr_output_damage *output_damage, + struct timespec *when, pixman_region32_t *damage); +void wlr_output_damage_add(struct wlr_output_damage *output_damage, + pixman_region32_t *damage); +void wlr_output_damage_add_whole(struct wlr_output_damage *output_damage); +void wlr_output_damage_add_box(struct wlr_output_damage *output_damage, + struct wlr_box *box); + +#endif -- cgit v1.2.3 From 5a8f098eea1637213d29a6ec831bcebc11c92aaa Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 11 Feb 2018 13:04:00 +0100 Subject: output, output_damage: add docs --- include/wlr/types/wlr_output.h | 9 +++++++++ include/wlr/types/wlr_output_damage.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'include') diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index a653d527..8eed06fe 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -38,6 +38,15 @@ struct wlr_output_cursor { struct wlr_output_impl; +/** + * A compositor output region. This typically corresponds to a monitor that + * displays part of the compositor space. + * + * Compositors should listen to the `frame` event to render an output. They + * should call `wlr_output_make_current`, render and then call + * `wlr_output_swap_buffers`. No rendering should happen outside a `frame` event + * handler. + */ struct wlr_output { const struct wlr_output_impl *impl; struct wlr_backend *backend; diff --git a/include/wlr/types/wlr_output_damage.h b/include/wlr/types/wlr_output_damage.h index eadbff29..ec5fcd0d 100644 --- a/include/wlr/types/wlr_output_damage.h +++ b/include/wlr/types/wlr_output_damage.h @@ -10,6 +10,14 @@ */ #define WLR_OUTPUT_DAMAGE_PREVIOUS_LEN 2 +/** + * Tracks damage for an output. + * + * When a `frame` event is emitted, `wlr_output_damage_make_current` should be + * called. If necessary, the output should be repainted and + * `wlr_output_damage_swap_buffers` should be called. No rendering should happen + * outside a `frame` event handler. + */ struct wlr_output_damage { struct wlr_output *output; @@ -32,13 +40,33 @@ struct wlr_output_damage { struct wlr_output_damage *wlr_output_damage_create(struct wlr_output *output); void wlr_output_damage_destroy(struct wlr_output_damage *output_damage); +/** + * Makes the output rendering context current. `needs_swap` is set to true if + * `wlr_output_damage_swap_buffers` needs to be called. The region of the output + * that needs to be repainted is added to `damage`. + */ bool wlr_output_damage_make_current(struct wlr_output_damage *output_damage, bool *needs_swap, pixman_region32_t *damage); +/** + * Swaps the output buffers. If the time of the frame isn't known, set `when` to + * NULL. + * + * Swapping buffers schedules a `frame` event. + */ bool wlr_output_damage_swap_buffers(struct wlr_output_damage *output_damage, struct timespec *when, pixman_region32_t *damage); +/** + * Accumulates damage and schedules a `frame` event. + */ void wlr_output_damage_add(struct wlr_output_damage *output_damage, pixman_region32_t *damage); +/** + * Damages the whole output and schedules a `frame` event. + */ void wlr_output_damage_add_whole(struct wlr_output_damage *output_damage); +/** + * Accumulates damage from a box and schedules a `frame` event. + */ void wlr_output_damage_add_box(struct wlr_output_damage *output_damage, struct wlr_box *box); -- cgit v1.2.3 From a9632341bfcb1e0a172d93c4fd331291a842332c Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 11 Feb 2018 13:07:00 +0100 Subject: output_damage: listen to transform and scale output events --- include/wlr/types/wlr_output_damage.h | 4 ++++ types/wlr_output_damage.c | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'include') diff --git a/include/wlr/types/wlr_output_damage.h b/include/wlr/types/wlr_output_damage.h index ec5fcd0d..52cbce78 100644 --- a/include/wlr/types/wlr_output_damage.h +++ b/include/wlr/types/wlr_output_damage.h @@ -1,7 +1,9 @@ #ifndef WLR_TYPES_WLR_OUTPUT_DAMAGE_H #define WLR_TYPES_WLR_OUTPUT_DAMAGE_H +#include #include +#include /** * Damage tracking requires to keep track of previous frames' damage. To allow @@ -34,6 +36,8 @@ struct wlr_output_damage { struct wl_listener output_destroy; struct wl_listener output_mode; + struct wl_listener output_transform; + struct wl_listener output_scale; struct wl_listener output_needs_swap; struct wl_listener output_frame; }; diff --git a/types/wlr_output_damage.c b/types/wlr_output_damage.c index 741360ac..354314b6 100644 --- a/types/wlr_output_damage.c +++ b/types/wlr_output_damage.c @@ -18,6 +18,18 @@ static void output_handle_mode(struct wl_listener *listener, void *data) { wlr_output_damage_add_whole(output_damage); } +static void output_handle_transform(struct wl_listener *listener, void *data) { + struct wlr_output_damage *output_damage = + wl_container_of(listener, output_damage, output_transform); + wlr_output_damage_add_whole(output_damage); +} + +static void output_handle_scale(struct wl_listener *listener, void *data) { + struct wlr_output_damage *output_damage = + wl_container_of(listener, output_damage, output_scale); + wlr_output_damage_add_whole(output_damage); +} + static void output_handle_needs_swap(struct wl_listener *listener, void *data) { struct wlr_output_damage *output_damage = wl_container_of(listener, output_damage, output_needs_swap); @@ -57,6 +69,10 @@ struct wlr_output_damage *wlr_output_damage_create(struct wlr_output *output) { output_damage->output_destroy.notify = output_handle_destroy; wl_signal_add(&output->events.mode, &output_damage->output_mode); output_damage->output_mode.notify = output_handle_mode; + wl_signal_add(&output->events.transform, &output_damage->output_transform); + output_damage->output_transform.notify = output_handle_transform; + wl_signal_add(&output->events.scale, &output_damage->output_scale); + output_damage->output_scale.notify = output_handle_scale; wl_signal_add(&output->events.needs_swap, &output_damage->output_needs_swap); output_damage->output_needs_swap.notify = output_handle_needs_swap; wl_signal_add(&output->events.frame, &output_damage->output_frame); @@ -72,6 +88,8 @@ void wlr_output_damage_destroy(struct wlr_output_damage *output_damage) { wl_signal_emit(&output_damage->events.destroy, output_damage); wl_list_remove(&output_damage->output_destroy.link); wl_list_remove(&output_damage->output_mode.link); + wl_list_remove(&output_damage->output_transform.link); + wl_list_remove(&output_damage->output_scale.link); wl_list_remove(&output_damage->output_needs_swap.link); wl_list_remove(&output_damage->output_frame.link); pixman_region32_fini(&output_damage->current); -- cgit v1.2.3