diff options
author | Simon Ser <contact@emersion.fr> | 2019-09-26 12:10:49 +0300 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-09-26 10:36:18 -0400 |
commit | 00c4c7e8cc437c6f905c6fbe94cf8eaf508f8644 (patch) | |
tree | 224a10fe66802900ca02dfc8db345fed92cb3124 /sway/desktop/render.c | |
parent | input: Add support for tablet protocol. (diff) | |
download | sway-00c4c7e8cc437c6f905c6fbe94cf8eaf508f8644.tar.gz sway-00c4c7e8cc437c6f905c6fbe94cf8eaf508f8644.tar.zst sway-00c4c7e8cc437c6f905c6fbe94cf8eaf508f8644.zip |
Fix direct scan-out flickering
Sometimes when using direct scan-out, some flickering between the
fullscreen app and the regular desktop could be seen.
This happened because we called wlr_output_attach_render and then
wlr_output_attach_buffer for direct scan-out. wlr_output_attach_render
makes the OpenGL context current but also attaches the OpenGL buffer to
the primary plane apparently (all of this happens inside
eglMakeCurrent).
This patch moves the scan-out logic outside of output_render, before
wlr_output_attach_render. This lines it up with rootston's
implementation. This also makes more sense since no rendering is
involved when using direct scan-out.
Sorry about that, I should've tested this with more clients. The new
code has been tested with mpv and a GLFW demo.
Diffstat (limited to 'sway/desktop/render.c')
-rw-r--r-- | sway/desktop/render.c | 85 |
1 files changed, 0 insertions, 85 deletions
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 5cec5949..916d4eba 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -927,72 +927,6 @@ static void render_seatops(struct sway_output *output, | |||
927 | } | 927 | } |
928 | } | 928 | } |
929 | 929 | ||
930 | static void count_surface_iterator(struct sway_output *output, | ||
931 | struct wlr_surface *surface, struct wlr_box *_box, float rotation, | ||
932 | void *data) { | ||
933 | size_t *n = data; | ||
934 | (*n)++; | ||
935 | } | ||
936 | |||
937 | static bool scan_out_fullscreen_view(struct sway_output *output, | ||
938 | struct sway_view *view) { | ||
939 | struct wlr_output *wlr_output = output->wlr_output; | ||
940 | struct sway_workspace *workspace = output->current.active_workspace; | ||
941 | if (!sway_assert(workspace, "Expected an active workspace")) { | ||
942 | return false; | ||
943 | } | ||
944 | |||
945 | if (view->saved_buffer) { | ||
946 | return false; | ||
947 | } | ||
948 | |||
949 | for (int i = 0; i < workspace->current.floating->length; ++i) { | ||
950 | struct sway_container *floater = | ||
951 | workspace->current.floating->items[i]; | ||
952 | if (container_is_transient_for(floater, view->container)) { | ||
953 | return false; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | #if HAVE_XWAYLAND | ||
958 | if (!wl_list_empty(&root->xwayland_unmanaged)) { | ||
959 | return false; | ||
960 | } | ||
961 | #endif | ||
962 | |||
963 | if (!wl_list_empty(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY])) { | ||
964 | return false; | ||
965 | } | ||
966 | if (!wl_list_empty(&root->drag_icons)) { | ||
967 | return false; | ||
968 | } | ||
969 | |||
970 | struct wlr_surface *surface = view->surface; | ||
971 | if (surface == NULL) { | ||
972 | return false; | ||
973 | } | ||
974 | size_t n_surfaces = 0; | ||
975 | output_view_for_each_surface(output, view, | ||
976 | count_surface_iterator, &n_surfaces); | ||
977 | if (n_surfaces != 1) { | ||
978 | return false; | ||
979 | } | ||
980 | |||
981 | if (surface->buffer == NULL) { | ||
982 | return false; | ||
983 | } | ||
984 | |||
985 | if ((float)surface->current.scale != wlr_output->scale || | ||
986 | surface->current.transform != wlr_output->transform) { | ||
987 | return false; | ||
988 | } | ||
989 | |||
990 | if (!wlr_output_attach_buffer(wlr_output, surface->buffer)) { | ||
991 | return false; | ||
992 | } | ||
993 | return wlr_output_commit(wlr_output); | ||
994 | } | ||
995 | |||
996 | void output_render(struct sway_output *output, struct timespec *when, | 930 | void output_render(struct sway_output *output, struct timespec *when, |
997 | pixman_region32_t *damage) { | 931 | pixman_region32_t *damage) { |
998 | struct wlr_output *wlr_output = output->wlr_output; | 932 | struct wlr_output *wlr_output = output->wlr_output; |
@@ -1014,25 +948,6 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
1014 | fullscreen_con = workspace->current.fullscreen; | 948 | fullscreen_con = workspace->current.fullscreen; |
1015 | } | 949 | } |
1016 | 950 | ||
1017 | if (fullscreen_con && fullscreen_con->view) { | ||
1018 | // Try to scan-out the fullscreen view | ||
1019 | static bool last_scanned_out = false; | ||
1020 | bool scanned_out = | ||
1021 | scan_out_fullscreen_view(output, fullscreen_con->view); | ||
1022 | |||
1023 | if (scanned_out && !last_scanned_out) { | ||
1024 | sway_log(SWAY_DEBUG, "Scanning out fullscreen view"); | ||
1025 | } | ||
1026 | if (last_scanned_out && !scanned_out) { | ||
1027 | sway_log(SWAY_DEBUG, "Stopping fullscreen view scan out"); | ||
1028 | } | ||
1029 | last_scanned_out = scanned_out; | ||
1030 | |||
1031 | if (scanned_out) { | ||
1032 | return; | ||
1033 | } | ||
1034 | } | ||
1035 | |||
1036 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); | 951 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); |
1037 | 952 | ||
1038 | if (!pixman_region32_not_empty(damage)) { | 953 | if (!pixman_region32_not_empty(damage)) { |