From 8a9b20b27e69dc0f77e305e2a0b829d89d264ca7 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sat, 11 Apr 2020 14:34:41 +0200 Subject: [PATCH] Add --render-driver command-line option Add an option to set a render driver hint (SDL_HINT_RENDER_DRIVER). --- app/scrcpy.1 | 8 ++++++++ app/src/cli.c | 12 ++++++++++++ app/src/scrcpy.c | 8 ++++++-- app/src/scrcpy.h | 2 ++ app/src/screen.c | 5 +++++ 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/scrcpy.1 b/app/scrcpy.1 index e3b9f4cc..99936732 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -106,6 +106,14 @@ option if set, or by the file extension (.mp4 or .mkv). .BI "\-\-record\-format " format Force recording format (either mp4 or mkv). +.TP +.BI "\-\-render\-driver " name +Request SDL to use the given render driver (this is just a hint). + +Supported names are currently "direct3d", "opengl", "opengles2", "opengles", "metal" and "software". +.UR https://wiki.libsdl.org/SDL_HINT_RENDER_DRIVER +.UE + .TP .B \-\-render\-expired\-frames By default, to minimize latency, scrcpy always renders the last available decoded frame, and drops any previous ones. This flag forces to render all frames, at a cost of a possible increased latency. diff --git a/app/src/cli.c b/app/src/cli.c index 488bbc33..9c79eb02 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -99,6 +99,13 @@ scrcpy_print_usage(const char *arg0) { " --record-format format\n" " Force recording format (either mp4 or mkv).\n" "\n" + " --render-driver name\n" + " Request SDL to use the given render driver (this is just a\n" + " hint).\n" + " Supported names are currently \"direct3d\", \"opengl\",\n" + " \"opengles2\", \"opengles\", \"metal\" and \"software\".\n" + " \n" + "\n" " --render-expired-frames\n" " By default, to minimize latency, scrcpy always renders the\n" " last available decoded frame, and drops any previous ones.\n" @@ -454,6 +461,7 @@ guess_record_format(const char *filename) { #define OPT_LOCK_VIDEO_ORIENTATION 1013 #define OPT_DISPLAY_ID 1014 #define OPT_ROTATION 1015 +#define OPT_RENDER_DRIVER 1016 bool scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { @@ -474,6 +482,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { {"push-target", required_argument, NULL, OPT_PUSH_TARGET}, {"record", required_argument, NULL, 'r'}, {"record-format", required_argument, NULL, OPT_RECORD_FORMAT}, + {"render-driver", required_argument, NULL, OPT_RENDER_DRIVER}, {"render-expired-frames", no_argument, NULL, OPT_RENDER_EXPIRED_FRAMES}, {"rotation", required_argument, NULL, OPT_ROTATION}, @@ -617,6 +626,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { return false; } break; + case OPT_RENDER_DRIVER: + opts->render_driver = optarg; + break; default: // getopt prints the error message on stderr return false; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 94e8cde5..0fe3d0f0 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -47,7 +47,7 @@ static struct input_manager input_manager = { // init SDL and set appropriate hints static bool -sdl_init_and_configure(bool display) { +sdl_init_and_configure(bool display, const char *render_driver) { uint32_t flags = display ? SDL_INIT_VIDEO : SDL_INIT_EVENTS; if (SDL_Init(flags)) { LOGC("Could not initialize SDL: %s", SDL_GetError()); @@ -60,6 +60,10 @@ sdl_init_and_configure(bool display) { return true; } + if (render_driver && !SDL_SetHint(SDL_HINT_RENDER_DRIVER, render_driver)) { + LOGW("Could not set render driver"); + } + // Linear filtering if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) { LOGW("Could not enable linear filtering"); @@ -310,7 +314,7 @@ scrcpy(const struct scrcpy_options *options) { bool controller_initialized = false; bool controller_started = false; - if (!sdl_init_and_configure(options->display)) { + if (!sdl_init_and_configure(options->display, options->render_driver)) { goto end; } diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h index 93ee6724..a53aaa21 100644 --- a/app/src/scrcpy.h +++ b/app/src/scrcpy.h @@ -15,6 +15,7 @@ struct scrcpy_options { const char *record_filename; const char *window_title; const char *push_target; + const char *render_driver; enum recorder_format record_format; struct port_range port_range; uint16_t max_size; @@ -44,6 +45,7 @@ struct scrcpy_options { .record_filename = NULL, \ .window_title = NULL, \ .push_target = NULL, \ + .render_driver = NULL, \ .record_format = RECORDER_FORMAT_AUTO, \ .port_range = { \ .first = DEFAULT_LOCAL_PORT_RANGE_FIRST, \ diff --git a/app/src/screen.c b/app/src/screen.c index 4dacaae2..83b07362 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -226,6 +226,11 @@ screen_init_rendering(struct screen *screen, const char *window_title, return false; } + SDL_RendererInfo renderer_info; + int r = SDL_GetRendererInfo(screen->renderer, &renderer_info); + const char *renderer_name = r ? NULL : renderer_info.name; + LOGI("Renderer: %s", renderer_name ? renderer_name : "(unknown)"); + if (SDL_RenderSetLogicalSize(screen->renderer, content_size.width, content_size.height)) { LOGE("Could not set renderer logical size: %s", SDL_GetError());