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 fbdef07f..d9ba6e30 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -103,11 +103,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 %d:%d.\n" @@ -154,6 +149,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" @@ -641,6 +641,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 @@ -667,6 +682,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[]) { @@ -703,6 +719,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'}, @@ -857,7 +874,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; @@ -885,6 +904,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 ed141d0e..31adf3ca 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -402,7 +402,7 @@ scrcpy(const struct scrcpy_options *options) { options->window_y, options->window_width, options->window_height, options->window_borderless, - options->rotation, options->mipmaps)) { + options->rotation, options->scale_filter)) { goto end; } diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h index 2253cc28..a89fa59c 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 = DEFAULT_MAX_SIZE, \ .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 b0bbe712..3c9da023 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" @@ -235,7 +234,7 @@ screen_init_rendering(struct screen *screen, const char *window_title, struct size frame_size, bool always_on_top, int16_t window_x, int16_t window_y, uint16_t window_width, uint16_t window_height, bool window_borderless, - uint8_t rotation, bool mipmaps) { + uint8_t rotation, enum sc_scale_filter scale_filter) { screen->frame_size = frame_size; screen->rotation = rotation; if (rotation) { @@ -289,6 +288,7 @@ screen_init_rendering(struct screen *screen, const char *window_title, // starts with "opengl" bool use_opengl = renderer_name && !strncmp(renderer_name, "opengl", 6); + bool mipmaps = scale_filter == SC_SCALE_FILTER_TRILINEAR; if (use_opengl) { struct sc_opengl *gl = &screen->gl; sc_opengl_init(gl); diff --git a/app/src/screen.h b/app/src/screen.h index 49ceb97b..53a62faf 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; @@ -50,7 +51,7 @@ screen_init_rendering(struct screen *screen, const char *window_title, struct size frame_size, bool always_on_top, int16_t window_x, int16_t window_y, uint16_t window_width, uint16_t window_height, bool window_borderless, - uint8_t rotation, bool mipmaps); + uint8_t rotation, enum sc_scale_filter scale_filter); // show the window void