aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar Simon Ser <contact@emersion.fr>2023-06-05 14:35:15 +0200
committerLibravatar Ronan Pigott <ronan@rjp.ie>2023-06-08 14:33:23 -0700
commitf3b8c9feeed9f79fc8f06e7f1dcfaadde522ce90 (patch)
tree21201243a154537b3d498b42cbe60661eeba4d3b /sway/desktop/output.c
parentHandle gamma-control-v1 set_gamma events (diff)
downloadsway-f3b8c9feeed9f79fc8f06e7f1dcfaadde522ce90.tar.gz
sway-f3b8c9feeed9f79fc8f06e7f1dcfaadde522ce90.tar.zst
sway-f3b8c9feeed9f79fc8f06e7f1dcfaadde522ce90.zip
desktop/output: use detached output state for page-flips
This avoids relying on the implicit wlr_output.pending state.
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 09353c15..9934576c 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -458,7 +458,7 @@ static void count_surface_iterator(struct sway_output *output,
458} 458}
459 459
460static bool scan_out_fullscreen_view(struct sway_output *output, 460static bool scan_out_fullscreen_view(struct sway_output *output,
461 struct sway_view *view) { 461 struct wlr_output_state *pending, struct sway_view *view) {
462 struct wlr_output *wlr_output = output->wlr_output; 462 struct wlr_output *wlr_output = output->wlr_output;
463 struct sway_workspace *workspace = output->current.active_workspace; 463 struct sway_workspace *workspace = output->current.active_workspace;
464 if (!sway_assert(workspace, "Expected an active workspace")) { 464 if (!sway_assert(workspace, "Expected an active workspace")) {
@@ -524,15 +524,16 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
524 return false; 524 return false;
525 } 525 }
526 526
527 wlr_output_attach_buffer(wlr_output, &surface->buffer->base); 527 wlr_output_state_set_buffer(pending, &surface->buffer->base);
528 if (!wlr_output_test(wlr_output)) { 528
529 if (!wlr_output_test_state(wlr_output, pending)) {
529 return false; 530 return false;
530 } 531 }
531 532
532 wlr_presentation_surface_sampled_on_output(server.presentation, surface, 533 wlr_presentation_surface_sampled_on_output(server.presentation, surface,
533 wlr_output); 534 wlr_output);
534 535
535 return wlr_output_commit(wlr_output); 536 return wlr_output_commit_state(wlr_output, pending);
536} 537}
537 538
538static void get_frame_damage(struct sway_output *output, 539static void get_frame_damage(struct sway_output *output,
@@ -580,29 +581,30 @@ static int output_repaint_timer_handler(void *data) {
580 fullscreen_con = workspace->current.fullscreen; 581 fullscreen_con = workspace->current.fullscreen;
581 } 582 }
582 583
584 struct wlr_output_state pending = {0};
585
583 if (output->gamma_lut_changed) { 586 if (output->gamma_lut_changed) {
584 struct wlr_gamma_control_v1 *gamma_control = 587 struct wlr_gamma_control_v1 *gamma_control =
585 wlr_gamma_control_manager_v1_get_control( 588 wlr_gamma_control_manager_v1_get_control(
586 server.gamma_control_manager_v1, wlr_output); 589 server.gamma_control_manager_v1, wlr_output);
587 if (!wlr_gamma_control_v1_apply(gamma_control, &wlr_output->pending)) { 590 if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
588 return 0; 591 goto out;
589 } 592 }
590 if (!wlr_output_test(wlr_output)) { 593 if (!wlr_output_test_state(wlr_output, &pending)) {
591 wlr_output_rollback(wlr_output); 594 wlr_output_state_finish(&pending);
595 pending = (struct wlr_output_state){0};
592 wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); 596 wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
593 } 597 }
594 } 598 }
595 599
596 pixman_region32_t frame_damage; 600 pending.committed |= WLR_OUTPUT_STATE_BUFFER;
597 get_frame_damage(output, &frame_damage); 601 get_frame_damage(output, &pending.damage);
598 wlr_output_set_damage(wlr_output, &frame_damage);
599 pixman_region32_fini(&frame_damage);
600 602
601 if (fullscreen_con && fullscreen_con->view && !debug.noscanout) { 603 if (fullscreen_con && fullscreen_con->view && !debug.noscanout) {
602 // Try to scan-out the fullscreen view 604 // Try to scan-out the fullscreen view
603 static bool last_scanned_out = false; 605 static bool last_scanned_out = false;
604 bool scanned_out = 606 bool scanned_out =
605 scan_out_fullscreen_view(output, fullscreen_con->view); 607 scan_out_fullscreen_view(output, &pending, fullscreen_con->view);
606 608
607 if (scanned_out && !last_scanned_out) { 609 if (scanned_out && !last_scanned_out) {
608 sway_log(SWAY_DEBUG, "Scanning out fullscreen view on %s", 610 sway_log(SWAY_DEBUG, "Scanning out fullscreen view on %s",
@@ -616,25 +618,25 @@ static int output_repaint_timer_handler(void *data) {
616 last_scanned_out = scanned_out; 618 last_scanned_out = scanned_out;
617 619
618 if (scanned_out) { 620 if (scanned_out) {
619 return 0; 621 goto out;
620 } 622 }
621 } 623 }
622 624
623 if (!wlr_output_configure_primary_swapchain(wlr_output, NULL, &wlr_output->swapchain)) { 625 if (!wlr_output_configure_primary_swapchain(wlr_output, &pending, &wlr_output->swapchain)) {
624 return false; 626 goto out;
625 } 627 }
626 628
627 int buffer_age; 629 int buffer_age;
628 struct wlr_buffer *buffer = wlr_swapchain_acquire(wlr_output->swapchain, &buffer_age); 630 struct wlr_buffer *buffer = wlr_swapchain_acquire(wlr_output->swapchain, &buffer_age);
629 if (buffer == NULL) { 631 if (buffer == NULL) {
630 return false; 632 goto out;
631 } 633 }
632 634
633 struct wlr_render_pass *render_pass = wlr_renderer_begin_buffer_pass( 635 struct wlr_render_pass *render_pass = wlr_renderer_begin_buffer_pass(
634 wlr_output->renderer, buffer, NULL); 636 wlr_output->renderer, buffer, NULL);
635 if (render_pass == NULL) { 637 if (render_pass == NULL) {
636 wlr_buffer_unlock(buffer); 638 wlr_buffer_unlock(buffer);
637 return false; 639 goto out;
638 } 640 }
639 641
640 pixman_region32_t damage; 642 pixman_region32_t damage;
@@ -663,19 +665,21 @@ static int output_repaint_timer_handler(void *data) {
663 665
664 if (!wlr_render_pass_submit(render_pass)) { 666 if (!wlr_render_pass_submit(render_pass)) {
665 wlr_buffer_unlock(buffer); 667 wlr_buffer_unlock(buffer);
666 return false; 668 goto out;
667 } 669 }
668 670
669 wlr_output_attach_buffer(wlr_output, buffer); 671 wlr_output_state_set_buffer(&pending, buffer);
670 wlr_buffer_unlock(buffer); 672 wlr_buffer_unlock(buffer);
671 673
672 if (!wlr_output_commit(wlr_output)) { 674 if (!wlr_output_commit_state(wlr_output, &pending)) {
673 return 0; 675 goto out;
674 } 676 }
675 677
676 wlr_damage_ring_rotate(&output->damage_ring); 678 wlr_damage_ring_rotate(&output->damage_ring);
677 output->last_frame = now; 679 output->last_frame = now;
678 680
681out:
682 wlr_output_state_finish(&pending);
679 return 0; 683 return 0;
680} 684}
681 685