scene: add primary output to wlr_scene_surface
This allows compositors to avoid sending multiple frame done events to a surface that is rendered on multiple outputs at once. This may also be used in the same way for presentation feedback.
This commit is contained in:
parent
0215dffba5
commit
fb1f613510
|
@ -74,6 +74,14 @@ struct wlr_scene_surface {
|
||||||
struct wlr_scene_node node;
|
struct wlr_scene_node node;
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The output that the largest area of this surface is displayed on.
|
||||||
|
* This may be NULL if the surface is not currently displayed on any
|
||||||
|
* outputs. This is the output that should be used for frame callbacks,
|
||||||
|
* presentation feedback, etc.
|
||||||
|
*/
|
||||||
|
struct wlr_output *primary_output;
|
||||||
|
|
||||||
// private state
|
// private state
|
||||||
|
|
||||||
int prev_width, prev_height;
|
int prev_width, prev_height;
|
||||||
|
|
|
@ -175,6 +175,9 @@ static void scene_surface_update_outputs(
|
||||||
.height = scene_surface->surface->current.height,
|
.height = scene_surface->surface->current.height,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int largest_overlap = 0;
|
||||||
|
scene_surface->primary_output = NULL;
|
||||||
|
|
||||||
struct wlr_scene_output *scene_output;
|
struct wlr_scene_output *scene_output;
|
||||||
wl_list_for_each(scene_output, &scene->outputs, link) {
|
wl_list_for_each(scene_output, &scene->outputs, link) {
|
||||||
struct wlr_box output_box = {
|
struct wlr_box output_box = {
|
||||||
|
@ -184,10 +187,16 @@ static void scene_surface_update_outputs(
|
||||||
wlr_output_effective_resolution(scene_output->output,
|
wlr_output_effective_resolution(scene_output->output,
|
||||||
&output_box.width, &output_box.height);
|
&output_box.width, &output_box.height);
|
||||||
|
|
||||||
// These enter/leave functions are a noop if the event has already been
|
|
||||||
// sent for the given output.
|
|
||||||
struct wlr_box intersection;
|
struct wlr_box intersection;
|
||||||
if (wlr_box_intersection(&intersection, &surface_box, &output_box)) {
|
if (wlr_box_intersection(&intersection, &surface_box, &output_box)) {
|
||||||
|
int overlap = intersection.width * intersection.height;
|
||||||
|
if (overlap > largest_overlap) {
|
||||||
|
largest_overlap = overlap;
|
||||||
|
scene_surface->primary_output = scene_output->output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These enter/leave functions are a noop if the event has already been
|
||||||
|
// sent for the given output.
|
||||||
wlr_surface_send_enter(scene_surface->surface, scene_output->output);
|
wlr_surface_send_enter(scene_surface->surface, scene_output->output);
|
||||||
} else {
|
} else {
|
||||||
wlr_surface_send_leave(scene_surface->surface, scene_output->output);
|
wlr_surface_send_leave(scene_surface->surface, scene_output->output);
|
||||||
|
|
Loading…
Reference in New Issue