fix: non texture, multi window, switch display (#8353)
* fix: non texture, multi window, switch display Signed-off-by: fufesou <linlong1266@gmail.com> * fix build Signed-off-by: fufesou <linlong1266@gmail.com> --------- Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
parent
70c20fc76f
commit
92dd0ee1dd
@ -2924,7 +2924,8 @@ openMonitorInNewTabOrWindow(int i, String peerId, PeerInfo pi,
|
|||||||
kMainWindowId, kWindowEventOpenMonitorSession, jsonEncode(args));
|
kMainWindowId, kWindowEventOpenMonitorSession, jsonEncode(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
setNewConnectWindowFrame(int windowId, String peerId, int? display, Rect? screenRect) async {
|
setNewConnectWindowFrame(
|
||||||
|
int windowId, String peerId, int? display, Rect? screenRect) async {
|
||||||
if (screenRect == null) {
|
if (screenRect == null) {
|
||||||
await restoreWindowPosition(WindowType.RemoteDesktop,
|
await restoreWindowPosition(WindowType.RemoteDesktop,
|
||||||
windowId: windowId, display: display, peerId: peerId);
|
windowId: windowId, display: display, peerId: peerId);
|
||||||
|
@ -2420,7 +2420,8 @@ class FFI {
|
|||||||
'Unreachable, failed to add existed session to $id, the displays is null while display is $display');
|
'Unreachable, failed to add existed session to $id, the displays is null while display is $display');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final addRes = bind.sessionAddExistedSync(id: id, sessionId: sessionId);
|
final addRes = bind.sessionAddExistedSync(
|
||||||
|
id: id, sessionId: sessionId, displays: Int32List.fromList(displays));
|
||||||
if (addRes != '') {
|
if (addRes != '') {
|
||||||
debugPrint(
|
debugPrint(
|
||||||
'Unreachable, failed to add existed session to $id, $addRes');
|
'Unreachable, failed to add existed session to $id, $addRes');
|
||||||
|
@ -59,7 +59,10 @@ class RustdeskImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String sessionAddExistedSync(
|
String sessionAddExistedSync(
|
||||||
{required String id, required UuidValue sessionId, dynamic hint}) {
|
{required String id,
|
||||||
|
required UuidValue sessionId,
|
||||||
|
required Int32List displays,
|
||||||
|
dynamic hint}) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +168,9 @@ pub unsafe extern "C" fn get_rustdesk_app_name(buffer: *mut u16, length: i32) ->
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct SessionHandler {
|
struct SessionHandler {
|
||||||
event_stream: Option<StreamSink<EventToUI>>,
|
event_stream: Option<StreamSink<EventToUI>>,
|
||||||
|
// displays of current session.
|
||||||
|
// We need this variable to check if the display is in use before pushing rgba to flutter.
|
||||||
|
displays: Vec<usize>,
|
||||||
renderer: VideoRenderer,
|
renderer: VideoRenderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,25 +411,6 @@ impl VideoRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_displays(&self, displays: &[i32]) {
|
|
||||||
let mut sessions_lock = self.map_display_sessions.write().unwrap();
|
|
||||||
for display in displays {
|
|
||||||
let d = *display as usize;
|
|
||||||
if !sessions_lock.contains_key(&d) {
|
|
||||||
sessions_lock.insert(
|
|
||||||
d,
|
|
||||||
DisplaySessionInfo {
|
|
||||||
texture_rgba_ptr: 0,
|
|
||||||
size: (0, 0),
|
|
||||||
#[cfg(feature = "vram")]
|
|
||||||
gpu_output_ptr: usize::default(),
|
|
||||||
notify_render_type: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub fn on_rgba(&self, display: usize, rgba: &scrap::ImageRgb) -> bool {
|
pub fn on_rgba(&self, display: usize, rgba: &scrap::ImageRgb) -> bool {
|
||||||
let mut write_lock = self.map_display_sessions.write().unwrap();
|
let mut write_lock = self.map_display_sessions.write().unwrap();
|
||||||
@ -598,6 +582,7 @@ impl FlutterHandler {
|
|||||||
pub fn update_use_texture_render(&self) {
|
pub fn update_use_texture_render(&self) {
|
||||||
self.use_texture_render
|
self.use_texture_render
|
||||||
.store(crate::ui_interface::use_texture_render(), Ordering::Relaxed);
|
.store(crate::ui_interface::use_texture_render(), Ordering::Relaxed);
|
||||||
|
self.display_rgbas.write().unwrap().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1058,26 +1043,39 @@ impl FlutterHandler {
|
|||||||
}
|
}
|
||||||
drop(rgba_write_lock);
|
drop(rgba_write_lock);
|
||||||
|
|
||||||
let is_multi_sessions = self.session_handlers.read().unwrap().len() > 1;
|
let mut is_sent = false;
|
||||||
|
let is_multi_sessions = self.is_multi_ui_session();
|
||||||
for h in self.session_handlers.read().unwrap().values() {
|
for h in self.session_handlers.read().unwrap().values() {
|
||||||
// `map_display_sessions` stores the display indices that are used by the video renderer.
|
// The soft renderer does not support multi-displays session for now.
|
||||||
let map_display_sessions = h.renderer.map_display_sessions.read().unwrap();
|
if h.displays.len() > 1 {
|
||||||
// The soft renderer does not support multi ui session for now.
|
|
||||||
if map_display_sessions.len() > 1 {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// If there're multiple ui sessions, we only notify the ui session that has the display.
|
// If there're multiple ui sessions, we only notify the ui session that has the display.
|
||||||
// We must make sure that the display is in the `map_display_sessions`.
|
|
||||||
// `session_start_with_displays()` can guarantee that.
|
|
||||||
if is_multi_sessions {
|
if is_multi_sessions {
|
||||||
if !map_display_sessions.contains_key(&display) {
|
if !h.displays.contains(&display) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(stream) = &h.event_stream {
|
if let Some(stream) = &h.event_stream {
|
||||||
stream.add(EventToUI::Rgba(display));
|
stream.add(EventToUI::Rgba(display));
|
||||||
|
is_sent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// We need `is_sent` here. Because we use texture render for multi-displays session.
|
||||||
|
//
|
||||||
|
// Eg. We have to windows, one is display 1, the other is displays 0&1.
|
||||||
|
// When image of display 0 is received, we will not send the event.
|
||||||
|
//
|
||||||
|
// 1. "display 1" will not send the event.
|
||||||
|
// 2. "displays 0&1" will not send the event. Because it uses texutre render for now.
|
||||||
|
if !is_sent {
|
||||||
|
self.display_rgbas
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.get_mut(&display)
|
||||||
|
.unwrap()
|
||||||
|
.valid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -1089,8 +1087,7 @@ impl FlutterHandler {
|
|||||||
rgba: &mut scrap::ImageRgb,
|
rgba: &mut scrap::ImageRgb,
|
||||||
) {
|
) {
|
||||||
for (_, session) in self.session_handlers.read().unwrap().iter() {
|
for (_, session) in self.session_handlers.read().unwrap().iter() {
|
||||||
if use_texture_render || session.renderer.map_display_sessions.read().unwrap().len() > 1
|
if use_texture_render || session.displays.len() > 1 {
|
||||||
{
|
|
||||||
if session.renderer.on_rgba(display, rgba) {
|
if session.renderer.on_rgba(display, rgba) {
|
||||||
if let Some(stream) = &session.event_stream {
|
if let Some(stream) = &session.event_stream {
|
||||||
stream.add(EventToUI::Rgba(display));
|
stream.add(EventToUI::Rgba(display));
|
||||||
@ -1102,8 +1099,12 @@ impl FlutterHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function is only used for the default connection session.
|
// This function is only used for the default connection session.
|
||||||
pub fn session_add_existed(peer_id: String, session_id: SessionID) -> ResultType<()> {
|
pub fn session_add_existed(
|
||||||
sessions::insert_peer_session_id(peer_id, ConnType::DEFAULT_CONN, session_id);
|
peer_id: String,
|
||||||
|
session_id: SessionID,
|
||||||
|
displays: Vec<i32>,
|
||||||
|
) -> ResultType<()> {
|
||||||
|
sessions::insert_peer_session_id(peer_id, ConnType::DEFAULT_CONN, session_id, displays);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1523,6 +1524,11 @@ pub fn session_set_size(session_id: SessionID, display: usize, width: usize, hei
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.get_mut(&session_id)
|
.get_mut(&session_id)
|
||||||
{
|
{
|
||||||
|
// If the session is the first connection, displays is not set yet.
|
||||||
|
// `displays`` is set while switching displays or adding a new session.
|
||||||
|
if !h.displays.contains(&display) {
|
||||||
|
h.displays.push(display);
|
||||||
|
}
|
||||||
h.renderer.set_size(display, width, height);
|
h.renderer.set_size(display, width, height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1562,21 +1568,6 @@ pub fn session_register_gpu_texture(_session_id: SessionID, _display: usize, _ou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn session_add_displays(session_id: &SessionID, displays: &[i32]) {
|
|
||||||
for s in sessions::get_sessions() {
|
|
||||||
if let Some(h) = s
|
|
||||||
.ui_handler
|
|
||||||
.session_handlers
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.get(session_id)
|
|
||||||
{
|
|
||||||
h.renderer.add_displays(displays);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(feature = "vram"))]
|
#[cfg(not(feature = "vram"))]
|
||||||
pub fn get_adapter_luid() -> Option<i64> {
|
pub fn get_adapter_luid() -> Option<i64> {
|
||||||
@ -1898,8 +1889,9 @@ pub mod sessions {
|
|||||||
|
|
||||||
pub fn session_switch_display(is_desktop: bool, session_id: SessionID, value: Vec<i32>) {
|
pub fn session_switch_display(is_desktop: bool, session_id: SessionID, value: Vec<i32>) {
|
||||||
for s in SESSIONS.read().unwrap().values() {
|
for s in SESSIONS.read().unwrap().values() {
|
||||||
let read_lock = s.ui_handler.session_handlers.read().unwrap();
|
let mut write_lock = s.ui_handler.session_handlers.write().unwrap();
|
||||||
if read_lock.contains_key(&session_id) {
|
if let Some(h) = write_lock.get_mut(&session_id) {
|
||||||
|
h.displays = value.iter().map(|x| *x as usize).collect::<_>();
|
||||||
if value.len() == 1 {
|
if value.len() == 1 {
|
||||||
// Switch display.
|
// Switch display.
|
||||||
// This operation will also cause the peer to send a switch display message.
|
// This operation will also cause the peer to send a switch display message.
|
||||||
@ -1915,7 +1907,7 @@ pub mod sessions {
|
|||||||
Some(value[0] as _),
|
Some(value[0] as _),
|
||||||
&session_id,
|
&session_id,
|
||||||
&s,
|
&s,
|
||||||
&read_lock,
|
&write_lock,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1947,9 +1939,11 @@ pub mod sessions {
|
|||||||
peer_id: String,
|
peer_id: String,
|
||||||
conn_type: ConnType,
|
conn_type: ConnType,
|
||||||
session_id: SessionID,
|
session_id: SessionID,
|
||||||
|
displays: Vec<i32>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some(s) = SESSIONS.read().unwrap().get(&(peer_id, conn_type)) {
|
if let Some(s) = SESSIONS.read().unwrap().get(&(peer_id, conn_type)) {
|
||||||
let mut h = SessionHandler::default();
|
let mut h = SessionHandler::default();
|
||||||
|
h.displays = displays.iter().map(|x| *x as usize).collect::<_>();
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
let is_support_multi_ui_session = crate::common::is_support_multi_ui_session(
|
let is_support_multi_ui_session = crate::common::is_support_multi_ui_session(
|
||||||
&s.ui_handler.peer_info.read().unwrap().version,
|
&s.ui_handler.peer_info.read().unwrap().version,
|
||||||
|
@ -102,8 +102,12 @@ pub fn peer_get_default_sessions_count(id: String) -> SyncReturn<usize> {
|
|||||||
SyncReturn(sessions::get_session_count(id, ConnType::DEFAULT_CONN))
|
SyncReturn(sessions::get_session_count(id, ConnType::DEFAULT_CONN))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn session_add_existed_sync(id: String, session_id: SessionID) -> SyncReturn<String> {
|
pub fn session_add_existed_sync(
|
||||||
if let Err(e) = session_add_existed(id.clone(), session_id) {
|
id: String,
|
||||||
|
session_id: SessionID,
|
||||||
|
displays: Vec<i32>,
|
||||||
|
) -> SyncReturn<String> {
|
||||||
|
if let Err(e) = session_add_existed(id.clone(), session_id, displays) {
|
||||||
SyncReturn(format!("Failed to add session with id {}, {}", &id, e))
|
SyncReturn(format!("Failed to add session with id {}, {}", &id, e))
|
||||||
} else {
|
} else {
|
||||||
SyncReturn("".to_owned())
|
SyncReturn("".to_owned())
|
||||||
@ -154,10 +158,6 @@ pub fn session_start_with_displays(
|
|||||||
) -> ResultType<()> {
|
) -> ResultType<()> {
|
||||||
session_start_(&session_id, &id, events2ui)?;
|
session_start_(&session_id, &id, events2ui)?;
|
||||||
|
|
||||||
// `session_add_displays` is used for software rendering, multi-ui sessions.
|
|
||||||
// We need to add displays to the session first, then capture the displays.
|
|
||||||
// Otherwise, the session may not send video frames to the flutter side.
|
|
||||||
super::flutter::session_add_displays(&session_id, &displays);
|
|
||||||
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
|
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
|
||||||
session.capture_displays(displays.clone(), vec![], vec![]);
|
session.capture_displays(displays.clone(), vec![], vec![]);
|
||||||
for display in displays {
|
for display in displays {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user