From 85968ec101aa38acf997f4dbadb1c36bfa30e031 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 30 Jul 2018 14:38:47 -0400 Subject: [PATCH] Revert "Refactor surface iterators" --- include/sway/output.h | 47 +++++--- sway/desktop/output.c | 274 ++++++++++++++++++++---------------------- sway/desktop/render.c | 33 +++-- 3 files changed, 183 insertions(+), 171 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 6283db68a..c225e541f 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -5,7 +5,6 @@ #include #include #include -#include "config.h" #include "sway/tree/view.h" struct sway_server; @@ -39,9 +38,15 @@ struct sway_output { } events; }; -typedef void (*sway_surface_iterator_func_t)(struct sway_output *output, - struct wlr_surface *surface, struct wlr_box *box, float rotation, - void *user_data); +/** + * 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; +}; void output_damage_whole(struct sway_output *output); @@ -67,22 +72,28 @@ 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_view_for_each_surface(struct sway_output *output, - struct sway_view *view, sway_surface_iterator_func_t iterator, +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_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 *user_data); -void output_layer_for_each_surface(struct sway_output *output, - struct wl_list *layer_surfaces, sway_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 sway_output *output, - struct wl_list *drag_icons, sway_surface_iterator_func_t iterator, - void *user_data); +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); #endif diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 6b2eb0c25..fb52e7b18 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -57,21 +57,9 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, *sy = ry + ph/2 - sh/2; } -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; -}; - -static bool get_surface_box(struct surface_iterator_data *data, - struct wlr_surface *surface, int sx, int sy, +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) { - struct sway_output *output = data->output; - if (!wlr_surface_has_buffer(surface)) { return false; } @@ -80,12 +68,12 @@ static bool get_surface_box(struct surface_iterator_data *data, int sh = surface->current.height; double _sx = sx, _sy = sy; - rotate_child_position(&_sx, &_sy, sw, sh, data->width, data->height, - data->rotation); + rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height, + geo->rotation); struct wlr_box box = { - .x = data->ox + _sx, - .y = data->oy + _sy, + .x = geo->x + _sx, + .y = geo->y + _sy, .width = sw, .height = sh, }; @@ -94,7 +82,7 @@ static bool get_surface_box(struct surface_iterator_data *data, } struct wlr_box rotated_box; - wlr_box_rotated_bounds(&box, data->rotation, &rotated_box); + wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box); struct wlr_box output_box = { .width = output->swayc->current.swayc_width, @@ -105,73 +93,46 @@ static bool get_surface_box(struct surface_iterator_data *data, return wlr_box_intersection(&output_box, &rotated_box, &intersection); } -static void output_for_each_surface_iterator(struct wlr_surface *surface, - int sx, int sy, void *_data) { - struct surface_iterator_data *data = _data; +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; - struct wlr_box box; - bool intersects = get_surface_box(data, surface, sx, sy, &box); - if (!intersects) { - return; - } - - data->user_iterator(data->output, surface, &box, data->rotation, - data->user_data); + wlr_surface_for_each_surface(surface, iterator, user_data); } -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, - .user_data = user_data, - .output = output, - .ox = ox, - .oy = oy, - .width = surface->current.width, - .height = surface->current.height, - .rotation = 0, - }; +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 - wlr_surface_for_each_surface(surface, - output_for_each_surface_iterator, &data); + view_for_each_surface(view, iterator, 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) { - 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, - output_for_each_surface_iterator, &data); -} - -void output_layer_for_each_surface(struct sway_output *output, - struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, +void output_layer_for_each_surface(struct wl_list *layer_surfaces, + struct root_geometry *geo, wlr_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(output, wlr_layer_surface->surface, - layer_surface->geo.x, layer_surface->geo.y, iterator, + output_surface_for_each_surface(wlr_layer_surface->surface, + layer_surface->geo.x, layer_surface->geo.y, geo, iterator, 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) { +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) { struct sway_xwayland_unmanaged *unmanaged_surface; wl_list_for_each(unmanaged_surface, unmanaged, link) { struct wlr_xwayland_surface *xsurface = @@ -179,24 +140,22 @@ 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, + output_surface_for_each_surface(xsurface->surface, ox, oy, geo, iterator, user_data); } } #endif - -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) { +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) { 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(output, - drag_icon->wlr_drag_icon->surface, ox, oy, - iterator, user_data); + output_surface_for_each_surface(drag_icon->wlr_drag_icon->surface, + ox, oy, geo, iterator, user_data); } } } @@ -252,38 +211,41 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { return false; } -static void send_frame_done_iterator(struct sway_output *output, - struct wlr_surface *surface, struct wlr_box *box, float rotation, - void *_data) { - 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 timespec *when) { - output_layer_for_each_surface(output, layer_surfaces, - send_frame_done_iterator, when); -} - -#ifdef HAVE_XWAYLAND -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 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 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_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); +} +#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, + send_frame_done_iterator, data); +} + static void send_frame_done_container_iterator(struct sway_container *con, void *_data) { struct send_frame_done_data *data = _data; @@ -295,21 +257,22 @@ static void send_frame_done_container_iterator(struct sway_container *con, return; } - output_view_for_each_surface(data->output, con->sway_view, - send_frame_done_iterator, data->when); + output_view_for_each_surface(con->sway_view, data->output, &data->root_geo, + send_frame_done_iterator, data); } -static void send_frame_done_container(struct sway_output *output, - struct sway_container *con, struct timespec *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) { 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; } @@ -318,38 +281,35 @@ 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, when); + workspace->current.ws_fullscreen, &data); } else { - send_frame_done_container(output, workspace->current.ws_fullscreen, - when); + send_frame_done_container(&data, workspace->current.ws_fullscreen); } #ifdef HAVE_XWAYLAND - send_frame_done_unmanaged(output, - &root_container.sway_root->xwayland_unmanaged, when); + send_frame_done_unmanaged(&data, + &root_container.sway_root->xwayland_unmanaged); #endif } else { - send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], when); - send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when); + 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_container(output, workspace, when); - send_frame_done_container(output, workspace->sway_workspace->floating, - when); + send_frame_done_container(&data, workspace); + send_frame_done_container(&data, workspace->sway_workspace->floating); #ifdef HAVE_XWAYLAND - send_frame_done_unmanaged(output, - &root_container.sway_root->xwayland_unmanaged, when); + send_frame_done_unmanaged(&data, + &root_container.sway_root->xwayland_unmanaged); #endif - send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); + send_frame_done_layer(&data, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } send_frame_overlay: - send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); - send_frame_done_drag_icons(output, &root_container.sway_root->drag_icons, - when); + send_frame_done_layer(&data, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); + send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); } static void damage_handle_frame(struct wl_listener *listener, void *data) { @@ -384,13 +344,26 @@ void output_damage_whole(struct sway_output *output) { wlr_output_damage_add_whole(output->damage); } -static void damage_surface_iterator(struct sway_output *output, - struct wlr_surface *surface, struct wlr_box *_box, float rotation, - void *_data) { - bool *data = _data; - bool whole = *data; +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; + } - struct wlr_box box = *_box; scale_box(&box, output->wlr_output->scale); int center_x = box.x + box.width/2; @@ -430,8 +403,13 @@ 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, - damage_surface_iterator, &whole); + struct damage_data data = { + .output = output, + .whole = whole, + }; + + output_surface_for_each_surface(surface, ox, oy, &data.root_geo, + damage_surface_iterator, &data); } static void output_damage_view(struct sway_output *output, @@ -444,7 +422,13 @@ static void output_damage_view(struct sway_output *output, return; } - output_view_for_each_surface(output, view, damage_surface_iterator, &whole); + struct damage_data data = { + .output = output, + .whole = whole, + }; + + output_view_for_each_surface(view, output, &data.root_geo, + damage_surface_iterator, &data); } void output_damage_from_view(struct sway_output *output, @@ -530,6 +514,10 @@ 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; diff --git a/sway/desktop/render.c b/sway/desktop/render.c index f25055b81..c9fdfd95e 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -29,7 +29,10 @@ #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; }; @@ -89,11 +92,11 @@ damage_finish: pixman_region32_fini(&damage); } -static void render_surface_iterator(struct sway_output *output, - struct wlr_surface *surface, struct wlr_box *_box, float rotation, +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 = output->wlr_output; + 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; @@ -102,7 +105,13 @@ static void render_surface_iterator(struct sway_output *output, return; } - struct wlr_box box = *_box; + 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]; @@ -117,32 +126,33 @@ static void render_surface_iterator(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, + 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) { struct render_data data = { + .output = output, .damage = damage, .alpha = 1.0f, }; - output_unmanaged_for_each_surface(output, unmanaged, + output_unmanaged_for_each_surface(unmanaged, output, &data.root_geo, 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, + output_drag_icons_for_each_surface(drag_icons, output, &data.root_geo, render_surface_iterator, &data); } @@ -189,10 +199,13 @@ 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_iterator, &data); + output_view_for_each_surface(view, output, &data.root_geo, + render_surface_iterator, &data); } static void render_saved_view(struct sway_view *view,