From 2fb4ec1931d3981bf9d7c1eb250eee066f4b970b Mon Sep 17 00:00:00 2001 From: Yukino Song Date: Wed, 21 Aug 2024 00:47:55 +0800 Subject: [PATCH] Add per-app resolution scale config --- src/process.cpp | 23 +++++++++++++------ src/process.h | 1 + src_assets/common/assets/web/apps.html | 12 +++++++++- .../assets/web/public/assets/locale/en.json | 10 ++++---- .../assets/web/public/assets/locale/zh.json | 8 ++++++- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/process.cpp b/src/process.cpp index 674cd0d1..729288cd 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -178,12 +178,17 @@ namespace proc { uint32_t render_width = client_width; uint32_t render_height = client_height; - if (launch_session->scale_factor != 100) { - render_width *= ((float)launch_session->scale_factor / 100); - render_height *= ((float)launch_session->scale_factor / 100); + int scale_factor = launch_session->scale_factor; + if (_app.scale_factor != 100) { + scale_factor = _app.scale_factor; + } + + if (scale_factor != 100) { + render_width *= ((float)scale_factor / 100); + render_height *= ((float)scale_factor / 100); // Chop the last bit to ensure the scaled resolution is even numbered - // Most odd resolution won't work well + // Most odd resolutions won't work well render_width &= ~1; render_height &= ~1; } @@ -197,7 +202,7 @@ namespace proc { _env["SUNSHINE_CLIENT_HEIGHT"] = std::to_string(render_height); _env["SUNSHINE_CLIENT_RENDER_WIDTH"] = std::to_string(launch_session->width); _env["SUNSHINE_CLIENT_RENDER_HEIGHT"] = std::to_string(launch_session->height); - _env["SUNSHINE_CLIENT_SCALE_FACTOR"] = std::to_string(launch_session->scale_factor); + _env["SUNSHINE_CLIENT_SCALE_FACTOR"] = std::to_string(scale_factor); _env["SUNSHINE_CLIENT_FPS"] = std::to_string(launch_session->fps); _env["SUNSHINE_CLIENT_HDR"] = launch_session->enable_hdr ? "true" : "false"; _env["SUNSHINE_CLIENT_GCMAP"] = std::to_string(launch_session->gcmap); @@ -699,6 +704,7 @@ namespace proc { std::vector apps; int i = 0; + #ifdef _WIN32 if (vDisplayDriverStatus == VDISPLAY::DRIVER_STATUS::OK) { proc::ctx_t ctx; ctx.name = "Virtual Display"; @@ -724,6 +730,7 @@ namespace proc { apps.emplace_back(std::move(ctx)); } + #endif for (auto &[_, app_node] : apps_node) { proc::ctx_t ctx; @@ -740,8 +747,9 @@ namespace proc { auto auto_detach = app_node.get_optional("auto-detach"s); auto wait_all = app_node.get_optional("wait-all"s); auto exit_timeout = app_node.get_optional("exit-timeout"s); - auto virtual_display = app_node.get_optional("virtual-display"); - auto virtual_display_primary = app_node.get_optional("virtual-display-primary"); + auto virtual_display = app_node.get_optional("virtual-display"s); + auto virtual_display_primary = app_node.get_optional("virtual-display-primary"s); + auto resolution_scale_factor = app_node.get_optional("scale-factor"s); std::vector prep_cmds; if (!exclude_global_prep.value_or(false)) { @@ -811,6 +819,7 @@ namespace proc { ctx.exit_timeout = std::chrono::seconds { exit_timeout.value_or(5) }; ctx.virtual_display = virtual_display.value_or(false); ctx.virtual_display_primary = virtual_display_primary.value_or(true); + ctx.scale_factor = resolution_scale_factor.value_or(100); auto possible_ids = calculate_app_id(name, ctx.image_path, i++); if (ids.count(std::get<0>(possible_ids)) == 0) { diff --git a/src/process.h b/src/process.h index 7dbc349b..199c888f 100644 --- a/src/process.h +++ b/src/process.h @@ -70,6 +70,7 @@ namespace proc { bool wait_all; bool virtual_display; bool virtual_display_primary; + int scale_factor; std::chrono::seconds exit_timeout; }; diff --git a/src_assets/common/assets/web/apps.html b/src_assets/common/assets/web/apps.html index ecb78f67..ce3a05d9 100644 --- a/src_assets/common/assets/web/apps.html +++ b/src_assets/common/assets/web/apps.html @@ -242,6 +242,12 @@ true-value="true" false-value="false" />
{{ $t('apps.virtual_display_primary_desc') }}
+ +
+ + +
{{ $t('apps.resolution_scale_factor_desc') }}
+
@@ -427,7 +433,8 @@ "prep-cmd": [], detached: [], "image-path": "", - "virtual-display-primary": true + "virtual-display-primary": true, + "scale-factor": "100" }; this.editForm.index = -1; this.showEditForm = true; @@ -456,6 +463,9 @@ if (typeof this.editForm["virtual-display-primary"] === "undefined") { this.editForm["virtual-display-primary"] = true; } + if (typeof this.editForm["scale-factor"] === "undefined") { + this.editForm["scale-factor"] = "100" + } this.showEditForm = true; }, showDeleteForm(id) { diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json index da271bbc..8a6c5d6b 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -80,10 +80,12 @@ "wait_all_desc": "This will continue streaming until all processes started by the app have terminated. When unchecked, streaming will stop when the initial app process exits, even if other app processes are still running.", "working_dir": "Working Directory", "working_dir_desc": "The working directory that should be passed to the process. For example, some applications use the working directory to search for configuration files. If not set, Apollo will default to the parent directory of the command", - "virtual_display": "Use Virtual Display", - "virtual_display_desc": "Always use Virtual Display on this app, overriding client request. Please make sure the SudoVDA driver is installed and enabled.", - "virtual_display_primary": "Set Virtual Display as Primary Display", - "virtual_display_primary_desc": "Automatically set the Virtual Display as Primary Display when the app starts. (Recommended to keep on)" + "virtual_display": "Always use Virtual Display", + "virtual_display_desc": "Always use virtual display on this app, overriding client request. Please make sure the SudoVDA driver is installed and enabled.", + "virtual_display_primary": "Set virtual display as primary display", + "virtual_display_primary_desc": "Automatically set the virtual display as primary display when the app starts. Virtual display will always be set to primary when client requests to use virtual display. (Recommended to keep on)", + "resolution_scale_factor": "Resolution Scale Factor", + "resolution_scale_factor_desc": "Scale the client requested resolution based on this factor. e.g. 2000x1000 with a factor of 120% will become 2400x1200. Overrides client requested factor when the number isn't 100%. This option won't affect client requested streaming resolution." }, "config": { "adapter_name": "Adapter Name", diff --git a/src_assets/common/assets/web/public/assets/locale/zh.json b/src_assets/common/assets/web/public/assets/locale/zh.json index 6e0ef55f..f916693b 100644 --- a/src_assets/common/assets/web/public/assets/locale/zh.json +++ b/src_assets/common/assets/web/public/assets/locale/zh.json @@ -77,7 +77,13 @@ "wait_all": "继续串流直到所有应用进程终止", "wait_all_desc": "这将继续串流直到应用程序启动的所有进程终止。 当未选中时,串流将在初始应用进程终止时停止,即使其他应用进程仍在运行。", "working_dir": "工作目录", - "working_dir_desc": "应传递给进程的工作目录。例如,某些应用程序使用工作目录搜索配置文件。如果不设置,Apollo 将默认使用命令的父目录" + "working_dir_desc": "应传递给进程的工作目录。例如,某些应用程序使用工作目录搜索配置文件。如果不设置,Apollo 将默认使用命令的父目录", + "virtual_display": "总是使用虚拟显示器", + "virtual_display_desc": "在使用这个App的时候总是使用虚拟显示器,覆盖客户端请求。请确保 SudoVDA 虚拟显示器驱动已安装并启用。", + "virtual_display_primary": "设置虚拟显示器为主显示器", + "virtual_display_primary_desc": "在App启动时自动将虚拟显示器设为主显示器。当客户端请求使用虚拟显示器时将无条件设为主显示器。(推荐保持开启)", + "resolution_scale_factor": "分辨率缩放比例", + "resolution_scale_factor_desc": "基于此比例缩放客户端请求的分辨率。例如 2000x1000 缩放 120% 将变成 2400x1200。当此项为非 100% 时覆盖客户端请求的缩放比例。此选项不会影响客户端请求的串流分辨率。" }, "config": { "adapter_name": "适配器名称",