diff options
-rw-r--r-- | include/sway/output.h | 18 | ||||
-rw-r--r-- | sway/desktop/output.c | 243 | ||||
-rw-r--r-- | sway/desktop/render.c | 49 |
3 files changed, 79 insertions, 231 deletions
diff --git a/include/sway/output.h b/include/sway/output.h index 7a458a84..70f631a0 100644 --- a/include/sway/output.h +++ b/include/sway/output.h | |||
@@ -39,16 +39,6 @@ struct sway_output { | |||
39 | } events; | 39 | } events; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /** | ||
43 | * Contains a surface's root geometry information. For instance, when rendering | ||
44 | * a popup, this will contain the parent view's position and size. | ||
45 | */ | ||
46 | struct root_geometry { | ||
47 | double x, y; | ||
48 | int width, height; | ||
49 | float rotation; | ||
50 | }; | ||
51 | |||
52 | typedef void (*sway_surface_iterator_func_t)(struct sway_output *output, | 42 | typedef void (*sway_surface_iterator_func_t)(struct sway_output *output, |
53 | struct wlr_surface *surface, struct wlr_box *box, float rotation, | 43 | struct wlr_surface *surface, struct wlr_box *box, float rotation, |
54 | void *user_data); | 44 | void *user_data); |
@@ -77,14 +67,6 @@ struct sway_container *output_get_active_workspace(struct sway_output *output); | |||
77 | void output_render(struct sway_output *output, struct timespec *when, | 67 | void output_render(struct sway_output *output, struct timespec *when, |
78 | pixman_region32_t *damage); | 68 | pixman_region32_t *damage); |
79 | 69 | ||
80 | bool output_get_surface_box(struct root_geometry *geo, | ||
81 | struct sway_output *output, struct wlr_surface *surface, int sx, int sy, | ||
82 | struct wlr_box *surface_box); | ||
83 | |||
84 | void output_surface_for_each_surface(struct wlr_surface *surface, | ||
85 | double ox, double oy, struct root_geometry *geo, | ||
86 | wlr_surface_iterator_func_t iterator, void *user_data); | ||
87 | |||
88 | void output_surface_for_each_surface2(struct sway_output *output, | 70 | void output_surface_for_each_surface2(struct sway_output *output, |
89 | struct wlr_surface *surface, double ox, double oy, float rotation, | 71 | struct wlr_surface *surface, double ox, double oy, float rotation, |
90 | sway_surface_iterator_func_t iterator, void *user_data); | 72 | sway_surface_iterator_func_t iterator, void *user_data); |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 31033ee3..e1d85b10 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -57,9 +57,21 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, | |||
57 | *sy = ry + ph/2 - sh/2; | 57 | *sy = ry + ph/2 - sh/2; |
58 | } | 58 | } |
59 | 59 | ||
60 | bool output_get_surface_box(struct root_geometry *geo, | 60 | struct surface_iterator_data { |
61 | struct sway_output *output, struct wlr_surface *surface, int sx, int sy, | 61 | sway_surface_iterator_func_t user_iterator; |
62 | void *user_data; | ||
63 | |||
64 | struct sway_output *output; | ||
65 | double ox, oy; | ||
66 | int width, height; | ||
67 | float rotation; | ||
68 | }; | ||
69 | |||
70 | static bool get_surface_box(struct surface_iterator_data *data, | ||
71 | struct wlr_surface *surface, int sx, int sy, | ||
62 | struct wlr_box *surface_box) { | 72 | struct wlr_box *surface_box) { |
73 | struct sway_output *output = data->output; | ||
74 | |||
63 | if (!wlr_surface_has_buffer(surface)) { | 75 | if (!wlr_surface_has_buffer(surface)) { |
64 | return false; | 76 | return false; |
65 | } | 77 | } |
@@ -68,12 +80,12 @@ bool output_get_surface_box(struct root_geometry *geo, | |||
68 | int sh = surface->current.height; | 80 | int sh = surface->current.height; |
69 | 81 | ||
70 | double _sx = sx, _sy = sy; | 82 | double _sx = sx, _sy = sy; |
71 | rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height, | 83 | rotate_child_position(&_sx, &_sy, sw, sh, data->width, data->height, |
72 | geo->rotation); | 84 | data->rotation); |
73 | 85 | ||
74 | struct wlr_box box = { | 86 | struct wlr_box box = { |
75 | .x = geo->x + _sx, | 87 | .x = data->ox + _sx, |
76 | .y = geo->y + _sy, | 88 | .y = data->oy + _sy, |
77 | .width = sw, | 89 | .width = sw, |
78 | .height = sh, | 90 | .height = sh, |
79 | }; | 91 | }; |
@@ -82,7 +94,7 @@ bool output_get_surface_box(struct root_geometry *geo, | |||
82 | } | 94 | } |
83 | 95 | ||
84 | struct wlr_box rotated_box; | 96 | struct wlr_box rotated_box; |
85 | wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box); | 97 | wlr_box_rotated_bounds(&box, data->rotation, &rotated_box); |
86 | 98 | ||
87 | struct wlr_box output_box = { | 99 | struct wlr_box output_box = { |
88 | .width = output->swayc->current.swayc_width, | 100 | .width = output->swayc->current.swayc_width, |
@@ -93,42 +105,12 @@ bool output_get_surface_box(struct root_geometry *geo, | |||
93 | return wlr_box_intersection(&output_box, &rotated_box, &intersection); | 105 | return wlr_box_intersection(&output_box, &rotated_box, &intersection); |
94 | } | 106 | } |
95 | 107 | ||
96 | void output_surface_for_each_surface(struct wlr_surface *surface, | 108 | void output_surface_for_each_surface_iterator(struct wlr_surface *surface, |
97 | double ox, double oy, struct root_geometry *geo, | ||
98 | wlr_surface_iterator_func_t iterator, void *user_data) { | ||
99 | geo->x = ox; | ||
100 | geo->y = oy; | ||
101 | geo->width = surface->current.width; | ||
102 | geo->height = surface->current.height; | ||
103 | geo->rotation = 0; | ||
104 | |||
105 | wlr_surface_for_each_surface(surface, iterator, user_data); | ||
106 | } | ||
107 | |||
108 | struct surface_iterator_data { | ||
109 | sway_surface_iterator_func_t user_iterator; | ||
110 | void *user_data; | ||
111 | |||
112 | struct sway_output *output; | ||
113 | double ox, oy; | ||
114 | int width, height; | ||
115 | float rotation; | ||
116 | }; | ||
117 | |||
118 | void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, | ||
119 | int sx, int sy, void *_data) { | 109 | int sx, int sy, void *_data) { |
120 | struct surface_iterator_data *data = _data; | 110 | struct surface_iterator_data *data = _data; |
121 | 111 | ||
122 | struct root_geometry geo = { | ||
123 | .x = data->ox, | ||
124 | .y = data->oy, | ||
125 | .width = data->width, | ||
126 | .height = data->height, | ||
127 | .rotation = data->rotation, | ||
128 | }; | ||
129 | struct wlr_box box; | 112 | struct wlr_box box; |
130 | bool intersects = output_get_surface_box(&geo, data->output, | 113 | bool intersects = get_surface_box(data, surface, sx, sy, &box); |
131 | surface, sx, sy, &box); | ||
132 | if (!intersects) { | 114 | if (!intersects) { |
133 | return; | 115 | return; |
134 | } | 116 | } |
@@ -137,7 +119,7 @@ void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, | |||
137 | data->user_data); | 119 | data->user_data); |
138 | } | 120 | } |
139 | 121 | ||
140 | void output_surface_for_each_surface2(struct sway_output *output, | 122 | void output_surface_for_each_surface(struct sway_output *output, |
141 | struct wlr_surface *surface, double ox, double oy, float rotation, | 123 | struct wlr_surface *surface, double ox, double oy, float rotation, |
142 | sway_surface_iterator_func_t iterator, void *user_data) { | 124 | sway_surface_iterator_func_t iterator, void *user_data) { |
143 | struct surface_iterator_data data = { | 125 | struct surface_iterator_data data = { |
@@ -152,7 +134,7 @@ void output_surface_for_each_surface2(struct sway_output *output, | |||
152 | }; | 134 | }; |
153 | 135 | ||
154 | wlr_surface_for_each_surface(surface, | 136 | wlr_surface_for_each_surface(surface, |
155 | output_surface_for_each_surface2_iterator, &data); | 137 | output_surface_for_each_surface_iterator, &data); |
156 | } | 138 | } |
157 | 139 | ||
158 | void output_view_for_each_surface(struct sway_output *output, | 140 | void output_view_for_each_surface(struct sway_output *output, |
@@ -170,7 +152,7 @@ void output_view_for_each_surface(struct sway_output *output, | |||
170 | }; | 152 | }; |
171 | 153 | ||
172 | view_for_each_surface(view, | 154 | view_for_each_surface(view, |
173 | output_surface_for_each_surface2_iterator, &data); | 155 | output_surface_for_each_surface_iterator, &data); |
174 | } | 156 | } |
175 | 157 | ||
176 | void output_layer_for_each_surface(struct sway_output *output, | 158 | void output_layer_for_each_surface(struct sway_output *output, |
@@ -180,7 +162,7 @@ void output_layer_for_each_surface(struct sway_output *output, | |||
180 | wl_list_for_each(layer_surface, layer_surfaces, link) { | 162 | wl_list_for_each(layer_surface, layer_surfaces, link) { |
181 | struct wlr_layer_surface *wlr_layer_surface = | 163 | struct wlr_layer_surface *wlr_layer_surface = |
182 | layer_surface->layer_surface; | 164 | layer_surface->layer_surface; |
183 | output_surface_for_each_surface2(output, wlr_layer_surface->surface, | 165 | output_surface_for_each_surface(output, wlr_layer_surface->surface, |
184 | layer_surface->geo.x, layer_surface->geo.y, 0, iterator, | 166 | layer_surface->geo.x, layer_surface->geo.y, 0, iterator, |
185 | user_data); | 167 | user_data); |
186 | } | 168 | } |
@@ -197,7 +179,7 @@ void output_unmanaged_for_each_surface(struct sway_output *output, | |||
197 | double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; | 179 | double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; |
198 | double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; | 180 | double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; |
199 | 181 | ||
200 | output_surface_for_each_surface2(output, xsurface->surface, ox, oy, 0, | 182 | output_surface_for_each_surface(output, xsurface->surface, ox, oy, 0, |
201 | iterator, user_data); | 183 | iterator, user_data); |
202 | } | 184 | } |
203 | } | 185 | } |
@@ -212,7 +194,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output, | |||
212 | double oy = drag_icon->y - output->swayc->y; | 194 | double oy = drag_icon->y - output->swayc->y; |
213 | 195 | ||
214 | if (drag_icon->wlr_drag_icon->mapped) { | 196 | if (drag_icon->wlr_drag_icon->mapped) { |
215 | output_surface_for_each_surface2(output, | 197 | output_surface_for_each_surface(output, |
216 | drag_icon->wlr_drag_icon->surface, ox, oy, 0, | 198 | drag_icon->wlr_drag_icon->surface, ox, oy, 0, |
217 | iterator, user_data); | 199 | iterator, user_data); |
218 | } | 200 | } |
@@ -270,50 +252,38 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { | |||
270 | return false; | 252 | return false; |
271 | } | 253 | } |
272 | 254 | ||
273 | struct send_frame_done_data { | 255 | static void send_frame_done_iterator(struct sway_output *output, |
274 | struct root_geometry root_geo; | ||
275 | struct sway_output *output; | ||
276 | struct timespec *when; | ||
277 | }; | ||
278 | |||
279 | static void send_frame_done_iterator(struct wlr_surface *surface, | ||
280 | int sx, int sy, void *_data) { | ||
281 | struct send_frame_done_data *data = _data; | ||
282 | |||
283 | bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, | ||
284 | sx, sy, NULL); | ||
285 | if (intersects) { | ||
286 | wlr_surface_send_frame_done(surface, data->when); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | static void send_frame_done_iterator2(struct sway_output *output, | ||
291 | struct wlr_surface *surface, struct wlr_box *box, float rotation, | 256 | struct wlr_surface *surface, struct wlr_box *box, float rotation, |
292 | void *_data) { | 257 | void *_data) { |
293 | struct send_frame_done_data *data = _data; | 258 | struct timespec *when = _data; |
294 | wlr_surface_send_frame_done(surface, data->when); | 259 | wlr_surface_send_frame_done(surface, when); |
295 | } | 260 | } |
296 | 261 | ||
297 | static void send_frame_done_layer(struct sway_output *output, | 262 | static void send_frame_done_layer(struct sway_output *output, |
298 | struct wl_list *layer_surfaces, struct send_frame_done_data *data) { | 263 | struct wl_list *layer_surfaces, struct timespec *when) { |
299 | output_layer_for_each_surface(output, layer_surfaces, | 264 | output_layer_for_each_surface(output, layer_surfaces, |
300 | send_frame_done_iterator2, data); | 265 | send_frame_done_iterator, when); |
301 | } | 266 | } |
302 | 267 | ||
303 | #ifdef HAVE_XWAYLAND | 268 | #ifdef HAVE_XWAYLAND |
304 | static void send_frame_done_unmanaged(struct send_frame_done_data *data, | 269 | static void send_frame_done_unmanaged(struct sway_output *output, |
305 | struct wl_list *unmanaged) { | 270 | struct wl_list *unmanaged, struct timespec *when) { |
306 | output_unmanaged_for_each_surface(data->output, unmanaged, | 271 | output_unmanaged_for_each_surface(output, unmanaged, |
307 | send_frame_done_iterator2, data); | 272 | send_frame_done_iterator, when); |
308 | } | 273 | } |
309 | #endif | 274 | #endif |
310 | 275 | ||
311 | static void send_frame_done_drag_icons(struct send_frame_done_data *data, | 276 | static void send_frame_done_drag_icons(struct sway_output *output, |
312 | struct wl_list *drag_icons) { | 277 | struct wl_list *drag_icons, struct timespec *when) { |
313 | output_drag_icons_for_each_surface(data->output, drag_icons, | 278 | output_drag_icons_for_each_surface(output, drag_icons, |
314 | send_frame_done_iterator2, data); | 279 | send_frame_done_iterator, when); |
315 | } | 280 | } |
316 | 281 | ||
282 | struct send_frame_done_data { | ||
283 | struct sway_output *output; | ||
284 | struct timespec *when; | ||
285 | }; | ||
286 | |||
317 | static void send_frame_done_container_iterator(struct sway_container *con, | 287 | static void send_frame_done_container_iterator(struct sway_container *con, |
318 | void *_data) { | 288 | void *_data) { |
319 | struct send_frame_done_data *data = _data; | 289 | struct send_frame_done_data *data = _data; |
@@ -326,21 +296,20 @@ static void send_frame_done_container_iterator(struct sway_container *con, | |||
326 | } | 296 | } |
327 | 297 | ||
328 | output_view_for_each_surface(data->output, con->sway_view, | 298 | output_view_for_each_surface(data->output, con->sway_view, |
329 | send_frame_done_iterator2, data); | 299 | send_frame_done_iterator, data->when); |
330 | } | ||
331 | |||
332 | static void send_frame_done_container(struct send_frame_done_data *data, | ||
333 | struct sway_container *con) { | ||
334 | container_descendants(con, C_VIEW, | ||
335 | send_frame_done_container_iterator, data); | ||
336 | } | 300 | } |
337 | 301 | ||
338 | static void send_frame_done(struct sway_output *output, struct timespec *when) { | 302 | static void send_frame_done_container(struct sway_output *output, |
303 | struct sway_container *con, struct timespec *when) { | ||
339 | struct send_frame_done_data data = { | 304 | struct send_frame_done_data data = { |
340 | .output = output, | 305 | .output = output, |
341 | .when = when, | 306 | .when = when, |
342 | }; | 307 | }; |
308 | container_descendants(con, C_VIEW, | ||
309 | send_frame_done_container_iterator, &data); | ||
310 | } | ||
343 | 311 | ||
312 | static void send_frame_done(struct sway_output *output, struct timespec *when) { | ||
344 | if (output_has_opaque_overlay_layer_surface(output)) { | 313 | if (output_has_opaque_overlay_layer_surface(output)) { |
345 | goto send_frame_overlay; | 314 | goto send_frame_overlay; |
346 | } | 315 | } |
@@ -349,35 +318,38 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { | |||
349 | if (workspace->current.ws_fullscreen) { | 318 | if (workspace->current.ws_fullscreen) { |
350 | if (workspace->current.ws_fullscreen->type == C_VIEW) { | 319 | if (workspace->current.ws_fullscreen->type == C_VIEW) { |
351 | send_frame_done_container_iterator( | 320 | send_frame_done_container_iterator( |
352 | workspace->current.ws_fullscreen, &data); | 321 | workspace->current.ws_fullscreen, when); |
353 | } else { | 322 | } else { |
354 | send_frame_done_container(&data, workspace->current.ws_fullscreen); | 323 | send_frame_done_container(output, workspace->current.ws_fullscreen, |
324 | when); | ||
355 | } | 325 | } |
356 | #ifdef HAVE_XWAYLAND | 326 | #ifdef HAVE_XWAYLAND |
357 | send_frame_done_unmanaged(&data, | 327 | send_frame_done_unmanaged(output, |
358 | &root_container.sway_root->xwayland_unmanaged); | 328 | &root_container.sway_root->xwayland_unmanaged, when); |
359 | #endif | 329 | #endif |
360 | } else { | 330 | } else { |
361 | send_frame_done_layer(output, | 331 | send_frame_done_layer(output, |
362 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &data); | 332 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], when); |
363 | send_frame_done_layer(output, | 333 | send_frame_done_layer(output, |
364 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &data); | 334 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when); |
365 | 335 | ||
366 | send_frame_done_container(&data, workspace); | 336 | send_frame_done_container(output, workspace, when); |
367 | send_frame_done_container(&data, workspace->sway_workspace->floating); | 337 | send_frame_done_container(output, workspace->sway_workspace->floating, |
338 | when); | ||
368 | 339 | ||
369 | #ifdef HAVE_XWAYLAND | 340 | #ifdef HAVE_XWAYLAND |
370 | send_frame_done_unmanaged(&data, | 341 | send_frame_done_unmanaged(output, |
371 | &root_container.sway_root->xwayland_unmanaged); | 342 | &root_container.sway_root->xwayland_unmanaged, when); |
372 | #endif | 343 | #endif |
373 | send_frame_done_layer(output, | 344 | send_frame_done_layer(output, |
374 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &data); | 345 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); |
375 | } | 346 | } |
376 | 347 | ||
377 | send_frame_overlay: | 348 | send_frame_overlay: |
378 | send_frame_done_layer(output, | 349 | send_frame_done_layer(output, |
379 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &data); | 350 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); |
380 | send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); | 351 | send_frame_done_drag_icons(output, &root_container.sway_root->drag_icons, |
352 | when); | ||
381 | } | 353 | } |
382 | 354 | ||
383 | static void damage_handle_frame(struct wl_listener *listener, void *data) { | 355 | static void damage_handle_frame(struct wl_listener *listener, void *data) { |
@@ -412,68 +384,11 @@ void output_damage_whole(struct sway_output *output) { | |||
412 | wlr_output_damage_add_whole(output->damage); | 384 | wlr_output_damage_add_whole(output->damage); |
413 | } | 385 | } |
414 | 386 | ||
415 | struct damage_data { | 387 | static void damage_surface_iterator(struct sway_output *output, |
416 | struct root_geometry root_geo; | ||
417 | struct sway_output *output; | ||
418 | bool whole; | ||
419 | }; | ||
420 | |||
421 | static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, | ||
422 | void *_data) { | ||
423 | struct damage_data *data = _data; | ||
424 | struct sway_output *output = data->output; | ||
425 | float rotation = data->root_geo.rotation; | ||
426 | bool whole = data->whole; | ||
427 | |||
428 | struct wlr_box box; | ||
429 | bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, | ||
430 | sx, sy, &box); | ||
431 | if (!intersects) { | ||
432 | return; | ||
433 | } | ||
434 | |||
435 | scale_box(&box, output->wlr_output->scale); | ||
436 | |||
437 | int center_x = box.x + box.width/2; | ||
438 | int center_y = box.y + box.height/2; | ||
439 | |||
440 | if (pixman_region32_not_empty(&surface->buffer_damage)) { | ||
441 | enum wl_output_transform transform = | ||
442 | wlr_output_transform_invert(surface->current.transform); | ||
443 | |||
444 | pixman_region32_t damage; | ||
445 | pixman_region32_init(&damage); | ||
446 | pixman_region32_copy(&damage, &surface->buffer_damage); | ||
447 | wlr_region_transform(&damage, &damage, transform, | ||
448 | surface->current.buffer_width, surface->current.buffer_height); | ||
449 | wlr_region_scale(&damage, &damage, | ||
450 | output->wlr_output->scale / (float)surface->current.scale); | ||
451 | if (ceil(output->wlr_output->scale) > surface->current.scale) { | ||
452 | // When scaling up a surface, it'll become blurry so we need to | ||
453 | // expand the damage region | ||
454 | wlr_region_expand(&damage, &damage, | ||
455 | ceil(output->wlr_output->scale) - surface->current.scale); | ||
456 | } | ||
457 | pixman_region32_translate(&damage, box.x, box.y); | ||
458 | wlr_region_rotated_bounds(&damage, &damage, rotation, | ||
459 | center_x, center_y); | ||
460 | wlr_output_damage_add(output->damage, &damage); | ||
461 | pixman_region32_fini(&damage); | ||
462 | } | ||
463 | |||
464 | if (whole) { | ||
465 | wlr_box_rotated_bounds(&box, rotation, &box); | ||
466 | wlr_output_damage_add_box(output->damage, &box); | ||
467 | } | ||
468 | |||
469 | wlr_output_schedule_frame(output->wlr_output); | ||
470 | } | ||
471 | |||
472 | static void damage_surface_iterator2(struct sway_output *output, | ||
473 | struct wlr_surface *surface, struct wlr_box *_box, float rotation, | 388 | struct wlr_surface *surface, struct wlr_box *_box, float rotation, |
474 | void *_data) { | 389 | void *_data) { |
475 | struct damage_data *data = _data; | 390 | bool *data = _data; |
476 | bool whole = data->whole; | 391 | bool whole = *data; |
477 | 392 | ||
478 | struct wlr_box box = *_box; | 393 | struct wlr_box box = *_box; |
479 | scale_box(&box, output->wlr_output->scale); | 394 | scale_box(&box, output->wlr_output->scale); |
@@ -515,13 +430,8 @@ static void damage_surface_iterator2(struct sway_output *output, | |||
515 | 430 | ||
516 | void output_damage_surface(struct sway_output *output, double ox, double oy, | 431 | void output_damage_surface(struct sway_output *output, double ox, double oy, |
517 | struct wlr_surface *surface, bool whole) { | 432 | struct wlr_surface *surface, bool whole) { |
518 | struct damage_data data = { | 433 | output_surface_for_each_surface(output, surface, ox, oy, 0, |
519 | .output = output, | 434 | damage_surface_iterator, &whole); |
520 | .whole = whole, | ||
521 | }; | ||
522 | |||
523 | output_surface_for_each_surface(surface, ox, oy, &data.root_geo, | ||
524 | damage_surface_iterator, &data); | ||
525 | } | 435 | } |
526 | 436 | ||
527 | static void output_damage_view(struct sway_output *output, | 437 | static void output_damage_view(struct sway_output *output, |
@@ -534,12 +444,7 @@ static void output_damage_view(struct sway_output *output, | |||
534 | return; | 444 | return; |
535 | } | 445 | } |
536 | 446 | ||
537 | struct damage_data data = { | 447 | output_view_for_each_surface(output, view, damage_surface_iterator, &whole); |
538 | .output = output, | ||
539 | .whole = whole, | ||
540 | }; | ||
541 | |||
542 | output_view_for_each_surface(output, view, damage_surface_iterator2, &data); | ||
543 | } | 448 | } |
544 | 449 | ||
545 | void output_damage_from_view(struct sway_output *output, | 450 | void output_damage_from_view(struct sway_output *output, |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 18d076df..f25055b8 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -29,10 +29,7 @@ | |||
29 | #include "sway/tree/workspace.h" | 29 | #include "sway/tree/workspace.h" |
30 | 30 | ||
31 | struct render_data { | 31 | struct render_data { |
32 | struct root_geometry root_geo; | ||
33 | struct sway_output *output; | ||
34 | pixman_region32_t *damage; | 32 | pixman_region32_t *damage; |
35 | struct sway_view *view; | ||
36 | float alpha; | 33 | float alpha; |
37 | }; | 34 | }; |
38 | 35 | ||
@@ -92,38 +89,7 @@ damage_finish: | |||
92 | pixman_region32_fini(&damage); | 89 | pixman_region32_fini(&damage); |
93 | } | 90 | } |
94 | 91 | ||
95 | static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, | 92 | static void render_surface_iterator(struct sway_output *output, |
96 | void *_data) { | ||
97 | struct render_data *data = _data; | ||
98 | struct wlr_output *wlr_output = data->output->wlr_output; | ||
99 | float rotation = data->root_geo.rotation; | ||
100 | pixman_region32_t *output_damage = data->damage; | ||
101 | float alpha = data->alpha; | ||
102 | |||
103 | struct wlr_texture *texture = wlr_surface_get_texture(surface); | ||
104 | if (!texture) { | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | struct wlr_box box; | ||
109 | bool intersects = output_get_surface_box(&data->root_geo, data->output, | ||
110 | surface, sx, sy, &box); | ||
111 | if (!intersects) { | ||
112 | return; | ||
113 | } | ||
114 | |||
115 | scale_box(&box, wlr_output->scale); | ||
116 | |||
117 | float matrix[9]; | ||
118 | enum wl_output_transform transform = | ||
119 | wlr_output_transform_invert(surface->current.transform); | ||
120 | wlr_matrix_project_box(matrix, &box, transform, rotation, | ||
121 | wlr_output->transform_matrix); | ||
122 | |||
123 | render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); | ||
124 | } | ||
125 | |||
126 | static void render_surface_iterator2(struct sway_output *output, | ||
127 | struct wlr_surface *surface, struct wlr_box *_box, float rotation, | 93 | struct wlr_surface *surface, struct wlr_box *_box, float rotation, |
128 | void *_data) { | 94 | void *_data) { |
129 | struct render_data *data = _data; | 95 | struct render_data *data = _data; |
@@ -151,36 +117,33 @@ static void render_surface_iterator2(struct sway_output *output, | |||
151 | static void render_layer(struct sway_output *output, | 117 | static void render_layer(struct sway_output *output, |
152 | pixman_region32_t *damage, struct wl_list *layer_surfaces) { | 118 | pixman_region32_t *damage, struct wl_list *layer_surfaces) { |
153 | struct render_data data = { | 119 | struct render_data data = { |
154 | .output = output, | ||
155 | .damage = damage, | 120 | .damage = damage, |
156 | .alpha = 1.0f, | 121 | .alpha = 1.0f, |
157 | }; | 122 | }; |
158 | output_layer_for_each_surface(output, layer_surfaces, | 123 | output_layer_for_each_surface(output, layer_surfaces, |
159 | render_surface_iterator2, &data); | 124 | render_surface_iterator, &data); |
160 | } | 125 | } |
161 | 126 | ||
162 | #ifdef HAVE_XWAYLAND | 127 | #ifdef HAVE_XWAYLAND |
163 | static void render_unmanaged(struct sway_output *output, | 128 | static void render_unmanaged(struct sway_output *output, |
164 | pixman_region32_t *damage, struct wl_list *unmanaged) { | 129 | pixman_region32_t *damage, struct wl_list *unmanaged) { |
165 | struct render_data data = { | 130 | struct render_data data = { |
166 | .output = output, | ||
167 | .damage = damage, | 131 | .damage = damage, |
168 | .alpha = 1.0f, | 132 | .alpha = 1.0f, |
169 | }; | 133 | }; |
170 | output_unmanaged_for_each_surface(output, unmanaged, | 134 | output_unmanaged_for_each_surface(output, unmanaged, |
171 | render_surface_iterator2, &data); | 135 | render_surface_iterator, &data); |
172 | } | 136 | } |
173 | #endif | 137 | #endif |
174 | 138 | ||
175 | static void render_drag_icons(struct sway_output *output, | 139 | static void render_drag_icons(struct sway_output *output, |
176 | pixman_region32_t *damage, struct wl_list *drag_icons) { | 140 | pixman_region32_t *damage, struct wl_list *drag_icons) { |
177 | struct render_data data = { | 141 | struct render_data data = { |
178 | .output = output, | ||
179 | .damage = damage, | 142 | .damage = damage, |
180 | .alpha = 1.0f, | 143 | .alpha = 1.0f, |
181 | }; | 144 | }; |
182 | output_drag_icons_for_each_surface(output, drag_icons, | 145 | output_drag_icons_for_each_surface(output, drag_icons, |
183 | render_surface_iterator2, &data); | 146 | render_surface_iterator, &data); |
184 | } | 147 | } |
185 | 148 | ||
186 | static void render_rect(struct wlr_output *wlr_output, | 149 | static void render_rect(struct wlr_output *wlr_output, |
@@ -226,12 +189,10 @@ static void premultiply_alpha(float color[4], float opacity) { | |||
226 | static void render_view_surfaces(struct sway_view *view, | 189 | static void render_view_surfaces(struct sway_view *view, |
227 | struct sway_output *output, pixman_region32_t *damage, float alpha) { | 190 | struct sway_output *output, pixman_region32_t *damage, float alpha) { |
228 | struct render_data data = { | 191 | struct render_data data = { |
229 | .output = output, | ||
230 | .damage = damage, | 192 | .damage = damage, |
231 | .view = view, | ||
232 | .alpha = alpha, | 193 | .alpha = alpha, |
233 | }; | 194 | }; |
234 | output_view_for_each_surface(output, view, render_surface_iterator2, &data); | 195 | output_view_for_each_surface(output, view, render_surface_iterator, &data); |
235 | } | 196 | } |
236 | 197 | ||
237 | static void render_saved_view(struct sway_view *view, | 198 | static void render_saved_view(struct sway_view *view, |