From d76db3ad6209bb4cf4584366b9ad39fc25872db7 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Tue, 16 Feb 2021 23:29:27 +0100 Subject: [PATCH] scale_filter --- app/scrcpy.1 | 7 +++++++ app/src/cli.c | 36 ++++++++++++++++++++++++++++++------ app/src/scrcpy.c | 2 +- app/src/scrcpy.h | 9 +++++++-- app/src/screen.c | 6 +++--- app/src/screen.h | 3 ++- 6 files changed, 50 insertions(+), 13 deletions(-) diff --git a/app/scrcpy.1 b/app/scrcpy.1 index 92b8e1e3..7ebb3430 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -167,6 +167,13 @@ Set the initial display rotation. Possibles values are 0, 1, 2 and 3. Each incre .BI "\-s, \-\-serial " number The device serial number. Mandatory only if several devices are connected to adb. +.TP +.BI "\-\-scale\-filter filter +Supported filters are "none" and "trilinear". + +Trilinear filtering is only available if the renderer is OpenGL 3.0+ or OpenGL +ES 2.0+. + .TP .BI "\-\-shortcut\-mod " key[+...]][,...] Specify the modifiers to use for scrcpy shortcuts. Possible keys are "lctrl", "rctrl", "lalt", "ralt", "lsuper" and "rsuper". diff --git a/app/src/cli.c b/app/src/cli.c index 7f31b32c..4543835e 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -106,11 +106,6 @@ scrcpy_print_usage(const char *arg0) { " --no-key-repeat\n" " Do not forward repeated key events when a key is held down.\n" "\n" - " --no-mipmaps\n" - " If the renderer is OpenGL 3.0+ or OpenGL ES 2.0+, then\n" - " mipmaps are automatically generated to improve downscaling\n" - " quality. This option disables the generation of mipmaps.\n" - "\n" " -p, --port port[:port]\n" " Set the TCP port (range) used by the client to listen.\n" " Default is " STR(DEFAULT_LOCAL_PORT_RANGE_FIRST) ":" @@ -158,6 +153,11 @@ scrcpy_print_usage(const char *arg0) { " The device serial number. Mandatory only if several devices\n" " are connected to adb.\n" "\n" + " --scale-filter filter\n" + " Supported filters are \"none\" and \"trilinear\".\n" + " Trilinear filtering is only available if the renderer is\n" + " OpenGL 3.0+ or OpenGL ES 2.0+.\n" + "\n" " --shortcut-mod key[+...]][,...]\n" " Specify the modifiers to use for scrcpy shortcuts.\n" " Possible keys are \"lctrl\", \"rctrl\", \"lalt\", \"ralt\",\n" @@ -640,6 +640,21 @@ guess_record_format(const char *filename) { return 0; } +static bool +parse_scale_filter(const char *optarg, enum sc_scale_filter *filter) { + if (!strcmp(optarg, "none")) { + *filter = SC_SCALE_FILTER_NONE; + return true; + } + if (!strcmp(optarg, "trilinear")) { + *filter = SC_SCALE_FILTER_TRILINEAR; + return true; + } + LOGE("Unsupported scale filter: %s " + "(expected \"none\" or \"trilinear\")", optarg); + return false; +} + #define OPT_RENDER_EXPIRED_FRAMES 1000 #define OPT_WINDOW_TITLE 1001 #define OPT_PUSH_TARGET 1002 @@ -666,6 +681,7 @@ guess_record_format(const char *filename) { #define OPT_FORWARD_ALL_CLICKS 1023 #define OPT_LEGACY_PASTE 1024 #define OPT_ENCODER_NAME 1025 +#define OPT_SCALE_FILTER 1026 bool scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { @@ -702,6 +718,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { {"render-expired-frames", no_argument, NULL, OPT_RENDER_EXPIRED_FRAMES}, {"rotation", required_argument, NULL, OPT_ROTATION}, + {"scale-filter", required_argument, NULL, OPT_SCALE_FILTER}, {"serial", required_argument, NULL, 's'}, {"shortcut-mod", required_argument, NULL, OPT_SHORTCUT_MOD}, {"show-touches", no_argument, NULL, 't'}, @@ -856,7 +873,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { opts->render_driver = optarg; break; case OPT_NO_MIPMAPS: - opts->mipmaps = false; + LOGW("Deprecated option --no-mipmaps. " + "Use --scale-filter=none instead."); + opts->scale_filter = SC_SCALE_FILTER_NONE; break; case OPT_NO_KEY_REPEAT: opts->forward_key_repeat = false; @@ -884,6 +903,11 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { case OPT_LEGACY_PASTE: opts->legacy_paste = true; break; + case OPT_SCALE_FILTER: + if (!parse_scale_filter(optarg, &opts->scale_filter)) { + return false; + } + break; default: // getopt prints the error message on stderr return false; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 7ed9cb2c..3dafc703 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -392,7 +392,7 @@ scrcpy(const struct scrcpy_options *options) { .window_height = options->window_height, .window_borderless = options->window_borderless, .rotation = options->rotation, - .mipmaps = options->mipmaps, + .scale_filter = options->scale_filter, }; if (!screen_init(&screen, &video_buffer, &fps_counter, diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h index b877a987..62fe1fce 100644 --- a/app/src/scrcpy.h +++ b/app/src/scrcpy.h @@ -41,6 +41,11 @@ struct sc_port_range { uint16_t last; }; +enum sc_scale_filter { + SC_SCALE_FILTER_NONE, + SC_SCALE_FILTER_TRILINEAR, // mipmaps +}; + #define SC_WINDOW_POSITION_UNDEFINED (-0x8000) struct scrcpy_options { @@ -56,6 +61,7 @@ struct scrcpy_options { enum sc_record_format record_format; struct sc_port_range port_range; struct sc_shortcut_mods shortcut_mods; + enum sc_scale_filter scale_filter; uint16_t max_size; uint32_t bit_rate; uint16_t max_fps; @@ -75,7 +81,6 @@ struct scrcpy_options { bool render_expired_frames; bool prefer_text; bool window_borderless; - bool mipmaps; bool stay_awake; bool force_adb_forward; bool disable_screensaver; @@ -103,6 +108,7 @@ struct scrcpy_options { .data = {SC_MOD_LALT, SC_MOD_LSUPER}, \ .count = 2, \ }, \ + .scale_filter = SC_SCALE_FILTER_TRILINEAR, \ .max_size = 0, \ .bit_rate = DEFAULT_BIT_RATE, \ .max_fps = 0, \ @@ -122,7 +128,6 @@ struct scrcpy_options { .render_expired_frames = false, \ .prefer_text = false, \ .window_borderless = false, \ - .mipmaps = true, \ .stay_awake = false, \ .force_adb_forward = false, \ .disable_screensaver = false, \ diff --git a/app/src/screen.c b/app/src/screen.c index b48dfb69..6ff4950f 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -6,7 +6,6 @@ #include "events.h" #include "icon.xpm" -#include "scrcpy.h" #include "tiny_xpm.h" #include "video_buffer.h" #include "util/log.h" @@ -314,13 +313,14 @@ screen_init(struct screen *screen, struct video_buffer *vb, // starts with "opengl" bool use_opengl = renderer_name && !strncmp(renderer_name, "opengl", 6); + bool mipmaps = params->scale_filter == SC_SCALE_FILTER_TRILINEAR; if (use_opengl) { struct sc_opengl *gl = &screen->gl; sc_opengl_init(gl); LOGI("OpenGL version: %s", gl->version); - if (params->mipmaps) { + if (mipmaps) { bool supports_mipmaps = sc_opengl_version_at_least(gl, 3, 0, /* OpenGL 3.0+ */ 2, 0 /* OpenGL ES 2.0+ */); @@ -334,7 +334,7 @@ screen_init(struct screen *screen, struct video_buffer *vb, } else { LOGI("Trilinear filtering disabled"); } - } else if (params->mipmaps) { + } else if (mipmaps) { LOGD("Trilinear filtering disabled (not an OpenGL renderer)"); } diff --git a/app/src/screen.h b/app/src/screen.h index ad7892c9..a9bddc6c 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -9,6 +9,7 @@ #include "coords.h" #include "opengl.h" +#include "scrcpy.h" struct video_buffer; @@ -53,7 +54,7 @@ struct screen_params { bool window_borderless; uint8_t rotation; - bool mipmaps; + enum sc_scale_filter scale_filter; }; // initialize screen, create window, renderer and texture (window is hidden)