diff options
-rw-r--r-- | include/sway/output.h | 8 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 1 | ||||
-rw-r--r-- | sway/desktop/output.c | 111 | ||||
-rw-r--r-- | sway/desktop/render.c | 6 | ||||
-rw-r--r-- | sway/tree/output.c | 1 |
5 files changed, 81 insertions, 46 deletions
diff --git a/include/sway/output.h b/include/sway/output.h index d72bf1b2..7ccaa09c 100644 --- a/include/sway/output.h +++ b/include/sway/output.h | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <time.h> | 3 | #include <time.h> |
4 | #include <unistd.h> | 4 | #include <unistd.h> |
5 | #include <wayland-server-core.h> | 5 | #include <wayland-server-core.h> |
6 | #include <wlr/types/wlr_damage_ring.h> | ||
6 | #include <wlr/types/wlr_output.h> | 7 | #include <wlr/types/wlr_output.h> |
7 | #include "config.h" | 8 | #include "config.h" |
8 | #include "sway/tree/node.h" | 9 | #include "sway/tree/node.h" |
@@ -26,7 +27,7 @@ struct sway_output { | |||
26 | struct wlr_box usable_area; | 27 | struct wlr_box usable_area; |
27 | 28 | ||
28 | struct timespec last_frame; | 29 | struct timespec last_frame; |
29 | struct wlr_output_damage *damage; | 30 | struct wlr_damage_ring damage_ring; |
30 | 31 | ||
31 | int lx, ly; // layout coords | 32 | int lx, ly; // layout coords |
32 | int width, height; // transformed buffer size | 33 | int width, height; // transformed buffer size |
@@ -44,8 +45,9 @@ struct sway_output { | |||
44 | struct wl_listener commit; | 45 | struct wl_listener commit; |
45 | struct wl_listener mode; | 46 | struct wl_listener mode; |
46 | struct wl_listener present; | 47 | struct wl_listener present; |
47 | struct wl_listener damage_destroy; | 48 | struct wl_listener damage; |
48 | struct wl_listener damage_frame; | 49 | struct wl_listener frame; |
50 | struct wl_listener needs_frame; | ||
49 | 51 | ||
50 | struct { | 52 | struct { |
51 | struct wl_signal disable; | 53 | struct wl_signal disable; |
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index d44d6338..6e3cc0e2 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -3,7 +3,6 @@ | |||
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include <wayland-server-core.h> | 4 | #include <wayland-server-core.h> |
5 | #include <wlr/types/wlr_layer_shell_v1.h> | 5 | #include <wlr/types/wlr_layer_shell_v1.h> |
6 | #include <wlr/types/wlr_output_damage.h> | ||
7 | #include <wlr/types/wlr_output.h> | 6 | #include <wlr/types/wlr_output.h> |
8 | #include <wlr/types/wlr_subcompositor.h> | 7 | #include <wlr/types/wlr_subcompositor.h> |
9 | #include "log.h" | 8 | #include "log.h" |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 3f3f9494..75651a7a 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <wlr/types/wlr_buffer.h> | 10 | #include <wlr/types/wlr_buffer.h> |
11 | #include <wlr/types/wlr_drm_lease_v1.h> | 11 | #include <wlr/types/wlr_drm_lease_v1.h> |
12 | #include <wlr/types/wlr_matrix.h> | 12 | #include <wlr/types/wlr_matrix.h> |
13 | #include <wlr/types/wlr_output_damage.h> | ||
14 | #include <wlr/types/wlr_output_layout.h> | 13 | #include <wlr/types/wlr_output_layout.h> |
15 | #include <wlr/types/wlr_output.h> | 14 | #include <wlr/types/wlr_output.h> |
16 | #include <wlr/types/wlr_presentation_time.h> | 15 | #include <wlr/types/wlr_presentation_time.h> |
@@ -553,31 +552,43 @@ static int output_repaint_timer_handler(void *data) { | |||
553 | } | 552 | } |
554 | } | 553 | } |
555 | 554 | ||
556 | bool needs_frame; | 555 | int buffer_age; |
556 | if (!wlr_output_attach_render(output->wlr_output, &buffer_age)) { | ||
557 | return 0; | ||
558 | } | ||
559 | |||
557 | pixman_region32_t damage; | 560 | pixman_region32_t damage; |
558 | pixman_region32_init(&damage); | 561 | pixman_region32_init(&damage); |
559 | if (!wlr_output_damage_attach_render(output->damage, | 562 | wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage); |
560 | &needs_frame, &damage)) { | 563 | if (!output->wlr_output->needs_frame && |
564 | !pixman_region32_not_empty(&output->damage_ring.current)) { | ||
565 | pixman_region32_fini(&damage); | ||
566 | wlr_output_rollback(output->wlr_output); | ||
561 | return 0; | 567 | return 0; |
562 | } | 568 | } |
563 | 569 | ||
564 | if (needs_frame) { | 570 | struct timespec now; |
565 | struct timespec now; | 571 | clock_gettime(CLOCK_MONOTONIC, &now); |
566 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
567 | 572 | ||
568 | output_render(output, &now, &damage); | 573 | output_render(output, &now, &damage); |
569 | } else { | ||
570 | wlr_output_rollback(output->wlr_output); | ||
571 | } | ||
572 | 574 | ||
573 | pixman_region32_fini(&damage); | 575 | pixman_region32_fini(&damage); |
574 | 576 | ||
575 | return 0; | 577 | return 0; |
576 | } | 578 | } |
577 | 579 | ||
578 | static void damage_handle_frame(struct wl_listener *listener, void *user_data) { | 580 | static void handle_damage(struct wl_listener *listener, void *user_data) { |
579 | struct sway_output *output = | 581 | struct sway_output *output = |
580 | wl_container_of(listener, output, damage_frame); | 582 | wl_container_of(listener, output, damage); |
583 | struct wlr_output_event_damage *event = user_data; | ||
584 | if (wlr_damage_ring_add(&output->damage_ring, event->damage)) { | ||
585 | wlr_output_schedule_frame(output->wlr_output); | ||
586 | } | ||
587 | } | ||
588 | |||
589 | static void handle_frame(struct wl_listener *listener, void *user_data) { | ||
590 | struct sway_output *output = | ||
591 | wl_container_of(listener, output, frame); | ||
581 | if (!output->enabled || !output->wlr_output->enabled) { | 592 | if (!output->enabled || !output->wlr_output->enabled) { |
582 | return; | 593 | return; |
583 | } | 594 | } |
@@ -640,11 +651,18 @@ static void damage_handle_frame(struct wl_listener *listener, void *user_data) { | |||
640 | send_frame_done(output, &data); | 651 | send_frame_done(output, &data); |
641 | } | 652 | } |
642 | 653 | ||
654 | static void handle_needs_frame(struct wl_listener *listener, void *user_data) { | ||
655 | struct sway_output *output = | ||
656 | wl_container_of(listener, output, needs_frame); | ||
657 | wlr_output_schedule_frame(output->wlr_output); | ||
658 | } | ||
659 | |||
643 | void output_damage_whole(struct sway_output *output) { | 660 | void output_damage_whole(struct sway_output *output) { |
644 | // The output can exist with no wlr_output if it's just been disconnected | 661 | // The output can exist with no wlr_output if it's just been disconnected |
645 | // and the transaction to evacuate it has't completed yet. | 662 | // and the transaction to evacuate it has't completed yet. |
646 | if (output && output->wlr_output && output->damage) { | 663 | if (output != NULL && output->wlr_output != NULL) { |
647 | wlr_output_damage_add_whole(output->damage); | 664 | wlr_damage_ring_add_whole(&output->damage_ring); |
665 | wlr_output_schedule_frame(output->wlr_output); | ||
648 | } | 666 | } |
649 | } | 667 | } |
650 | 668 | ||
@@ -668,11 +686,15 @@ static void damage_surface_iterator(struct sway_output *output, | |||
668 | ceil(output->wlr_output->scale) - surface->current.scale); | 686 | ceil(output->wlr_output->scale) - surface->current.scale); |
669 | } | 687 | } |
670 | pixman_region32_translate(&damage, box.x, box.y); | 688 | pixman_region32_translate(&damage, box.x, box.y); |
671 | wlr_output_damage_add(output->damage, &damage); | 689 | if (wlr_damage_ring_add(&output->damage_ring, &damage)) { |
690 | wlr_output_schedule_frame(output->wlr_output); | ||
691 | } | ||
672 | pixman_region32_fini(&damage); | 692 | pixman_region32_fini(&damage); |
673 | 693 | ||
674 | if (whole) { | 694 | if (whole) { |
675 | wlr_output_damage_add_box(output->damage, &box); | 695 | if (wlr_damage_ring_add_box(&output->damage_ring, &box)) { |
696 | wlr_output_schedule_frame(output->wlr_output); | ||
697 | } | ||
676 | } | 698 | } |
677 | 699 | ||
678 | if (!wl_list_empty(&surface->current.frame_callback_list)) { | 700 | if (!wl_list_empty(&surface->current.frame_callback_list)) { |
@@ -702,7 +724,9 @@ void output_damage_box(struct sway_output *output, struct wlr_box *_box) { | |||
702 | box.x -= output->lx; | 724 | box.x -= output->lx; |
703 | box.y -= output->ly; | 725 | box.y -= output->ly; |
704 | scale_box(&box, output->wlr_output->scale); | 726 | scale_box(&box, output->wlr_output->scale); |
705 | wlr_output_damage_add_box(output->damage, &box); | 727 | if (wlr_damage_ring_add_box(&output->damage_ring, &box)) { |
728 | wlr_output_schedule_frame(output->wlr_output); | ||
729 | } | ||
706 | } | 730 | } |
707 | 731 | ||
708 | static void damage_child_views_iterator(struct sway_container *con, | 732 | static void damage_child_views_iterator(struct sway_container *con, |
@@ -726,7 +750,9 @@ void output_damage_whole_container(struct sway_output *output, | |||
726 | .height = con->current.height + 2, | 750 | .height = con->current.height + 2, |
727 | }; | 751 | }; |
728 | scale_box(&box, output->wlr_output->scale); | 752 | scale_box(&box, output->wlr_output->scale); |
729 | wlr_output_damage_add_box(output->damage, &box); | 753 | if (wlr_damage_ring_add_box(&output->damage_ring, &box)) { |
754 | wlr_output_schedule_frame(output->wlr_output); | ||
755 | } | ||
730 | // Damage subsurfaces as well, which may extend outside the box | 756 | // Damage subsurfaces as well, which may extend outside the box |
731 | if (con->view) { | 757 | if (con->view) { |
732 | damage_child_views_iterator(con, output); | 758 | damage_child_views_iterator(con, output); |
@@ -735,20 +761,6 @@ void output_damage_whole_container(struct sway_output *output, | |||
735 | } | 761 | } |
736 | } | 762 | } |
737 | 763 | ||
738 | static void damage_handle_destroy(struct wl_listener *listener, void *data) { | ||
739 | struct sway_output *output = | ||
740 | wl_container_of(listener, output, damage_destroy); | ||
741 | if (!output->enabled) { | ||
742 | return; | ||
743 | } | ||
744 | output_disable(output); | ||
745 | |||
746 | wl_list_remove(&output->damage_destroy.link); | ||
747 | wl_list_remove(&output->damage_frame.link); | ||
748 | |||
749 | transaction_commit_dirty(); | ||
750 | } | ||
751 | |||
752 | static void update_output_manager_config(struct sway_server *server) { | 764 | static void update_output_manager_config(struct sway_server *server) { |
753 | struct wlr_output_configuration_v1 *config = | 765 | struct wlr_output_configuration_v1 *config = |
754 | wlr_output_configuration_v1_create(); | 766 | wlr_output_configuration_v1_create(); |
@@ -778,18 +790,24 @@ static void update_output_manager_config(struct sway_server *server) { | |||
778 | static void handle_destroy(struct wl_listener *listener, void *data) { | 790 | static void handle_destroy(struct wl_listener *listener, void *data) { |
779 | struct sway_output *output = wl_container_of(listener, output, destroy); | 791 | struct sway_output *output = wl_container_of(listener, output, destroy); |
780 | struct sway_server *server = output->server; | 792 | struct sway_server *server = output->server; |
781 | output_begin_destroy(output); | ||
782 | 793 | ||
783 | if (output->enabled) { | 794 | if (output->enabled) { |
784 | output_disable(output); | 795 | output_disable(output); |
785 | } | 796 | } |
786 | 797 | ||
798 | output_begin_destroy(output); | ||
799 | |||
787 | wl_list_remove(&output->link); | 800 | wl_list_remove(&output->link); |
788 | 801 | ||
789 | wl_list_remove(&output->destroy.link); | 802 | wl_list_remove(&output->destroy.link); |
790 | wl_list_remove(&output->commit.link); | 803 | wl_list_remove(&output->commit.link); |
791 | wl_list_remove(&output->mode.link); | 804 | wl_list_remove(&output->mode.link); |
792 | wl_list_remove(&output->present.link); | 805 | wl_list_remove(&output->present.link); |
806 | wl_list_remove(&output->damage.link); | ||
807 | wl_list_remove(&output->frame.link); | ||
808 | wl_list_remove(&output->needs_frame.link); | ||
809 | |||
810 | wlr_damage_ring_finish(&output->damage_ring); | ||
793 | 811 | ||
794 | output->wlr_output->data = NULL; | 812 | output->wlr_output->data = NULL; |
795 | output->wlr_output = NULL; | 813 | output->wlr_output = NULL; |
@@ -817,10 +835,15 @@ static void handle_mode(struct wl_listener *listener, void *data) { | |||
817 | if (!output->enabled) { | 835 | if (!output->enabled) { |
818 | return; | 836 | return; |
819 | } | 837 | } |
838 | |||
820 | arrange_layers(output); | 839 | arrange_layers(output); |
821 | arrange_output(output); | 840 | arrange_output(output); |
822 | transaction_commit_dirty(); | 841 | transaction_commit_dirty(); |
823 | 842 | ||
843 | wlr_damage_ring_set_bounds(&output->damage_ring, | ||
844 | output->width, output->height); | ||
845 | wlr_output_schedule_frame(output->wlr_output); | ||
846 | |||
824 | update_output_manager_config(output->server); | 847 | update_output_manager_config(output->server); |
825 | } | 848 | } |
826 | 849 | ||
@@ -848,6 +871,14 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
848 | 871 | ||
849 | update_output_manager_config(output->server); | 872 | update_output_manager_config(output->server); |
850 | } | 873 | } |
874 | |||
875 | if (event->committed & (WLR_OUTPUT_STATE_MODE | | ||
876 | WLR_OUTPUT_STATE_TRANSFORM | | ||
877 | WLR_OUTPUT_STATE_SCALE)) { | ||
878 | wlr_damage_ring_set_bounds(&output->damage_ring, | ||
879 | output->width, output->height); | ||
880 | wlr_output_schedule_frame(output->wlr_output); | ||
881 | } | ||
851 | } | 882 | } |
852 | 883 | ||
853 | static void handle_present(struct wl_listener *listener, void *data) { | 884 | static void handle_present(struct wl_listener *listener, void *data) { |
@@ -903,7 +934,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
903 | return; | 934 | return; |
904 | } | 935 | } |
905 | output->server = server; | 936 | output->server = server; |
906 | output->damage = wlr_output_damage_create(wlr_output); | 937 | wlr_damage_ring_init(&output->damage_ring); |
907 | 938 | ||
908 | wl_signal_add(&wlr_output->events.destroy, &output->destroy); | 939 | wl_signal_add(&wlr_output->events.destroy, &output->destroy); |
909 | output->destroy.notify = handle_destroy; | 940 | output->destroy.notify = handle_destroy; |
@@ -913,10 +944,12 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
913 | output->mode.notify = handle_mode; | 944 | output->mode.notify = handle_mode; |
914 | wl_signal_add(&wlr_output->events.present, &output->present); | 945 | wl_signal_add(&wlr_output->events.present, &output->present); |
915 | output->present.notify = handle_present; | 946 | output->present.notify = handle_present; |
916 | wl_signal_add(&output->damage->events.frame, &output->damage_frame); | 947 | wl_signal_add(&wlr_output->events.damage, &output->damage); |
917 | output->damage_frame.notify = damage_handle_frame; | 948 | output->damage.notify = handle_damage; |
918 | wl_signal_add(&output->damage->events.destroy, &output->damage_destroy); | 949 | wl_signal_add(&wlr_output->events.frame, &output->frame); |
919 | output->damage_destroy.notify = damage_handle_destroy; | 950 | output->frame.notify = handle_frame; |
951 | wl_signal_add(&wlr_output->events.needs_frame, &output->needs_frame); | ||
952 | output->needs_frame.notify = handle_needs_frame; | ||
920 | 953 | ||
921 | output->repaint_timer = wl_event_loop_add_timer(server->wl_event_loop, | 954 | output->repaint_timer = wl_event_loop_add_timer(server->wl_event_loop, |
922 | output_repaint_timer_handler, output); | 955 | output_repaint_timer_handler, output); |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index ed9ad490..efa3a0d9 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -8,8 +8,8 @@ | |||
8 | #include <wlr/render/gles2.h> | 8 | #include <wlr/render/gles2.h> |
9 | #include <wlr/render/wlr_renderer.h> | 9 | #include <wlr/render/wlr_renderer.h> |
10 | #include <wlr/types/wlr_buffer.h> | 10 | #include <wlr/types/wlr_buffer.h> |
11 | #include <wlr/types/wlr_damage_ring.h> | ||
11 | #include <wlr/types/wlr_matrix.h> | 12 | #include <wlr/types/wlr_matrix.h> |
12 | #include <wlr/types/wlr_output_damage.h> | ||
13 | #include <wlr/types/wlr_output_layout.h> | 13 | #include <wlr/types/wlr_output_layout.h> |
14 | #include <wlr/types/wlr_output.h> | 14 | #include <wlr/types/wlr_output.h> |
15 | #include <wlr/types/wlr_compositor.h> | 15 | #include <wlr/types/wlr_compositor.h> |
@@ -1186,7 +1186,7 @@ renderer_end: | |||
1186 | 1186 | ||
1187 | enum wl_output_transform transform = | 1187 | enum wl_output_transform transform = |
1188 | wlr_output_transform_invert(wlr_output->transform); | 1188 | wlr_output_transform_invert(wlr_output->transform); |
1189 | wlr_region_transform(&frame_damage, &output->damage->current, | 1189 | wlr_region_transform(&frame_damage, &output->damage_ring.current, |
1190 | transform, width, height); | 1190 | transform, width, height); |
1191 | 1191 | ||
1192 | if (debug.damage != DAMAGE_DEFAULT) { | 1192 | if (debug.damage != DAMAGE_DEFAULT) { |
@@ -1200,5 +1200,7 @@ renderer_end: | |||
1200 | if (!wlr_output_commit(wlr_output)) { | 1200 | if (!wlr_output_commit(wlr_output)) { |
1201 | return; | 1201 | return; |
1202 | } | 1202 | } |
1203 | |||
1204 | wlr_damage_ring_rotate(&output->damage_ring); | ||
1203 | output->last_frame = *when; | 1205 | output->last_frame = *when; |
1204 | } | 1206 | } |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 368f0541..eccab2f7 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -3,7 +3,6 @@ | |||
3 | #include <ctype.h> | 3 | #include <ctype.h> |
4 | #include <string.h> | 4 | #include <string.h> |
5 | #include <strings.h> | 5 | #include <strings.h> |
6 | #include <wlr/types/wlr_output_damage.h> | ||
7 | #include "sway/ipc-server.h" | 6 | #include "sway/ipc-server.h" |
8 | #include "sway/layers.h" | 7 | #include "sway/layers.h" |
9 | #include "sway/output.h" | 8 | #include "sway/output.h" |