forked from emersion/xdg-desktop-portal-wlr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Control how many frames are captured per second
The goal is to control the rate of the capturing, as it can represent a performance issue and can cause a laggy mouse; see emersion#66. The delay for the current frame is based on the time it took to capture the previous frame. The targeted frame rate is a constant. Added code to measure the average FPS every 5 seconds and print it with DEBUG level.
- Loading branch information
1 parent
5401e7f
commit e3c5ceb
Showing
6 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#ifndef FPS_LIMIT_H | ||
#define FPS_LIMIT_H | ||
|
||
#include <stdint.h> | ||
|
||
struct fps_limit_state { | ||
uint64_t last_time_us; | ||
|
||
uint64_t fps_measurement_last_time_us; | ||
uint32_t fps_measurement_frame_count; | ||
}; | ||
|
||
void fps_limit_apply(struct fps_limit_state* state); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright (c) 2019 - 2020 Andri Yngvason | ||
* | ||
* Permission to use, copy, modify, and/or distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | ||
* copyright notice and this permission notice appear in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | ||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
* PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <time.h> | ||
#include <stdint.h> | ||
|
||
static inline uint64_t timespec_to_us(const struct timespec* ts) | ||
{ | ||
return (uint64_t)ts->tv_sec * UINT64_C(1000000) + | ||
(uint64_t)ts->tv_nsec / UINT64_C(1000); | ||
} | ||
|
||
static inline void us_to_timespec(uint64_t time_us, struct timespec* ts) | ||
{ | ||
ts->tv_sec = time_us / UINT64_C(1000000); | ||
ts->tv_nsec = time_us % UINT64_C(1000000) * UINT64_C(1000); | ||
} | ||
|
||
static inline uint64_t timespec_to_ms(const struct timespec* ts) | ||
{ | ||
return (uint64_t)ts->tv_sec * UINT64_C(1000) + | ||
(uint64_t)ts->tv_nsec / UINT64_C(1000000); | ||
} | ||
|
||
static inline uint64_t gettime_us(void) | ||
{ | ||
struct timespec ts = { 0 }; | ||
clock_gettime(CLOCK_MONOTONIC, &ts); | ||
return timespec_to_us(&ts); | ||
} | ||
|
||
static inline uint64_t gettime_ms(void) | ||
{ | ||
struct timespec ts = { 0 }; | ||
clock_gettime(CLOCK_MONOTONIC, &ts); | ||
return timespec_to_ms(&ts); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include "fps_limit.h" | ||
#include "logger.h" | ||
#include "time-util.h" | ||
#include <stdint.h> | ||
#include <unistd.h> | ||
|
||
#define FPS_MEASURE_PERIOD_SEC 5.0 | ||
#define TARGET_FPS 10.0 | ||
|
||
void measure_fps(struct fps_limit_state* state, uint64_t now_us); | ||
|
||
void fps_limit_apply(struct fps_limit_state* state, double max_fps) { | ||
if (max_fps <= 0.0) | ||
return; | ||
|
||
uint64_t now_us = gettime_us(); | ||
|
||
if (state->last_time_us == 0) { | ||
state->last_time_us = now_us; | ||
state->fps_measurement_last_time_us = now_us; | ||
} else { | ||
uint64_t elapsed_us = now_us - state->last_time_us; | ||
|
||
measure_fps(state, now_us); | ||
|
||
uint64_t target_us = (1.0 / TARGET_FPS) * 1e6; | ||
int64_t delay_us = target_us - elapsed_us; | ||
if (delay_us > 0) { | ||
logprint(TRACE, "fps_limit: elapsed time since the end of last sleep: %u, sleeping for %u (microseconds)", elapsed_us, delay_us); | ||
|
||
struct timespec delay; | ||
us_to_timespec(delay_us, &delay); | ||
nanosleep(&delay, NULL); | ||
} | ||
|
||
state->last_time_us = gettime_us(); | ||
} | ||
} | ||
|
||
void measure_fps(struct fps_limit_state* state, uint64_t now_us) { | ||
state->fps_measurement_frame_count++; | ||
|
||
double elapsed_since_last_measure_sec = (now_us - state->fps_measurement_last_time_us) / 1e6; | ||
if (elapsed_since_last_measure_sec >= FPS_MEASURE_PERIOD_SEC) { | ||
double average_delay_sec = elapsed_since_last_measure_sec / state->fps_measurement_frame_count; | ||
double average_frames_per_sec = 1.0 / average_delay_sec; | ||
|
||
logprint(DEBUG, "fps_limit: average FPS in the last %0.0f seconds: %0.2f", FPS_MEASURE_PERIOD_SEC, average_frames_per_sec); | ||
|
||
state->fps_measurement_last_time_us = now_us; | ||
state->fps_measurement_frame_count = 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters