diff options
-rw-r--r-- | sway/desktop/output.c | 167 |
1 files changed, 91 insertions, 76 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 9eeed9b9..47461736 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -189,6 +189,36 @@ static void scissor_output(struct wlr_output *wlr_output, | |||
189 | wlr_renderer_scissor(renderer, &box); | 189 | wlr_renderer_scissor(renderer, &box); |
190 | } | 190 | } |
191 | 191 | ||
192 | static 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 | struct wlr_box box = *_box; | ||
199 | scale_box(&box, wlr_output->scale); | ||
200 | |||
201 | pixman_region32_t damage; | ||
202 | pixman_region32_init(&damage); | ||
203 | pixman_region32_union_rect(&damage, &damage, box.x, box.y, | ||
204 | box.width, box.height); | ||
205 | pixman_region32_intersect(&damage, &damage, output_damage); | ||
206 | bool damaged = pixman_region32_not_empty(&damage); | ||
207 | if (!damaged) { | ||
208 | goto damage_finish; | ||
209 | } | ||
210 | |||
211 | int nrects; | ||
212 | pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); | ||
213 | for (int i = 0; i < nrects; ++i) { | ||
214 | scissor_output(wlr_output, &rects[i]); | ||
215 | wlr_render_texture_with_matrix(renderer, texture, matrix, alpha); | ||
216 | } | ||
217 | |||
218 | damage_finish: | ||
219 | pixman_region32_fini(&damage); | ||
220 | } | ||
221 | |||
192 | static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, | 222 | static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, |
193 | void *_data) { | 223 | void *_data) { |
194 | struct render_data *data = _data; | 224 | struct render_data *data = _data; |
@@ -208,41 +238,14 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, | |||
208 | return; | 238 | return; |
209 | } | 239 | } |
210 | 240 | ||
211 | scale_box(&box, wlr_output->scale); | ||
212 | |||
213 | pixman_region32_t damage; | ||
214 | pixman_region32_init(&damage); | ||
215 | pixman_region32_union_rect(&damage, &damage, box.x, box.y, | ||
216 | box.width, box.height); | ||
217 | pixman_region32_intersect(&damage, &damage, output_damage); | ||
218 | bool damaged = pixman_region32_not_empty(&damage); | ||
219 | if (!damaged) { | ||
220 | goto damage_finish; | ||
221 | } | ||
222 | |||
223 | struct wlr_renderer *renderer = | ||
224 | wlr_backend_get_renderer(wlr_output->backend); | ||
225 | if (!sway_assert(renderer != NULL, | ||
226 | "expected the output backend to have a renderer")) { | ||
227 | return; | ||
228 | } | ||
229 | |||
230 | float matrix[9]; | 241 | float matrix[9]; |
231 | enum wl_output_transform transform = | 242 | enum wl_output_transform transform = |
232 | wlr_output_transform_invert(surface->current->transform); | 243 | wlr_output_transform_invert(surface->current->transform); |
233 | wlr_matrix_project_box(matrix, &box, transform, rotation, | 244 | wlr_matrix_project_box(matrix, &box, transform, rotation, |
234 | wlr_output->transform_matrix); | 245 | wlr_output->transform_matrix); |
235 | 246 | ||
236 | int nrects; | 247 | render_texture(wlr_output, output_damage, surface->texture, &box, matrix, |
237 | pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); | 248 | alpha); |
238 | for (int i = 0; i < nrects; ++i) { | ||
239 | scissor_output(wlr_output, &rects[i]); | ||
240 | wlr_render_texture_with_matrix(renderer, surface->texture, matrix, | ||
241 | alpha); | ||
242 | } | ||
243 | |||
244 | damage_finish: | ||
245 | pixman_region32_fini(&damage); | ||
246 | } | 249 | } |
247 | 250 | ||
248 | static void render_layer(struct sway_output *output, | 251 | static void render_layer(struct sway_output *output, |
@@ -278,14 +281,44 @@ static void render_view(struct sway_view *view, struct sway_output *output, | |||
278 | view, &data.root_geo, render_surface_iterator, &data); | 281 | view, &data.root_geo, render_surface_iterator, &data); |
279 | } | 282 | } |
280 | 283 | ||
284 | static void render_rect(struct wlr_output *wlr_output, | ||
285 | pixman_region32_t *output_damage, const struct wlr_box *_box, | ||
286 | float color[static 4]) { | ||
287 | struct wlr_renderer *renderer = | ||
288 | wlr_backend_get_renderer(wlr_output->backend); | ||
289 | |||
290 | struct wlr_box box = *_box; | ||
291 | scale_box(&box, wlr_output->scale); | ||
292 | |||
293 | pixman_region32_t damage; | ||
294 | pixman_region32_init(&damage); | ||
295 | pixman_region32_union_rect(&damage, &damage, box.x, box.y, | ||
296 | box.width, box.height); | ||
297 | pixman_region32_intersect(&damage, &damage, output_damage); | ||
298 | bool damaged = pixman_region32_not_empty(&damage); | ||
299 | if (!damaged) { | ||
300 | goto damage_finish; | ||
301 | } | ||
302 | |||
303 | int nrects; | ||
304 | pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); | ||
305 | for (int i = 0; i < nrects; ++i) { | ||
306 | scissor_output(wlr_output, &rects[i]); | ||
307 | wlr_render_rect(renderer, &box, color, | ||
308 | wlr_output->transform_matrix); | ||
309 | } | ||
310 | |||
311 | damage_finish: | ||
312 | pixman_region32_fini(&damage); | ||
313 | } | ||
314 | |||
281 | /** | 315 | /** |
282 | * Render decorations for a view with "border normal". | 316 | * Render decorations for a view with "border normal". |
283 | */ | 317 | */ |
284 | static void render_container_simple_border_normal(struct sway_output *output, | 318 | static void render_container_simple_border_normal(struct sway_output *output, |
319 | pixman_region32_t *output_damage, | ||
285 | struct sway_container *con, struct border_colors *colors, | 320 | struct sway_container *con, struct border_colors *colors, |
286 | struct wlr_texture *title_texture) { | 321 | struct wlr_texture *title_texture) { |
287 | struct wlr_renderer *renderer = | ||
288 | wlr_backend_get_renderer(output->wlr_output->backend); | ||
289 | struct wlr_box box; | 322 | struct wlr_box box; |
290 | float color[4]; | 323 | float color[4]; |
291 | 324 | ||
@@ -296,9 +329,7 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
296 | box.y = con->y + 1; | 329 | box.y = con->y + 1; |
297 | box.width = con->sway_view->border_thickness; | 330 | box.width = con->sway_view->border_thickness; |
298 | box.height = con->height - 1; | 331 | box.height = con->height - 1; |
299 | scale_box(&box, output->wlr_output->scale); | 332 | render_rect(output->wlr_output, output_damage, &box, color); |
300 | wlr_render_rect(renderer, &box, color, | ||
301 | output->wlr_output->transform_matrix); | ||
302 | 333 | ||
303 | // Child border - right edge | 334 | // Child border - right edge |
304 | if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { | 335 | if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { |
@@ -311,9 +342,7 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
311 | box.y = con->y + 1; | 342 | box.y = con->y + 1; |
312 | box.width = con->sway_view->border_thickness; | 343 | box.width = con->sway_view->border_thickness; |
313 | box.height = con->height - 1; | 344 | box.height = con->height - 1; |
314 | scale_box(&box, output->wlr_output->scale); | 345 | render_rect(output->wlr_output, output_damage, &box, color); |
315 | wlr_render_rect(renderer, &box, color, | ||
316 | output->wlr_output->transform_matrix); | ||
317 | 346 | ||
318 | // Child border - bottom edge | 347 | // Child border - bottom edge |
319 | if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { | 348 | if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { |
@@ -326,9 +355,7 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
326 | box.y = con->y + con->height - con->sway_view->border_thickness; | 355 | box.y = con->y + con->height - con->sway_view->border_thickness; |
327 | box.width = con->width; | 356 | box.width = con->width; |
328 | box.height = con->sway_view->border_thickness; | 357 | box.height = con->sway_view->border_thickness; |
329 | scale_box(&box, output->wlr_output->scale); | 358 | render_rect(output->wlr_output, output_damage, &box, color); |
330 | wlr_render_rect(renderer, &box, color, | ||
331 | output->wlr_output->transform_matrix); | ||
332 | 359 | ||
333 | // Single pixel bar above title | 360 | // Single pixel bar above title |
334 | memcpy(&color, colors->border, sizeof(float) * 4); | 361 | memcpy(&color, colors->border, sizeof(float) * 4); |
@@ -337,18 +364,14 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
337 | box.y = con->y; | 364 | box.y = con->y; |
338 | box.width = con->width; | 365 | box.width = con->width; |
339 | box.height = 1; | 366 | box.height = 1; |
340 | scale_box(&box, output->wlr_output->scale); | 367 | render_rect(output->wlr_output, output_damage, &box, color); |
341 | wlr_render_rect(renderer, &box, color, | ||
342 | output->wlr_output->transform_matrix); | ||
343 | 368 | ||
344 | // Single pixel bar below title | 369 | // Single pixel bar below title |
345 | box.x = con->x + con->sway_view->border_thickness; | 370 | box.x = con->x + con->sway_view->border_thickness; |
346 | box.y = con->sway_view->y - 1; | 371 | box.y = con->sway_view->y - 1; |
347 | box.width = con->width - con->sway_view->border_thickness * 2; | 372 | box.width = con->width - con->sway_view->border_thickness * 2; |
348 | box.height = 1; | 373 | box.height = 1; |
349 | scale_box(&box, output->wlr_output->scale); | 374 | render_rect(output->wlr_output, output_damage, &box, color); |
350 | wlr_render_rect(renderer, &box, color, | ||
351 | output->wlr_output->transform_matrix); | ||
352 | 375 | ||
353 | // Title background | 376 | // Title background |
354 | memcpy(&color, colors->background, sizeof(float) * 4); | 377 | memcpy(&color, colors->background, sizeof(float) * 4); |
@@ -357,20 +380,20 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
357 | box.y = con->y + 1; | 380 | box.y = con->y + 1; |
358 | box.width = con->width - con->sway_view->border_thickness * 2; | 381 | box.width = con->width - con->sway_view->border_thickness * 2; |
359 | box.height = con->sway_view->y - con->y - 2; | 382 | box.height = con->sway_view->y - con->y - 2; |
360 | scale_box(&box, output->wlr_output->scale); | 383 | render_rect(output->wlr_output, output_damage, &box, color); |
361 | wlr_render_rect(renderer, &box, color, | ||
362 | output->wlr_output->transform_matrix); | ||
363 | 384 | ||
364 | // Title text | 385 | // Title text |
365 | if (title_texture) { | 386 | if (title_texture) { |
366 | struct wlr_box scissor_box; | 387 | struct wlr_box texture_box = { .x = box.x, .y = box.y }; |
367 | wlr_box_transform(&box, | 388 | wlr_texture_get_size(title_texture, |
368 | wlr_output_transform_invert(output->wlr_output->transform), | 389 | &texture_box.width, &texture_box.height); |
369 | output->swayc->width, output->swayc->height, &scissor_box); | 390 | |
370 | wlr_renderer_scissor(renderer, &scissor_box); | 391 | float matrix[9]; |
371 | wlr_render_texture(renderer, title_texture, | 392 | wlr_matrix_project_box(matrix, &texture_box, WL_OUTPUT_TRANSFORM_NORMAL, |
372 | output->wlr_output->transform_matrix, box.x, box.y, 1); | 393 | 0.0, output->wlr_output->transform_matrix); |
373 | wlr_renderer_scissor(renderer, NULL); | 394 | |
395 | render_texture(output->wlr_output, output_damage, title_texture, &box, | ||
396 | matrix, 1.0); | ||
374 | } | 397 | } |
375 | } | 398 | } |
376 | 399 | ||
@@ -378,9 +401,8 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
378 | * Render decorations for a view with "border pixel". | 401 | * Render decorations for a view with "border pixel". |
379 | */ | 402 | */ |
380 | static void render_container_simple_border_pixel(struct sway_output *output, | 403 | static void render_container_simple_border_pixel(struct sway_output *output, |
381 | struct sway_container *con, struct border_colors *colors) { | 404 | pixman_region32_t *output_damage, struct sway_container *con, |
382 | struct wlr_renderer *renderer = | 405 | struct border_colors *colors) { |
383 | wlr_backend_get_renderer(output->wlr_output->backend); | ||
384 | struct wlr_box box; | 406 | struct wlr_box box; |
385 | float color[4]; | 407 | float color[4]; |
386 | 408 | ||
@@ -391,9 +413,7 @@ static void render_container_simple_border_pixel(struct sway_output *output, | |||
391 | box.y = con->y; | 413 | box.y = con->y; |
392 | box.width = con->sway_view->border_thickness; | 414 | box.width = con->sway_view->border_thickness; |
393 | box.height = con->height; | 415 | box.height = con->height; |
394 | scale_box(&box, output->wlr_output->scale); | 416 | render_rect(output->wlr_output, output_damage, &box, color); |
395 | wlr_render_rect(renderer, &box, color, | ||
396 | output->wlr_output->transform_matrix); | ||
397 | 417 | ||
398 | // Child border - right edge | 418 | // Child border - right edge |
399 | if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { | 419 | if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { |
@@ -406,18 +426,14 @@ static void render_container_simple_border_pixel(struct sway_output *output, | |||
406 | box.y = con->y; | 426 | box.y = con->y; |
407 | box.width = con->sway_view->border_thickness; | 427 | box.width = con->sway_view->border_thickness; |
408 | box.height = con->height; | 428 | box.height = con->height; |
409 | scale_box(&box, output->wlr_output->scale); | 429 | render_rect(output->wlr_output, output_damage, &box, color); |
410 | wlr_render_rect(renderer, &box, color, | ||
411 | output->wlr_output->transform_matrix); | ||
412 | 430 | ||
413 | // Child border - top edge | 431 | // Child border - top edge |
414 | box.x = con->x; | 432 | box.x = con->x; |
415 | box.y = con->y; | 433 | box.y = con->y; |
416 | box.width = con->width; | 434 | box.width = con->width; |
417 | box.height = con->sway_view->border_thickness; | 435 | box.height = con->sway_view->border_thickness; |
418 | scale_box(&box, output->wlr_output->scale); | 436 | render_rect(output->wlr_output, output_damage, &box, color); |
419 | wlr_render_rect(renderer, &box, color, | ||
420 | output->wlr_output->transform_matrix); | ||
421 | 437 | ||
422 | // Child border - bottom edge | 438 | // Child border - bottom edge |
423 | if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { | 439 | if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { |
@@ -430,9 +446,7 @@ static void render_container_simple_border_pixel(struct sway_output *output, | |||
430 | box.y = con->y + con->height - con->sway_view->border_thickness; | 446 | box.y = con->y + con->height - con->sway_view->border_thickness; |
431 | box.width = con->width; | 447 | box.width = con->width; |
432 | box.height = con->sway_view->border_thickness; | 448 | box.height = con->sway_view->border_thickness; |
433 | scale_box(&box, output->wlr_output->scale); | 449 | render_rect(output->wlr_output, output_damage, &box, color); |
434 | wlr_render_rect(renderer, &box, color, | ||
435 | output->wlr_output->transform_matrix); | ||
436 | } | 450 | } |
437 | 451 | ||
438 | static void render_container(struct sway_output *output, | 452 | static void render_container(struct sway_output *output, |
@@ -468,10 +482,11 @@ static void render_container_simple(struct sway_output *output, | |||
468 | } | 482 | } |
469 | 483 | ||
470 | if (child->sway_view->border == B_NORMAL) { | 484 | if (child->sway_view->border == B_NORMAL) { |
471 | render_container_simple_border_normal(output, child, | 485 | render_container_simple_border_normal(output, damage, |
472 | colors, title_texture); | 486 | child, colors, title_texture); |
473 | } else { | 487 | } else { |
474 | render_container_simple_border_pixel(output, child, colors); | 488 | render_container_simple_border_pixel(output, damage, child, |
489 | colors); | ||
475 | } | 490 | } |
476 | } | 491 | } |
477 | render_view(child->sway_view, output, damage); | 492 | render_view(child->sway_view, output, damage); |
@@ -551,7 +566,7 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
551 | goto renderer_end; | 566 | goto renderer_end; |
552 | } | 567 | } |
553 | 568 | ||
554 | wlr_renderer_clear(renderer, (float[]){1, 1, 0, 0}); | 569 | //wlr_renderer_clear(renderer, (float[]){1, 1, 0, 0}); |
555 | 570 | ||
556 | struct sway_container *workspace = output_get_active_workspace(output); | 571 | struct sway_container *workspace = output_get_active_workspace(output); |
557 | 572 | ||