wlr_scene: Send intersecting list of scene outputs for outputs_update signal

This commit is contained in:
Alexander Orzechowski 2023-01-21 16:23:30 -05:00
parent 843b874f22
commit 5007e713b4
2 changed files with 30 additions and 2 deletions

View file

@ -123,6 +123,11 @@ struct wlr_scene_rect {
float color[4]; float color[4];
}; };
struct wlr_scene_outputs_update_event {
struct wlr_scene_output **active;
size_t size;
};
/** A scene-graph node displaying a buffer */ /** A scene-graph node displaying a buffer */
struct wlr_scene_buffer { struct wlr_scene_buffer {
struct wlr_scene_node node; struct wlr_scene_node node;
@ -131,7 +136,7 @@ struct wlr_scene_buffer {
struct wlr_buffer *buffer; struct wlr_buffer *buffer;
struct { 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_enter; // struct wlr_scene_output
struct wl_signal output_leave; // struct wlr_scene_output struct wl_signal output_leave; // struct wlr_scene_output
struct wl_signal output_present; // struct wlr_scene_output struct wl_signal output_present; // struct wlr_scene_output

View file

@ -309,6 +309,7 @@ static void update_node_update_outputs(struct wlr_scene_node *node,
uint32_t largest_overlap = 0; uint32_t largest_overlap = 0;
scene_buffer->primary_output = NULL; scene_buffer->primary_output = NULL;
size_t count = 0;
uint64_t active_outputs = 0; uint64_t active_outputs = 0;
// let's update the outputs in two steps: // 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; active_outputs |= 1ull << scene_output->index;
count++;
} }
pixman_region32_fini(&intersection); pixman_region32_fini(&intersection);
@ -371,7 +373,28 @@ static void update_node_update_outputs(struct wlr_scene_node *node,
// output // output
assert(!scene_buffer->active_outputs || scene_buffer->primary_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, static bool scene_node_update_iterator(struct wlr_scene_node *node,