Skip to content

Commit

Permalink
refact: texture render as an option (rustdesk#8168)
Browse files Browse the repository at this point in the history
* refact: texture render as an option

Signed-off-by: fufesou <[email protected]>

* refact: texture render, translation

Signed-off-by: fufesou <[email protected]>

* refact: texture render as option

Signed-off-by: fufesou <[email protected]>

* Update ui_interface.rs

---------

Signed-off-by: fufesou <[email protected]>
Co-authored-by: RustDesk <[email protected]>
  • Loading branch information
fufesou and rustdesk authored May 28, 2024
1 parent 010b175 commit 72ec86b
Show file tree
Hide file tree
Showing 66 changed files with 482 additions and 283 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/flutter-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -548,13 +548,14 @@ jobs:
- {
target: x86_64-apple-darwin,
os: macos-13, #macos-latest or macos-14 use M1 now, https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#:~:text=14%20GB-,macos%2Dlatest%20or%20macos%2D14,-The%20macos%2Dlatestlabel
extra-build-args: "--disable-flutter-texture-render",
extra-build-args: "",
arch: x86_64,
}
- {
target: aarch64-apple-darwin,
os: macos-latest,
extra-build-args: "--disable-flutter-texture-render", # disable this for mac, because we see a lot of users reporting flickering both on arm and x64, and we can not confirm if texture rendering has better performance if htere is no vram, https://github.com/rustdesk/rustdesk/issues/6296
# extra-build-args: "--disable-flutter-texture-render", # disable this for mac, because we see a lot of users reporting flickering both on arm and x64, and we can not confirm if texture rendering has better performance if htere is no vram, https://github.com/rustdesk/rustdesk/issues/6296
extra-build-args: "",
arch: aarch64,
}
steps:
Expand Down Expand Up @@ -1124,7 +1125,7 @@ jobs:
export JOBS=""
fi
echo $JOBS
cargo build --lib $JOBS --features hwcodec,flutter,flutter_texture_render --release
cargo build --lib $JOBS --features hwcodec,flutter --release
rm -rf target/release/deps target/release/build
rm -rf ~/.cargo
Expand Down
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ path = "src/naming.rs"
[features]
inline = []
cli = []
flutter_texture_render = []
use_samplerate = ["samplerate"]
use_rubato = ["rubato"]
use_dasp = ["dasp"]
Expand Down
4 changes: 0 additions & 4 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ def make_parser():
'Available: PrivacyMode. Special value is "ALL" and empty "". Default is empty.')
parser.add_argument('--flutter', action='store_true',
help='Build flutter package', default=False)
parser.add_argument('--disable-flutter-texture-render', action='store_true',
help='Build flutter package', default=False)
parser.add_argument(
'--hwcodec',
action='store_true',
Expand Down Expand Up @@ -278,8 +276,6 @@ def get_features(args):
features.append('vram')
if args.flutter:
features.append('flutter')
if not args.disable_flutter_texture_render:
features.append('flutter_texture_render')
if args.unix_file_copy_paste:
features.append('unix-file-copy-paste')
print("features:", features)
Expand Down
6 changes: 0 additions & 6 deletions flutter/lib/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import 'package:flutter_hbb/common/formatter/id_formatter.dart';
import 'package:flutter_hbb/desktop/widgets/refresh_wrapper.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/main.dart';
import 'package:flutter_hbb/models/desktop_render_texture.dart';
import 'package:flutter_hbb/models/peer_model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart';
Expand Down Expand Up @@ -2799,11 +2798,6 @@ sessionRefreshVideo(SessionID sessionId, PeerInfo pi) async {
}
}

bool isChooseDisplayToOpenInNewWindow(PeerInfo pi, SessionID sessionId) =>
pi.isSupportMultiDisplay &&
useTextureRender &&
bind.sessionGetDisplaysAsIndividualWindows(sessionId: sessionId) == 'Y';

Future<List<Rect>> getScreenListWayland() async {
final screenRectList = <Rect>[];
if (isMainDesktopWindow) {
Expand Down
8 changes: 3 additions & 5 deletions flutter/lib/common/widgets/setting_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/models/desktop_render_texture.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import 'package:get/get.dart';

Expand Down Expand Up @@ -227,21 +226,20 @@ List<(String, String)> otherDefaultSettings() {
if ((isDesktop || isWebDesktop)) ('Zoom cursor', kOptionZoomCursor),
('Show quality monitor', kOptionShowQualityMonitor),
('Mute', kOptionDisableAudio),
if (isDesktop)
('Enable file copy and paste', kOptionEnableFileCopyPaste),
if (isDesktop) ('Enable file copy and paste', kOptionEnableFileCopyPaste),
('Disable clipboard', kOptionDisableClipboard),
('Lock after session end', kOptionLockAfterSessionEnd),
('Privacy mode', kOptionPrivacyMode),
if (isMobile) ('Touch mode', kOptionTouchMode),
('True color (4:4:4)', kOptionI444),
('Reverse mouse wheel', kKeyReverseMouseWheel),
('swap-left-right-mouse', kOptionSwapLeftRightMouse),
if (isDesktop && useTextureRender)
if (isDesktop && bind.mainGetUseTextureRender())
(
'Show displays as individual windows',
kKeyShowDisplaysAsIndividualWindows
),
if (isDesktop && useTextureRender)
if (isDesktop && bind.mainGetUseTextureRender())
(
'Use all my displays for the remote session',
kKeyUseAllMyDisplaysForTheRemoteSession
Expand Down
7 changes: 4 additions & 3 deletions flutter/lib/common/widgets/toolbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:flutter_hbb/common/widgets/dialog.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/models/model.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/models/desktop_render_texture.dart';
import 'package:get/get.dart';

bool isEditOsPassword = false;
Expand Down Expand Up @@ -581,7 +580,7 @@ Future<List<TToggleMenu>> toolbarDisplayToggle(
child: Text(translate('Lock after session end'))));
}

if (useTextureRender &&
if (bind.mainGetUseTextureRender() &&
pi.isSupportMultiDisplay &&
PrivacyModeState.find(id).isEmpty &&
pi.displaysCount.value > 1 &&
Expand All @@ -600,7 +599,9 @@ Future<List<TToggleMenu>> toolbarDisplayToggle(
}

final isMultiScreens = !isWeb && (await getScreenRectList()).length > 1;
if (useTextureRender && pi.isSupportMultiDisplay && isMultiScreens) {
if (bind.mainGetUseTextureRender() &&
pi.isSupportMultiDisplay &&
isMultiScreens) {
final value = bind.sessionGetUseAllMyDisplaysForTheRemoteSession(
sessionId: ffi.sessionId) ==
'Y';
Expand Down
3 changes: 3 additions & 0 deletions flutter/lib/consts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const String kOptionViewStyle = "view_style";
const String kOptionScrollStyle = "scroll_style";
const String kOptionImageQuality = "image_quality";
const String kOptionOpenNewConnInTabs = "enable-open-new-connections-in-tabs";
const String kOptionTextureRender = "use-texture-render";
const String kOptionOpenInTabs = "allow-open-in-tabs";
const String kOptionOpenInWindows = "allow-open-in-windows";
const String kOptionForceAlwaysRelay = "force-always-relay";
Expand Down Expand Up @@ -153,6 +154,8 @@ const String kKeyUseAllMyDisplaysForTheRemoteSession =
const String kKeyShowMonitorsToolbar = 'show_monitors_toolbar';
const String kKeyReverseMouseWheel = "reverse_mouse_wheel";

const String kMsgboxTextWaitingForImage = 'Connected, waiting for image...';

// the executable name of the portable version
const String kEnvPortableExecutable = "RUSTDESK_APPNAME";

Expand Down
71 changes: 47 additions & 24 deletions flutter/lib/desktop/pages/desktop_setting_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,25 @@ class _GeneralState extends State<_General> {
isServer: false,
),
// though this is related to GUI, but opengl problem affects all users, so put in config rather than local
if (isLinux)
Tooltip(
message: translate('software_render_tip'),
child: _OptionCheckBox(
context,
"Always use software rendering",
kOptionAllowAlwaysSoftwareRender,
),
),
Tooltip(
message: translate('software_render_tip'),
child: _OptionCheckBox(context, "Always use software rendering",
kOptionAllowAlwaysSoftwareRender),
message: translate('texture_render_tip'),
child: _OptionCheckBox(
context,
"Use texture rendering",
kOptionTextureRender,
optGetter: bind.mainGetUseTextureRender,
optSetter: (k, v) async =>
await bind.mainSetLocalOption(key: k, value: v ? 'Y' : 'N'),
),
),
if (!bind.isCustomClient())
_OptionCheckBox(
Expand Down Expand Up @@ -426,7 +441,7 @@ class _GeneralState extends State<_General> {
context,
'Remove wallpaper during incoming sessions',
kOptionAllowRemoveWallpaper,
update: () {
update: (bool v) {
setState(() {});
},
),
Expand Down Expand Up @@ -457,8 +472,8 @@ class _GeneralState extends State<_General> {
context,
'Enable hardware codec',
kOptionEnableHwcodec,
update: () {
if (mainGetBoolOptionSync(kOptionEnableHwcodec)) {
update: (bool v) {
if (v) {
bind.mainCheckHwcodec();
}
},
Expand Down Expand Up @@ -941,7 +956,7 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin {

List<Widget> directIp(BuildContext context) {
TextEditingController controller = TextEditingController();
update() => setState(() {});
update(bool v) => setState(() {});
RxBool applyEnabled = false.obs;
return [
_OptionCheckBox(context, 'Enable direct IP access', kOptionDirectServer,
Expand Down Expand Up @@ -1102,7 +1117,7 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin {

List<Widget> autoDisconnect(BuildContext context) {
TextEditingController controller = TextEditingController();
update() => setState(() {});
update(bool v) => setState(() {});
RxBool applyEnabled = false.obs;
return [
_OptionCheckBox(
Expand Down Expand Up @@ -1803,33 +1818,41 @@ Widget _Card(
}

// ignore: non_constant_identifier_names
Widget _OptionCheckBox(BuildContext context, String label, String key,
{Function()? update,
bool reverse = false,
bool enabled = true,
Icon? checkedIcon,
bool? fakeValue,
bool isServer = true}) {
bool value =
isServer ? mainGetBoolOptionSync(key) : mainGetLocalBoolOptionSync(key);
Widget _OptionCheckBox(
BuildContext context,
String label,
String key, {
Function(bool)? update,
bool reverse = false,
bool enabled = true,
Icon? checkedIcon,
bool? fakeValue,
bool isServer = true,
bool Function()? optGetter,
Future<void> Function(String, bool)? optSetter,
}) {
getOpt() => optGetter != null
? optGetter()
: (isServer
? mainGetBoolOptionSync(key)
: mainGetLocalBoolOptionSync(key));
bool value = getOpt();
final isOptFixed = isOptionFixed(key);
if (reverse) value = !value;
var ref = value.obs;
onChanged(option) async {
if (option != null) {
if (reverse) option = !option;
isServer
? await mainSetBoolOption(key, option)
: await mainSetLocalBoolOption(key, option);
final readOption = isServer
? mainGetBoolOptionSync(key)
: mainGetLocalBoolOptionSync(key);
final setter =
optSetter ?? (isServer ? mainSetBoolOption : mainSetLocalBoolOption);
await setter(key, option);
final readOption = getOpt();
if (reverse) {
ref.value = !readOption;
} else {
ref.value = readOption;
}
update?.call();
update?.call(readOption);
}
}

Expand Down
6 changes: 2 additions & 4 deletions flutter/lib/desktop/pages/remote_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import '../../common.dart';
import '../../common/widgets/dialog.dart';
import '../../common/widgets/toolbar.dart';
import '../../models/model.dart';
import '../../models/desktop_render_texture.dart';
import '../../models/platform_model.dart';
import '../../common/shared_state.dart';
import '../../utils/image.dart';
Expand Down Expand Up @@ -593,12 +592,11 @@ class _ImagePaintState extends State<ImagePaint> {
onHover: (evt) {},
child: child);
});

if (c.imageOverflow.isTrue && c.scrollStyle == ScrollStyle.scrollbar) {
final paintWidth = c.getDisplayWidth() * s;
final paintHeight = c.getDisplayHeight() * s;
final paintSize = Size(paintWidth, paintHeight);
final paintWidget = useTextureRender
final paintWidget = m.useTextureRender
? _BuildPaintTextureRender(
c, s, Offset.zero, paintSize, isViewOriginal())
: _buildScrollbarNonTextureRender(m, paintSize, s);
Expand All @@ -619,7 +617,7 @@ class _ImagePaintState extends State<ImagePaint> {
));
} else {
if (c.size.width > 0 && c.size.height > 0) {
final paintWidget = useTextureRender
final paintWidget = m.useTextureRender
? _BuildPaintTextureRender(
c,
s,
Expand Down
40 changes: 25 additions & 15 deletions flutter/lib/desktop/widgets/remote_toolbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'package:flutter_hbb/common/widgets/audio_input.dart';
import 'package:flutter_hbb/common/widgets/toolbar.dart';
import 'package:flutter_hbb/models/chat_model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/models/desktop_render_texture.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart';
import 'package:flutter_hbb/plugin/widgets/desc_ui.dart';
Expand Down Expand Up @@ -615,14 +614,14 @@ class _MonitorMenu extends StatelessWidget {
bind.mainGetUserDefaultOption(key: kKeyShowMonitorsToolbar) == 'Y';

bool get supportIndividualWindows =>
useTextureRender && ffi.ffiModel.pi.isSupportMultiDisplay;
!isWeb && ffi.ffiModel.pi.isSupportMultiDisplay;

@override
Widget build(BuildContext context) => showMonitorsToolbar
? buildMultiMonitorMenu()
: Obx(() => buildMonitorMenu());
? buildMultiMonitorMenu(context)
: Obx(() => buildMonitorMenu(context));

Widget buildMonitorMenu() {
Widget buildMonitorMenu(BuildContext context) {
final width = SimpleWrapper<double>(0);
final monitorsIcon =
globalMonitorsWidget(width, Colors.white, Colors.black38);
Expand All @@ -636,20 +635,23 @@ class _MonitorMenu extends StatelessWidget {
menuStyle: MenuStyle(
padding:
MaterialStatePropertyAll(EdgeInsets.symmetric(horizontal: 6))),
menuChildrenGetter: () => [buildMonitorSubmenuWidget()]);
menuChildrenGetter: () => [buildMonitorSubmenuWidget(context)]);
}

Widget buildMultiMonitorMenu() {
return Row(children: buildMonitorList(true));
Widget buildMultiMonitorMenu(BuildContext context) {
return Row(children: buildMonitorList(context, true));
}

Widget buildMonitorSubmenuWidget() {
Widget buildMonitorSubmenuWidget(BuildContext context) {
final m = Provider.of<ImageModel>(context);
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(children: buildMonitorList(false)),
supportIndividualWindows ? Divider() : Offstage(),
supportIndividualWindows ? chooseDisplayBehavior() : Offstage(),
Row(children: buildMonitorList(context, false)),
supportIndividualWindows && m.useTextureRender ? Divider() : Offstage(),
supportIndividualWindows && m.useTextureRender
? chooseDisplayBehavior()
: Offstage(),
],
);
}
Expand Down Expand Up @@ -680,7 +682,7 @@ class _MonitorMenu extends StatelessWidget {
),
);

List<Widget> buildMonitorList(bool isMulti) {
List<Widget> buildMonitorList(BuildContext context, bool isMulti) {
final List<Widget> monitorList = [];
final pi = ffi.ffiModel.pi;

Expand Down Expand Up @@ -735,7 +737,10 @@ class _MonitorMenu extends StatelessWidget {
for (int i = 0; i < pi.displays.length; i++) {
monitorList.add(buildMonitorButton(i));
}
if (supportIndividualWindows && pi.displays.length > 1) {
final m = Provider.of<ImageModel>(context);
if (supportIndividualWindows &&
m.useTextureRender &&
pi.displays.length > 1) {
monitorList.add(buildMonitorButton(kAllDisplayValue));
}
return monitorList;
Expand Down Expand Up @@ -818,7 +823,12 @@ class _MonitorMenu extends StatelessWidget {
}
RxInt display = CurrentDisplayState.find(id);
if (display.value != i) {
if (isChooseDisplayToOpenInNewWindow(pi, ffi.sessionId)) {
final isChooseDisplayToOpenInNewWindow = pi.isSupportMultiDisplay &&
bind.mainGetUseTextureRender() &&
bind.sessionGetDisplaysAsIndividualWindows(
sessionId: ffi.sessionId) ==
'Y';
if (isChooseDisplayToOpenInNewWindow) {
openMonitorInNewTabOrWindow(i, ffi.id, pi);
} else {
openMonitorInTheSameTab(i, ffi, pi, updateCursorPos: !isMulti);
Expand Down
Loading

0 comments on commit 72ec86b

Please sign in to comment.