From d2172bd331937ab406175a6b4c5a76db6f406fbe Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:17:47 +0100 Subject: [PATCH 1/8] wip: redesign output_unmanaged_for_each_surface iterator --- include/sway/output.h | 17 ++++++++-- sway/desktop/output.c | 73 +++++++++++++++++++++++++++++++++++++++---- sway/desktop/render.c | 31 ++++++++++++++++-- 3 files changed, 110 insertions(+), 11 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index c225e541f..99b0bcc6e 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -5,6 +5,7 @@ #include #include #include +#include "config.h" #include "sway/tree/view.h" struct sway_server; @@ -48,6 +49,10 @@ struct root_geometry { float rotation; }; +typedef void (*sway_surface_iterator_func_t)(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *user_data); + void output_damage_whole(struct sway_output *output); void output_damage_surface(struct sway_output *output, double ox, double oy, @@ -80,6 +85,10 @@ void output_surface_for_each_surface(struct wlr_surface *surface, double ox, double oy, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data); +void output_surface_for_each_surface2(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation, + sway_surface_iterator_func_t iterator, void *user_data); + void output_view_for_each_surface(struct sway_view *view, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data); @@ -88,9 +97,11 @@ void output_layer_for_each_surface(struct wl_list *layer_surfaces, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data); -void output_unmanaged_for_each_surface(struct wl_list *unmanaged, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data); +#ifdef HAVE_XWAYLAND +void output_unmanaged_for_each_surface(struct sway_output *output, + struct wl_list *unmanaged, sway_surface_iterator_func_t iterator, + void *user_data); +#endif void output_drag_icons_for_each_surface(struct wl_list *drag_icons, struct sway_output *output, struct root_geometry *geo, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index cecd300a7..9c2a1a077 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -105,6 +105,56 @@ void output_surface_for_each_surface(struct wlr_surface *surface, wlr_surface_for_each_surface(surface, iterator, user_data); } +struct surface_iterator_data { + sway_surface_iterator_func_t user_iterator; + void *user_data; + + struct sway_output *output; + double ox, oy; + int width, height; + float rotation; +}; + +void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, + int sx, int sy, void *_data) { + struct surface_iterator_data *data = _data; + + struct root_geometry geo = { + .x = data->ox, + .y = data->oy, + .width = data->width, + .height = data->height, + .rotation = data->rotation, + }; + struct wlr_box box; + bool intersects = output_get_surface_box(&geo, data->output, + surface, sx, sy, &box); + if (!intersects) { + return; + } + + data->user_iterator(data->output, surface, &box, data->rotation, + data->user_data); +} + +void output_surface_for_each_surface2(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation, + sway_surface_iterator_func_t iterator, void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = ox, + .oy = oy, + .width = surface->current.width, + .height = surface->current.height, + .rotation = rotation, + }; + + wlr_surface_for_each_surface(surface, + output_surface_for_each_surface2_iterator, &data); +} + void output_view_for_each_surface(struct sway_view *view, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { @@ -129,10 +179,11 @@ void output_layer_for_each_surface(struct wl_list *layer_surfaces, user_data); } } + #ifdef HAVE_XWAYLAND -void output_unmanaged_for_each_surface(struct wl_list *unmanaged, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { +void output_unmanaged_for_each_surface(struct sway_output *output, + struct wl_list *unmanaged, sway_surface_iterator_func_t iterator, + void *user_data) { struct sway_xwayland_unmanaged *unmanaged_surface; wl_list_for_each(unmanaged_surface, unmanaged, link) { struct wlr_xwayland_surface *xsurface = @@ -140,11 +191,12 @@ void output_unmanaged_for_each_surface(struct wl_list *unmanaged, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface(xsurface->surface, ox, oy, geo, + output_surface_for_each_surface2(output, xsurface->surface, ox, oy, 0, iterator, user_data); } } #endif + void output_drag_icons_for_each_surface(struct wl_list *drag_icons, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { @@ -228,18 +280,27 @@ static void send_frame_done_iterator(struct wlr_surface *surface, } } +static void send_frame_done_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *_data) { + struct send_frame_done_data *data = _data; + wlr_surface_send_frame_done(surface, data->when); +} + static void send_frame_done_layer(struct send_frame_done_data *data, struct wl_list *layer_surfaces) { output_layer_for_each_surface(layer_surfaces, &data->root_geo, send_frame_done_iterator, data); } + #ifdef HAVE_XWAYLAND static void send_frame_done_unmanaged(struct send_frame_done_data *data, struct wl_list *unmanaged) { - output_unmanaged_for_each_surface(unmanaged, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_unmanaged_for_each_surface(data->output, unmanaged, + send_frame_done_iterator2, data); } #endif + static void send_frame_done_drag_icons(struct send_frame_done_data *data, struct wl_list *drag_icons) { output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index c9fdfd95e..8eea19e00 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -123,6 +123,31 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); } +static void render_surface_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *_box, float rotation, + void *_data) { + struct render_data *data = _data; + struct wlr_output *wlr_output = output->wlr_output; + pixman_region32_t *output_damage = data->damage; + float alpha = data->alpha; + + struct wlr_texture *texture = wlr_surface_get_texture(surface); + if (!texture) { + return; + } + + struct wlr_box box = *_box; + scale_box(&box, wlr_output->scale); + + float matrix[9]; + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + wlr_matrix_project_box(matrix, &box, transform, rotation, + wlr_output->transform_matrix); + + render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); +} + static void render_layer(struct sway_output *output, pixman_region32_t *damage, struct wl_list *layer_surfaces) { struct render_data data = { @@ -133,6 +158,7 @@ static void render_layer(struct sway_output *output, output_layer_for_each_surface(layer_surfaces, &data.root_geo, render_surface_iterator, &data); } + #ifdef HAVE_XWAYLAND static void render_unmanaged(struct sway_output *output, pixman_region32_t *damage, struct wl_list *unmanaged) { @@ -141,10 +167,11 @@ static void render_unmanaged(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_unmanaged_for_each_surface(unmanaged, output, &data.root_geo, - render_surface_iterator, &data); + output_unmanaged_for_each_surface(output, unmanaged, + render_surface_iterator2, &data); } #endif + static void render_drag_icons(struct sway_output *output, pixman_region32_t *damage, struct wl_list *drag_icons) { struct render_data data = { From dbf6dd0daec9e712a002c3e01accbd0fee769fac Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:44:36 +0100 Subject: [PATCH 2/8] wip: redesign output_drag_icons_for_each_surface iterator --- include/sway/output.h | 6 +++--- sway/desktop/output.c | 15 ++++++++------- sway/desktop/render.c | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 99b0bcc6e..10a142077 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -103,8 +103,8 @@ void output_unmanaged_for_each_surface(struct sway_output *output, void *user_data); #endif -void output_drag_icons_for_each_surface(struct wl_list *drag_icons, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data); +void output_drag_icons_for_each_surface(struct sway_output *output, + struct wl_list *drag_icons, sway_surface_iterator_func_t iterator, + void *user_data); #endif diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 9c2a1a077..e83a9a3d3 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -197,17 +197,18 @@ void output_unmanaged_for_each_surface(struct sway_output *output, } #endif -void output_drag_icons_for_each_surface(struct wl_list *drag_icons, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { +void output_drag_icons_for_each_surface(struct sway_output *output, + struct wl_list *drag_icons, sway_surface_iterator_func_t iterator, + void *user_data) { struct sway_drag_icon *drag_icon; wl_list_for_each(drag_icon, drag_icons, link) { double ox = drag_icon->x - output->swayc->x; double oy = drag_icon->y - output->swayc->y; if (drag_icon->wlr_drag_icon->mapped) { - output_surface_for_each_surface(drag_icon->wlr_drag_icon->surface, - ox, oy, geo, iterator, user_data); + output_surface_for_each_surface2(output, + drag_icon->wlr_drag_icon->surface, ox, oy, 0, + iterator, user_data); } } } @@ -303,8 +304,8 @@ static void send_frame_done_unmanaged(struct send_frame_done_data *data, static void send_frame_done_drag_icons(struct send_frame_done_data *data, struct wl_list *drag_icons) { - output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_drag_icons_for_each_surface(data->output, drag_icons, + send_frame_done_iterator2, data); } static void send_frame_done_container_iterator(struct sway_container *con, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 8eea19e00..1270b7cfb 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -179,8 +179,8 @@ static void render_drag_icons(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_drag_icons_for_each_surface(drag_icons, output, &data.root_geo, - render_surface_iterator, &data); + output_drag_icons_for_each_surface(output, drag_icons, + render_surface_iterator2, &data); } static void render_rect(struct wlr_output *wlr_output, From a0dd9776172796f65b0fce0a8e5cfb66bdb2e2e5 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:53:15 +0100 Subject: [PATCH 3/8] wip: redesign output_layer_for_each_surface iterator --- include/sway/output.h | 4 ++-- sway/desktop/output.c | 32 ++++++++++++++++---------------- sway/desktop/render.c | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 10a142077..c1763b266 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -93,8 +93,8 @@ void output_view_for_each_surface(struct sway_view *view, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data); -void output_layer_for_each_surface(struct wl_list *layer_surfaces, - struct root_geometry *geo, wlr_surface_iterator_func_t iterator, +void output_layer_for_each_surface(struct sway_output *output, + struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data); #ifdef HAVE_XWAYLAND diff --git a/sway/desktop/output.c b/sway/desktop/output.c index e83a9a3d3..5e309250d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -167,15 +167,15 @@ void output_view_for_each_surface(struct sway_view *view, view_for_each_surface(view, iterator, user_data); } -void output_layer_for_each_surface(struct wl_list *layer_surfaces, - struct root_geometry *geo, wlr_surface_iterator_func_t iterator, +void output_layer_for_each_surface(struct sway_output *output, + struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { struct sway_layer_surface *layer_surface; wl_list_for_each(layer_surface, layer_surfaces, link) { struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; - output_surface_for_each_surface(wlr_layer_surface->surface, - layer_surface->geo.x, layer_surface->geo.y, geo, iterator, + output_surface_for_each_surface2(output, wlr_layer_surface->surface, + layer_surface->geo.x, layer_surface->geo.y, 0, iterator, user_data); } } @@ -288,10 +288,10 @@ static void send_frame_done_iterator2(struct sway_output *output, wlr_surface_send_frame_done(surface, data->when); } -static void send_frame_done_layer(struct send_frame_done_data *data, - struct wl_list *layer_surfaces) { - output_layer_for_each_surface(layer_surfaces, &data->root_geo, - send_frame_done_iterator, data); +static void send_frame_done_layer(struct sway_output *output, + struct wl_list *layer_surfaces, struct send_frame_done_data *data) { + output_layer_for_each_surface(output, layer_surfaces, + send_frame_done_iterator2, data); } #ifdef HAVE_XWAYLAND @@ -352,10 +352,10 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { &root_container.sway_root->xwayland_unmanaged); #endif } else { - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &data); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &data); send_frame_done_container(&data, workspace); send_frame_done_container(&data, workspace->sway_workspace->floating); @@ -364,13 +364,13 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { send_frame_done_unmanaged(&data, &root_container.sway_root->xwayland_unmanaged); #endif - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &data); } send_frame_overlay: - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &data); send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); } diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 1270b7cfb..35dc3edce 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -155,8 +155,8 @@ static void render_layer(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_layer_for_each_surface(layer_surfaces, &data.root_geo, - render_surface_iterator, &data); + output_layer_for_each_surface(output, layer_surfaces, + render_surface_iterator2, &data); } #ifdef HAVE_XWAYLAND From e9d674cfd294f13a32893dd584826ed7481e05e3 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:59:14 +0100 Subject: [PATCH 4/8] wip: redesign output_view_for_each_surface iterator --- include/sway/output.h | 6 ++-- sway/desktop/output.c | 75 +++++++++++++++++++++++++++++++++++-------- sway/desktop/render.c | 3 +- 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index c1763b266..7a458a84a 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -89,9 +89,9 @@ void output_surface_for_each_surface2(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, float rotation, sway_surface_iterator_func_t iterator, void *user_data); -void output_view_for_each_surface(struct sway_view *view, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data); +void output_view_for_each_surface(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data); void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 5e309250d..31033ee36 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -155,16 +155,22 @@ void output_surface_for_each_surface2(struct sway_output *output, output_surface_for_each_surface2_iterator, &data); } -void output_view_for_each_surface(struct sway_view *view, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { - geo->x = view->swayc->current.view_x - output->swayc->current.swayc_x; - geo->y = view->swayc->current.view_y - output->swayc->current.swayc_y; - geo->width = view->swayc->current.view_width; - geo->height = view->swayc->current.view_height; - geo->rotation = 0; // TODO +void output_view_for_each_surface(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, + .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, + .width = view->swayc->current.view_width, + .height = view->swayc->current.view_height, + .rotation = 0, // TODO + }; - view_for_each_surface(view, iterator, user_data); + view_for_each_surface(view, + output_surface_for_each_surface2_iterator, &data); } void output_layer_for_each_surface(struct sway_output *output, @@ -319,8 +325,8 @@ static void send_frame_done_container_iterator(struct sway_container *con, return; } - output_view_for_each_surface(con->sway_view, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_view_for_each_surface(data->output, con->sway_view, + send_frame_done_iterator2, data); } static void send_frame_done_container(struct send_frame_done_data *data, @@ -463,6 +469,50 @@ static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, wlr_output_schedule_frame(output->wlr_output); } +static void damage_surface_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *_box, float rotation, + void *_data) { + struct damage_data *data = _data; + bool whole = data->whole; + + struct wlr_box box = *_box; + scale_box(&box, output->wlr_output->scale); + + int center_x = box.x + box.width/2; + int center_y = box.y + box.height/2; + + if (pixman_region32_not_empty(&surface->buffer_damage)) { + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + + pixman_region32_t damage; + pixman_region32_init(&damage); + pixman_region32_copy(&damage, &surface->buffer_damage); + wlr_region_transform(&damage, &damage, transform, + surface->current.buffer_width, surface->current.buffer_height); + wlr_region_scale(&damage, &damage, + output->wlr_output->scale / (float)surface->current.scale); + if (ceil(output->wlr_output->scale) > surface->current.scale) { + // When scaling up a surface, it'll become blurry so we need to + // expand the damage region + wlr_region_expand(&damage, &damage, + ceil(output->wlr_output->scale) - surface->current.scale); + } + pixman_region32_translate(&damage, box.x, box.y); + wlr_region_rotated_bounds(&damage, &damage, rotation, + center_x, center_y); + wlr_output_damage_add(output->damage, &damage); + pixman_region32_fini(&damage); + } + + if (whole) { + wlr_box_rotated_bounds(&box, rotation, &box); + wlr_output_damage_add_box(output->damage, &box); + } + + wlr_output_schedule_frame(output->wlr_output); +} + void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { struct damage_data data = { @@ -489,8 +539,7 @@ static void output_damage_view(struct sway_output *output, .whole = whole, }; - output_view_for_each_surface(view, output, &data.root_geo, - damage_surface_iterator, &data); + output_view_for_each_surface(output, view, damage_surface_iterator2, &data); } void output_damage_from_view(struct sway_output *output, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 35dc3edce..18d076df0 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -231,8 +231,7 @@ static void render_view_surfaces(struct sway_view *view, .view = view, .alpha = alpha, }; - output_view_for_each_surface(view, output, &data.root_geo, - render_surface_iterator, &data); + output_view_for_each_surface(output, view, render_surface_iterator2, &data); } static void render_saved_view(struct sway_view *view, From 8d5cc8625ce04c657eab6bd5f242a02e97ddd647 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 19:16:36 +0100 Subject: [PATCH 5/8] Completely switch over to new iterators --- include/sway/output.h | 18 --- sway/desktop/output.c | 281 ++++++++++++++---------------------------- sway/desktop/render.c | 49 +------- 3 files changed, 98 insertions(+), 250 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 7a458a84a..70f631a05 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -39,16 +39,6 @@ struct sway_output { } events; }; -/** - * Contains a surface's root geometry information. For instance, when rendering - * a popup, this will contain the parent view's position and size. - */ -struct root_geometry { - double x, y; - int width, height; - float rotation; -}; - typedef void (*sway_surface_iterator_func_t)(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *box, float rotation, void *user_data); @@ -77,14 +67,6 @@ struct sway_container *output_get_active_workspace(struct sway_output *output); void output_render(struct sway_output *output, struct timespec *when, pixman_region32_t *damage); -bool output_get_surface_box(struct root_geometry *geo, - struct sway_output *output, struct wlr_surface *surface, int sx, int sy, - struct wlr_box *surface_box); - -void output_surface_for_each_surface(struct wlr_surface *surface, - double ox, double oy, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data); - void output_surface_for_each_surface2(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, float rotation, sway_surface_iterator_func_t iterator, void *user_data); diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 31033ee36..e1d85b10e 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -57,54 +57,6 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, *sy = ry + ph/2 - sh/2; } -bool output_get_surface_box(struct root_geometry *geo, - struct sway_output *output, struct wlr_surface *surface, int sx, int sy, - struct wlr_box *surface_box) { - if (!wlr_surface_has_buffer(surface)) { - return false; - } - - int sw = surface->current.width; - int sh = surface->current.height; - - double _sx = sx, _sy = sy; - rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height, - geo->rotation); - - struct wlr_box box = { - .x = geo->x + _sx, - .y = geo->y + _sy, - .width = sw, - .height = sh, - }; - if (surface_box != NULL) { - memcpy(surface_box, &box, sizeof(struct wlr_box)); - } - - struct wlr_box rotated_box; - wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box); - - struct wlr_box output_box = { - .width = output->swayc->current.swayc_width, - .height = output->swayc->current.swayc_height, - }; - - struct wlr_box intersection; - return wlr_box_intersection(&output_box, &rotated_box, &intersection); -} - -void output_surface_for_each_surface(struct wlr_surface *surface, - double ox, double oy, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { - geo->x = ox; - geo->y = oy; - geo->width = surface->current.width; - geo->height = surface->current.height; - geo->rotation = 0; - - wlr_surface_for_each_surface(surface, iterator, user_data); -} - struct surface_iterator_data { sway_surface_iterator_func_t user_iterator; void *user_data; @@ -115,20 +67,50 @@ struct surface_iterator_data { float rotation; }; -void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, +static bool get_surface_box(struct surface_iterator_data *data, + struct wlr_surface *surface, int sx, int sy, + struct wlr_box *surface_box) { + struct sway_output *output = data->output; + + if (!wlr_surface_has_buffer(surface)) { + return false; + } + + int sw = surface->current.width; + int sh = surface->current.height; + + double _sx = sx, _sy = sy; + rotate_child_position(&_sx, &_sy, sw, sh, data->width, data->height, + data->rotation); + + struct wlr_box box = { + .x = data->ox + _sx, + .y = data->oy + _sy, + .width = sw, + .height = sh, + }; + if (surface_box != NULL) { + memcpy(surface_box, &box, sizeof(struct wlr_box)); + } + + struct wlr_box rotated_box; + wlr_box_rotated_bounds(&box, data->rotation, &rotated_box); + + struct wlr_box output_box = { + .width = output->swayc->current.swayc_width, + .height = output->swayc->current.swayc_height, + }; + + struct wlr_box intersection; + return wlr_box_intersection(&output_box, &rotated_box, &intersection); +} + +void output_surface_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *_data) { struct surface_iterator_data *data = _data; - struct root_geometry geo = { - .x = data->ox, - .y = data->oy, - .width = data->width, - .height = data->height, - .rotation = data->rotation, - }; struct wlr_box box; - bool intersects = output_get_surface_box(&geo, data->output, - surface, sx, sy, &box); + bool intersects = get_surface_box(data, surface, sx, sy, &box); if (!intersects) { return; } @@ -137,7 +119,7 @@ void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, data->user_data); } -void output_surface_for_each_surface2(struct sway_output *output, +void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, float rotation, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -152,7 +134,7 @@ void output_surface_for_each_surface2(struct sway_output *output, }; wlr_surface_for_each_surface(surface, - output_surface_for_each_surface2_iterator, &data); + output_surface_for_each_surface_iterator, &data); } void output_view_for_each_surface(struct sway_output *output, @@ -170,7 +152,7 @@ void output_view_for_each_surface(struct sway_output *output, }; view_for_each_surface(view, - output_surface_for_each_surface2_iterator, &data); + output_surface_for_each_surface_iterator, &data); } void output_layer_for_each_surface(struct sway_output *output, @@ -180,7 +162,7 @@ void output_layer_for_each_surface(struct sway_output *output, wl_list_for_each(layer_surface, layer_surfaces, link) { struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; - output_surface_for_each_surface2(output, wlr_layer_surface->surface, + output_surface_for_each_surface(output, wlr_layer_surface->surface, layer_surface->geo.x, layer_surface->geo.y, 0, iterator, user_data); } @@ -197,7 +179,7 @@ void output_unmanaged_for_each_surface(struct sway_output *output, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface2(output, xsurface->surface, ox, oy, 0, + output_surface_for_each_surface(output, xsurface->surface, ox, oy, 0, iterator, user_data); } } @@ -212,7 +194,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output, double oy = drag_icon->y - output->swayc->y; if (drag_icon->wlr_drag_icon->mapped) { - output_surface_for_each_surface2(output, + output_surface_for_each_surface(output, drag_icon->wlr_drag_icon->surface, ox, oy, 0, iterator, user_data); } @@ -270,50 +252,38 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { return false; } -struct send_frame_done_data { - struct root_geometry root_geo; - struct sway_output *output; - struct timespec *when; -}; - -static void send_frame_done_iterator(struct wlr_surface *surface, - int sx, int sy, void *_data) { - struct send_frame_done_data *data = _data; - - bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, - sx, sy, NULL); - if (intersects) { - wlr_surface_send_frame_done(surface, data->when); - } -} - -static void send_frame_done_iterator2(struct sway_output *output, +static void send_frame_done_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *box, float rotation, void *_data) { - struct send_frame_done_data *data = _data; - wlr_surface_send_frame_done(surface, data->when); + struct timespec *when = _data; + wlr_surface_send_frame_done(surface, when); } static void send_frame_done_layer(struct sway_output *output, - struct wl_list *layer_surfaces, struct send_frame_done_data *data) { + struct wl_list *layer_surfaces, struct timespec *when) { output_layer_for_each_surface(output, layer_surfaces, - send_frame_done_iterator2, data); + send_frame_done_iterator, when); } #ifdef HAVE_XWAYLAND -static void send_frame_done_unmanaged(struct send_frame_done_data *data, - struct wl_list *unmanaged) { - output_unmanaged_for_each_surface(data->output, unmanaged, - send_frame_done_iterator2, data); +static void send_frame_done_unmanaged(struct sway_output *output, + struct wl_list *unmanaged, struct timespec *when) { + output_unmanaged_for_each_surface(output, unmanaged, + send_frame_done_iterator, when); } #endif -static void send_frame_done_drag_icons(struct send_frame_done_data *data, - struct wl_list *drag_icons) { - output_drag_icons_for_each_surface(data->output, drag_icons, - send_frame_done_iterator2, data); +static void send_frame_done_drag_icons(struct sway_output *output, + struct wl_list *drag_icons, struct timespec *when) { + output_drag_icons_for_each_surface(output, drag_icons, + send_frame_done_iterator, when); } +struct send_frame_done_data { + struct sway_output *output; + struct timespec *when; +}; + static void send_frame_done_container_iterator(struct sway_container *con, void *_data) { struct send_frame_done_data *data = _data; @@ -326,21 +296,20 @@ static void send_frame_done_container_iterator(struct sway_container *con, } output_view_for_each_surface(data->output, con->sway_view, - send_frame_done_iterator2, data); + send_frame_done_iterator, data->when); } -static void send_frame_done_container(struct send_frame_done_data *data, - struct sway_container *con) { - container_descendants(con, C_VIEW, - send_frame_done_container_iterator, data); -} - -static void send_frame_done(struct sway_output *output, struct timespec *when) { +static void send_frame_done_container(struct sway_output *output, + struct sway_container *con, struct timespec *when) { struct send_frame_done_data data = { .output = output, .when = when, }; + container_descendants(con, C_VIEW, + send_frame_done_container_iterator, &data); +} +static void send_frame_done(struct sway_output *output, struct timespec *when) { if (output_has_opaque_overlay_layer_surface(output)) { goto send_frame_overlay; } @@ -349,35 +318,38 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { if (workspace->current.ws_fullscreen) { if (workspace->current.ws_fullscreen->type == C_VIEW) { send_frame_done_container_iterator( - workspace->current.ws_fullscreen, &data); + workspace->current.ws_fullscreen, when); } else { - send_frame_done_container(&data, workspace->current.ws_fullscreen); + send_frame_done_container(output, workspace->current.ws_fullscreen, + when); } #ifdef HAVE_XWAYLAND - send_frame_done_unmanaged(&data, - &root_container.sway_root->xwayland_unmanaged); + send_frame_done_unmanaged(output, + &root_container.sway_root->xwayland_unmanaged, when); #endif } else { send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], when); send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when); - send_frame_done_container(&data, workspace); - send_frame_done_container(&data, workspace->sway_workspace->floating); + send_frame_done_container(output, workspace, when); + send_frame_done_container(output, workspace->sway_workspace->floating, + when); #ifdef HAVE_XWAYLAND - send_frame_done_unmanaged(&data, - &root_container.sway_root->xwayland_unmanaged); + send_frame_done_unmanaged(output, + &root_container.sway_root->xwayland_unmanaged, when); #endif send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); } send_frame_overlay: send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &data); - send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); + send_frame_done_drag_icons(output, &root_container.sway_root->drag_icons, + when); } static void damage_handle_frame(struct wl_listener *listener, void *data) { @@ -412,68 +384,11 @@ void output_damage_whole(struct sway_output *output) { wlr_output_damage_add_whole(output->damage); } -struct damage_data { - struct root_geometry root_geo; - struct sway_output *output; - bool whole; -}; - -static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, - void *_data) { - struct damage_data *data = _data; - struct sway_output *output = data->output; - float rotation = data->root_geo.rotation; - bool whole = data->whole; - - struct wlr_box box; - bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, - sx, sy, &box); - if (!intersects) { - return; - } - - scale_box(&box, output->wlr_output->scale); - - int center_x = box.x + box.width/2; - int center_y = box.y + box.height/2; - - if (pixman_region32_not_empty(&surface->buffer_damage)) { - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - - pixman_region32_t damage; - pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->buffer_damage); - wlr_region_transform(&damage, &damage, transform, - surface->current.buffer_width, surface->current.buffer_height); - wlr_region_scale(&damage, &damage, - output->wlr_output->scale / (float)surface->current.scale); - if (ceil(output->wlr_output->scale) > surface->current.scale) { - // When scaling up a surface, it'll become blurry so we need to - // expand the damage region - wlr_region_expand(&damage, &damage, - ceil(output->wlr_output->scale) - surface->current.scale); - } - pixman_region32_translate(&damage, box.x, box.y); - wlr_region_rotated_bounds(&damage, &damage, rotation, - center_x, center_y); - wlr_output_damage_add(output->damage, &damage); - pixman_region32_fini(&damage); - } - - if (whole) { - wlr_box_rotated_bounds(&box, rotation, &box); - wlr_output_damage_add_box(output->damage, &box); - } - - wlr_output_schedule_frame(output->wlr_output); -} - -static void damage_surface_iterator2(struct sway_output *output, +static void damage_surface_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *_box, float rotation, void *_data) { - struct damage_data *data = _data; - bool whole = data->whole; + bool *data = _data; + bool whole = *data; struct wlr_box box = *_box; scale_box(&box, output->wlr_output->scale); @@ -515,13 +430,8 @@ static void damage_surface_iterator2(struct sway_output *output, void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { - struct damage_data data = { - .output = output, - .whole = whole, - }; - - output_surface_for_each_surface(surface, ox, oy, &data.root_geo, - damage_surface_iterator, &data); + output_surface_for_each_surface(output, surface, ox, oy, 0, + damage_surface_iterator, &whole); } static void output_damage_view(struct sway_output *output, @@ -534,12 +444,7 @@ static void output_damage_view(struct sway_output *output, return; } - struct damage_data data = { - .output = output, - .whole = whole, - }; - - output_view_for_each_surface(output, view, damage_surface_iterator2, &data); + output_view_for_each_surface(output, view, damage_surface_iterator, &whole); } void output_damage_from_view(struct sway_output *output, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 18d076df0..f25055b81 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -29,10 +29,7 @@ #include "sway/tree/workspace.h" struct render_data { - struct root_geometry root_geo; - struct sway_output *output; pixman_region32_t *damage; - struct sway_view *view; float alpha; }; @@ -92,38 +89,7 @@ damage_finish: pixman_region32_fini(&damage); } -static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, - void *_data) { - struct render_data *data = _data; - struct wlr_output *wlr_output = data->output->wlr_output; - float rotation = data->root_geo.rotation; - pixman_region32_t *output_damage = data->damage; - float alpha = data->alpha; - - struct wlr_texture *texture = wlr_surface_get_texture(surface); - if (!texture) { - return; - } - - struct wlr_box box; - bool intersects = output_get_surface_box(&data->root_geo, data->output, - surface, sx, sy, &box); - if (!intersects) { - return; - } - - scale_box(&box, wlr_output->scale); - - float matrix[9]; - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - wlr_matrix_project_box(matrix, &box, transform, rotation, - wlr_output->transform_matrix); - - render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); -} - -static void render_surface_iterator2(struct sway_output *output, +static void render_surface_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *_box, float rotation, void *_data) { struct render_data *data = _data; @@ -151,36 +117,33 @@ static void render_surface_iterator2(struct sway_output *output, static void render_layer(struct sway_output *output, pixman_region32_t *damage, struct wl_list *layer_surfaces) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_layer_for_each_surface(output, layer_surfaces, - render_surface_iterator2, &data); + render_surface_iterator, &data); } #ifdef HAVE_XWAYLAND static void render_unmanaged(struct sway_output *output, pixman_region32_t *damage, struct wl_list *unmanaged) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_unmanaged_for_each_surface(output, unmanaged, - render_surface_iterator2, &data); + render_surface_iterator, &data); } #endif static void render_drag_icons(struct sway_output *output, pixman_region32_t *damage, struct wl_list *drag_icons) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_drag_icons_for_each_surface(output, drag_icons, - render_surface_iterator2, &data); + render_surface_iterator, &data); } static void render_rect(struct wlr_output *wlr_output, @@ -226,12 +189,10 @@ static void premultiply_alpha(float color[4], float opacity) { static void render_view_surfaces(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { - .output = output, .damage = damage, - .view = view, .alpha = alpha, }; - output_view_for_each_surface(output, view, render_surface_iterator2, &data); + output_view_for_each_surface(output, view, render_surface_iterator, &data); } static void render_saved_view(struct sway_view *view, From fe0750fec107f692be4f47659b446ed3d8d8f3b6 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 19:19:30 +0100 Subject: [PATCH 6/8] Remove output_surface_for_each_surface from header --- include/sway/output.h | 4 ---- sway/desktop/output.c | 14 +++++++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 70f631a05..6283db68a 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -67,10 +67,6 @@ struct sway_container *output_get_active_workspace(struct sway_output *output); void output_render(struct sway_output *output, struct timespec *when, pixman_region32_t *damage); -void output_surface_for_each_surface2(struct sway_output *output, - struct wlr_surface *surface, double ox, double oy, float rotation, - sway_surface_iterator_func_t iterator, void *user_data); - void output_view_for_each_surface(struct sway_output *output, struct sway_view *view, sway_surface_iterator_func_t iterator, void *user_data); diff --git a/sway/desktop/output.c b/sway/desktop/output.c index e1d85b10e..8272b35bb 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,8 +119,8 @@ void output_surface_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -void output_surface_for_each_surface(struct sway_output *output, - struct wlr_surface *surface, double ox, double oy, float rotation, +static void output_surface_for_each_surface(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { .user_iterator = iterator, @@ -130,7 +130,7 @@ void output_surface_for_each_surface(struct sway_output *output, .oy = oy, .width = surface->current.width, .height = surface->current.height, - .rotation = rotation, + .rotation = 0, }; wlr_surface_for_each_surface(surface, @@ -163,7 +163,7 @@ void output_layer_for_each_surface(struct sway_output *output, struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; output_surface_for_each_surface(output, wlr_layer_surface->surface, - layer_surface->geo.x, layer_surface->geo.y, 0, iterator, + layer_surface->geo.x, layer_surface->geo.y, iterator, user_data); } } @@ -179,7 +179,7 @@ void output_unmanaged_for_each_surface(struct sway_output *output, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface(output, xsurface->surface, ox, oy, 0, + output_surface_for_each_surface(output, xsurface->surface, ox, oy, iterator, user_data); } } @@ -195,7 +195,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output, if (drag_icon->wlr_drag_icon->mapped) { output_surface_for_each_surface(output, - drag_icon->wlr_drag_icon->surface, ox, oy, 0, + drag_icon->wlr_drag_icon->surface, ox, oy, iterator, user_data); } } @@ -430,7 +430,7 @@ static void damage_surface_iterator(struct sway_output *output, void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { - output_surface_for_each_surface(output, surface, ox, oy, 0, + output_surface_for_each_surface(output, surface, ox, oy, damage_surface_iterator, &whole); } From 9951b2ec334545f636c892742ed034d917146558 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 19:23:38 +0100 Subject: [PATCH 7/8] Remove unused output_from_wlr_output --- sway/desktop/output.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 8272b35bb..fc767cca6 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -534,10 +534,6 @@ static void handle_scale(struct wl_listener *listener, void *data) { transaction_commit_dirty(); } -struct sway_output *output_from_wlr_output(struct wlr_output *wlr_output) { - return wlr_output->data; -} - void handle_new_output(struct wl_listener *listener, void *data) { struct sway_server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; From 0ad865f0b7db2407e151796253b632036a240c7f Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 29 Jul 2018 14:34:48 +0100 Subject: [PATCH 8/8] Make output_surface_for_each_surface_iterator static --- sway/desktop/output.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index fc767cca6..d9ccb00dc 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -105,7 +105,7 @@ static bool get_surface_box(struct surface_iterator_data *data, return wlr_box_intersection(&output_box, &rotated_box, &intersection); } -void output_surface_for_each_surface_iterator(struct wlr_surface *surface, +static void output_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *_data) { struct surface_iterator_data *data = _data; @@ -134,7 +134,7 @@ static void output_surface_for_each_surface(struct sway_output *output, }; wlr_surface_for_each_surface(surface, - output_surface_for_each_surface_iterator, &data); + output_for_each_surface_iterator, &data); } void output_view_for_each_surface(struct sway_output *output, @@ -152,7 +152,7 @@ void output_view_for_each_surface(struct sway_output *output, }; view_for_each_surface(view, - output_surface_for_each_surface_iterator, &data); + output_for_each_surface_iterator, &data); } void output_layer_for_each_surface(struct sway_output *output,