mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
refact: texture render as an option (#8168)
* refact: texture render as an option Signed-off-by: fufesou <linlong1266@gmail.com> * refact: texture render, translation Signed-off-by: fufesou <linlong1266@gmail.com> * refact: texture render as option Signed-off-by: fufesou <linlong1266@gmail.com> * Update ui_interface.rs --------- Signed-off-by: fufesou <linlong1266@gmail.com> Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
This commit is contained in:
@@ -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';
|
||||
@@ -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) {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -227,8 +226,7 @@ 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),
|
||||
@@ -236,12 +234,12 @@ List<(String, String)> otherDefaultSettings() {
|
||||
('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
|
||||
|
||||
@@ -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;
|
||||
@@ -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 &&
|
||||
@@ -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';
|
||||
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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(
|
||||
@@ -426,7 +441,7 @@ class _GeneralState extends State<_General> {
|
||||
context,
|
||||
'Remove wallpaper during incoming sessions',
|
||||
kOptionAllowRemoveWallpaper,
|
||||
update: () {
|
||||
update: (bool v) {
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
@@ -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();
|
||||
}
|
||||
},
|
||||
@@ -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,
|
||||
@@ -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(
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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';
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
|
||||
@@ -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';
|
||||
@@ -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);
|
||||
@@ -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(),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -11,15 +11,10 @@ import './platform_model.dart';
|
||||
import 'package:texture_rgba_renderer/texture_rgba_renderer.dart'
|
||||
if (dart.library.html) 'package:flutter_hbb/web/texture_rgba_renderer.dart';
|
||||
|
||||
// Feature flutter_texture_render need to be enabled if feature vram is enabled.
|
||||
final useTextureRender = !isWeb &&
|
||||
(bind.mainHasPixelbufferTextureRender() || bind.mainHasGpuTextureRender());
|
||||
|
||||
class _PixelbufferTexture {
|
||||
int _textureKey = -1;
|
||||
int _display = 0;
|
||||
SessionID? _sessionId;
|
||||
final support = bind.mainHasPixelbufferTextureRender();
|
||||
bool _destroying = false;
|
||||
int? _id;
|
||||
|
||||
@@ -28,26 +23,24 @@ class _PixelbufferTexture {
|
||||
int get display => _display;
|
||||
|
||||
create(int d, SessionID sessionId, FFI ffi) {
|
||||
if (support) {
|
||||
_display = d;
|
||||
_textureKey = bind.getNextTextureKey();
|
||||
_sessionId = sessionId;
|
||||
_display = d;
|
||||
_textureKey = bind.getNextTextureKey();
|
||||
_sessionId = sessionId;
|
||||
|
||||
textureRenderer.createTexture(_textureKey).then((id) async {
|
||||
_id = id;
|
||||
if (id != -1) {
|
||||
ffi.textureModel.setRgbaTextureId(display: d, id: id);
|
||||
final ptr = await textureRenderer.getTexturePtr(_textureKey);
|
||||
platformFFI.registerPixelbufferTexture(sessionId, display, ptr);
|
||||
debugPrint(
|
||||
"create pixelbuffer texture: peerId: ${ffi.id} display:$_display, textureId:$id, texturePtr:$ptr");
|
||||
}
|
||||
});
|
||||
}
|
||||
textureRenderer.createTexture(_textureKey).then((id) async {
|
||||
_id = id;
|
||||
if (id != -1) {
|
||||
ffi.textureModel.setRgbaTextureId(display: d, id: id);
|
||||
final ptr = await textureRenderer.getTexturePtr(_textureKey);
|
||||
platformFFI.registerPixelbufferTexture(sessionId, display, ptr);
|
||||
debugPrint(
|
||||
"create pixelbuffer texture: peerId: ${ffi.id} display:$_display, textureId:$id, texturePtr:$ptr");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
destroy(bool unregisterTexture, FFI ffi) async {
|
||||
if (!_destroying && support && _textureKey != -1 && _sessionId != null) {
|
||||
if (!_destroying && _textureKey != -1 && _sessionId != null) {
|
||||
_destroying = true;
|
||||
if (unregisterTexture) {
|
||||
platformFFI.registerPixelbufferTexture(_sessionId!, display, 0);
|
||||
|
||||
@@ -244,7 +244,7 @@ class FfiModel with ChangeNotifier {
|
||||
handleMsgBox({
|
||||
'type': 'success',
|
||||
'title': 'Successful',
|
||||
'text': 'Connected, waiting for image...',
|
||||
'text': kMsgboxTextWaitingForImage,
|
||||
'link': '',
|
||||
}, sessionId, peerId);
|
||||
updatePrivacyMode(data.updatePrivacyMode, sessionId, peerId);
|
||||
@@ -380,12 +380,22 @@ class FfiModel with ChangeNotifier {
|
||||
_handleSyncPeerOption(evt, peerId);
|
||||
} else if (name == 'follow_current_display') {
|
||||
handleFollowCurrentDisplay(evt, sessionId, peerId);
|
||||
} else if (name == 'use_texture_render') {
|
||||
_handleUseTextureRender(evt, sessionId, peerId);
|
||||
} else {
|
||||
debugPrint('Unknown event name: $name');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
_handleUseTextureRender(
|
||||
Map<String, dynamic> evt, SessionID sessionId, String peerId) {
|
||||
parent.target?.imageModel.setUseTextureRender(evt['v'] == 'Y');
|
||||
waitForFirstImage.value = true;
|
||||
showConnectedWaitingForImage(parent.target!.dialogManager, sessionId,
|
||||
'success', 'Successful', kMsgboxTextWaitingForImage);
|
||||
}
|
||||
|
||||
_handleSyncPeerOption(Map<String, dynamic> evt, String peer) {
|
||||
final k = evt['k'];
|
||||
final v = evt['v'];
|
||||
@@ -572,7 +582,7 @@ class FfiModel with ChangeNotifier {
|
||||
showElevationError(sessionId, type, title, text, dialogManager);
|
||||
} else if (type == 'relay-hint' || type == 'relay-hint2') {
|
||||
showRelayHintDialog(sessionId, type, title, text, dialogManager, peerId);
|
||||
} else if (text == 'Connected, waiting for image...') {
|
||||
} else if (text == kMsgboxTextWaitingForImage) {
|
||||
showConnectedWaitingForImage(dialogManager, sessionId, type, title, text);
|
||||
} else if (title == 'Privacy mode') {
|
||||
final hasRetry = evt['hasRetry'] == 'true';
|
||||
@@ -1156,6 +1166,8 @@ class ImageModel with ChangeNotifier {
|
||||
|
||||
late final SessionID sessionId;
|
||||
|
||||
bool _useTextureRender = false;
|
||||
|
||||
WeakReference<FFI> parent;
|
||||
|
||||
final List<Function(String)> callbacksOnFirstImage = [];
|
||||
@@ -1164,6 +1176,8 @@ class ImageModel with ChangeNotifier {
|
||||
sessionId = parent.target!.sessionId;
|
||||
}
|
||||
|
||||
get useTextureRender => _useTextureRender;
|
||||
|
||||
addCallbackOnFirstImage(Function(String) cb) => callbacksOnFirstImage.add(cb);
|
||||
|
||||
onRgba(int display, Uint8List rgba) {
|
||||
@@ -1233,6 +1247,19 @@ class ImageModel with ChangeNotifier {
|
||||
return min(xscale, yscale) / 1.5;
|
||||
}
|
||||
|
||||
updateUserTextureRender() {
|
||||
final preValue = _useTextureRender;
|
||||
_useTextureRender = isDesktop && bind.mainGetUseTextureRender();
|
||||
if (preValue != _useTextureRender) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
setUseTextureRender(bool value) {
|
||||
_useTextureRender = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void disposeImage() {
|
||||
_image?.dispose();
|
||||
_image = null;
|
||||
@@ -2387,7 +2414,7 @@ class FFI {
|
||||
sessionId: sessionId, displays: Int32List.fromList(displays));
|
||||
ffiModel.pi.currentDisplay = display;
|
||||
}
|
||||
if (connType == ConnType.defaultConn && useTextureRender) {
|
||||
if (isDesktop && connType == ConnType.defaultConn) {
|
||||
textureModel.updateCurrentDisplay(display ?? 0);
|
||||
}
|
||||
final stream = bind.sessionStart(sessionId: sessionId, id: id);
|
||||
@@ -2409,9 +2436,8 @@ class FFI {
|
||||
}
|
||||
}
|
||||
|
||||
final hasPixelBufferTextureRender = bind.mainHasPixelbufferTextureRender();
|
||||
imageModel.updateUserTextureRender();
|
||||
final hasGpuTextureRender = bind.mainHasGpuTextureRender();
|
||||
|
||||
final SimpleWrapper<bool> isToNewWindowNotified = SimpleWrapper(false);
|
||||
// Preserved for the rgba data.
|
||||
stream.listen((message) {
|
||||
@@ -2460,7 +2486,7 @@ class FFI {
|
||||
}
|
||||
} else if (message is EventToUI_Rgba) {
|
||||
final display = message.field0;
|
||||
if (hasPixelBufferTextureRender) {
|
||||
if (imageModel.useTextureRender) {
|
||||
debugPrint("EventToUI_Rgba display:$display");
|
||||
textureModel.setTextureType(display: display, gpuTexture: false);
|
||||
onEvent2UIRgba();
|
||||
|
||||
@@ -1414,10 +1414,6 @@ class RustdeskImpl {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
bool mainHasPixelbufferTextureRender({dynamic hint}) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mainHasFileClipboard({dynamic hint}) {
|
||||
return false;
|
||||
}
|
||||
@@ -1608,5 +1604,9 @@ class RustdeskImpl {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
bool mainGetUseTextureRender({dynamic hint}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
void dispose() {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user