aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orzechowski <alex@ozal.ski>2023-01-21 16:23:30 -0500
committerAlexander Orzechowski <alex@ozal.ski>2023-01-21 16:23:30 -0500
commit5007e713b4c0d0f0cd8e97503294b81a250d3459 (patch)
treef7b57bb00bc97582f553a3c0ea2acfacfdb51101
parent843b874f22b87140a04bfc279852e025967c055e (diff)
wlr_scene: Send intersecting list of scene outputs for outputs_update signal
-rw-r--r--include/wlr/types/wlr_scene.h7
-rw-r--r--types/scene/wlr_scene.c25
2 files changed, 30 insertions, 2 deletions
diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h
index 6d1e75b7..659a8b33 100644
--- a/include/wlr/types/wlr_scene.h
+++ b/include/wlr/types/wlr_scene.h
@@ -123,6 +123,11 @@ struct wlr_scene_rect {
float color[4];
};
+struct wlr_scene_outputs_update_event {
+ struct wlr_scene_output **active;
+ size_t size;
+};
+
/** A scene-graph node displaying a buffer */
struct wlr_scene_buffer {
struct wlr_scene_node node;
@@ -131,7 +136,7 @@ struct wlr_scene_buffer {
struct wlr_buffer *buffer;
struct {
- struct wl_signal outputs_update;
+ struct wl_signal outputs_update; // struct wlr_scene_outputs_update_event
struct wl_signal output_enter; // struct wlr_scene_output
struct wl_signal output_leave; // struct wlr_scene_output
struct wl_signal output_present; // struct wlr_scene_output
diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c
index 3ede2f2f..293d44bd 100644
--- a/types/scene/wlr_scene.c
+++ b/types/scene/wlr_scene.c
@@ -309,6 +309,7 @@ static void update_node_update_outputs(struct wlr_scene_node *node,
uint32_t largest_overlap = 0;
scene_buffer->primary_output = NULL;
+ size_t count = 0;
uint64_t active_outputs = 0;
// let's update the outputs in two steps:
@@ -347,6 +348,7 @@ static void update_node_update_outputs(struct wlr_scene_node *node,
}
active_outputs |= 1ull << scene_output->index;
+ count++;
}
pixman_region32_fini(&intersection);
@@ -371,7 +373,28 @@ static void update_node_update_outputs(struct wlr_scene_node *node,
// output
assert(!scene_buffer->active_outputs || scene_buffer->primary_output);
- wl_signal_emit_mutable(&scene_buffer->events.outputs_update, NULL);
+ // if no outputs changes intersection status, skip calling outputs_update
+ if (old_active == active_outputs) {
+ return;
+ }
+
+ struct wlr_scene_output *outputs_array[64];
+ struct wlr_scene_outputs_update_event event = {
+ .active = outputs_array,
+ .size = count,
+ };
+
+ size_t i = 0;
+ wl_list_for_each(scene_output, outputs, link) {
+ if (~active_outputs & (1ull << scene_output->index)) {
+ continue;
+ }
+
+ assert(i < count);
+ outputs_array[i++] = scene_output;
+ }
+
+ wl_signal_emit_mutable(&scene_buffer->events.outputs_update, &event);
}
static bool scene_node_update_iterator(struct wlr_scene_node *node,