aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Alexander Orzechowski <alex@ozal.ski>2023-04-27 11:19:58 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2023-05-02 18:31:55 +0200
commitd5cc474aef6bf5a23694053ab9c8770ea3f21e6f (patch)
tree9bead7ab099de9675204d82ae397746cec232ff8
parentxdg_shell: Fix crash if popup generates while toplevel is in the scratchpad (diff)
downloadsway-d5cc474aef6bf5a23694053ab9c8770ea3f21e6f.tar.gz
sway-d5cc474aef6bf5a23694053ab9c8770ea3f21e6f.tar.zst
sway-d5cc474aef6bf5a23694053ab9c8770ea3f21e6f.zip
render: pass rendering state together in a struct
This lets us easily add rendering state that we need in the future
-rw-r--r--include/sway/input/seat.h7
-rw-r--r--include/sway/output.h11
-rw-r--r--sway/desktop/output.c14
-rw-r--r--sway/desktop/render.c269
-rw-r--r--sway/input/seat.c5
-rw-r--r--sway/input/seatop_move_tiling.c9
6 files changed, 156 insertions, 159 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index 7b2d3d07..6d29cf3b 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -12,6 +12,7 @@
12#include "sway/input/text_input.h" 12#include "sway/input/text_input.h"
13 13
14struct sway_seat; 14struct sway_seat;
15struct render_context;
15 16
16struct sway_seatop_impl { 17struct sway_seatop_impl {
17 void (*button)(struct sway_seat *seat, uint32_t time_msec, 18 void (*button)(struct sway_seat *seat, uint32_t time_msec,
@@ -49,8 +50,7 @@ struct sway_seatop_impl {
49 uint32_t time_msec, enum wlr_tablet_tool_tip_state state); 50 uint32_t time_msec, enum wlr_tablet_tool_tip_state state);
50 void (*end)(struct sway_seat *seat); 51 void (*end)(struct sway_seat *seat);
51 void (*unref)(struct sway_seat *seat, struct sway_container *con); 52 void (*unref)(struct sway_seat *seat, struct sway_container *con);
52 void (*render)(struct sway_seat *seat, struct sway_output *output, 53 void (*render)(struct sway_seat *seat, struct render_context *ctx);
53 const pixman_region32_t *damage);
54 bool allow_set_cursor; 54 bool allow_set_cursor;
55}; 55};
56 56
@@ -356,8 +356,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con);
356 * Instructs a seatop to render anything that it needs to render 356 * Instructs a seatop to render anything that it needs to render
357 * (eg. dropzone for move-tiling) 357 * (eg. dropzone for move-tiling)
358 */ 358 */
359void seatop_render(struct sway_seat *seat, struct sway_output *output, 359void seatop_render(struct sway_seat *seat, struct render_context *ctx);
360 const pixman_region32_t *damage);
361 360
362bool seatop_allows_set_cursor(struct sway_seat *seat); 361bool seatop_allows_set_cursor(struct sway_seat *seat);
363 362
diff --git a/include/sway/output.h b/include/sway/output.h
index 04202976..b397c8e2 100644
--- a/include/sway/output.h
+++ b/include/sway/output.h
@@ -65,6 +65,12 @@ struct sway_output_non_desktop {
65 struct wl_listener destroy; 65 struct wl_listener destroy;
66}; 66};
67 67
68struct render_context {
69 struct sway_output *output;
70 struct wlr_renderer *renderer;
71 const pixman_region32_t *output_damage;
72};
73
68struct sway_output *output_create(struct wlr_output *wlr_output); 74struct sway_output *output_create(struct wlr_output *wlr_output);
69 75
70void output_destroy(struct sway_output *output); 76void output_destroy(struct sway_output *output);
@@ -115,7 +121,7 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output);
115 121
116struct sway_workspace *output_get_active_workspace(struct sway_output *output); 122struct sway_workspace *output_get_active_workspace(struct sway_output *output);
117 123
118void output_render(struct sway_output *output, pixman_region32_t *damage); 124void output_render(struct render_context *ctx);
119 125
120void output_surface_for_each_surface(struct sway_output *output, 126void output_surface_for_each_surface(struct sway_output *output,
121 struct wlr_surface *surface, double ox, double oy, 127 struct wlr_surface *surface, double ox, double oy,
@@ -168,8 +174,7 @@ void output_get_box(struct sway_output *output, struct wlr_box *box);
168enum sway_container_layout output_get_default_layout( 174enum sway_container_layout output_get_default_layout(
169 struct sway_output *output); 175 struct sway_output *output);
170 176
171void render_rect(struct sway_output *output, 177void render_rect(struct render_context *ctx, const struct wlr_box *_box,
172 const pixman_region32_t *output_damage, const struct wlr_box *_box,
173 float color[static 4]); 178 float color[static 4]);
174 179
175void premultiply_alpha(float color[4], float opacity); 180void premultiply_alpha(float color[4], float opacity);
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 2255b551..02e08bd2 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -613,10 +613,22 @@ static int output_repaint_timer_handler(void *data) {
613 pixman_region32_init(&damage); 613 pixman_region32_init(&damage);
614 wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage); 614 wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage);
615 615
616 if (debug.damage == DAMAGE_RERENDER) {
617 int width, height;
618 wlr_output_transformed_resolution(wlr_output, &width, &height);
619 pixman_region32_union_rect(&damage, &damage, 0, 0, width, height);
620 }
621
622 struct render_context ctx = {
623 .output_damage = &damage,
624 .renderer = wlr_output->renderer,
625 .output = output,
626 };
627
616 struct timespec now; 628 struct timespec now;
617 clock_gettime(CLOCK_MONOTONIC, &now); 629 clock_gettime(CLOCK_MONOTONIC, &now);
618 630
619 output_render(output, &damage); 631 output_render(&ctx);
620 632
621 pixman_region32_fini(&damage); 633 pixman_region32_fini(&damage);
622 634
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index a4d633e0..f011e0ff 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -32,6 +32,7 @@
32#endif 32#endif
33 33
34struct render_data { 34struct render_data {
35 struct render_context *ctx;
35 const pixman_region32_t *damage; 36 const pixman_region32_t *damage;
36 float alpha; 37 float alpha;
37 struct wlr_box *clip_box; 38 struct wlr_box *clip_box;
@@ -101,18 +102,17 @@ static void set_scale_filter(struct wlr_output *wlr_output,
101#endif 102#endif
102} 103}
103 104
104static void render_texture(struct wlr_output *wlr_output, 105static void render_texture(struct render_context *ctx, struct wlr_texture *texture,
105 const pixman_region32_t *output_damage, struct wlr_texture *texture,
106 const struct wlr_fbox *src_box, const struct wlr_box *dst_box, 106 const struct wlr_fbox *src_box, const struct wlr_box *dst_box,
107 const float matrix[static 9], float alpha) { 107 const float matrix[static 9], float alpha) {
108 struct wlr_renderer *renderer = wlr_output->renderer; 108 struct wlr_renderer *renderer = ctx->renderer;
109 struct sway_output *output = wlr_output->data; 109 struct sway_output *output = ctx->output;
110 110
111 pixman_region32_t damage; 111 pixman_region32_t damage;
112 pixman_region32_init(&damage); 112 pixman_region32_init(&damage);
113 pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y, 113 pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y,
114 dst_box->width, dst_box->height); 114 dst_box->width, dst_box->height);
115 pixman_region32_intersect(&damage, &damage, output_damage); 115 pixman_region32_intersect(&damage, &damage, ctx->output_damage);
116 bool damaged = pixman_region32_not_empty(&damage); 116 bool damaged = pixman_region32_not_empty(&damage);
117 if (!damaged) { 117 if (!damaged) {
118 goto damage_finish; 118 goto damage_finish;
@@ -121,8 +121,8 @@ static void render_texture(struct wlr_output *wlr_output,
121 int nrects; 121 int nrects;
122 pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); 122 pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
123 for (int i = 0; i < nrects; ++i) { 123 for (int i = 0; i < nrects; ++i) {
124 scissor_output(wlr_output, &rects[i]); 124 scissor_output(output->wlr_output, &rects[i]);
125 set_scale_filter(wlr_output, texture, output->scale_filter); 125 set_scale_filter(output->wlr_output, texture, output->scale_filter);
126 if (src_box != NULL) { 126 if (src_box != NULL) {
127 wlr_render_subtexture_with_matrix(renderer, texture, src_box, matrix, alpha); 127 wlr_render_subtexture_with_matrix(renderer, texture, src_box, matrix, alpha);
128 } else { 128 } else {
@@ -139,7 +139,6 @@ static void render_surface_iterator(struct sway_output *output,
139 struct wlr_box *_box, void *_data) { 139 struct wlr_box *_box, void *_data) {
140 struct render_data *data = _data; 140 struct render_data *data = _data;
141 struct wlr_output *wlr_output = output->wlr_output; 141 struct wlr_output *wlr_output = output->wlr_output;
142 const pixman_region32_t *output_damage = data->damage;
143 float alpha = data->alpha; 142 float alpha = data->alpha;
144 143
145 struct wlr_texture *texture = wlr_surface_get_texture(surface); 144 struct wlr_texture *texture = wlr_surface_get_texture(surface);
@@ -167,73 +166,68 @@ static void render_surface_iterator(struct sway_output *output,
167 } 166 }
168 scale_box(&dst_box, wlr_output->scale); 167 scale_box(&dst_box, wlr_output->scale);
169 168
170 render_texture(wlr_output, output_damage, texture, 169 render_texture(data->ctx, texture,
171 &src_box, &dst_box, matrix, alpha); 170 &src_box, &dst_box, matrix, alpha);
172 171
173 wlr_presentation_surface_sampled_on_output(server.presentation, surface, 172 wlr_presentation_surface_sampled_on_output(server.presentation, surface,
174 wlr_output); 173 wlr_output);
175} 174}
176 175
177static void render_layer_toplevel(struct sway_output *output, 176static void render_layer_toplevel(struct render_context *ctx, struct wl_list *layer_surfaces) {
178 const pixman_region32_t *damage, struct wl_list *layer_surfaces) {
179 struct render_data data = { 177 struct render_data data = {
180 .damage = damage,
181 .alpha = 1.0f, 178 .alpha = 1.0f,
179 .ctx = ctx,
182 }; 180 };
183 output_layer_for_each_toplevel_surface(output, layer_surfaces, 181 output_layer_for_each_toplevel_surface(ctx->output, layer_surfaces,
184 render_surface_iterator, &data); 182 render_surface_iterator, &data);
185} 183}
186 184
187static void render_layer_popups(struct sway_output *output, 185static void render_layer_popups(struct render_context *ctx, struct wl_list *layer_surfaces) {
188 const pixman_region32_t *damage, struct wl_list *layer_surfaces) {
189 struct render_data data = { 186 struct render_data data = {
190 .damage = damage,
191 .alpha = 1.0f, 187 .alpha = 1.0f,
188 .ctx = ctx,
192 }; 189 };
193 output_layer_for_each_popup_surface(output, layer_surfaces, 190 output_layer_for_each_popup_surface(ctx->output, layer_surfaces,
194 render_surface_iterator, &data); 191 render_surface_iterator, &data);
195} 192}
196 193
197#if HAVE_XWAYLAND 194#if HAVE_XWAYLAND
198static void render_unmanaged(struct sway_output *output, 195static void render_unmanaged(struct render_context *ctx, struct wl_list *unmanaged) {
199 const pixman_region32_t *damage, struct wl_list *unmanaged) {
200 struct render_data data = { 196 struct render_data data = {
201 .damage = damage,
202 .alpha = 1.0f, 197 .alpha = 1.0f,
198 .ctx = ctx,
203 }; 199 };
204 output_unmanaged_for_each_surface(output, unmanaged, 200 output_unmanaged_for_each_surface(ctx->output, unmanaged,
205 render_surface_iterator, &data); 201 render_surface_iterator, &data);
206} 202}
207#endif 203#endif
208 204
209static void render_drag_icons(struct sway_output *output, 205static void render_drag_icons(struct render_context *ctx, struct wl_list *drag_icons) {
210 const pixman_region32_t *damage, struct wl_list *drag_icons) {
211 struct render_data data = { 206 struct render_data data = {
212 .damage = damage,
213 .alpha = 1.0f, 207 .alpha = 1.0f,
208 .ctx = ctx,
214 }; 209 };
215 output_drag_icons_for_each_surface(output, drag_icons, 210 output_drag_icons_for_each_surface(ctx->output, drag_icons,
216 render_surface_iterator, &data); 211 render_surface_iterator, &data);
217} 212}
218 213
219// _box.x and .y are expected to be layout-local 214// _box.x and .y are expected to be layout-local
220// _box.width and .height are expected to be output-buffer-local 215// _box.width and .height are expected to be output-buffer-local
221void render_rect(struct sway_output *output, 216void render_rect(struct render_context *ctx, const struct wlr_box *_box,
222 const pixman_region32_t *output_damage, const struct wlr_box *_box,
223 float color[static 4]) { 217 float color[static 4]) {
224 struct wlr_output *wlr_output = output->wlr_output; 218 struct wlr_output *wlr_output = ctx->output->wlr_output;
225 struct wlr_renderer *renderer = wlr_output->renderer; 219 struct wlr_renderer *renderer = ctx->renderer;
226 220
227 struct wlr_box box; 221 struct wlr_box box;
228 memcpy(&box, _box, sizeof(struct wlr_box)); 222 memcpy(&box, _box, sizeof(struct wlr_box));
229 box.x -= output->lx * wlr_output->scale; 223 box.x -= ctx->output->lx * wlr_output->scale;
230 box.y -= output->ly * wlr_output->scale; 224 box.y -= ctx->output->ly * wlr_output->scale;
231 225
232 pixman_region32_t damage; 226 pixman_region32_t damage;
233 pixman_region32_init(&damage); 227 pixman_region32_init(&damage);
234 pixman_region32_union_rect(&damage, &damage, box.x, box.y, 228 pixman_region32_union_rect(&damage, &damage, box.x, box.y,
235 box.width, box.height); 229 box.width, box.height);
236 pixman_region32_intersect(&damage, &damage, output_damage); 230 pixman_region32_intersect(&damage, &damage, ctx->output_damage);
237 bool damaged = pixman_region32_not_empty(&damage); 231 bool damaged = pixman_region32_not_empty(&damage);
238 if (!damaged) { 232 if (!damaged) {
239 goto damage_finish; 233 goto damage_finish;
@@ -258,11 +252,11 @@ void premultiply_alpha(float color[4], float opacity) {
258 color[2] *= color[3]; 252 color[2] *= color[3];
259} 253}
260 254
261static void render_view_toplevels(struct sway_view *view, 255static void render_view_toplevels(struct render_context *ctx,
262 struct sway_output *output, const pixman_region32_t *damage, float alpha) { 256 struct sway_view *view, float alpha) {
263 struct render_data data = { 257 struct render_data data = {
264 .damage = damage,
265 .alpha = alpha, 258 .alpha = alpha,
259 .ctx = ctx,
266 }; 260 };
267 struct wlr_box clip_box; 261 struct wlr_box clip_box;
268 if (!container_is_current_floating(view->container)) { 262 if (!container_is_current_floating(view->container)) {
@@ -274,25 +268,26 @@ static void render_view_toplevels(struct sway_view *view,
274 } 268 }
275 // Render all toplevels without descending into popups 269 // Render all toplevels without descending into popups
276 double ox = view->container->surface_x - 270 double ox = view->container->surface_x -
277 output->lx - view->geometry.x; 271 ctx->output->lx - view->geometry.x;
278 double oy = view->container->surface_y - 272 double oy = view->container->surface_y -
279 output->ly - view->geometry.y; 273 ctx->output->ly - view->geometry.y;
280 output_surface_for_each_surface(output, view->surface, ox, oy, 274 output_surface_for_each_surface(ctx->output, view->surface, ox, oy,
281 render_surface_iterator, &data); 275 render_surface_iterator, &data);
282} 276}
283 277
284static void render_view_popups(struct sway_view *view, 278static void render_view_popups(struct render_context *ctx, struct sway_view *view,
285 struct sway_output *output, const pixman_region32_t *damage, float alpha) { 279 float alpha) {
286 struct render_data data = { 280 struct render_data data = {
287 .damage = damage,
288 .alpha = alpha, 281 .alpha = alpha,
282 .ctx = ctx,
289 }; 283 };
290 output_view_for_each_popup_surface(output, view, 284 output_view_for_each_popup_surface(ctx->output, view,
291 render_surface_iterator, &data); 285 render_surface_iterator, &data);
292} 286}
293 287
294static void render_saved_view(struct sway_view *view, 288static void render_saved_view(struct render_context *ctx, struct sway_view *view,
295 struct sway_output *output, const pixman_region32_t *damage, float alpha) { 289 float alpha) {
290 struct sway_output *output = ctx->output;
296 struct wlr_output *wlr_output = output->wlr_output; 291 struct wlr_output *wlr_output = output->wlr_output;
297 292
298 if (wl_list_empty(&view->saved_buffers)) { 293 if (wl_list_empty(&view->saved_buffers)) {
@@ -343,7 +338,7 @@ static void render_saved_view(struct sway_view *view,
343 } 338 }
344 scale_box(&dst_box, wlr_output->scale); 339 scale_box(&dst_box, wlr_output->scale);
345 340
346 render_texture(wlr_output, damage, saved_buf->buffer->texture, 341 render_texture(ctx, saved_buf->buffer->texture,
347 &saved_buf->source_box, &dst_box, matrix, alpha); 342 &saved_buf->source_box, &dst_box, matrix, alpha);
348 } 343 }
349 344
@@ -355,13 +350,13 @@ static void render_saved_view(struct sway_view *view,
355/** 350/**
356 * Render a view's surface and left/bottom/right borders. 351 * Render a view's surface and left/bottom/right borders.
357 */ 352 */
358static void render_view(struct sway_output *output, const pixman_region32_t *damage, 353static void render_view(struct render_context *ctx,
359 struct sway_container *con, struct border_colors *colors) { 354 struct sway_container *con, struct border_colors *colors) {
360 struct sway_view *view = con->view; 355 struct sway_view *view = con->view;
361 if (!wl_list_empty(&view->saved_buffers)) { 356 if (!wl_list_empty(&view->saved_buffers)) {
362 render_saved_view(view, output, damage, view->container->alpha); 357 render_saved_view(ctx, view, view->container->alpha);
363 } else if (view->surface) { 358 } else if (view->surface) {
364 render_view_toplevels(view, output, damage, view->container->alpha); 359 render_view_toplevels(ctx, view, view->container->alpha);
365 } 360 }
366 361
367 if (con->current.border == B_NONE || con->current.border == B_CSD) { 362 if (con->current.border == B_NONE || con->current.border == B_CSD) {
@@ -369,7 +364,7 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
369 } 364 }
370 365
371 struct wlr_box box; 366 struct wlr_box box;
372 float output_scale = output->wlr_output->scale; 367 float output_scale = ctx->output->wlr_output->scale;
373 float color[4]; 368 float color[4];
374 struct sway_container_state *state = &con->current; 369 struct sway_container_state *state = &con->current;
375 370
@@ -381,7 +376,7 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
381 box.width = state->border_thickness; 376 box.width = state->border_thickness;
382 box.height = state->content_height; 377 box.height = state->content_height;
383 scale_box(&box, output_scale); 378 scale_box(&box, output_scale);
384 render_rect(output, damage, &box, color); 379 render_rect(ctx, &box, color);
385 } 380 }
386 381
387 list_t *siblings = container_get_current_siblings(con); 382 list_t *siblings = container_get_current_siblings(con);
@@ -400,7 +395,7 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
400 box.width = state->border_thickness; 395 box.width = state->border_thickness;
401 box.height = state->content_height; 396 box.height = state->content_height;
402 scale_box(&box, output_scale); 397 scale_box(&box, output_scale);
403 render_rect(output, damage, &box, color); 398 render_rect(ctx, &box, color);
404 } 399 }
405 400
406 if (state->border_bottom) { 401 if (state->border_bottom) {
@@ -415,7 +410,7 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
415 box.width = state->width; 410 box.width = state->width;
416 box.height = state->border_thickness; 411 box.height = state->border_thickness;
417 scale_box(&box, output_scale); 412 scale_box(&box, output_scale);
418 render_rect(output, damage, &box, color); 413 render_rect(ctx, &box, color);
419 } 414 }
420} 415}
421 416
@@ -428,13 +423,13 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
428 * The height is: 1px border, 3px padding, font height, 3px padding, 1px border 423 * The height is: 1px border, 3px padding, font height, 3px padding, 1px border
429 * The left side is: 1px border, 2px padding, title 424 * The left side is: 1px border, 2px padding, title
430 */ 425 */
431static void render_titlebar(struct sway_output *output, 426static void render_titlebar(struct render_context *ctx, struct sway_container *con,
432 const pixman_region32_t *output_damage, struct sway_container *con,
433 int x, int y, int width, 427 int x, int y, int width,
434 struct border_colors *colors, struct wlr_texture *title_texture, 428 struct border_colors *colors, struct wlr_texture *title_texture,
435 struct wlr_texture *marks_texture) { 429 struct wlr_texture *marks_texture) {
436 struct wlr_box box; 430 struct wlr_box box;
437 float color[4]; 431 float color[4];
432 struct sway_output *output = ctx->output;
438 float output_scale = output->wlr_output->scale; 433 float output_scale = output->wlr_output->scale;
439 double output_x = output->lx; 434 double output_x = output->lx;
440 double output_y = output->ly; 435 double output_y = output->ly;
@@ -451,7 +446,7 @@ static void render_titlebar(struct sway_output *output,
451 box.width = width; 446 box.width = width;
452 box.height = titlebar_border_thickness; 447 box.height = titlebar_border_thickness;
453 scale_box(&box, output_scale); 448 scale_box(&box, output_scale);
454 render_rect(output, output_damage, &box, color); 449 render_rect(ctx, &box, color);
455 450
456 // Single pixel bar below title 451 // Single pixel bar below title
457 box.x = x; 452 box.x = x;
@@ -459,7 +454,7 @@ static void render_titlebar(struct sway_output *output,
459 box.width = width; 454 box.width = width;
460 box.height = titlebar_border_thickness; 455 box.height = titlebar_border_thickness;
461 scale_box(&box, output_scale); 456 scale_box(&box, output_scale);
462 render_rect(output, output_damage, &box, color); 457 render_rect(ctx, &box, color);
463 458
464 // Single pixel left edge 459 // Single pixel left edge
465 box.x = x; 460 box.x = x;
@@ -467,7 +462,7 @@ static void render_titlebar(struct sway_output *output,
467 box.width = titlebar_border_thickness; 462 box.width = titlebar_border_thickness;
468 box.height = container_titlebar_height() - titlebar_border_thickness * 2; 463 box.height = container_titlebar_height() - titlebar_border_thickness * 2;
469 scale_box(&box, output_scale); 464 scale_box(&box, output_scale);
470 render_rect(output, output_damage, &box, color); 465 render_rect(ctx, &box, color);
471 466
472 // Single pixel right edge 467 // Single pixel right edge
473 box.x = x + width - titlebar_border_thickness; 468 box.x = x + width - titlebar_border_thickness;
@@ -475,7 +470,7 @@ static void render_titlebar(struct sway_output *output,
475 box.width = titlebar_border_thickness; 470 box.width = titlebar_border_thickness;
476 box.height = container_titlebar_height() - titlebar_border_thickness * 2; 471 box.height = container_titlebar_height() - titlebar_border_thickness * 2;
477 scale_box(&box, output_scale); 472 scale_box(&box, output_scale);
478 render_rect(output, output_damage, &box, color); 473 render_rect(ctx, &box, color);
479 474
480 int inner_x = x - output_x + titlebar_h_padding; 475 int inner_x = x - output_x + titlebar_h_padding;
481 int bg_y = y + titlebar_border_thickness; 476 int bg_y = y + titlebar_border_thickness;
@@ -524,7 +519,7 @@ static void render_titlebar(struct sway_output *output,
524 if (ob_inner_width < texture_box.width) { 519 if (ob_inner_width < texture_box.width) {
525 texture_box.width = ob_inner_width; 520 texture_box.width = ob_inner_width;
526 } 521 }
527 render_texture(output->wlr_output, output_damage, marks_texture, 522 render_texture(ctx, marks_texture,
528 NULL, &texture_box, matrix, con->alpha); 523 NULL, &texture_box, matrix, con->alpha);
529 524
530 // Padding above 525 // Padding above
@@ -534,12 +529,12 @@ static void render_titlebar(struct sway_output *output,
534 box.y = roundf((y + titlebar_border_thickness) * output_scale); 529 box.y = roundf((y + titlebar_border_thickness) * output_scale);
535 box.width = texture_box.width; 530 box.width = texture_box.width;
536 box.height = ob_padding_above; 531 box.height = ob_padding_above;
537 render_rect(output, output_damage, &box, color); 532 render_rect(ctx, &box, color);
538 533
539 // Padding below 534 // Padding below
540 box.y += ob_padding_above + texture_box.height; 535 box.y += ob_padding_above + texture_box.height;
541 box.height = ob_padding_below; 536 box.height = ob_padding_below;
542 render_rect(output, output_damage, &box, color); 537 render_rect(ctx, &box, color);
543 } 538 }
544 539
545 // Title text 540 // Title text
@@ -600,7 +595,7 @@ static void render_titlebar(struct sway_output *output,
600 texture_box.width = ob_inner_width - ob_marks_width; 595 texture_box.width = ob_inner_width - ob_marks_width;
601 } 596 }
602 597
603 render_texture(output->wlr_output, output_damage, title_texture, 598 render_texture(ctx, title_texture,
604 NULL, &texture_box, matrix, con->alpha); 599 NULL, &texture_box, matrix, con->alpha);
605 600
606 // Padding above 601 // Padding above
@@ -610,12 +605,12 @@ static void render_titlebar(struct sway_output *output,
610 box.y = roundf((y + titlebar_border_thickness) * output_scale); 605 box.y = roundf((y + titlebar_border_thickness) * output_scale);
611 box.width = texture_box.width; 606 box.width = texture_box.width;
612 box.height = ob_padding_above; 607 box.height = ob_padding_above;
613 render_rect(output, output_damage, &box, color); 608 render_rect(ctx, &box, color);
614 609
615 // Padding below 610 // Padding below
616 box.y += ob_padding_above + texture_box.height; 611 box.y += ob_padding_above + texture_box.height;
617 box.height = ob_padding_below; 612 box.height = ob_padding_below;
618 render_rect(output, output_damage, &box, color); 613 render_rect(ctx, &box, color);
619 } 614 }
620 615
621 // Determine the left + right extends of the textures (output-buffer local) 616 // Determine the left + right extends of the textures (output-buffer local)
@@ -649,7 +644,7 @@ static void render_titlebar(struct sway_output *output,
649 box.x = ob_left_x + ob_left_width + round(output_x * output_scale); 644 box.x = ob_left_x + ob_left_width + round(output_x * output_scale);
650 box.y = roundf(bg_y * output_scale); 645 box.y = roundf(bg_y * output_scale);
651 box.height = ob_bg_height; 646 box.height = ob_bg_height;
652 render_rect(output, output_damage, &box, color); 647 render_rect(ctx, &box, color);
653 } 648 }
654 649
655 // Padding on left side 650 // Padding on left side
@@ -663,7 +658,7 @@ static void render_titlebar(struct sway_output *output,
663 if (box.x + box.width < left_x) { 658 if (box.x + box.width < left_x) {
664 box.width += left_x - box.x - box.width; 659 box.width += left_x - box.x - box.width;
665 } 660 }
666 render_rect(output, output_damage, &box, color); 661 render_rect(ctx, &box, color);
667 662
668 // Padding on right side 663 // Padding on right side
669 box.x = x + width - titlebar_h_padding; 664 box.x = x + width - titlebar_h_padding;
@@ -677,14 +672,13 @@ static void render_titlebar(struct sway_output *output,
677 box.width += box.x - right_rx; 672 box.width += box.x - right_rx;
678 box.x = right_rx; 673 box.x = right_rx;
679 } 674 }
680 render_rect(output, output_damage, &box, color); 675 render_rect(ctx, &box, color);
681} 676}
682 677
683/** 678/**
684 * Render the top border line for a view using "border pixel". 679 * Render the top border line for a view using "border pixel".
685 */ 680 */
686static void render_top_border(struct sway_output *output, 681static void render_top_border(struct render_context *ctx, struct sway_container *con,
687 const pixman_region32_t *output_damage, struct sway_container *con,
688 struct border_colors *colors) { 682 struct border_colors *colors) {
689 struct sway_container_state *state = &con->current; 683 struct sway_container_state *state = &con->current;
690 if (!state->border_top) { 684 if (!state->border_top) {
@@ -692,7 +686,7 @@ static void render_top_border(struct sway_output *output,
692 } 686 }
693 struct wlr_box box; 687 struct wlr_box box;
694 float color[4]; 688 float color[4];
695 float output_scale = output->wlr_output->scale; 689 float output_scale = ctx->output->wlr_output->scale;
696 690
697 // Child border - top edge 691 // Child border - top edge
698 memcpy(&color, colors->child_border, sizeof(float) * 4); 692 memcpy(&color, colors->child_border, sizeof(float) * 4);
@@ -702,7 +696,7 @@ static void render_top_border(struct sway_output *output,
702 box.width = state->width; 696 box.width = state->width;
703 box.height = state->border_thickness; 697 box.height = state->border_thickness;
704 scale_box(&box, output_scale); 698 scale_box(&box, output_scale);
705 render_rect(output, output_damage, &box, color); 699 render_rect(ctx, &box, color);
706} 700}
707 701
708struct parent_data { 702struct parent_data {
@@ -713,8 +707,8 @@ struct parent_data {
713 struct sway_container *active_child; 707 struct sway_container *active_child;
714}; 708};
715 709
716static void render_container(struct sway_output *output, 710static void render_container(struct render_context *ctx,
717 const pixman_region32_t *damage, struct sway_container *con, bool parent_focused); 711 struct sway_container *con, bool parent_focused);
718 712
719/** 713/**
720 * Render a container's children using a L_HORIZ or L_VERT layout. 714 * Render a container's children using a L_HORIZ or L_VERT layout.
@@ -722,8 +716,7 @@ static void render_container(struct sway_output *output,
722 * Wrap child views in borders and leave child containers borderless because 716 * Wrap child views in borders and leave child containers borderless because
723 * they'll apply their own borders to their children. 717 * they'll apply their own borders to their children.
724 */ 718 */
725static void render_containers_linear(struct sway_output *output, 719static void render_containers_linear(struct render_context *ctx, struct parent_data *parent) {
726 const pixman_region32_t *damage, struct parent_data *parent) {
727 for (int i = 0; i < parent->children->length; ++i) { 720 for (int i = 0; i < parent->children->length; ++i) {
728 struct sway_container *child = parent->children->items[i]; 721 struct sway_container *child = parent->children->items[i];
729 722
@@ -753,15 +746,15 @@ static void render_containers_linear(struct sway_output *output,
753 } 746 }
754 747
755 if (state->border == B_NORMAL) { 748 if (state->border == B_NORMAL) {
756 render_titlebar(output, damage, child, floor(state->x), 749 render_titlebar(ctx, child, floor(state->x),
757 floor(state->y), state->width, colors, 750 floor(state->y), state->width, colors,
758 title_texture, marks_texture); 751 title_texture, marks_texture);
759 } else if (state->border == B_PIXEL) { 752 } else if (state->border == B_PIXEL) {
760 render_top_border(output, damage, child, colors); 753 render_top_border(ctx, child, colors);
761 } 754 }
762 render_view(output, damage, child, colors); 755 render_view(ctx, child, colors);
763 } else { 756 } else {
764 render_container(output, damage, child, 757 render_container(ctx, child,
765 parent->focused || child->current.focused); 758 parent->focused || child->current.focused);
766 } 759 }
767 } 760 }
@@ -778,8 +771,7 @@ static bool container_has_focused_child(struct sway_container *con) {
778/** 771/**
779 * Render a container's children using the L_TABBED layout. 772 * Render a container's children using the L_TABBED layout.
780 */ 773 */
781static void render_containers_tabbed(struct sway_output *output, 774static void render_containers_tabbed(struct render_context *ctx, struct parent_data *parent) {
782 const pixman_region32_t *damage, struct parent_data *parent) {
783 if (!parent->children->length) { 775 if (!parent->children->length) {
784 return; 776 return;
785 } 777 }
@@ -827,7 +819,7 @@ static void render_containers_tabbed(struct sway_output *output,
827 tab_width = parent->box.width - tab_width * i; 819 tab_width = parent->box.width - tab_width * i;
828 } 820 }
829 821
830 render_titlebar(output, damage, child, x, parent->box.y, tab_width, 822 render_titlebar(ctx, child, x, parent->box.y, tab_width,
831 colors, title_texture, marks_texture); 823 colors, title_texture, marks_texture);
832 824
833 if (child == current) { 825 if (child == current) {
@@ -837,9 +829,9 @@ static void render_containers_tabbed(struct sway_output *output,
837 829
838 // Render surface and left/right/bottom borders 830 // Render surface and left/right/bottom borders
839 if (current->view) { 831 if (current->view) {
840 render_view(output, damage, current, current_colors); 832 render_view(ctx, current, current_colors);
841 } else { 833 } else {
842 render_container(output, damage, current, 834 render_container(ctx, current,
843 parent->focused || current->current.focused); 835 parent->focused || current->current.focused);
844 } 836 }
845} 837}
@@ -847,8 +839,7 @@ static void render_containers_tabbed(struct sway_output *output,
847/** 839/**
848 * Render a container's children using the L_STACKED layout. 840 * Render a container's children using the L_STACKED layout.
849 */ 841 */
850static void render_containers_stacked(struct sway_output *output, 842static void render_containers_stacked(struct render_context *ctx, struct parent_data *parent) {
851 const pixman_region32_t *damage, struct parent_data *parent) {
852 if (!parent->children->length) { 843 if (!parent->children->length) {
853 return; 844 return;
854 } 845 }
@@ -890,7 +881,7 @@ static void render_containers_stacked(struct sway_output *output,
890 } 881 }
891 882
892 int y = parent->box.y + titlebar_height * i; 883 int y = parent->box.y + titlebar_height * i;
893 render_titlebar(output, damage, child, parent->box.x, y, 884 render_titlebar(ctx, child, parent->box.x, y,
894 parent->box.width, colors, title_texture, marks_texture); 885 parent->box.width, colors, title_texture, marks_texture);
895 886
896 if (child == current) { 887 if (child == current) {
@@ -900,19 +891,18 @@ static void render_containers_stacked(struct sway_output *output,
900 891
901 // Render surface and left/right/bottom borders 892 // Render surface and left/right/bottom borders
902 if (current->view) { 893 if (current->view) {
903 render_view(output, damage, current, current_colors); 894 render_view(ctx, current, current_colors);
904 } else { 895 } else {
905 render_container(output, damage, current, 896 render_container(ctx, current,
906 parent->focused || current->current.focused); 897 parent->focused || current->current.focused);
907 } 898 }
908} 899}
909 900
910static void render_containers(struct sway_output *output, 901static void render_containers(struct render_context *ctx, struct parent_data *parent) {
911 const pixman_region32_t *damage, struct parent_data *parent) {
912 if (config->hide_lone_tab && parent->children->length == 1) { 902 if (config->hide_lone_tab && parent->children->length == 1) {
913 struct sway_container *child = parent->children->items[0]; 903 struct sway_container *child = parent->children->items[0];
914 if (child->view) { 904 if (child->view) {
915 render_containers_linear(output,damage, parent); 905 render_containers_linear(ctx, parent);
916 return; 906 return;
917 } 907 }
918 } 908 }
@@ -921,19 +911,19 @@ static void render_containers(struct sway_output *output,
921 case L_NONE: 911 case L_NONE:
922 case L_HORIZ: 912 case L_HORIZ:
923 case L_VERT: 913 case L_VERT:
924 render_containers_linear(output, damage, parent); 914 render_containers_linear(ctx, parent);
925 break; 915 break;
926 case L_STACKED: 916 case L_STACKED:
927 render_containers_stacked(output, damage, parent); 917 render_containers_stacked(ctx, parent);
928 break; 918 break;
929 case L_TABBED: 919 case L_TABBED:
930 render_containers_tabbed(output, damage, parent); 920 render_containers_tabbed(ctx, parent);
931 break; 921 break;
932 } 922 }
933} 923}
934 924
935static void render_container(struct sway_output *output, 925static void render_container(struct render_context *ctx,
936 const pixman_region32_t *damage, struct sway_container *con, bool focused) { 926 struct sway_container *con, bool focused) {
937 struct parent_data data = { 927 struct parent_data data = {
938 .layout = con->current.layout, 928 .layout = con->current.layout,
939 .box = { 929 .box = {
@@ -946,11 +936,11 @@ static void render_container(struct sway_output *output,
946 .focused = focused, 936 .focused = focused,
947 .active_child = con->current.focused_inactive_child, 937 .active_child = con->current.focused_inactive_child,
948 }; 938 };
949 render_containers(output, damage, &data); 939 render_containers(ctx, &data);
950} 940}
951 941
952static void render_workspace(struct sway_output *output, 942static void render_workspace(struct render_context *ctx,
953 const pixman_region32_t *damage, struct sway_workspace *ws, bool focused) { 943 struct sway_workspace *ws, bool focused) {
954 struct parent_data data = { 944 struct parent_data data = {
955 .layout = ws->current.layout, 945 .layout = ws->current.layout,
956 .box = { 946 .box = {
@@ -963,11 +953,11 @@ static void render_workspace(struct sway_output *output,
963 .focused = focused, 953 .focused = focused,
964 .active_child = ws->current.focused_inactive_child, 954 .active_child = ws->current.focused_inactive_child,
965 }; 955 };
966 render_containers(output, damage, &data); 956 render_containers(ctx, &data);
967} 957}
968 958
969static void render_floating_container(struct sway_output *soutput, 959static void render_floating_container(struct render_context *ctx,
970 const pixman_region32_t *damage, struct sway_container *con) { 960 struct sway_container *con) {
971 if (con->view) { 961 if (con->view) {
972 struct sway_view *view = con->view; 962 struct sway_view *view = con->view;
973 struct border_colors *colors; 963 struct border_colors *colors;
@@ -989,20 +979,19 @@ static void render_floating_container(struct sway_output *soutput,
989 } 979 }
990 980
991 if (con->current.border == B_NORMAL) { 981 if (con->current.border == B_NORMAL) {
992 render_titlebar(soutput, damage, con, floor(con->current.x), 982 render_titlebar(ctx, con, floor(con->current.x),
993 floor(con->current.y), con->current.width, colors, 983 floor(con->current.y), con->current.width, colors,
994 title_texture, marks_texture); 984 title_texture, marks_texture);
995 } else if (con->current.border == B_PIXEL) { 985 } else if (con->current.border == B_PIXEL) {
996 render_top_border(soutput, damage, con, colors); 986 render_top_border(ctx, con, colors);
997 } 987 }
998 render_view(soutput, damage, con, colors); 988 render_view(ctx, con, colors);
999 } else { 989 } else {
1000 render_container(soutput, damage, con, con->current.focused); 990 render_container(ctx, con, con->current.focused);
1001 } 991 }
1002} 992}
1003 993
1004static void render_floating(struct sway_output *soutput, 994static void render_floating(struct render_context *ctx) {
1005 const pixman_region32_t *damage) {
1006 for (int i = 0; i < root->outputs->length; ++i) { 995 for (int i = 0; i < root->outputs->length; ++i) {
1007 struct sway_output *output = root->outputs->items[i]; 996 struct sway_output *output = root->outputs->items[i];
1008 for (int j = 0; j < output->current.workspaces->length; ++j) { 997 for (int j = 0; j < output->current.workspaces->length; ++j) {
@@ -1015,23 +1004,24 @@ static void render_floating(struct sway_output *soutput,
1015 if (floater->current.fullscreen_mode != FULLSCREEN_NONE) { 1004 if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
1016 continue; 1005 continue;
1017 } 1006 }
1018 render_floating_container(soutput, damage, floater); 1007 render_floating_container(ctx, floater);
1019 } 1008 }
1020 } 1009 }
1021 } 1010 }
1022} 1011}
1023 1012
1024static void render_seatops(struct sway_output *output, 1013static void render_seatops(struct render_context *ctx) {
1025 const pixman_region32_t *damage) {
1026 struct sway_seat *seat; 1014 struct sway_seat *seat;
1027 wl_list_for_each(seat, &server.input->seats, link) { 1015 wl_list_for_each(seat, &server.input->seats, link) {
1028 seatop_render(seat, output, damage); 1016 seatop_render(seat, ctx);
1029 } 1017 }
1030} 1018}
1031 1019
1032void output_render(struct sway_output *output, pixman_region32_t *damage) { 1020void output_render(struct render_context *ctx) {
1033 struct wlr_output *wlr_output = output->wlr_output; 1021 struct wlr_output *wlr_output = ctx->output->wlr_output;
1034 struct wlr_renderer *renderer = output->server->renderer; 1022 struct wlr_renderer *renderer = ctx->renderer;
1023 struct sway_output *output = ctx->output;
1024 const pixman_region32_t *damage = ctx->output_damage;
1035 1025
1036 struct sway_workspace *workspace = output->current.active_workspace; 1026 struct sway_workspace *workspace = output->current.active_workspace;
1037 if (workspace == NULL) { 1027 if (workspace == NULL) {
@@ -1047,12 +1037,6 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
1047 return; 1037 return;
1048 } 1038 }
1049 1039
1050 if (debug.damage == DAMAGE_RERENDER) {
1051 int width, height;
1052 wlr_output_transformed_resolution(wlr_output, &width, &height);
1053 pixman_region32_union_rect(damage, damage, 0, 0, width, height);
1054 }
1055
1056 if (!pixman_region32_not_empty(damage)) { 1040 if (!pixman_region32_not_empty(damage)) {
1057 // Output isn't damaged but needs buffer swap 1041 // Output isn't damaged but needs buffer swap
1058 goto renderer_end; 1042 goto renderer_end;
@@ -1077,8 +1061,8 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
1077 1061
1078 if (server.session_lock.lock != NULL) { 1062 if (server.session_lock.lock != NULL) {
1079 struct render_data data = { 1063 struct render_data data = {
1080 .damage = damage,
1081 .alpha = 1.0f, 1064 .alpha = 1.0f,
1065 .ctx = ctx,
1082 }; 1066 };
1083 1067
1084 struct wlr_session_lock_surface_v1 *lock_surface; 1068 struct wlr_session_lock_surface_v1 *lock_surface;
@@ -1113,13 +1097,12 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
1113 1097
1114 if (fullscreen_con->view) { 1098 if (fullscreen_con->view) {
1115 if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) { 1099 if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) {
1116 render_saved_view(fullscreen_con->view, output, damage, 1.0f); 1100 render_saved_view(ctx, fullscreen_con->view, 1.0f);
1117 } else if (fullscreen_con->view->surface) { 1101 } else if (fullscreen_con->view->surface) {
1118 render_view_toplevels(fullscreen_con->view, 1102 render_view_toplevels(ctx, fullscreen_con->view, 1.0f);
1119 output, damage, 1.0f);
1120 } 1103 }
1121 } else { 1104 } else {
1122 render_container(output, damage, fullscreen_con, 1105 render_container(ctx, fullscreen_con,
1123 fullscreen_con->current.focused); 1106 fullscreen_con->current.focused);
1124 } 1107 }
1125 1108
@@ -1127,11 +1110,11 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
1127 struct sway_container *floater = 1110 struct sway_container *floater =
1128 workspace->current.floating->items[i]; 1111 workspace->current.floating->items[i];
1129 if (container_is_transient_for(floater, fullscreen_con)) { 1112 if (container_is_transient_for(floater, fullscreen_con)) {
1130 render_floating_container(output, damage, floater); 1113 render_floating_container(ctx, floater);
1131 } 1114 }
1132 } 1115 }
1133#if HAVE_XWAYLAND 1116#if HAVE_XWAYLAND
1134 render_unmanaged(output, damage, &root->xwayland_unmanaged); 1117 render_unmanaged(ctx, &root->xwayland_unmanaged);
1135#endif 1118#endif
1136 } else { 1119 } else {
1137 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; 1120 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
@@ -1143,41 +1126,41 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
1143 wlr_renderer_clear(renderer, clear_color); 1126 wlr_renderer_clear(renderer, clear_color);
1144 } 1127 }
1145 1128
1146 render_layer_toplevel(output, damage, 1129 render_layer_toplevel(ctx,
1147 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); 1130 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
1148 render_layer_toplevel(output, damage, 1131 render_layer_toplevel(ctx,
1149 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); 1132 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
1150 1133
1151 render_workspace(output, damage, workspace, workspace->current.focused); 1134 render_workspace(ctx, workspace, workspace->current.focused);
1152 render_floating(output, damage); 1135 render_floating(ctx);
1153#if HAVE_XWAYLAND 1136#if HAVE_XWAYLAND
1154 render_unmanaged(output, damage, &root->xwayland_unmanaged); 1137 render_unmanaged(ctx, &root->xwayland_unmanaged);
1155#endif 1138#endif
1156 render_layer_toplevel(output, damage, 1139 render_layer_toplevel(ctx,
1157 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); 1140 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
1158 1141
1159 render_layer_popups(output, damage, 1142 render_layer_popups(ctx,
1160 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); 1143 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
1161 render_layer_popups(output, damage, 1144 render_layer_popups(ctx,
1162 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); 1145 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
1163 render_layer_popups(output, damage, 1146 render_layer_popups(ctx,
1164 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); 1147 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
1165 } 1148 }
1166 1149
1167 render_seatops(output, damage); 1150 render_seatops(ctx);
1168 1151
1169 struct sway_seat *seat = input_manager_current_seat(); 1152 struct sway_seat *seat = input_manager_current_seat();
1170 struct sway_container *focus = seat_get_focused_container(seat); 1153 struct sway_container *focus = seat_get_focused_container(seat);
1171 if (focus && focus->view) { 1154 if (focus && focus->view) {
1172 render_view_popups(focus->view, output, damage, focus->alpha); 1155 render_view_popups(ctx, focus->view, focus->alpha);
1173 } 1156 }
1174 1157
1175render_overlay: 1158render_overlay:
1176 render_layer_toplevel(output, damage, 1159 render_layer_toplevel(ctx,
1177 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); 1160 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
1178 render_layer_popups(output, damage, 1161 render_layer_popups(ctx,
1179 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); 1162 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
1180 render_drag_icons(output, damage, &root->drag_icons); 1163 render_drag_icons(ctx, &root->drag_icons);
1181 1164
1182renderer_end: 1165renderer_end:
1183 wlr_renderer_scissor(renderer, NULL); 1166 wlr_renderer_scissor(renderer, NULL);
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 14931ce0..6b95e46a 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1726,10 +1726,9 @@ void seatop_end(struct sway_seat *seat) {
1726 seat->seatop_impl = NULL; 1726 seat->seatop_impl = NULL;
1727} 1727}
1728 1728
1729void seatop_render(struct sway_seat *seat, struct sway_output *output, 1729void seatop_render(struct sway_seat *seat, struct render_context *ctx) {
1730 const pixman_region32_t *damage) {
1731 if (seat->seatop_impl->render) { 1730 if (seat->seatop_impl->render) {
1732 seat->seatop_impl->render(seat, output, damage); 1731 seat->seatop_impl->render(seat, ctx);
1733 } 1732 }
1734} 1733}
1735 1734
diff --git a/sway/input/seatop_move_tiling.c b/sway/input/seatop_move_tiling.c
index 5498e909..26704d0d 100644
--- a/sway/input/seatop_move_tiling.c
+++ b/sway/input/seatop_move_tiling.c
@@ -31,21 +31,20 @@ struct seatop_move_tiling_event {
31 bool insert_after_target; 31 bool insert_after_target;
32}; 32};
33 33
34static void handle_render(struct sway_seat *seat, 34static void handle_render(struct sway_seat *seat, struct render_context *ctx) {
35 struct sway_output *output, const pixman_region32_t *damage) {
36 struct seatop_move_tiling_event *e = seat->seatop_data; 35 struct seatop_move_tiling_event *e = seat->seatop_data;
37 if (!e->threshold_reached) { 36 if (!e->threshold_reached) {
38 return; 37 return;
39 } 38 }
40 if (e->target_node && node_get_output(e->target_node) == output) { 39 if (e->target_node && node_get_output(e->target_node) == ctx->output) {
41 float color[4]; 40 float color[4];
42 memcpy(&color, config->border_colors.focused.indicator, 41 memcpy(&color, config->border_colors.focused.indicator,
43 sizeof(float) * 4); 42 sizeof(float) * 4);
44 premultiply_alpha(color, 0.5); 43 premultiply_alpha(color, 0.5);
45 struct wlr_box box; 44 struct wlr_box box;
46 memcpy(&box, &e->drop_box, sizeof(struct wlr_box)); 45 memcpy(&box, &e->drop_box, sizeof(struct wlr_box));
47 scale_box(&box, output->wlr_output->scale); 46 scale_box(&box, ctx->output->wlr_output->scale);
48 render_rect(output, damage, &box, color); 47 render_rect(ctx, &box, color);
49 } 48 }
50} 49}
51 50