aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/render.c')
-rw-r--r--sway/desktop/render.c124
1 files changed, 80 insertions, 44 deletions
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index bd85282c..bf1b8666 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -32,6 +32,7 @@
32struct render_data { 32struct render_data {
33 pixman_region32_t *damage; 33 pixman_region32_t *damage;
34 float alpha; 34 float alpha;
35 struct wlr_box *clip_box;
35}; 36};
36 37
37/** 38/**
@@ -104,9 +105,6 @@ static void render_texture(struct wlr_output *wlr_output,
104 wlr_backend_get_renderer(wlr_output->backend); 105 wlr_backend_get_renderer(wlr_output->backend);
105 struct sway_output *output = wlr_output->data; 106 struct sway_output *output = wlr_output->data;
106 107
107 struct wlr_gles2_texture_attribs attribs;
108 wlr_gles2_texture_get_attribs(texture, &attribs);
109
110 pixman_region32_t damage; 108 pixman_region32_t damage;
111 pixman_region32_init(&damage); 109 pixman_region32_init(&damage);
112 pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y, 110 pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y,
@@ -133,9 +131,9 @@ damage_finish:
133 pixman_region32_fini(&damage); 131 pixman_region32_fini(&damage);
134} 132}
135 133
136static void render_surface_iterator(struct sway_output *output, struct sway_view *view, 134static void render_surface_iterator(struct sway_output *output,
137 struct wlr_surface *surface, struct wlr_box *_box, float rotation, 135 struct sway_view *view, struct wlr_surface *surface,
138 void *_data) { 136 struct wlr_box *_box, void *_data) {
139 struct render_data *data = _data; 137 struct render_data *data = _data;
140 struct wlr_output *wlr_output = output->wlr_output; 138 struct wlr_output *wlr_output = output->wlr_output;
141 pixman_region32_t *output_damage = data->damage; 139 pixman_region32_t *output_damage = data->damage;
@@ -149,15 +147,23 @@ static void render_surface_iterator(struct sway_output *output, struct sway_view
149 struct wlr_fbox src_box; 147 struct wlr_fbox src_box;
150 wlr_surface_get_buffer_source_box(surface, &src_box); 148 wlr_surface_get_buffer_source_box(surface, &src_box);
151 149
152 struct wlr_box dst_box = *_box; 150 struct wlr_box proj_box = *_box;
153 scale_box(&dst_box, wlr_output->scale); 151 scale_box(&proj_box, wlr_output->scale);
154 152
155 float matrix[9]; 153 float matrix[9];
156 enum wl_output_transform transform = 154 enum wl_output_transform transform =
157 wlr_output_transform_invert(surface->current.transform); 155 wlr_output_transform_invert(surface->current.transform);
158 wlr_matrix_project_box(matrix, &dst_box, transform, rotation, 156 wlr_matrix_project_box(matrix, &proj_box, transform, 0.0,
159 wlr_output->transform_matrix); 157 wlr_output->transform_matrix);
160 158
159 struct wlr_box dst_box = *_box;
160 struct wlr_box *clip_box = data->clip_box;
161 if (clip_box != NULL) {
162 dst_box.width = fmin(dst_box.width, clip_box->width);
163 dst_box.height = fmin(dst_box.height, clip_box->height);
164 }
165 scale_box(&dst_box, wlr_output->scale);
166
161 render_texture(wlr_output, output_damage, texture, 167 render_texture(wlr_output, output_damage, texture,
162 &src_box, &dst_box, matrix, alpha); 168 &src_box, &dst_box, matrix, alpha);
163 169
@@ -256,6 +262,14 @@ static void render_view_toplevels(struct sway_view *view,
256 .damage = damage, 262 .damage = damage,
257 .alpha = alpha, 263 .alpha = alpha,
258 }; 264 };
265 struct wlr_box clip_box;
266 if (!container_is_current_floating(view->container)) {
267 // As we pass the geometry offsets to the surface iterator, we will
268 // need to account for the offsets in the clip dimensions.
269 clip_box.width = view->container->current.content_width + view->geometry.x;
270 clip_box.height = view->container->current.content_height + view->geometry.y;
271 data.clip_box = &clip_box;
272 }
259 // Render all toplevels without descending into popups 273 // Render all toplevels without descending into popups
260 double ox = view->container->surface_x - 274 double ox = view->container->surface_x -
261 output->lx - view->geometry.x; 275 output->lx - view->geometry.x;
@@ -282,17 +296,18 @@ static void render_saved_view(struct sway_view *view,
282 if (wl_list_empty(&view->saved_buffers)) { 296 if (wl_list_empty(&view->saved_buffers)) {
283 return; 297 return;
284 } 298 }
299
300 bool floating = container_is_current_floating(view->container);
301
285 struct sway_saved_buffer *saved_buf; 302 struct sway_saved_buffer *saved_buf;
286 wl_list_for_each(saved_buf, &view->saved_buffers, link) { 303 wl_list_for_each(saved_buf, &view->saved_buffers, link) {
287 if (!saved_buf->buffer->texture) { 304 if (!saved_buf->buffer->texture) {
288 continue; 305 continue;
289 } 306 }
290 307
291 struct wlr_box box = { 308 struct wlr_box proj_box = {
292 .x = view->container->surface_x - output->lx - 309 .x = saved_buf->x - view->saved_geometry.x - output->lx,
293 view->saved_geometry.x + saved_buf->x, 310 .y = saved_buf->y - view->saved_geometry.y - output->ly,
294 .y = view->container->surface_y - output->ly -
295 view->saved_geometry.y + saved_buf->y,
296 .width = saved_buf->width, 311 .width = saved_buf->width,
297 .height = saved_buf->height, 312 .height = saved_buf->height,
298 }; 313 };
@@ -303,20 +318,31 @@ static void render_saved_view(struct sway_view *view,
303 }; 318 };
304 319
305 struct wlr_box intersection; 320 struct wlr_box intersection;
306 bool intersects = wlr_box_intersection(&intersection, &output_box, &box); 321 bool intersects = wlr_box_intersection(&intersection, &output_box, &proj_box);
307 if (!intersects) { 322 if (!intersects) {
308 continue; 323 continue;
309 } 324 }
310 325
311 scale_box(&box, wlr_output->scale); 326 struct wlr_box dst_box = proj_box;
327 scale_box(&proj_box, wlr_output->scale);
312 328
313 float matrix[9]; 329 float matrix[9];
314 enum wl_output_transform transform = wlr_output_transform_invert(saved_buf->transform); 330 enum wl_output_transform transform = wlr_output_transform_invert(saved_buf->transform);
315 wlr_matrix_project_box(matrix, &box, transform, 0, 331 wlr_matrix_project_box(matrix, &proj_box, transform, 0,
316 wlr_output->transform_matrix); 332 wlr_output->transform_matrix);
317 333
334 if (!floating) {
335 dst_box.width = fmin(dst_box.width,
336 view->container->current.content_width -
337 (saved_buf->x - view->container->current.content_x) + view->saved_geometry.x);
338 dst_box.height = fmin(dst_box.height,
339 view->container->current.content_height -
340 (saved_buf->y - view->container->current.content_y) + view->saved_geometry.y);
341 }
342 scale_box(&dst_box, wlr_output->scale);
343
318 render_texture(wlr_output, damage, saved_buf->buffer->texture, 344 render_texture(wlr_output, damage, saved_buf->buffer->texture,
319 &saved_buf->source_box, &box, matrix, alpha); 345 &saved_buf->source_box, &dst_box, matrix, alpha);
320 } 346 }
321 347
322 // FIXME: we should set the surface that this saved buffer originates from 348 // FIXME: we should set the surface that this saved buffer originates from
@@ -348,8 +374,8 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
348 if (state->border_left) { 374 if (state->border_left) {
349 memcpy(&color, colors->child_border, sizeof(float) * 4); 375 memcpy(&color, colors->child_border, sizeof(float) * 4);
350 premultiply_alpha(color, con->alpha); 376 premultiply_alpha(color, con->alpha);
351 box.x = state->x; 377 box.x = floor(state->x);
352 box.y = state->content_y; 378 box.y = floor(state->content_y);
353 box.width = state->border_thickness; 379 box.width = state->border_thickness;
354 box.height = state->content_height; 380 box.height = state->content_height;
355 scale_box(&box, output_scale); 381 scale_box(&box, output_scale);
@@ -361,14 +387,14 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
361 container_current_parent_layout(con); 387 container_current_parent_layout(con);
362 388
363 if (state->border_right) { 389 if (state->border_right) {
364 if (!container_is_floating(con) && siblings->length == 1 && layout == L_HORIZ) { 390 if (!container_is_current_floating(con) && siblings->length == 1 && layout == L_HORIZ) {
365 memcpy(&color, colors->indicator, sizeof(float) * 4); 391 memcpy(&color, colors->indicator, sizeof(float) * 4);
366 } else { 392 } else {
367 memcpy(&color, colors->child_border, sizeof(float) * 4); 393 memcpy(&color, colors->child_border, sizeof(float) * 4);
368 } 394 }
369 premultiply_alpha(color, con->alpha); 395 premultiply_alpha(color, con->alpha);
370 box.x = state->content_x + state->content_width; 396 box.x = floor(state->content_x + state->content_width);
371 box.y = state->content_y; 397 box.y = floor(state->content_y);
372 box.width = state->border_thickness; 398 box.width = state->border_thickness;
373 box.height = state->content_height; 399 box.height = state->content_height;
374 scale_box(&box, output_scale); 400 scale_box(&box, output_scale);
@@ -376,14 +402,14 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
376 } 402 }
377 403
378 if (state->border_bottom) { 404 if (state->border_bottom) {
379 if (!container_is_floating(con) && siblings->length == 1 && layout == L_VERT) { 405 if (!container_is_current_floating(con) && siblings->length == 1 && layout == L_VERT) {
380 memcpy(&color, colors->indicator, sizeof(float) * 4); 406 memcpy(&color, colors->indicator, sizeof(float) * 4);
381 } else { 407 } else {
382 memcpy(&color, colors->child_border, sizeof(float) * 4); 408 memcpy(&color, colors->child_border, sizeof(float) * 4);
383 } 409 }
384 premultiply_alpha(color, con->alpha); 410 premultiply_alpha(color, con->alpha);
385 box.x = state->x; 411 box.x = floor(state->x);
386 box.y = state->content_y + state->content_height; 412 box.y = floor(state->content_y + state->content_height);
387 box.width = state->width; 413 box.width = state->width;
388 box.height = state->border_thickness; 414 box.height = state->border_thickness;
389 scale_box(&box, output_scale); 415 scale_box(&box, output_scale);
@@ -464,9 +490,10 @@ static void render_titlebar(struct sway_output *output,
464 int ob_marks_x = 0; // output-buffer-local 490 int ob_marks_x = 0; // output-buffer-local
465 int ob_marks_width = 0; // output-buffer-local 491 int ob_marks_width = 0; // output-buffer-local
466 if (config->show_marks && marks_texture) { 492 if (config->show_marks && marks_texture) {
467 struct wlr_box texture_box; 493 struct wlr_box texture_box = {
468 wlr_texture_get_size(marks_texture, 494 .width = marks_texture->width,
469 &texture_box.width, &texture_box.height); 495 .height = marks_texture->height,
496 };
470 ob_marks_width = texture_box.width; 497 ob_marks_width = texture_box.width;
471 498
472 // The marks texture might be shorter than the config->font_height, in 499 // The marks texture might be shorter than the config->font_height, in
@@ -517,9 +544,18 @@ static void render_titlebar(struct sway_output *output,
517 int ob_title_x = 0; // output-buffer-local 544 int ob_title_x = 0; // output-buffer-local
518 int ob_title_width = 0; // output-buffer-local 545 int ob_title_width = 0; // output-buffer-local
519 if (title_texture) { 546 if (title_texture) {
520 struct wlr_box texture_box; 547 struct wlr_box texture_box = {
521 wlr_texture_get_size(title_texture, 548 .width = title_texture->width,
522 &texture_box.width, &texture_box.height); 549 .height = title_texture->height,
550 };
551
552 // The effective output may be NULL when con is not on any output.
553 // This can happen because we render all children of containers,
554 // even those that are out of the bounds of any output.
555 struct sway_output *effective = container_get_effective_output(con);
556 float title_scale = effective ? effective->wlr_output->scale : output_scale;
557 texture_box.width = texture_box.width * output_scale / title_scale;
558 texture_box.height = texture_box.height * output_scale / title_scale;
523 ob_title_width = texture_box.width; 559 ob_title_width = texture_box.width;
524 560
525 // The title texture might be shorter than the config->font_height, 561 // The title texture might be shorter than the config->font_height,
@@ -660,8 +696,8 @@ static void render_top_border(struct sway_output *output,
660 // Child border - top edge 696 // Child border - top edge
661 memcpy(&color, colors->child_border, sizeof(float) * 4); 697 memcpy(&color, colors->child_border, sizeof(float) * 4);
662 premultiply_alpha(color, con->alpha); 698 premultiply_alpha(color, con->alpha);
663 box.x = state->x; 699 box.x = floor(state->x);
664 box.y = state->y; 700 box.y = floor(state->y);
665 box.width = state->width; 701 box.width = state->width;
666 box.height = state->border_thickness; 702 box.height = state->border_thickness;
667 scale_box(&box, output_scale); 703 scale_box(&box, output_scale);
@@ -716,8 +752,8 @@ static void render_containers_linear(struct sway_output *output,
716 } 752 }
717 753
718 if (state->border == B_NORMAL) { 754 if (state->border == B_NORMAL) {
719 render_titlebar(output, damage, child, state->x, 755 render_titlebar(output, damage, child, floor(state->x),
720 state->y, state->width, colors, 756 floor(state->y), state->width, colors,
721 title_texture, marks_texture); 757 title_texture, marks_texture);
722 } else if (state->border == B_PIXEL) { 758 } else if (state->border == B_PIXEL) {
723 render_top_border(output, damage, child, colors); 759 render_top_border(output, damage, child, colors);
@@ -771,7 +807,7 @@ static void render_containers_tabbed(struct sway_output *output,
771 marks_texture = child->marks_unfocused; 807 marks_texture = child->marks_unfocused;
772 } 808 }
773 809
774 int x = cstate->x + tab_width * i; 810 int x = floor(cstate->x + tab_width * i);
775 811
776 // Make last tab use the remaining width of the parent 812 // Make last tab use the remaining width of the parent
777 if (i == parent->children->length - 1) { 813 if (i == parent->children->length - 1) {
@@ -884,8 +920,8 @@ static void render_container(struct sway_output *output,
884 struct parent_data data = { 920 struct parent_data data = {
885 .layout = con->current.layout, 921 .layout = con->current.layout,
886 .box = { 922 .box = {
887 .x = con->current.x, 923 .x = floor(con->current.x),
888 .y = con->current.y, 924 .y = floor(con->current.y),
889 .width = con->current.width, 925 .width = con->current.width,
890 .height = con->current.height, 926 .height = con->current.height,
891 }, 927 },
@@ -901,8 +937,8 @@ static void render_workspace(struct sway_output *output,
901 struct parent_data data = { 937 struct parent_data data = {
902 .layout = ws->current.layout, 938 .layout = ws->current.layout,
903 .box = { 939 .box = {
904 .x = ws->current.x, 940 .x = floor(ws->current.x),
905 .y = ws->current.y, 941 .y = floor(ws->current.y),
906 .width = ws->current.width, 942 .width = ws->current.width,
907 .height = ws->current.height, 943 .height = ws->current.height,
908 }, 944 },
@@ -936,8 +972,8 @@ static void render_floating_container(struct sway_output *soutput,
936 } 972 }
937 973
938 if (con->current.border == B_NORMAL) { 974 if (con->current.border == B_NORMAL) {
939 render_titlebar(soutput, damage, con, con->current.x, 975 render_titlebar(soutput, damage, con, floor(con->current.x),
940 con->current.y, con->current.width, colors, 976 floor(con->current.y), con->current.width, colors,
941 title_texture, marks_texture); 977 title_texture, marks_texture);
942 } else if (con->current.border == B_PIXEL) { 978 } else if (con->current.border == B_PIXEL) {
943 render_top_border(soutput, damage, con, colors); 979 render_top_border(soutput, damage, con, colors);
@@ -959,7 +995,7 @@ static void render_floating(struct sway_output *soutput,
959 } 995 }
960 for (int k = 0; k < ws->current.floating->length; ++k) { 996 for (int k = 0; k < ws->current.floating->length; ++k) {
961 struct sway_container *floater = ws->current.floating->items[k]; 997 struct sway_container *floater = ws->current.floating->items[k];
962 if (floater->fullscreen_mode != FULLSCREEN_NONE) { 998 if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
963 continue; 999 continue;
964 } 1000 }
965 render_floating_container(soutput, damage, floater); 1001 render_floating_container(soutput, damage, floater);