diff options
author | Simon Ser <contact@emersion.fr> | 2023-06-05 14:35:15 +0200 |
---|---|---|
committer | Ronan Pigott <ronan@rjp.ie> | 2023-06-08 14:33:23 -0700 |
commit | f3b8c9feeed9f79fc8f06e7f1dcfaadde522ce90 (patch) | |
tree | 21201243a154537b3d498b42cbe60661eeba4d3b /sway/desktop/output.c | |
parent | Handle gamma-control-v1 set_gamma events (diff) | |
download | sway-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.c | 48 |
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 | ||
460 | static bool scan_out_fullscreen_view(struct sway_output *output, | 460 | static 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 | ||
538 | static void get_frame_damage(struct sway_output *output, | 539 | static 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 | ||
681 | out: | ||
682 | wlr_output_state_finish(&pending); | ||
679 | return 0; | 683 | return 0; |
680 | } | 684 | } |
681 | 685 | ||