Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b018be789 | ||
|
|
fa93c8a91b | ||
|
|
03705b828b | ||
|
|
85edba20e7 | ||
|
|
2a872c3865 |
@@ -215,6 +215,15 @@ scrcpy --max-fps 15
|
|||||||
|
|
||||||
This is officially supported since Android 10, but may work on earlier versions.
|
This is officially supported since Android 10, but may work on earlier versions.
|
||||||
|
|
||||||
|
The actual capture framerate may be printed to the console:
|
||||||
|
|
||||||
|
```
|
||||||
|
scrcpy --print-fps
|
||||||
|
```
|
||||||
|
|
||||||
|
It may also be enabled or disabled at any time with <kbd>MOD</kbd>+<kbd>i</kbd>.
|
||||||
|
|
||||||
|
|
||||||
#### Crop
|
#### Crop
|
||||||
|
|
||||||
The device screen may be cropped to mirror only part of the screen.
|
The device screen may be cropped to mirror only part of the screen.
|
||||||
|
|||||||
@@ -211,6 +211,10 @@ Inject alpha characters and space as text events instead of key events.
|
|||||||
This avoids issues when combining multiple keys to enter special characters,
|
This avoids issues when combining multiple keys to enter special characters,
|
||||||
but breaks the expected behavior of alpha keys in games (typically WASD).
|
but breaks the expected behavior of alpha keys in games (typically WASD).
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B "\-\-print\-fps
|
||||||
|
Start FPS counter, to print framerate logs to the console. It can be started or stopped at any time with MOD+i.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "\-\-push\-target " path
|
.BI "\-\-push\-target " path
|
||||||
Set the target directory for pushing files to the device by drag & drop. It is passed as\-is to "adb push".
|
Set the target directory for pushing files to the device by drag & drop. It is passed as\-is to "adb push".
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#define OPT_NO_DOWNSIZE_ON_ERROR 1035
|
#define OPT_NO_DOWNSIZE_ON_ERROR 1035
|
||||||
#define OPT_OTG 1036
|
#define OPT_OTG 1036
|
||||||
#define OPT_NO_CLEANUP 1037
|
#define OPT_NO_CLEANUP 1037
|
||||||
|
#define OPT_PRINT_FPS 1038
|
||||||
|
|
||||||
struct sc_option {
|
struct sc_option {
|
||||||
char shortopt;
|
char shortopt;
|
||||||
@@ -336,6 +337,12 @@ static const struct sc_option options[] = {
|
|||||||
"special character, but breaks the expected behavior of alpha "
|
"special character, but breaks the expected behavior of alpha "
|
||||||
"keys in games (typically WASD).",
|
"keys in games (typically WASD).",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.longopt_id = OPT_PRINT_FPS,
|
||||||
|
.longopt = "print-fps",
|
||||||
|
.text = "Start FPS counter, to print framerate logs to the console. "
|
||||||
|
"It can be started or stopped at any time with MOD+i.",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.longopt_id = OPT_PUSH_TARGET,
|
.longopt_id = OPT_PUSH_TARGET,
|
||||||
.longopt = "push-target",
|
.longopt = "push-target",
|
||||||
@@ -1547,6 +1554,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
case OPT_NO_CLEANUP:
|
case OPT_NO_CLEANUP:
|
||||||
opts->cleanup = false;
|
opts->cleanup = false;
|
||||||
break;
|
break;
|
||||||
|
case OPT_PRINT_FPS:
|
||||||
|
opts->start_fps_counter = true;
|
||||||
|
break;
|
||||||
case OPT_OTG:
|
case OPT_OTG:
|
||||||
#ifdef HAVE_USB
|
#ifdef HAVE_USB
|
||||||
opts->otg = true;
|
opts->otg = true;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
|
||||||
#define FPS_COUNTER_INTERVAL SC_TICK_FROM_SEC(1)
|
#define SC_FPS_COUNTER_INTERVAL SC_TICK_FROM_SEC(1)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fps_counter_init(struct fps_counter *counter) {
|
sc_fps_counter_init(struct sc_fps_counter *counter) {
|
||||||
bool ok = sc_mutex_init(&counter->mutex);
|
bool ok = sc_mutex_init(&counter->mutex);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return false;
|
return false;
|
||||||
@@ -27,26 +27,26 @@ fps_counter_init(struct fps_counter *counter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_destroy(struct fps_counter *counter) {
|
sc_fps_counter_destroy(struct sc_fps_counter *counter) {
|
||||||
sc_cond_destroy(&counter->state_cond);
|
sc_cond_destroy(&counter->state_cond);
|
||||||
sc_mutex_destroy(&counter->mutex);
|
sc_mutex_destroy(&counter->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
is_started(struct fps_counter *counter) {
|
is_started(struct sc_fps_counter *counter) {
|
||||||
return atomic_load_explicit(&counter->started, memory_order_acquire);
|
return atomic_load_explicit(&counter->started, memory_order_acquire);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
set_started(struct fps_counter *counter, bool started) {
|
set_started(struct sc_fps_counter *counter, bool started) {
|
||||||
atomic_store_explicit(&counter->started, started, memory_order_release);
|
atomic_store_explicit(&counter->started, started, memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
// must be called with mutex locked
|
// must be called with mutex locked
|
||||||
static void
|
static void
|
||||||
display_fps(struct fps_counter *counter) {
|
display_fps(struct sc_fps_counter *counter) {
|
||||||
unsigned rendered_per_second =
|
unsigned rendered_per_second =
|
||||||
counter->nr_rendered * SC_TICK_FREQ / FPS_COUNTER_INTERVAL;
|
counter->nr_rendered * SC_TICK_FREQ / SC_FPS_COUNTER_INTERVAL;
|
||||||
if (counter->nr_skipped) {
|
if (counter->nr_skipped) {
|
||||||
LOGI("%u fps (+%u frames skipped)", rendered_per_second,
|
LOGI("%u fps (+%u frames skipped)", rendered_per_second,
|
||||||
counter->nr_skipped);
|
counter->nr_skipped);
|
||||||
@@ -57,7 +57,7 @@ display_fps(struct fps_counter *counter) {
|
|||||||
|
|
||||||
// must be called with mutex locked
|
// must be called with mutex locked
|
||||||
static void
|
static void
|
||||||
check_interval_expired(struct fps_counter *counter, uint32_t now) {
|
check_interval_expired(struct sc_fps_counter *counter, sc_tick now) {
|
||||||
if (now < counter->next_timestamp) {
|
if (now < counter->next_timestamp) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -67,13 +67,13 @@ check_interval_expired(struct fps_counter *counter, uint32_t now) {
|
|||||||
counter->nr_skipped = 0;
|
counter->nr_skipped = 0;
|
||||||
// add a multiple of the interval
|
// add a multiple of the interval
|
||||||
uint32_t elapsed_slices =
|
uint32_t elapsed_slices =
|
||||||
(now - counter->next_timestamp) / FPS_COUNTER_INTERVAL + 1;
|
(now - counter->next_timestamp) / SC_FPS_COUNTER_INTERVAL + 1;
|
||||||
counter->next_timestamp += FPS_COUNTER_INTERVAL * elapsed_slices;
|
counter->next_timestamp += SC_FPS_COUNTER_INTERVAL * elapsed_slices;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
run_fps_counter(void *data) {
|
run_fps_counter(void *data) {
|
||||||
struct fps_counter *counter = data;
|
struct sc_fps_counter *counter = data;
|
||||||
|
|
||||||
sc_mutex_lock(&counter->mutex);
|
sc_mutex_lock(&counter->mutex);
|
||||||
while (!counter->interrupted) {
|
while (!counter->interrupted) {
|
||||||
@@ -94,9 +94,9 @@ run_fps_counter(void *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fps_counter_start(struct fps_counter *counter) {
|
sc_fps_counter_start(struct sc_fps_counter *counter) {
|
||||||
sc_mutex_lock(&counter->mutex);
|
sc_mutex_lock(&counter->mutex);
|
||||||
counter->next_timestamp = sc_tick_now() + FPS_COUNTER_INTERVAL;
|
counter->next_timestamp = sc_tick_now() + SC_FPS_COUNTER_INTERVAL;
|
||||||
counter->nr_rendered = 0;
|
counter->nr_rendered = 0;
|
||||||
counter->nr_skipped = 0;
|
counter->nr_skipped = 0;
|
||||||
sc_mutex_unlock(&counter->mutex);
|
sc_mutex_unlock(&counter->mutex);
|
||||||
@@ -117,22 +117,24 @@ fps_counter_start(struct fps_counter *counter) {
|
|||||||
counter->thread_started = true;
|
counter->thread_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGI("FPS counter started");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_stop(struct fps_counter *counter) {
|
sc_fps_counter_stop(struct sc_fps_counter *counter) {
|
||||||
set_started(counter, false);
|
set_started(counter, false);
|
||||||
sc_cond_signal(&counter->state_cond);
|
sc_cond_signal(&counter->state_cond);
|
||||||
|
LOGI("FPS counter stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fps_counter_is_started(struct fps_counter *counter) {
|
sc_fps_counter_is_started(struct sc_fps_counter *counter) {
|
||||||
return is_started(counter);
|
return is_started(counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_interrupt(struct fps_counter *counter) {
|
sc_fps_counter_interrupt(struct sc_fps_counter *counter) {
|
||||||
if (!counter->thread_started) {
|
if (!counter->thread_started) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -145,7 +147,7 @@ fps_counter_interrupt(struct fps_counter *counter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_join(struct fps_counter *counter) {
|
sc_fps_counter_join(struct sc_fps_counter *counter) {
|
||||||
if (counter->thread_started) {
|
if (counter->thread_started) {
|
||||||
// interrupted must be set by the thread calling join(), so no need to
|
// interrupted must be set by the thread calling join(), so no need to
|
||||||
// lock for the assertion
|
// lock for the assertion
|
||||||
@@ -156,7 +158,7 @@ fps_counter_join(struct fps_counter *counter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_add_rendered_frame(struct fps_counter *counter) {
|
sc_fps_counter_add_rendered_frame(struct sc_fps_counter *counter) {
|
||||||
if (!is_started(counter)) {
|
if (!is_started(counter)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -169,7 +171,7 @@ fps_counter_add_rendered_frame(struct fps_counter *counter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_add_skipped_frame(struct fps_counter *counter) {
|
sc_fps_counter_add_skipped_frame(struct sc_fps_counter *counter) {
|
||||||
if (!is_started(counter)) {
|
if (!is_started(counter)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
|
|
||||||
struct fps_counter {
|
struct sc_fps_counter {
|
||||||
sc_thread thread;
|
sc_thread thread;
|
||||||
sc_mutex mutex;
|
sc_mutex mutex;
|
||||||
sc_cond state_cond;
|
sc_cond state_cond;
|
||||||
@@ -28,32 +28,32 @@ struct fps_counter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fps_counter_init(struct fps_counter *counter);
|
sc_fps_counter_init(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_destroy(struct fps_counter *counter);
|
sc_fps_counter_destroy(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fps_counter_start(struct fps_counter *counter);
|
sc_fps_counter_start(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_stop(struct fps_counter *counter);
|
sc_fps_counter_stop(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fps_counter_is_started(struct fps_counter *counter);
|
sc_fps_counter_is_started(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
// request to stop the thread (on quit)
|
// request to stop the thread (on quit)
|
||||||
// must be called before fps_counter_join()
|
// must be called before sc_fps_counter_join()
|
||||||
void
|
void
|
||||||
fps_counter_interrupt(struct fps_counter *counter);
|
sc_fps_counter_interrupt(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_join(struct fps_counter *counter);
|
sc_fps_counter_join(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_add_rendered_frame(struct fps_counter *counter);
|
sc_fps_counter_add_rendered_frame(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_add_skipped_frame(struct fps_counter *counter);
|
sc_fps_counter_add_skipped_frame(struct sc_fps_counter *counter);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -242,18 +242,14 @@ set_screen_power_mode(struct sc_controller *controller,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
switch_fps_counter_state(struct fps_counter *fps_counter) {
|
switch_fps_counter_state(struct sc_fps_counter *fps_counter) {
|
||||||
// the started state can only be written from the current thread, so there
|
// the started state can only be written from the current thread, so there
|
||||||
// is no ToCToU issue
|
// is no ToCToU issue
|
||||||
if (fps_counter_is_started(fps_counter)) {
|
if (sc_fps_counter_is_started(fps_counter)) {
|
||||||
fps_counter_stop(fps_counter);
|
sc_fps_counter_stop(fps_counter);
|
||||||
LOGI("FPS counter stopped");
|
|
||||||
} else {
|
} else {
|
||||||
if (fps_counter_start(fps_counter)) {
|
sc_fps_counter_start(fps_counter);
|
||||||
LOGI("FPS counter started");
|
// Any error is already logged
|
||||||
} else {
|
|
||||||
LOGE("FPS counter starting failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,4 +63,5 @@ const struct scrcpy_options scrcpy_options_default = {
|
|||||||
.select_tcpip = false,
|
.select_tcpip = false,
|
||||||
.select_usb = false,
|
.select_usb = false,
|
||||||
.cleanup = true,
|
.cleanup = true,
|
||||||
|
.start_fps_counter = false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ struct scrcpy_options {
|
|||||||
bool select_usb;
|
bool select_usb;
|
||||||
bool select_tcpip;
|
bool select_tcpip;
|
||||||
bool cleanup;
|
bool cleanup;
|
||||||
|
bool start_fps_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct scrcpy_options scrcpy_options_default;
|
extern const struct scrcpy_options scrcpy_options_default;
|
||||||
|
|||||||
@@ -588,6 +588,7 @@ aoa_hid_end:
|
|||||||
.rotation = options->rotation,
|
.rotation = options->rotation,
|
||||||
.mipmaps = options->mipmaps,
|
.mipmaps = options->mipmaps,
|
||||||
.fullscreen = options->fullscreen,
|
.fullscreen = options->fullscreen,
|
||||||
|
.start_fps_counter = options->start_fps_counter,
|
||||||
.buffering_time = options->display_buffer,
|
.buffering_time = options->display_buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped,
|
|||||||
|
|
||||||
bool need_new_event;
|
bool need_new_event;
|
||||||
if (previous_skipped) {
|
if (previous_skipped) {
|
||||||
fps_counter_add_skipped_frame(&screen->fps_counter);
|
sc_fps_counter_add_skipped_frame(&screen->fps_counter);
|
||||||
// The EVENT_NEW_FRAME triggered for the previous frame will consume
|
// The EVENT_NEW_FRAME triggered for the previous frame will consume
|
||||||
// this new frame instead, unless the previous event failed
|
// this new frame instead, unless the previous event failed
|
||||||
need_new_event = screen->event_failed;
|
need_new_event = screen->event_failed;
|
||||||
@@ -386,6 +386,7 @@ sc_screen_init(struct sc_screen *screen,
|
|||||||
screen->req.width = params->window_width;
|
screen->req.width = params->window_width;
|
||||||
screen->req.height = params->window_height;
|
screen->req.height = params->window_height;
|
||||||
screen->req.fullscreen = params->fullscreen;
|
screen->req.fullscreen = params->fullscreen;
|
||||||
|
screen->req.start_fps_counter = params->start_fps_counter;
|
||||||
|
|
||||||
static const struct sc_video_buffer_callbacks cbs = {
|
static const struct sc_video_buffer_callbacks cbs = {
|
||||||
.on_new_frame = sc_video_buffer_on_new_frame,
|
.on_new_frame = sc_video_buffer_on_new_frame,
|
||||||
@@ -402,7 +403,7 @@ sc_screen_init(struct sc_screen *screen,
|
|||||||
goto error_destroy_video_buffer;
|
goto error_destroy_video_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fps_counter_init(&screen->fps_counter)) {
|
if (!sc_fps_counter_init(&screen->fps_counter)) {
|
||||||
goto error_stop_and_join_video_buffer;
|
goto error_stop_and_join_video_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,7 +535,7 @@ error_destroy_renderer:
|
|||||||
error_destroy_window:
|
error_destroy_window:
|
||||||
SDL_DestroyWindow(screen->window);
|
SDL_DestroyWindow(screen->window);
|
||||||
error_destroy_fps_counter:
|
error_destroy_fps_counter:
|
||||||
fps_counter_destroy(&screen->fps_counter);
|
sc_fps_counter_destroy(&screen->fps_counter);
|
||||||
error_stop_and_join_video_buffer:
|
error_stop_and_join_video_buffer:
|
||||||
sc_video_buffer_stop(&screen->vb);
|
sc_video_buffer_stop(&screen->vb);
|
||||||
sc_video_buffer_join(&screen->vb);
|
sc_video_buffer_join(&screen->vb);
|
||||||
@@ -562,6 +563,10 @@ sc_screen_show_initial_window(struct sc_screen *screen) {
|
|||||||
sc_screen_switch_fullscreen(screen);
|
sc_screen_switch_fullscreen(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (screen->req.start_fps_counter) {
|
||||||
|
sc_fps_counter_start(&screen->fps_counter);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_ShowWindow(screen->window);
|
SDL_ShowWindow(screen->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,13 +578,13 @@ sc_screen_hide_window(struct sc_screen *screen) {
|
|||||||
void
|
void
|
||||||
sc_screen_interrupt(struct sc_screen *screen) {
|
sc_screen_interrupt(struct sc_screen *screen) {
|
||||||
sc_video_buffer_stop(&screen->vb);
|
sc_video_buffer_stop(&screen->vb);
|
||||||
fps_counter_interrupt(&screen->fps_counter);
|
sc_fps_counter_interrupt(&screen->fps_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sc_screen_join(struct sc_screen *screen) {
|
sc_screen_join(struct sc_screen *screen) {
|
||||||
sc_video_buffer_join(&screen->vb);
|
sc_video_buffer_join(&screen->vb);
|
||||||
fps_counter_join(&screen->fps_counter);
|
sc_fps_counter_join(&screen->fps_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -591,7 +596,7 @@ sc_screen_destroy(struct sc_screen *screen) {
|
|||||||
SDL_DestroyTexture(screen->texture);
|
SDL_DestroyTexture(screen->texture);
|
||||||
SDL_DestroyRenderer(screen->renderer);
|
SDL_DestroyRenderer(screen->renderer);
|
||||||
SDL_DestroyWindow(screen->window);
|
SDL_DestroyWindow(screen->window);
|
||||||
fps_counter_destroy(&screen->fps_counter);
|
sc_fps_counter_destroy(&screen->fps_counter);
|
||||||
sc_video_buffer_destroy(&screen->vb);
|
sc_video_buffer_destroy(&screen->vb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,7 +706,7 @@ sc_screen_update_frame(struct sc_screen *screen) {
|
|||||||
sc_video_buffer_consume(&screen->vb, screen->frame);
|
sc_video_buffer_consume(&screen->vb, screen->frame);
|
||||||
AVFrame *frame = screen->frame;
|
AVFrame *frame = screen->frame;
|
||||||
|
|
||||||
fps_counter_add_rendered_frame(&screen->fps_counter);
|
sc_fps_counter_add_rendered_frame(&screen->fps_counter);
|
||||||
|
|
||||||
struct sc_size new_frame_size = {frame->width, frame->height};
|
struct sc_size new_frame_size = {frame->width, frame->height};
|
||||||
if (!prepare_for_frame(screen, new_frame_size)) {
|
if (!prepare_for_frame(screen, new_frame_size)) {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ struct sc_screen {
|
|||||||
|
|
||||||
struct sc_input_manager im;
|
struct sc_input_manager im;
|
||||||
struct sc_video_buffer vb;
|
struct sc_video_buffer vb;
|
||||||
struct fps_counter fps_counter;
|
struct sc_fps_counter fps_counter;
|
||||||
|
|
||||||
// The initial requested window properties
|
// The initial requested window properties
|
||||||
struct {
|
struct {
|
||||||
@@ -35,6 +35,7 @@ struct sc_screen {
|
|||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
|
bool start_fps_counter;
|
||||||
} req;
|
} req;
|
||||||
|
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
@@ -93,6 +94,7 @@ struct sc_screen_params {
|
|||||||
bool mipmaps;
|
bool mipmaps;
|
||||||
|
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
|
bool start_fps_counter;
|
||||||
|
|
||||||
sc_tick buffering_time;
|
sc_tick buffering_time;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -136,7 +136,9 @@ sc_cond_timedwait(sc_cond *cond, sc_mutex *mutex, sc_tick deadline) {
|
|||||||
return false; // timeout
|
return false; // timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ms = SC_TICK_TO_MS(deadline - now);
|
// Round up to the next millisecond to guarantee that the deadline is
|
||||||
|
// reached when returning due to timeout
|
||||||
|
uint32_t ms = SC_TICK_TO_MS(deadline - now + SC_TICK_FROM_MS(1) - 1);
|
||||||
int r = SDL_CondWaitTimeout(cond->cond, mutex->mutex, ms);
|
int r = SDL_CondWaitTimeout(cond->cond, mutex->mutex, ms);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@@ -148,6 +150,8 @@ sc_cond_timedwait(sc_cond *cond, sc_mutex *mutex, sc_tick deadline) {
|
|||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
#endif
|
#endif
|
||||||
assert(r == 0 || r == SDL_MUTEX_TIMEDOUT);
|
assert(r == 0 || r == SDL_MUTEX_TIMEDOUT);
|
||||||
|
// The deadline is reached on timeout
|
||||||
|
assert(r != SDL_MUTEX_TIMEDOUT || sc_tick_now() >= deadline);
|
||||||
return r == 0;
|
return r == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user