aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_output.h13
-rw-r--r--include/wlr/types/wlr_output_damage.h1
-rw-r--r--types/wlr_output.c31
-rw-r--r--types/wlr_output_damage.c12
4 files changed, 43 insertions, 14 deletions
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 436bcac3..9d6e85b3 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -138,7 +138,6 @@ struct wlr_output {
bool needs_frame;
// damage for cursors and fullscreen surface, in output-local coordinates
- pixman_region32_t damage;
bool frame_pending;
float transform_matrix[9];
@@ -150,8 +149,11 @@ struct wlr_output {
struct {
// Request to render a frame
struct wl_signal frame;
- // Emitted when buffers need to be swapped (because software cursors or
- // fullscreen damage or because of backend-specific logic)
+ // Emitted when software cursors or backend-specific logic damage the
+ // output
+ struct wl_signal damage; // wlr_output_event_damage
+ // Emitted when a new frame needs to be committed (because of
+ // backend-specific logic)
struct wl_signal needs_frame;
// Emitted right before commit
struct wl_signal precommit; // wlr_output_event_precommit
@@ -181,6 +183,11 @@ struct wlr_output {
void *data;
};
+struct wlr_output_event_damage {
+ struct wlr_output *output;
+ pixman_region32_t *damage; // output-buffer-local coordinates
+};
+
struct wlr_output_event_precommit {
struct wlr_output *output;
struct timespec *when;
diff --git a/include/wlr/types/wlr_output_damage.h b/include/wlr/types/wlr_output_damage.h
index 708ee9b6..4cdb0a54 100644
--- a/include/wlr/types/wlr_output_damage.h
+++ b/include/wlr/types/wlr_output_damage.h
@@ -52,6 +52,7 @@ struct wlr_output_damage {
struct wl_listener output_transform;
struct wl_listener output_scale;
struct wl_listener output_needs_frame;
+ struct wl_listener output_damage;
struct wl_listener output_frame;
struct wl_listener output_commit;
};
diff --git a/types/wlr_output.c b/types/wlr_output.c
index f9edd29a..4855fa4b 100644
--- a/types/wlr_output.c
+++ b/types/wlr_output.c
@@ -328,6 +328,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
wl_list_init(&output->cursors);
wl_list_init(&output->resources);
wl_signal_init(&output->events.frame);
+ wl_signal_init(&output->events.damage);
wl_signal_init(&output->events.needs_frame);
wl_signal_init(&output->events.precommit);
wl_signal_init(&output->events.commit);
@@ -338,7 +339,6 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
wl_signal_init(&output->events.transform);
wl_signal_init(&output->events.description);
wl_signal_init(&output->events.destroy);
- pixman_region32_init(&output->damage);
pixman_region32_init(&output->pending.damage);
const char *no_hardware_cursors = getenv("WLR_NO_HARDWARE_CURSORS");
@@ -382,7 +382,6 @@ void wlr_output_destroy(struct wlr_output *output) {
free(output->description);
pixman_region32_fini(&output->pending.damage);
- pixman_region32_fini(&output->damage);
if (output->impl && output->impl->destroy) {
output->impl->destroy(output);
@@ -562,7 +561,6 @@ bool wlr_output_commit(struct wlr_output *output) {
if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
output->frame_pending = true;
output->needs_frame = false;
- pixman_region32_clear(&output->damage);
}
output_state_clear(&output->pending);
@@ -697,9 +695,16 @@ void wlr_output_damage_whole(struct wlr_output *output) {
int width, height;
wlr_output_transformed_resolution(output, &width, &height);
- pixman_region32_union_rect(&output->damage, &output->damage, 0, 0,
- width, height);
- wlr_output_update_needs_frame(output);
+ pixman_region32_t damage;
+ pixman_region32_init_rect(&damage, 0, 0, width, height);
+
+ struct wlr_output_event_damage event = {
+ .output = output,
+ .damage = &damage,
+ };
+ wlr_signal_emit_safe(&output->events.damage, &event);
+
+ pixman_region32_fini(&damage);
}
struct wlr_output *wlr_output_from_resource(struct wl_resource *resource) {
@@ -855,9 +860,17 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor,
static void output_cursor_damage_whole(struct wlr_output_cursor *cursor) {
struct wlr_box box;
output_cursor_get_box(cursor, &box);
- pixman_region32_union_rect(&cursor->output->damage, &cursor->output->damage,
- box.x, box.y, box.width, box.height);
- wlr_output_update_needs_frame(cursor->output);
+
+ pixman_region32_t damage;
+ pixman_region32_init_rect(&damage, box.x, box.y, box.width, box.height);
+
+ struct wlr_output_event_damage event = {
+ .output = cursor->output,
+ .damage = &damage,
+ };
+ wlr_signal_emit_safe(&cursor->output->events.damage, &event);
+
+ pixman_region32_fini(&damage);
}
static void output_cursor_reset(struct wlr_output_cursor *cursor) {
diff --git a/types/wlr_output_damage.c b/types/wlr_output_damage.c
index 8c288e44..ade0375e 100644
--- a/types/wlr_output_damage.c
+++ b/types/wlr_output_damage.c
@@ -35,11 +35,16 @@ static void output_handle_needs_frame(struct wl_listener *listener,
void *data) {
struct wlr_output_damage *output_damage =
wl_container_of(listener, output_damage, output_needs_frame);
- pixman_region32_union(&output_damage->current, &output_damage->current,
- &output_damage->output->damage);
wlr_output_schedule_frame(output_damage->output);
}
+static void output_handle_damage(struct wl_listener *listener, void *data) {
+ struct wlr_output_damage *output_damage =
+ wl_container_of(listener, output_damage, output_damage);
+ struct wlr_output_event_damage *event = data;
+ wlr_output_damage_add(output_damage, event->damage);
+}
+
static void output_handle_frame(struct wl_listener *listener, void *data) {
struct wlr_output_damage *output_damage =
wl_container_of(listener, output_damage, output_frame);
@@ -108,6 +113,8 @@ struct wlr_output_damage *wlr_output_damage_create(struct wlr_output *output) {
output_damage->output_scale.notify = output_handle_scale;
wl_signal_add(&output->events.needs_frame, &output_damage->output_needs_frame);
output_damage->output_needs_frame.notify = output_handle_needs_frame;
+ wl_signal_add(&output->events.damage, &output_damage->output_damage);
+ output_damage->output_damage.notify = output_handle_damage;
wl_signal_add(&output->events.frame, &output_damage->output_frame);
output_damage->output_frame.notify = output_handle_frame;
wl_signal_add(&output->events.commit, &output_damage->output_commit);
@@ -126,6 +133,7 @@ void wlr_output_damage_destroy(struct wlr_output_damage *output_damage) {
wl_list_remove(&output_damage->output_transform.link);
wl_list_remove(&output_damage->output_scale.link);
wl_list_remove(&output_damage->output_needs_frame.link);
+ wl_list_remove(&output_damage->output_damage.link);
wl_list_remove(&output_damage->output_frame.link);
wl_list_remove(&output_damage->output_commit.link);
pixman_region32_fini(&output_damage->current);