mirror of
https://github.com/swaywm/sway.git
synced 2026-04-21 06:46:22 -04:00
Merge ff14df6db3 into a7b9f6fedc
This commit is contained in:
commit
789c570f7c
8 changed files with 107 additions and 6 deletions
|
|
@ -21,6 +21,9 @@
|
||||||
|
|
||||||
// TODO: Refactor this shit
|
// TODO: Refactor this shit
|
||||||
|
|
||||||
|
#define MAX_RENDER_TIME_OFF 0
|
||||||
|
#define MAX_RENDER_TIME_AUTO -2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a variable created via the `set` command.
|
* Describes a variable created via the `set` command.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,14 @@ struct sway_output {
|
||||||
uint32_t refresh_nsec;
|
uint32_t refresh_nsec;
|
||||||
int max_render_time; // In milliseconds
|
int max_render_time; // In milliseconds
|
||||||
struct wl_event_source *repaint_timer;
|
struct wl_event_source *repaint_timer;
|
||||||
|
|
||||||
|
struct timespec render_begin_time;
|
||||||
|
struct wlr_render_timestamp *render_end_ts;
|
||||||
|
|
||||||
|
int auto_max_render_time; // in milliseconds
|
||||||
|
// TODO: Make this adjustable:
|
||||||
|
uint8_t render_time_window[60];
|
||||||
|
int render_time_window_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_output_non_desktop {
|
struct sway_output_non_desktop {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ struct cmd_results *output_cmd_max_render_time(int argc, char **argv) {
|
||||||
|
|
||||||
int max_render_time;
|
int max_render_time;
|
||||||
if (!strcmp(*argv, "off")) {
|
if (!strcmp(*argv, "off")) {
|
||||||
max_render_time = 0;
|
max_render_time = MAX_RENDER_TIME_OFF;
|
||||||
|
} else if (!strcmp(*argv, "auto")) {
|
||||||
|
max_render_time = MAX_RENDER_TIME_AUTO;
|
||||||
} else {
|
} else {
|
||||||
char *end;
|
char *end;
|
||||||
max_render_time = strtol(*argv, &end, 10);
|
max_render_time = strtol(*argv, &end, 10);
|
||||||
|
|
|
||||||
|
|
@ -581,6 +581,10 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
sway_log(SWAY_DEBUG, "Set %s max render time to %d",
|
sway_log(SWAY_DEBUG, "Set %s max render time to %d",
|
||||||
oc->name, oc->max_render_time);
|
oc->name, oc->max_render_time);
|
||||||
output->max_render_time = oc->max_render_time;
|
output->max_render_time = oc->max_render_time;
|
||||||
|
} else if (oc && oc->max_render_time == MAX_RENDER_TIME_AUTO) {
|
||||||
|
sway_log(SWAY_DEBUG, "Set %s max render time to auto",
|
||||||
|
oc->name);
|
||||||
|
output->max_render_time = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconfigure all devices, since input config may have been applied before
|
// Reconfigure all devices, since input config may have been applied before
|
||||||
|
|
@ -618,7 +622,7 @@ static void default_output_config(struct output_config *oc,
|
||||||
struct sway_output *output = wlr_output->data;
|
struct sway_output *output = wlr_output->data;
|
||||||
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 = MAX_RENDER_TIME_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct output_config *get_output_config(char *identifier,
|
static struct output_config *get_output_config(char *identifier,
|
||||||
|
|
|
||||||
|
|
@ -601,7 +601,14 @@ static void handle_frame(struct wl_listener *listener, void *user_data) {
|
||||||
// delaying both output rendering and surface frame callbacks.
|
// delaying both output rendering and surface frame callbacks.
|
||||||
int msec_until_refresh = 0;
|
int msec_until_refresh = 0;
|
||||||
|
|
||||||
if (output->max_render_time != 0) {
|
int max_render_time = 0;
|
||||||
|
if (output->max_render_time == -1) {
|
||||||
|
max_render_time = output->auto_max_render_time;
|
||||||
|
} else if (output->max_render_time != 0) {
|
||||||
|
max_render_time = output->max_render_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_render_time != 0) {
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
clockid_t presentation_clock
|
clockid_t presentation_clock
|
||||||
= wlr_backend_get_presentation_clock(server.backend);
|
= wlr_backend_get_presentation_clock(server.backend);
|
||||||
|
|
@ -637,7 +644,7 @@ 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 - max_render_time;
|
||||||
|
|
||||||
// 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.
|
// then just render right away.
|
||||||
|
|
@ -795,6 +802,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
struct sway_output *output = wl_container_of(listener, output, destroy);
|
struct sway_output *output = wl_container_of(listener, output, destroy);
|
||||||
struct sway_server *server = output->server;
|
struct sway_server *server = output->server;
|
||||||
|
|
||||||
|
wlr_render_timestamp_destroy(output->render_end_ts);
|
||||||
|
|
||||||
if (output->enabled) {
|
if (output->enabled) {
|
||||||
output_disable(output);
|
output_disable(output);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1029,6 +1029,59 @@ static void render_seatops(struct sway_output *output,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t aggregate_render_times(struct sway_output *output, uint8_t in)
|
||||||
|
{
|
||||||
|
int len = sizeof(output->render_time_window);
|
||||||
|
|
||||||
|
int i = output->render_time_window_index++;
|
||||||
|
if (output->render_time_window_index >= len) {
|
||||||
|
output->render_time_window_index = 0;
|
||||||
|
}
|
||||||
|
output->render_time_window[i] = in;
|
||||||
|
|
||||||
|
uint8_t max = 0;
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
uint8_t t = output->render_time_window[i];
|
||||||
|
if (t > max) {
|
||||||
|
max = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void calculate_max_render_time(struct sway_output *output)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
if (!wlr_render_timestamp_get_time(output->render_end_ts, &ts)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t end_time_us = ts.tv_sec * UINT64_C(1000000) +
|
||||||
|
ts.tv_nsec / UINT64_C(1000);
|
||||||
|
|
||||||
|
uint64_t begin_time_us =
|
||||||
|
output->render_begin_time.tv_sec * UINT64_C(1000000) +
|
||||||
|
output->render_begin_time.tv_nsec / UINT64_C(1000);
|
||||||
|
|
||||||
|
if (begin_time_us > end_time_us) {
|
||||||
|
// rollover
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t duration_us = end_time_us - begin_time_us;
|
||||||
|
|
||||||
|
int dt_ms = ceil(duration_us / 1e3);
|
||||||
|
int max = aggregate_render_times(output, dt_ms);
|
||||||
|
|
||||||
|
if (max != output->auto_max_render_time) {
|
||||||
|
output->auto_max_render_time = max;
|
||||||
|
|
||||||
|
sway_log(SWAY_DEBUG,
|
||||||
|
"Adjusted output max_render_time to %d ms", max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void output_render(struct sway_output *output, struct timespec *when,
|
void output_render(struct sway_output *output, struct timespec *when,
|
||||||
pixman_region32_t *damage) {
|
pixman_region32_t *damage) {
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
struct wlr_output *wlr_output = output->wlr_output;
|
||||||
|
|
@ -1044,7 +1097,14 @@ void output_render(struct sway_output *output, struct timespec *when,
|
||||||
fullscreen_con = workspace->current.fullscreen;
|
fullscreen_con = workspace->current.fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (output->max_render_time == -1 && output->render_end_ts) {
|
||||||
|
calculate_max_render_time(output);
|
||||||
|
wlr_render_timestamp_destroy(output->render_end_ts);
|
||||||
|
output->render_end_ts = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
|
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
|
||||||
|
wlr_renderer_get_time(renderer, &output->render_begin_time);
|
||||||
|
|
||||||
if (debug.damage == DAMAGE_RERENDER) {
|
if (debug.damage == DAMAGE_RERENDER) {
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
@ -1181,6 +1241,7 @@ render_overlay:
|
||||||
renderer_end:
|
renderer_end:
|
||||||
wlr_renderer_scissor(renderer, NULL);
|
wlr_renderer_scissor(renderer, NULL);
|
||||||
wlr_output_render_software_cursors(wlr_output, damage);
|
wlr_output_render_software_cursors(wlr_output, damage);
|
||||||
|
output->render_end_ts = wlr_renderer_create_timestamp(renderer);
|
||||||
wlr_renderer_end(renderer);
|
wlr_renderer_end(renderer);
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,14 @@ static void ipc_json_describe_enabled_output(struct sway_output *output,
|
||||||
json_object_object_add(object, "percent", json_object_new_double(percent));
|
json_object_object_add(object, "percent", json_object_new_double(percent));
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time));
|
int max_render_time;
|
||||||
|
if (output->max_render_time == -1) {
|
||||||
|
max_render_time = -output->auto_max_render_time;
|
||||||
|
} else {
|
||||||
|
max_render_time = output->max_render_time;
|
||||||
|
}
|
||||||
|
json_object_object_add(object, "max_render_time",
|
||||||
|
json_object_new_int(max_render_time));
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
|
json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
|
||||||
|
|
|
||||||
|
|
@ -249,8 +249,15 @@ static void pretty_print_output(json_object *o) {
|
||||||
);
|
);
|
||||||
|
|
||||||
int max_render_time_int = json_object_get_int(max_render_time);
|
int max_render_time_int = json_object_get_int(max_render_time);
|
||||||
|
|
||||||
printf(" Max render time: ");
|
printf(" Max render time: ");
|
||||||
printf(max_render_time_int == 0 ? "off\n" : "%d ms\n", max_render_time_int);
|
if (max_render_time_int == 0) {
|
||||||
|
printf("off\n");
|
||||||
|
} else if (max_render_time_int > 0) {
|
||||||
|
printf("%d ms\n", max_render_time_int);
|
||||||
|
} else {
|
||||||
|
printf("%d ms (auto)\n", -max_render_time_int);
|
||||||
|
}
|
||||||
|
|
||||||
printf(" Adaptive sync: %s\n",
|
printf(" Adaptive sync: %s\n",
|
||||||
json_object_get_string(adaptive_sync_status));
|
json_object_get_string(adaptive_sync_status));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue