tearing_control: adjust to latest sway changes

* changed all remaining tearing_allowed booleans to allow_tearing to better reflect the config options
This commit is contained in:
Ricardo Steijn 2024-01-28 01:01:04 +01:00
parent cce9b0a7f1
commit e12ac32741
10 changed files with 77 additions and 59 deletions

View file

@ -289,7 +289,7 @@ struct output_config {
enum render_bit_depth render_bit_depth; enum render_bit_depth render_bit_depth;
bool set_color_transform; bool set_color_transform;
struct wlr_color_transform *color_transform; struct wlr_color_transform *color_transform;
int tearing_allowed; int allow_tearing;
char *background; char *background;
char *background_option; char *background_option;

View file

@ -73,7 +73,8 @@ struct sway_output {
int max_render_time; // In milliseconds int max_render_time; // In milliseconds
struct wl_event_source *repaint_timer; struct wl_event_source *repaint_timer;
bool gamma_lut_changed; bool gamma_lut_changed;
bool tearing_allowed; bool allow_tearing;
bool tearing_state, tearing_state_changed;
}; };
struct sway_output_non_desktop { struct sway_output_non_desktop {

View file

@ -4,6 +4,7 @@
#include <wlr/config.h> #include <wlr/config.h>
#include <wlr/types/wlr_compositor.h> #include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_scene.h> #include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_tearing_control_v1.h>
#include "sway/config.h" #include "sway/config.h"
#if WLR_HAS_XWAYLAND #if WLR_HAS_XWAYLAND
#include <wlr/xwayland.h> #include <wlr/xwayland.h>
@ -119,7 +120,7 @@ struct sway_view {
enum seat_config_shortcuts_inhibit shortcuts_inhibit; enum seat_config_shortcuts_inhibit shortcuts_inhibit;
enum sway_view_tearing_mode tearing_mode; enum sway_view_tearing_mode tearing_mode;
bool tearing_hint; enum wp_tearing_control_v1_presentation_hint tearing_hint;
}; };
struct sway_xdg_shell_view { struct sway_xdg_shell_view {

View file

@ -11,9 +11,9 @@ struct cmd_results *output_cmd_allow_tearing(int argc, char **argv) {
} }
if (parse_boolean(argv[0], true)) { if (parse_boolean(argv[0], true)) {
config->handler_context.output_config->tearing_allowed = 1; config->handler_context.output_config->allow_tearing = 1;
} else { } else {
config->handler_context.output_config->tearing_allowed = 0; config->handler_context.output_config->allow_tearing = 0;
} }
config->handler_context.leftovers.argc = argc - 1; config->handler_context.leftovers.argc = argc - 1;

View file

@ -79,7 +79,7 @@ struct output_config *new_output_config(const char *name) {
oc->set_color_transform = false; oc->set_color_transform = false;
oc->color_transform = NULL; oc->color_transform = NULL;
oc->power = -1; oc->power = -1;
oc->tearing_allowed = -1; oc->allow_tearing = -1;
return oc; return oc;
} }
@ -217,8 +217,8 @@ static void merge_output_config(struct output_config *dst, struct output_config
if (src->power != -1) { if (src->power != -1) {
dst->power = src->power; dst->power = src->power;
} }
if (src->tearing_allowed != -1) { if (src->allow_tearing != -1) {
dst->tearing_allowed = src->tearing_allowed; dst->allow_tearing = src->allow_tearing;
} }
} }
@ -262,11 +262,11 @@ void store_output_config(struct output_config *oc) {
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
"position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) " "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
"(max render time: %d) (tearing allowed: %d)", "(max render time: %d) (allow tearing: %d)",
oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate, oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate,
oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel), oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel),
oc->transform, oc->background, oc->background_option, oc->power, oc->transform, oc->background, oc->background_option, oc->power,
oc->max_render_time, oc->tearing_allowed); oc->max_render_time, oc->allow_tearing);
// If the configuration was not merged into an existing configuration, add // If the configuration was not merged into an existing configuration, add
// it to the list. Otherwise we're done with it and can free it. // it to the list. Otherwise we're done with it and can free it.
@ -579,10 +579,10 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
output->color_transform = oc->color_transform; output->color_transform = oc->color_transform;
} }
if (oc && oc->tearing_allowed >= 0) { if (oc && oc->allow_tearing >= 0) {
sway_log(SWAY_DEBUG, "Set %s allow tearing to %d", sway_log(SWAY_DEBUG, "Set %s allow tearing to %d",
oc->name, oc->tearing_allowed); oc->name, oc->allow_tearing);
output->tearing_allowed = oc->tearing_allowed; output->allow_tearing = oc->allow_tearing;
} }
return true; return true;
@ -605,7 +605,7 @@ static void default_output_config(struct output_config *oc,
oc->subpixel = output->detected_subpixel; oc->subpixel = output->detected_subpixel;
oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
oc->max_render_time = 0; oc->max_render_time = 0;
oc->tearing_allowed = 0; oc->allow_tearing = 0;
} }
// find_output_config returns a merged output_config containing all stored // find_output_config returns a merged output_config containing all stored

View file

@ -85,20 +85,6 @@ struct sway_workspace *output_get_active_workspace(struct sway_output *output) {
return focus->sway_workspace; return focus->sway_workspace;
} }
bool output_can_tear_fullscreen_view(struct sway_output *output,
struct sway_view *view) {
if (!view) {
return false;
}
#ifdef WLR_HAS_DRM_BACKEND
if (wlr_backend_is_drm(output->wlr_output->backend) &&
output->tearing_allowed && view_can_tear(view)) {
return true;
}
#endif
return false;
}
struct send_frame_done_data { struct send_frame_done_data {
struct timespec when; struct timespec when;
int msec_until_refresh; int msec_until_refresh;
@ -155,6 +141,20 @@ static struct buffer_timer *buffer_timer_get_or_create(struct wlr_scene_buffer *
return timer; return timer;
} }
static bool output_can_tear_fullscreen_view(struct sway_output *output,
struct sway_view *view) {
if (!view) {
return false;
}
#ifdef WLR_HAS_DRM_BACKEND
if (wlr_backend_is_drm(output->wlr_output->backend) &&
output->allow_tearing && view_can_tear(view)) {
return true;
}
#endif
return false;
}
static void send_frame_done_iterator(struct wlr_scene_buffer *buffer, static void send_frame_done_iterator(struct wlr_scene_buffer *buffer,
int x, int y, void *user_data) { int x, int y, void *user_data) {
struct send_frame_done_data *data = user_data; struct send_frame_done_data *data = user_data;
@ -255,24 +255,6 @@ static void output_configure_scene(struct sway_output *output,
} }
} }
static struct sway_view *output_get_fullscreen_view(
struct sway_output *output) {
struct sway_workspace *workspace = output->current.active_workspace;
if (!workspace) {
return NULL;
}
struct sway_container *fullscreen_con = root->fullscreen_global;
if (!fullscreen_con) {
fullscreen_con = workspace->current.fullscreen;
}
if (fullscreen_con) {
return fullscreen_con->view;
}
return NULL;
}
static int output_repaint_timer_handler(void *data) { static int output_repaint_timer_handler(void *data) {
struct sway_output *output = data; struct sway_output *output = data;
@ -317,6 +299,17 @@ static int output_repaint_timer_handler(void *data) {
} }
} }
if (output->tearing_state_changed) {
output->tearing_state_changed = false;
pending.tearing_page_flip = output->tearing_state;
if (!wlr_output_test_state(output->wlr_output, &pending)) {
output->allow_tearing = false;
wlr_output_state_finish(&pending);
return 0;
}
}
if (!wlr_output_commit_state(output->wlr_output, &pending)) { if (!wlr_output_commit_state(output->wlr_output, &pending)) {
sway_log(SWAY_ERROR, "Page-flip failed on output %s", output->wlr_output->name); sway_log(SWAY_ERROR, "Page-flip failed on output %s", output->wlr_output->name);
} }
@ -324,6 +317,24 @@ static int output_repaint_timer_handler(void *data) {
return 0; return 0;
} }
static struct sway_view *output_get_fullscreen_view(
struct sway_output *output) {
struct sway_workspace *workspace = output->current.active_workspace;
if (!workspace) {
return NULL;
}
struct sway_container *fullscreen_con = root->fullscreen_global;
if (!fullscreen_con) {
fullscreen_con = workspace->current.fullscreen;
}
if (fullscreen_con) {
return fullscreen_con->view;
}
return NULL;
}
static void handle_frame(struct wl_listener *listener, void *user_data) { static void handle_frame(struct wl_listener *listener, void *user_data) {
struct sway_output *output = struct sway_output *output =
wl_container_of(listener, output, frame); wl_container_of(listener, output, frame);
@ -372,13 +383,15 @@ static void handle_frame(struct wl_listener *listener, void *user_data) {
int delay = msec_until_refresh - output->max_render_time; int delay = msec_until_refresh - output->max_render_time;
struct sway_view *fullscreen_view = output_get_fullscreen_view(output); struct sway_view *fullscreen_view = output_get_fullscreen_view(output);
if (output_can_tear_fullscreen_view(output, fullscreen_view)) { bool can_tear = output_can_tear_fullscreen_view(output, fullscreen_view);
delay = 0; if (can_tear != output->tearing_state) {
output->tearing_state_changed = true;
} }
output->tearing_state = can_tear;
// If the delay is less than 1 millisecond (which is the least we can wait) // If the delay is less than 1 millisecond (which is the least we can wait)
// then just render right away. // or if the output is allowed to tear, then just render right away.
if (delay < 1) { if (delay < 1 || can_tear) {
output_repaint_timer_handler(output); output_repaint_timer_handler(output);
} else { } else {
output->wlr_output->frame_pending = true; output->wlr_output->frame_pending = true;

View file

@ -1,6 +1,8 @@
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include <wlr/types/wlr_tearing_control_v1.h>
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/view.h" #include "sway/tree/view.h"
#include "sway/output.h"
#include "log.h" #include "log.h"
struct sway_tearing_controller { struct sway_tearing_controller {
@ -19,12 +21,12 @@ static void handle_tearing_controller_set_hint(struct wl_listener *listener,
struct sway_view *view = view_from_wlr_surface( struct sway_view *view = view_from_wlr_surface(
controller->tearing_control->surface); controller->tearing_control->surface);
if (view) { if (view) {
view->tearing_hint = controller->tearing_control->hint; view->tearing_hint = controller->tearing_control->current;
} }
} }
static void handle_tearing_controller_destroy(struct wl_listener *listener, static void handle_tearing_controller_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct sway_tearing_controller *controller = struct sway_tearing_controller *controller =
wl_container_of(listener, controller, destroy); wl_container_of(listener, controller, destroy);
wl_list_remove(&controller->link); wl_list_remove(&controller->link);

View file

@ -400,7 +400,7 @@ static void ipc_json_describe_enabled_output(struct sway_output *output,
json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time)); json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time));
json_object_object_add(object, "tearing_allowed", json_object_new_boolean(output->tearing_allowed)); json_object_object_add(object, "allow_tearing", json_object_new_boolean(output->allow_tearing));
} }
json_object *ipc_json_describe_disabled_output(struct sway_output *output) { json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
@ -595,7 +595,7 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
json_object_object_add(object, "max_render_time", json_object_new_int(c->view->max_render_time)); json_object_object_add(object, "max_render_time", json_object_new_int(c->view->max_render_time));
json_object_object_add(object, "tearing_allowed", json_object_new_boolean(view_can_tear(c->view))); json_object_object_add(object, "allow_tearing", json_object_new_boolean(view_can_tear(c->view)));
json_object_object_add(object, "shell", json_object_new_string(view_get_shell(c->view))); json_object_object_add(object, "shell", json_object_new_string(view_get_shell(c->view)));

View file

@ -1268,7 +1268,8 @@ bool view_can_tear(struct sway_view *view) {
case TEARING_OVERRIDE_TRUE: case TEARING_OVERRIDE_TRUE:
return true; return true;
case TEARING_WINDOW_HINT: case TEARING_WINDOW_HINT:
return view->tearing_hint; return view->tearing_hint ==
WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
} }
return false; return false;
} }

View file

@ -193,7 +193,7 @@ static void pretty_print_output(json_object *o) {
json_object_object_get_ex(o, "current_workspace", &ws); json_object_object_get_ex(o, "current_workspace", &ws);
json_object_object_get_ex(o, "non_desktop", &non_desktop); json_object_object_get_ex(o, "non_desktop", &non_desktop);
json_object *make, *model, *serial, *scale, *scale_filter, *subpixel, json_object *make, *model, *serial, *scale, *scale_filter, *subpixel,
*transform, *max_render_time, *adaptive_sync_status, *tearing_allowed; *transform, *max_render_time, *adaptive_sync_status, *allow_tearing;
json_object_object_get_ex(o, "make", &make); json_object_object_get_ex(o, "make", &make);
json_object_object_get_ex(o, "model", &model); json_object_object_get_ex(o, "model", &model);
json_object_object_get_ex(o, "serial", &serial); json_object_object_get_ex(o, "serial", &serial);
@ -203,7 +203,7 @@ static void pretty_print_output(json_object *o) {
json_object_object_get_ex(o, "transform", &transform); json_object_object_get_ex(o, "transform", &transform);
json_object_object_get_ex(o, "max_render_time", &max_render_time); json_object_object_get_ex(o, "max_render_time", &max_render_time);
json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status); json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status);
json_object_object_get_ex(o, "tearing_allowed", &tearing_allowed); json_object_object_get_ex(o, "allow_tearing", &allow_tearing);
json_object *x, *y; json_object *x, *y;
json_object_object_get_ex(rect, "x", &x); json_object_object_get_ex(rect, "x", &x);
json_object_object_get_ex(rect, "y", &y); json_object_object_get_ex(rect, "y", &y);
@ -258,8 +258,8 @@ static void pretty_print_output(json_object *o) {
printf(" Adaptive sync: %s\n", printf(" Adaptive sync: %s\n",
json_object_get_string(adaptive_sync_status)); json_object_get_string(adaptive_sync_status));
printf(" Tearing allowed: %s\n", printf(" Allow tearing: %s\n",
json_object_get_boolean(tearing_allowed) ? "yes" : "no"); json_object_get_boolean(allow_tearing) ? "yes" : "no");
} else { } else {
printf( printf(
"Output %s '%s %s %s' (disabled)\n", "Output %s '%s %s %s' (disabled)\n",