mirror of
https://github.com/swaywm/sway.git
synced 2026-04-22 06:46:27 -04:00
sway/desktop: Implement dynamic max_render_time
This commit is contained in:
parent
b0fc83485d
commit
f78bffa4ab
3 changed files with 80 additions and 2 deletions
|
|
@ -55,6 +55,14 @@ struct sway_output {
|
|||
uint32_t refresh_nsec;
|
||||
int max_render_time; // In milliseconds
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -586,7 +586,14 @@ static void damage_handle_frame(struct wl_listener *listener, void *user_data) {
|
|||
// delaying both output rendering and surface frame callbacks.
|
||||
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;
|
||||
clockid_t presentation_clock
|
||||
= wlr_backend_get_presentation_clock(server.backend);
|
||||
|
|
@ -622,7 +629,7 @@ static void damage_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)
|
||||
// then just render right away.
|
||||
|
|
@ -780,6 +787,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
|||
struct sway_server *server = output->server;
|
||||
output_begin_destroy(output);
|
||||
|
||||
wlr_render_timestamp_destroy(output->render_end_ts);
|
||||
|
||||
if (output->enabled) {
|
||||
output_disable(output);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1024,6 +1024,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,
|
||||
pixman_region32_t *damage) {
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
|
@ -1039,7 +1092,14 @@ void output_render(struct sway_output *output, struct timespec *when,
|
|||
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_get_time(renderer, &output->render_begin_time);
|
||||
|
||||
if (debug.damage == DAMAGE_RERENDER) {
|
||||
int width, height;
|
||||
|
|
@ -1176,6 +1236,7 @@ render_overlay:
|
|||
renderer_end:
|
||||
wlr_renderer_scissor(renderer, NULL);
|
||||
wlr_output_render_software_cursors(wlr_output, damage);
|
||||
output->render_end_ts = wlr_renderer_create_timestamp(renderer);
|
||||
wlr_renderer_end(renderer);
|
||||
|
||||
int width, height;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue