Skip to content

Commit

Permalink
Introduce an optional CLI argument for the max FPS
Browse files Browse the repository at this point in the history
The default value is 0, meaning unlimited FPS; this also disables the
measuring and logging of the average FPS.
  • Loading branch information
zsolt-donca committed Feb 16, 2021
1 parent 4792788 commit 2c1d532
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 9 deletions.
2 changes: 1 addition & 1 deletion include/fps_limit.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ struct fps_limit_state {
uint32_t fps_measurement_frame_count;
};

void fps_limit_apply(struct fps_limit_state* state);
void fps_limit_apply(struct fps_limit_state* state, double max_fps);

#endif
2 changes: 2 additions & 0 deletions include/screencast_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct xdpw_screencast_context {

// cli options
const char *output_name;
double max_fps;

// sessions
struct wl_list screencast_instances;
Expand Down Expand Up @@ -95,6 +96,7 @@ struct xdpw_screencast_instance {
bool quit;

// fps limit
double max_fps; // 0 means no limit
struct fps_limit_state fps_limit;
};

Expand Down
2 changes: 1 addition & 1 deletion include/xdpw.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ enum {
};

int xdpw_screenshot_init(struct xdpw_state *state);
int xdpw_screencast_init(struct xdpw_state *state, const char *output_name);
int xdpw_screencast_init(struct xdpw_state *state, const char *output_name, double max_fps);

struct xdpw_request *xdpw_request_create(sd_bus *bus, const char *object_path);
void xdpw_request_destroy(struct xdpw_request *req);
Expand Down
10 changes: 8 additions & 2 deletions src/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static int xdpw_usage(FILE* stream, int rc) {
" -o, --output=<name> Select output to capture.\n"
" metadata (performs no conversion).\n"
" -r, --replace Replace a running instance.\n"
" -f, --max-fps=<fps> Set the FPS limit (default 0, no limit).\n"
" -h, --help Get help (this text).\n"
"\n";

Expand All @@ -42,12 +43,14 @@ int main(int argc, char *argv[]) {
const char* output_name = NULL;
enum LOGLEVEL loglevel = ERROR;
bool replace = false;
double max_fps = 0;

static const char* shortopts = "l:o:rh";
static const char* shortopts = "l:o:f:rh";
static const struct option longopts[] = {
{ "loglevel", required_argument, NULL, 'l' },
{ "output", required_argument, NULL, 'o' },
{ "replace", no_argument, NULL, 'r' },
{ "max-fps", required_argument, NULL, 'f' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};
Expand All @@ -67,6 +70,9 @@ int main(int argc, char *argv[]) {
case 'r':
replace = true;
break;
case 'f':
max_fps = atof(optarg);
break;
case 'h':
return xdpw_usage(stdout, EXIT_SUCCESS);
default:
Expand Down Expand Up @@ -116,7 +122,7 @@ int main(int argc, char *argv[]) {
wl_list_init(&state.xdpw_sessions);

xdpw_screenshot_init(&state);
ret = xdpw_screencast_init(&state, output_name);
ret = xdpw_screencast_init(&state, output_name, max_fps);
if (ret < 0) {
logprint(ERROR, "xdpw: failed to initialize screencast");
goto error;
Expand Down
5 changes: 2 additions & 3 deletions src/screencast/fps_limit.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
#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) {
Expand All @@ -23,7 +22,7 @@ void fps_limit_apply(struct fps_limit_state* state, double max_fps) {

measure_fps(state, now_us);

uint64_t target_us = (1.0 / TARGET_FPS) * 1e6;
uint64_t target_us = (1.0 / max_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);
Expand Down
4 changes: 3 additions & 1 deletion src/screencast/screencast.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ void xdpw_screencast_instance_init(struct xdpw_screencast_context *ctx,
struct xdpw_screencast_instance *cast, struct xdpw_wlr_output *out, bool with_cursor) {
cast->ctx = ctx;
cast->target_output = out;
cast->max_fps = ctx->max_fps;
cast->framerate = out->framerate;
cast->with_cursor = with_cursor;
cast->refcount = 1;
Expand Down Expand Up @@ -434,12 +435,13 @@ static const sd_bus_vtable screencast_vtable[] = {
SD_BUS_VTABLE_END
};

int xdpw_screencast_init(struct xdpw_state *state, const char *output_name) {
int xdpw_screencast_init(struct xdpw_state *state, const char *output_name, double max_fps) {
sd_bus_slot *slot = NULL;

state->screencast = (struct xdpw_screencast_context) { 0 };
state->screencast.state = state;
state->screencast.output_name = output_name;
state->screencast.max_fps = max_fps;

int err;
err = xdpw_pwr_core_connect(state);
Expand Down
2 changes: 1 addition & 1 deletion src/screencast/wlr_screencast.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static void wlr_frame_buffer_done(void *data,

logprint(TRACE, "wlroots: buffer_done event handler");

fps_limit_apply(&cast->fps_limit);
fps_limit_apply(&cast->fps_limit, cast->max_fps);

zwlr_screencopy_frame_v1_copy_with_damage(frame, cast->simple_frame.buffer);
logprint(TRACE, "wlroots: frame copied");
Expand Down

0 comments on commit 2c1d532

Please sign in to comment.