aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-05-10 18:46:14 -0400
committerLibravatar GitHub <noreply@github.com>2018-05-10 18:46:14 -0400
commitfbddd34b47fd774631d2a5495e4b0b69acb34688 (patch)
tree7b74a17124cb1d8a0adf777b9cb337574bea52a7 /sway/desktop
parentMerge pull request #1932 from emersion/fix-layer-shell-exclusive (diff)
parentFix damage tracking on HiDPI (diff)
downloadsway-fbddd34b47fd774631d2a5495e4b0b69acb34688.tar.gz
sway-fbddd34b47fd774631d2a5495e4b0b69acb34688.tar.zst
sway-fbddd34b47fd774631d2a5495e4b0b69acb34688.zip
Merge pull request #1923 from emersion/full-damage-tracking
Implement full damage tracking
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/output.c317
-rw-r--r--sway/desktop/wl_shell.c2
-rw-r--r--sway/desktop/xdg_shell_v6.c2
-rw-r--r--sway/desktop/xwayland.c2
4 files changed, 210 insertions, 113 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 9b0f1ae3..c150270e 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -163,14 +163,65 @@ static void scale_box(struct wlr_box *box, float scale) {
163struct render_data { 163struct render_data {
164 struct root_geometry root_geo; 164 struct root_geometry root_geo;
165 struct sway_output *output; 165 struct sway_output *output;
166 pixman_region32_t *damage;
166 float alpha; 167 float alpha;
167}; 168};
168 169
170static void scissor_output(struct wlr_output *wlr_output,
171 pixman_box32_t *rect) {
172 struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
173 assert(renderer);
174
175 struct wlr_box box = {
176 .x = rect->x1,
177 .y = rect->y1,
178 .width = rect->x2 - rect->x1,
179 .height = rect->y2 - rect->y1,
180 };
181
182 int ow, oh;
183 wlr_output_transformed_resolution(wlr_output, &ow, &oh);
184
185 enum wl_output_transform transform =
186 wlr_output_transform_invert(wlr_output->transform);
187 wlr_box_transform(&box, transform, ow, oh, &box);
188
189 wlr_renderer_scissor(renderer, &box);
190}
191
192static void render_texture(struct wlr_output *wlr_output,
193 pixman_region32_t *output_damage, struct wlr_texture *texture,
194 const struct wlr_box *box, const float matrix[static 9], float alpha) {
195 struct wlr_renderer *renderer =
196 wlr_backend_get_renderer(wlr_output->backend);
197
198 pixman_region32_t damage;
199 pixman_region32_init(&damage);
200 pixman_region32_union_rect(&damage, &damage, box->x, box->y,
201 box->width, box->height);
202 pixman_region32_intersect(&damage, &damage, output_damage);
203 bool damaged = pixman_region32_not_empty(&damage);
204 if (!damaged) {
205 goto damage_finish;
206 }
207
208 int nrects;
209 pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
210 for (int i = 0; i < nrects; ++i) {
211 scissor_output(wlr_output, &rects[i]);
212 wlr_render_texture_with_matrix(renderer, texture, matrix, alpha);
213 }
214
215damage_finish:
216 pixman_region32_fini(&damage);
217}
218
169static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, 219static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
170 void *_data) { 220 void *_data) {
171 struct render_data *data = _data; 221 struct render_data *data = _data;
172 struct wlr_output *wlr_output = data->output->wlr_output; 222 struct wlr_output *wlr_output = data->output->wlr_output;
173 float rotation = data->root_geo.rotation; 223 float rotation = data->root_geo.rotation;
224 pixman_region32_t *output_damage = data->damage;
174 float alpha = data->alpha; 225 float alpha = data->alpha;
175 226
176 if (!wlr_surface_has_buffer(surface)) { 227 if (!wlr_surface_has_buffer(surface)) {
@@ -184,13 +235,6 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
184 return; 235 return;
185 } 236 }
186 237
187 struct wlr_renderer *renderer =
188 wlr_backend_get_renderer(wlr_output->backend);
189 if (!sway_assert(renderer != NULL,
190 "expected the output backend to have a renderer")) {
191 return;
192 }
193
194 scale_box(&box, wlr_output->scale); 238 scale_box(&box, wlr_output->scale);
195 239
196 float matrix[9]; 240 float matrix[9];
@@ -199,38 +243,81 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
199 wlr_matrix_project_box(matrix, &box, transform, rotation, 243 wlr_matrix_project_box(matrix, &box, transform, rotation,
200 wlr_output->transform_matrix); 244 wlr_output->transform_matrix);
201 245
202 wlr_render_texture_with_matrix(renderer, surface->texture, 246 render_texture(wlr_output, output_damage, surface->texture, &box, matrix,
203 matrix, alpha); 247 alpha);
204} 248}
205 249
206static void render_layer(struct sway_output *output, 250static void render_layer(struct sway_output *output,
207 struct wl_list *layer_surfaces) { 251 pixman_region32_t *damage, struct wl_list *layer_surfaces) {
208 struct render_data data = { .output = output, .alpha = 1.0f }; 252 struct render_data data = {
253 .output = output,
254 .damage = damage,
255 .alpha = 1.0f,
256 };
209 layer_for_each_surface(layer_surfaces, &data.root_geo, 257 layer_for_each_surface(layer_surfaces, &data.root_geo,
210 render_surface_iterator, &data); 258 render_surface_iterator, &data);
211} 259}
212 260
213static void render_unmanaged(struct sway_output *output, 261static void render_unmanaged(struct sway_output *output,
214 struct wl_list *unmanaged) { 262 pixman_region32_t *damage, struct wl_list *unmanaged) {
215 struct render_data data = { .output = output, .alpha = 1.0f }; 263 struct render_data data = {
264 .output = output,
265 .damage = damage,
266 .alpha = 1.0f,
267 };
216 unmanaged_for_each_surface(unmanaged, output, &data.root_geo, 268 unmanaged_for_each_surface(unmanaged, output, &data.root_geo,
217 render_surface_iterator, &data); 269 render_surface_iterator, &data);
218} 270}
219 271
220static void render_view(struct sway_view *view, struct sway_output *output) { 272static void render_view(struct sway_view *view, struct sway_output *output,
221 struct render_data data = { .output = output, .alpha = view->swayc->alpha }; 273 pixman_region32_t *damage) {
274 struct render_data data = {
275 .output = output,
276 .damage = damage,
277 .alpha = view->swayc->alpha,
278 };
222 output_view_for_each_surface( 279 output_view_for_each_surface(
223 view, &data.root_geo, render_surface_iterator, &data); 280 view, &data.root_geo, render_surface_iterator, &data);
224} 281}
225 282
283static void render_rect(struct wlr_output *wlr_output,
284 pixman_region32_t *output_damage, const struct wlr_box *_box,
285 float color[static 4]) {
286 struct wlr_renderer *renderer =
287 wlr_backend_get_renderer(wlr_output->backend);
288
289 struct wlr_box box = *_box;
290 scale_box(&box, wlr_output->scale);
291
292 pixman_region32_t damage;
293 pixman_region32_init(&damage);
294 pixman_region32_union_rect(&damage, &damage, box.x, box.y,
295 box.width, box.height);
296 pixman_region32_intersect(&damage, &damage, output_damage);
297 bool damaged = pixman_region32_not_empty(&damage);
298 if (!damaged) {
299 goto damage_finish;
300 }
301
302 int nrects;
303 pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
304 for (int i = 0; i < nrects; ++i) {
305 scissor_output(wlr_output, &rects[i]);
306 wlr_render_rect(renderer, &box, color,
307 wlr_output->transform_matrix);
308 }
309
310damage_finish:
311 pixman_region32_fini(&damage);
312}
313
226/** 314/**
227 * Render decorations for a view with "border normal". 315 * Render decorations for a view with "border normal".
228 */ 316 */
229static void render_container_simple_border_normal(struct sway_output *output, 317static void render_container_simple_border_normal(struct sway_output *output,
318 pixman_region32_t *output_damage,
230 struct sway_container *con, struct border_colors *colors, 319 struct sway_container *con, struct border_colors *colors,
231 struct wlr_texture *title_texture) { 320 struct wlr_texture *title_texture) {
232 struct wlr_renderer *renderer =
233 wlr_backend_get_renderer(output->wlr_output->backend);
234 struct wlr_box box; 321 struct wlr_box box;
235 float color[4]; 322 float color[4];
236 323
@@ -241,9 +328,7 @@ static void render_container_simple_border_normal(struct sway_output *output,
241 box.y = con->y + 1; 328 box.y = con->y + 1;
242 box.width = con->sway_view->border_thickness; 329 box.width = con->sway_view->border_thickness;
243 box.height = con->height - 1; 330 box.height = con->height - 1;
244 scale_box(&box, output->wlr_output->scale); 331 render_rect(output->wlr_output, output_damage, &box, color);
245 wlr_render_rect(renderer, &box, color,
246 output->wlr_output->transform_matrix);
247 332
248 // Child border - right edge 333 // Child border - right edge
249 if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { 334 if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) {
@@ -256,9 +341,7 @@ static void render_container_simple_border_normal(struct sway_output *output,
256 box.y = con->y + 1; 341 box.y = con->y + 1;
257 box.width = con->sway_view->border_thickness; 342 box.width = con->sway_view->border_thickness;
258 box.height = con->height - 1; 343 box.height = con->height - 1;
259 scale_box(&box, output->wlr_output->scale); 344 render_rect(output->wlr_output, output_damage, &box, color);
260 wlr_render_rect(renderer, &box, color,
261 output->wlr_output->transform_matrix);
262 345
263 // Child border - bottom edge 346 // Child border - bottom edge
264 if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { 347 if (con->parent->children->length == 1 && con->parent->layout == L_VERT) {
@@ -271,9 +354,7 @@ static void render_container_simple_border_normal(struct sway_output *output,
271 box.y = con->y + con->height - con->sway_view->border_thickness; 354 box.y = con->y + con->height - con->sway_view->border_thickness;
272 box.width = con->width; 355 box.width = con->width;
273 box.height = con->sway_view->border_thickness; 356 box.height = con->sway_view->border_thickness;
274 scale_box(&box, output->wlr_output->scale); 357 render_rect(output->wlr_output, output_damage, &box, color);
275 wlr_render_rect(renderer, &box, color,
276 output->wlr_output->transform_matrix);
277 358
278 // Single pixel bar above title 359 // Single pixel bar above title
279 memcpy(&color, colors->border, sizeof(float) * 4); 360 memcpy(&color, colors->border, sizeof(float) * 4);
@@ -282,18 +363,14 @@ static void render_container_simple_border_normal(struct sway_output *output,
282 box.y = con->y; 363 box.y = con->y;
283 box.width = con->width; 364 box.width = con->width;
284 box.height = 1; 365 box.height = 1;
285 scale_box(&box, output->wlr_output->scale); 366 render_rect(output->wlr_output, output_damage, &box, color);
286 wlr_render_rect(renderer, &box, color,
287 output->wlr_output->transform_matrix);
288 367
289 // Single pixel bar below title 368 // Single pixel bar below title
290 box.x = con->x + con->sway_view->border_thickness; 369 box.x = con->x + con->sway_view->border_thickness;
291 box.y = con->sway_view->y - 1; 370 box.y = con->sway_view->y - 1;
292 box.width = con->width - con->sway_view->border_thickness * 2; 371 box.width = con->width - con->sway_view->border_thickness * 2;
293 box.height = 1; 372 box.height = 1;
294 scale_box(&box, output->wlr_output->scale); 373 render_rect(output->wlr_output, output_damage, &box, color);
295 wlr_render_rect(renderer, &box, color,
296 output->wlr_output->transform_matrix);
297 374
298 // Title background 375 // Title background
299 memcpy(&color, colors->background, sizeof(float) * 4); 376 memcpy(&color, colors->background, sizeof(float) * 4);
@@ -302,20 +379,24 @@ static void render_container_simple_border_normal(struct sway_output *output,
302 box.y = con->y + 1; 379 box.y = con->y + 1;
303 box.width = con->width - con->sway_view->border_thickness * 2; 380 box.width = con->width - con->sway_view->border_thickness * 2;
304 box.height = con->sway_view->y - con->y - 2; 381 box.height = con->sway_view->y - con->y - 2;
305 scale_box(&box, output->wlr_output->scale); 382 render_rect(output->wlr_output, output_damage, &box, color);
306 wlr_render_rect(renderer, &box, color,
307 output->wlr_output->transform_matrix);
308 383
309 // Title text 384 // Title text
310 if (title_texture) { 385 if (title_texture) {
311 struct wlr_box scissor_box; 386 float output_scale = output->wlr_output->scale;
312 wlr_box_transform(&box, 387 struct wlr_box texture_box = {
313 wlr_output_transform_invert(output->wlr_output->transform), 388 .x = box.x * output_scale,
314 output->swayc->width, output->swayc->height, &scissor_box); 389 .y = box.y * output_scale,
315 wlr_renderer_scissor(renderer, &scissor_box); 390 };
316 wlr_render_texture(renderer, title_texture, 391 wlr_texture_get_size(title_texture,
317 output->wlr_output->transform_matrix, box.x, box.y, 1); 392 &texture_box.width, &texture_box.height);
318 wlr_renderer_scissor(renderer, NULL); 393
394 float matrix[9];
395 wlr_matrix_project_box(matrix, &texture_box, WL_OUTPUT_TRANSFORM_NORMAL,
396 0.0, output->wlr_output->transform_matrix);
397
398 render_texture(output->wlr_output, output_damage, title_texture,
399 &texture_box, matrix, 1.0);
319 } 400 }
320} 401}
321 402
@@ -323,9 +404,8 @@ static void render_container_simple_border_normal(struct sway_output *output,
323 * Render decorations for a view with "border pixel". 404 * Render decorations for a view with "border pixel".
324 */ 405 */
325static void render_container_simple_border_pixel(struct sway_output *output, 406static void render_container_simple_border_pixel(struct sway_output *output,
326 struct sway_container *con, struct border_colors *colors) { 407 pixman_region32_t *output_damage, struct sway_container *con,
327 struct wlr_renderer *renderer = 408 struct border_colors *colors) {
328 wlr_backend_get_renderer(output->wlr_output->backend);
329 struct wlr_box box; 409 struct wlr_box box;
330 float color[4]; 410 float color[4];
331 411
@@ -336,9 +416,7 @@ static void render_container_simple_border_pixel(struct sway_output *output,
336 box.y = con->y; 416 box.y = con->y;
337 box.width = con->sway_view->border_thickness; 417 box.width = con->sway_view->border_thickness;
338 box.height = con->height; 418 box.height = con->height;
339 scale_box(&box, output->wlr_output->scale); 419 render_rect(output->wlr_output, output_damage, &box, color);
340 wlr_render_rect(renderer, &box, color,
341 output->wlr_output->transform_matrix);
342 420
343 // Child border - right edge 421 // Child border - right edge
344 if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { 422 if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) {
@@ -351,18 +429,14 @@ static void render_container_simple_border_pixel(struct sway_output *output,
351 box.y = con->y; 429 box.y = con->y;
352 box.width = con->sway_view->border_thickness; 430 box.width = con->sway_view->border_thickness;
353 box.height = con->height; 431 box.height = con->height;
354 scale_box(&box, output->wlr_output->scale); 432 render_rect(output->wlr_output, output_damage, &box, color);
355 wlr_render_rect(renderer, &box, color,
356 output->wlr_output->transform_matrix);
357 433
358 // Child border - top edge 434 // Child border - top edge
359 box.x = con->x; 435 box.x = con->x;
360 box.y = con->y; 436 box.y = con->y;
361 box.width = con->width; 437 box.width = con->width;
362 box.height = con->sway_view->border_thickness; 438 box.height = con->sway_view->border_thickness;
363 scale_box(&box, output->wlr_output->scale); 439 render_rect(output->wlr_output, output_damage, &box, color);
364 wlr_render_rect(renderer, &box, color,
365 output->wlr_output->transform_matrix);
366 440
367 // Child border - bottom edge 441 // Child border - bottom edge
368 if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { 442 if (con->parent->children->length == 1 && con->parent->layout == L_VERT) {
@@ -375,13 +449,11 @@ static void render_container_simple_border_pixel(struct sway_output *output,
375 box.y = con->y + con->height - con->sway_view->border_thickness; 449 box.y = con->y + con->height - con->sway_view->border_thickness;
376 box.width = con->width; 450 box.width = con->width;
377 box.height = con->sway_view->border_thickness; 451 box.height = con->sway_view->border_thickness;
378 scale_box(&box, output->wlr_output->scale); 452 render_rect(output->wlr_output, output_damage, &box, color);
379 wlr_render_rect(renderer, &box, color,
380 output->wlr_output->transform_matrix);
381} 453}
382 454
383static void render_container(struct sway_output *output, 455static void render_container(struct sway_output *output,
384 struct sway_container *con); 456 pixman_region32_t *damage, struct sway_container *con);
385 457
386/** 458/**
387 * Render a container's children using a L_HORIZ or L_VERT layout. 459 * Render a container's children using a L_HORIZ or L_VERT layout.
@@ -390,7 +462,7 @@ static void render_container(struct sway_output *output,
390 * they'll apply their own borders to their children. 462 * they'll apply their own borders to their children.
391 */ 463 */
392static void render_container_simple(struct sway_output *output, 464static void render_container_simple(struct sway_output *output,
393 struct sway_container *con) { 465 pixman_region32_t *damage, struct sway_container *con) {
394 struct sway_seat *seat = input_manager_current_seat(input_manager); 466 struct sway_seat *seat = input_manager_current_seat(input_manager);
395 struct sway_container *focus = seat_get_focus(seat); 467 struct sway_container *focus = seat_get_focus(seat);
396 468
@@ -413,15 +485,16 @@ static void render_container_simple(struct sway_output *output,
413 } 485 }
414 486
415 if (child->sway_view->border == B_NORMAL) { 487 if (child->sway_view->border == B_NORMAL) {
416 render_container_simple_border_normal(output, child, 488 render_container_simple_border_normal(output, damage,
417 colors, title_texture); 489 child, colors, title_texture);
418 } else { 490 } else {
419 render_container_simple_border_pixel(output, child, colors); 491 render_container_simple_border_pixel(output, damage, child,
492 colors);
420 } 493 }
421 } 494 }
422 render_view(child->sway_view, output); 495 render_view(child->sway_view, output, damage);
423 } else { 496 } else {
424 render_container(output, child); 497 render_container(output, damage, child);
425 } 498 }
426 } 499 }
427} 500}
@@ -430,7 +503,7 @@ static void render_container_simple(struct sway_output *output,
430 * Render a container's children using the L_TABBED layout. 503 * Render a container's children using the L_TABBED layout.
431 */ 504 */
432static void render_container_tabbed(struct sway_output *output, 505static void render_container_tabbed(struct sway_output *output,
433 struct sway_container *con) { 506 pixman_region32_t *damage, struct sway_container *con) {
434 // TODO 507 // TODO
435} 508}
436 509
@@ -438,23 +511,23 @@ static void render_container_tabbed(struct sway_output *output,
438 * Render a container's children using the L_STACKED layout. 511 * Render a container's children using the L_STACKED layout.
439 */ 512 */
440static void render_container_stacked(struct sway_output *output, 513static void render_container_stacked(struct sway_output *output,
441 struct sway_container *con) { 514 pixman_region32_t *damage, struct sway_container *con) {
442 // TODO 515 // TODO
443} 516}
444 517
445static void render_container(struct sway_output *output, 518static void render_container(struct sway_output *output,
446 struct sway_container *con) { 519 pixman_region32_t *damage, struct sway_container *con) {
447 switch (con->layout) { 520 switch (con->layout) {
448 case L_NONE: 521 case L_NONE:
449 case L_HORIZ: 522 case L_HORIZ:
450 case L_VERT: 523 case L_VERT:
451 render_container_simple(output, con); 524 render_container_simple(output, damage, con);
452 break; 525 break;
453 case L_STACKED: 526 case L_STACKED:
454 render_container_stacked(output, con); 527 render_container_stacked(output, damage, con);
455 break; 528 break;
456 case L_TABBED: 529 case L_TABBED:
457 render_container_tabbed(output, con); 530 render_container_tabbed(output, damage, con);
458 break; 531 break;
459 case L_FLOATING: 532 case L_FLOATING:
460 // TODO 533 // TODO
@@ -496,37 +569,51 @@ static void render_output(struct sway_output *output, struct timespec *when,
496 goto renderer_end; 569 goto renderer_end;
497 } 570 }
498 571
499 // TODO: don't damage the whole output 572 //wlr_renderer_clear(renderer, (float[]){1, 1, 0, 1});
500 int width, height;
501 wlr_output_transformed_resolution(wlr_output, &width, &height);
502 pixman_region32_union_rect(damage, damage, 0, 0, width, height);
503 573
504 struct sway_container *workspace = output_get_active_workspace(output); 574 struct sway_container *workspace = output_get_active_workspace(output);
505 575
506 if (workspace->sway_workspace->fullscreen) { 576 if (workspace->sway_workspace->fullscreen) {
507 float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; 577 float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
508 wlr_renderer_clear(renderer, clear_color); 578
579 int nrects;
580 pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
581 for (int i = 0; i < nrects; ++i) {
582 scissor_output(wlr_output, &rects[i]);
583 wlr_renderer_clear(renderer, clear_color);
584 }
585
509 // TODO: handle views smaller than the output 586 // TODO: handle views smaller than the output
510 render_view(workspace->sway_workspace->fullscreen, output); 587 render_view(workspace->sway_workspace->fullscreen, output, damage);
511 588
512 if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) { 589 if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) {
513 render_unmanaged(output, 590 render_unmanaged(output, damage,
514 &root_container.sway_root->xwayland_unmanaged); 591 &root_container.sway_root->xwayland_unmanaged);
515 } 592 }
516 } else { 593 } else {
517 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; 594 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
518 wlr_renderer_clear(renderer, clear_color);
519 595
520 render_layer(output, 596 int nrects;
521 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); 597 pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
522 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); 598 for (int i = 0; i < nrects; ++i) {
599 scissor_output(wlr_output, &rects[i]);
600 wlr_renderer_clear(renderer, clear_color);
601 }
602
603 render_layer(output, damage,
604 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
605 render_layer(output, damage,
606 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
523 607
524 render_container(output, workspace); 608 render_container(output, damage, workspace);
525 609
526 render_unmanaged(output, &root_container.sway_root->xwayland_unmanaged); 610 render_unmanaged(output, damage,
527 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); 611 &root_container.sway_root->xwayland_unmanaged);
612 render_layer(output, damage,
613 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
528 } 614 }
529 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); 615 render_layer(output, damage,
616 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
530 617
531renderer_end: 618renderer_end:
532 if (root_container.sway_root->debug_tree) { 619 if (root_container.sway_root->debug_tree) {
@@ -534,6 +621,7 @@ renderer_end:
534 wlr_output->transform_matrix, 0, 0, 1); 621 wlr_output->transform_matrix, 0, 0, 1);
535 } 622 }
536 623
624 wlr_renderer_scissor(renderer, NULL);
537 wlr_renderer_end(renderer); 625 wlr_renderer_end(renderer);
538 if (!wlr_output_damage_swap_buffers(output->damage, when, damage)) { 626 if (!wlr_output_damage_swap_buffers(output->damage, when, damage)) {
539 return; 627 return;
@@ -663,28 +751,28 @@ static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy,
663 751
664 scale_box(&box, output->wlr_output->scale); 752 scale_box(&box, output->wlr_output->scale);
665 753
754 int center_x = box.x + box.width/2;
755 int center_y = box.y + box.height/2;
756
757 pixman_region32_t damage;
758 pixman_region32_init(&damage);
759 pixman_region32_copy(&damage, &surface->current->surface_damage);
760 wlr_region_scale(&damage, &damage, output->wlr_output->scale);
761 if (ceil(output->wlr_output->scale) > surface->current->scale) {
762 // When scaling up a surface, it'll become blurry so we need to
763 // expand the damage region
764 wlr_region_expand(&damage, &damage,
765 ceil(output->wlr_output->scale) - surface->current->scale);
766 }
767 pixman_region32_translate(&damage, box.x, box.y);
768 wlr_region_rotated_bounds(&damage, &damage, rotation,
769 center_x, center_y);
770 wlr_output_damage_add(output->damage, &damage);
771 pixman_region32_fini(&damage);
772
666 if (whole) { 773 if (whole) {
667 wlr_box_rotated_bounds(&box, rotation, &box); 774 wlr_box_rotated_bounds(&box, rotation, &box);
668 wlr_output_damage_add_box(output->damage, &box); 775 wlr_output_damage_add_box(output->damage, &box);
669 } else {
670 int center_x = box.x + box.width/2;
671 int center_y = box.y + box.height/2;
672
673 pixman_region32_t damage;
674 pixman_region32_init(&damage);
675 pixman_region32_copy(&damage, &surface->current->surface_damage);
676 wlr_region_scale(&damage, &damage, output->wlr_output->scale);
677 if (ceil(output->wlr_output->scale) > surface->current->scale) {
678 // When scaling up a surface, it'll become blurry so we need to
679 // expand the damage region
680 wlr_region_expand(&damage, &damage,
681 ceil(output->wlr_output->scale) - surface->current->scale);
682 }
683 pixman_region32_translate(&damage, box.x, box.y);
684 wlr_region_rotated_bounds(&damage, &damage, rotation,
685 center_x, center_y);
686 wlr_output_damage_add(output->damage, &damage);
687 pixman_region32_fini(&damage);
688 } 776 }
689} 777}
690 778
@@ -699,8 +787,8 @@ void output_damage_surface(struct sway_output *output, double ox, double oy,
699 damage_surface_iterator, &data); 787 damage_surface_iterator, &data);
700} 788}
701 789
702void output_damage_view(struct sway_output *output, struct sway_view *view, 790static void output_damage_view(struct sway_output *output,
703 bool whole) { 791 struct sway_view *view, bool whole) {
704 if (!sway_assert(view->swayc != NULL, "expected a view in the tree")) { 792 if (!sway_assert(view->swayc != NULL, "expected a view in the tree")) {
705 return; 793 return;
706 } 794 }
@@ -720,6 +808,11 @@ void output_damage_view(struct sway_output *output, struct sway_view *view,
720 damage_surface_iterator, &data); 808 damage_surface_iterator, &data);
721} 809}
722 810
811void output_damage_from_view(struct sway_output *output,
812 struct sway_view *view) {
813 output_damage_view(output, view, false);
814}
815
723static void output_damage_whole_container_iterator(struct sway_container *con, 816static void output_damage_whole_container_iterator(struct sway_container *con,
724 void *data) { 817 void *data) {
725 struct sway_output *output = data; 818 struct sway_output *output = data;
@@ -742,8 +835,12 @@ void output_damage_whole_container(struct sway_output *output,
742 }; 835 };
743 wlr_output_damage_add_box(output->damage, &box); 836 wlr_output_damage_add_box(output->damage, &box);
744 837
745 container_descendants(con, C_VIEW, output_damage_whole_container_iterator, 838 if (con->type == C_VIEW) {
746 output); 839 output_damage_whole_container_iterator(con, output);
840 } else {
841 container_descendants(con, C_VIEW,
842 output_damage_whole_container_iterator, output);
843 }
747} 844}
748 845
749static void damage_handle_destroy(struct wl_listener *listener, void *data) { 846static void damage_handle_destroy(struct wl_listener *listener, void *data) {
diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c
index e97a898e..99e8947b 100644
--- a/sway/desktop/wl_shell.c
+++ b/sway/desktop/wl_shell.c
@@ -85,7 +85,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
85 // TODO: Let floating views do whatever 85 // TODO: Let floating views do whatever
86 view_update_size(view, wl_shell_view->pending_width, 86 view_update_size(view, wl_shell_view->pending_width,
87 wl_shell_view->pending_height); 87 wl_shell_view->pending_height);
88 view_damage(view, false); 88 view_damage_from(view);
89} 89}
90 90
91static void handle_destroy(struct wl_listener *listener, void *data) { 91static void handle_destroy(struct wl_listener *listener, void *data) {
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index fcee8ce9..8ecb330d 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -177,7 +177,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
177 view_update_size(view, xdg_shell_v6_view->pending_width, 177 view_update_size(view, xdg_shell_v6_view->pending_width,
178 xdg_shell_v6_view->pending_height); 178 xdg_shell_v6_view->pending_height);
179 view_update_title(view, false); 179 view_update_title(view, false);
180 view_damage(view, false); 180 view_damage_from(view);
181} 181}
182 182
183static void handle_new_popup(struct wl_listener *listener, void *data) { 183static void handle_new_popup(struct wl_listener *listener, void *data) {
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index b4eda71f..8f935760 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -222,7 +222,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
222 // TODO: Let floating views do whatever 222 // TODO: Let floating views do whatever
223 view_update_size(view, xwayland_view->pending_width, 223 view_update_size(view, xwayland_view->pending_width,
224 xwayland_view->pending_height); 224 xwayland_view->pending_height);
225 view_damage(view, false); 225 view_damage_from(view);
226 view_update_title(view, false); 226 view_update_title(view, false);
227} 227}
228 228