mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-23 18:39:48 +01:00
Merge pull request #654 from emersion/send-frame-done
rootston: send frame done events unconditionally
This commit is contained in:
commit
69409ea3cb
1 changed files with 71 additions and 25 deletions
|
@ -182,6 +182,21 @@ static void xwayland_children_for_each_surface(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void drag_icons_for_each_surface(struct roots_input *input,
|
||||||
|
surface_iterator_func_t iterator, void *user_data) {
|
||||||
|
struct roots_seat *seat;
|
||||||
|
wl_list_for_each(seat, &input->seats, link) {
|
||||||
|
struct roots_drag_icon *drag_icon;
|
||||||
|
wl_list_for_each(drag_icon, &seat->drag_icons, link) {
|
||||||
|
if (!drag_icon->wlr_drag_icon->mapped) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
surface_for_each_surface(drag_icon->wlr_drag_icon->surface,
|
||||||
|
drag_icon->x, drag_icon->y, 0, iterator, user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct render_data {
|
struct render_data {
|
||||||
struct roots_output *output;
|
struct roots_output *output;
|
||||||
|
@ -190,18 +205,22 @@ struct render_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether a surface at (lx, ly) intersects an output. Sets `box` to the
|
* Checks whether a surface at (lx, ly) intersects an output. If `box` is not
|
||||||
* surface box in the output, in output-local coordinates.
|
* NULL, it populates it with the surface box in the output, in output-local
|
||||||
|
* coordinates.
|
||||||
*/
|
*/
|
||||||
static bool surface_intersect_output(struct wlr_surface *surface,
|
static bool surface_intersect_output(struct wlr_surface *surface,
|
||||||
struct wlr_output_layout *output_layout, struct wlr_output *wlr_output,
|
struct wlr_output_layout *output_layout, struct wlr_output *wlr_output,
|
||||||
double lx, double ly, float rotation, struct wlr_box *box) {
|
double lx, double ly, float rotation, struct wlr_box *box) {
|
||||||
double ox = lx, oy = ly;
|
double ox = lx, oy = ly;
|
||||||
wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy);
|
wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy);
|
||||||
|
|
||||||
|
if (box != NULL) {
|
||||||
box->x = ox * wlr_output->scale;
|
box->x = ox * wlr_output->scale;
|
||||||
box->y = oy * wlr_output->scale;
|
box->y = oy * wlr_output->scale;
|
||||||
box->width = surface->current->width * wlr_output->scale;
|
box->width = surface->current->width * wlr_output->scale;
|
||||||
box->height = surface->current->height * wlr_output->scale;
|
box->height = surface->current->height * wlr_output->scale;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_box layout_box = {
|
struct wlr_box layout_box = {
|
||||||
.x = lx, .y = ly,
|
.x = lx, .y = ly,
|
||||||
|
@ -239,7 +258,6 @@ static void render_surface(struct wlr_surface *surface, double lx, double ly,
|
||||||
float rotation, void *_data) {
|
float rotation, void *_data) {
|
||||||
struct render_data *data = _data;
|
struct render_data *data = _data;
|
||||||
struct roots_output *output = data->output;
|
struct roots_output *output = data->output;
|
||||||
struct timespec *when = data->when;
|
|
||||||
struct wlr_renderer *renderer =
|
struct wlr_renderer *renderer =
|
||||||
wlr_backend_get_renderer(output->wlr_output->backend);
|
wlr_backend_get_renderer(output->wlr_output->backend);
|
||||||
assert(renderer);
|
assert(renderer);
|
||||||
|
@ -281,8 +299,6 @@ static void render_surface(struct wlr_surface *surface, double lx, double ly,
|
||||||
wlr_render_with_matrix(renderer, surface->texture, &matrix);
|
wlr_render_with_matrix(renderer, surface->texture, &matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_surface_send_frame_done(surface, when);
|
|
||||||
|
|
||||||
damage_finish:
|
damage_finish:
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
}
|
}
|
||||||
|
@ -384,6 +400,20 @@ static bool has_standalone_surface(struct roots_view *view) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void surface_send_frame_done(struct wlr_surface *surface, double lx,
|
||||||
|
double ly, float rotation, void *_data) {
|
||||||
|
struct render_data *data = _data;
|
||||||
|
struct roots_output *output = data->output;
|
||||||
|
struct timespec *when = data->when;
|
||||||
|
|
||||||
|
if (!surface_intersect_output(surface, output->desktop->layout,
|
||||||
|
output->wlr_output, lx, ly, rotation, NULL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_surface_send_frame_done(surface, when);
|
||||||
|
}
|
||||||
|
|
||||||
static void render_output(struct roots_output *output) {
|
static void render_output(struct roots_output *output) {
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
struct wlr_output *wlr_output = output->wlr_output;
|
||||||
struct roots_desktop *desktop = output->desktop;
|
struct roots_desktop *desktop = output->desktop;
|
||||||
|
@ -434,17 +464,17 @@ static void render_output(struct roots_output *output) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needs_swap) {
|
|
||||||
// Output doesn't need swap and isn't damaged, skip rendering completely
|
|
||||||
goto damage_finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct render_data data = {
|
struct render_data data = {
|
||||||
.output = output,
|
.output = output,
|
||||||
.when = &now,
|
.when = &now,
|
||||||
.damage = &damage,
|
.damage = &damage,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!needs_swap) {
|
||||||
|
// Output doesn't need swap and isn't damaged, skip rendering completely
|
||||||
|
goto damage_finish;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_renderer_begin(renderer, wlr_output);
|
wlr_renderer_begin(renderer, wlr_output);
|
||||||
|
|
||||||
if (!pixman_region32_not_empty(&damage)) {
|
if (!pixman_region32_not_empty(&damage)) {
|
||||||
|
@ -490,17 +520,7 @@ static void render_output(struct roots_output *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render drag icons
|
// Render drag icons
|
||||||
struct roots_drag_icon *drag_icon = NULL;
|
drag_icons_for_each_surface(server->input, render_surface, &data);
|
||||||
struct roots_seat *seat = NULL;
|
|
||||||
wl_list_for_each(seat, &server->input->seats, link) {
|
|
||||||
wl_list_for_each(drag_icon, &seat->drag_icons, link) {
|
|
||||||
if (!drag_icon->wlr_drag_icon->mapped) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
render_surface(drag_icon->wlr_drag_icon->surface,
|
|
||||||
drag_icon->x, drag_icon->y, 0, &data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer_end:
|
renderer_end:
|
||||||
wlr_renderer_scissor(renderer, NULL);
|
wlr_renderer_scissor(renderer, NULL);
|
||||||
|
@ -512,6 +532,32 @@ renderer_end:
|
||||||
|
|
||||||
damage_finish:
|
damage_finish:
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
|
// Send frame done events to all surfaces
|
||||||
|
if (output->fullscreen_view != NULL) {
|
||||||
|
struct roots_view *view = output->fullscreen_view;
|
||||||
|
if (wlr_output->fullscreen_surface == view->wlr_surface) {
|
||||||
|
// The surface is managed by the wlr_output
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
view_for_each_surface(view, surface_send_frame_done, &data);
|
||||||
|
|
||||||
|
#ifdef WLR_HAS_XWAYLAND
|
||||||
|
if (view->type == ROOTS_XWAYLAND_VIEW) {
|
||||||
|
xwayland_children_for_each_surface(view->xwayland_surface,
|
||||||
|
surface_send_frame_done, &data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
struct roots_view *view;
|
||||||
|
wl_list_for_each_reverse(view, &desktop->views, link) {
|
||||||
|
view_for_each_surface(view, surface_send_frame_done, &data);
|
||||||
|
}
|
||||||
|
|
||||||
|
drag_icons_for_each_surface(server->input, surface_send_frame_done,
|
||||||
|
&data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_damage_whole(struct roots_output *output) {
|
void output_damage_whole(struct roots_output *output) {
|
||||||
|
|
Loading…
Reference in a new issue