fix, remove unused capturer when switching display

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou
2023-11-01 15:33:21 +08:00
parent 52a4d41c6f
commit 58d073b516
6 changed files with 98 additions and 42 deletions

View File

@@ -1466,25 +1466,7 @@ pub mod sessions {
if write_lock.is_empty() {
remove_peer_key = Some(peer_key.clone());
} else {
// Set capture displays if some are not used any more.
let mut remains_displays = HashSet::new();
for (_, h) in write_lock.iter() {
remains_displays.extend(
h.renderer
.map_display_sessions
.read()
.unwrap()
.keys()
.cloned(),
);
}
if !remains_displays.is_empty() {
s.capture_displays(
vec![],
vec![],
remains_displays.iter().map(|d| *d as i32).collect(),
);
}
check_remove_unused_displays(None, id, s, &write_lock);
}
break;
}
@@ -1494,6 +1476,68 @@ pub mod sessions {
SESSIONS.write().unwrap().remove(&remove_peer_key?)
}
#[cfg(feature = "flutter_texture_render")]
fn check_remove_unused_displays(
current: Option<usize>,
session_id: &SessionID,
session: &FlutterSession,
handlers: &HashMap<SessionID, SessionHandler>,
) {
// Set capture displays if some are not used any more.
let mut remains_displays = HashSet::new();
if let Some(current) = current {
remains_displays.insert(current);
}
for (k, h) in handlers.iter() {
if k == session_id {
continue;
}
remains_displays.extend(
h.renderer
.map_display_sessions
.read()
.unwrap()
.keys()
.cloned(),
);
}
if !remains_displays.is_empty() {
session.capture_displays(
vec![],
vec![],
remains_displays.iter().map(|d| *d as i32).collect(),
);
}
}
pub fn session_switch_display(session_id: SessionID, value: Vec<i32>) {
for s in SESSIONS.read().unwrap().values() {
let read_lock = s.ui_handler.session_handlers.read().unwrap();
if read_lock.contains_key(&session_id) {
if value.len() == 1 {
// Switch display.
// This operation will also cause the peer to send a switch display message.
// The switch display message will contain `SupportedResolutions`, which is useful when changing resolutions.
s.switch_display(value[0]);
// Check if other displays are needed.
if value.len() == 1 {
check_remove_unused_displays(
Some(value[0] as _),
&session_id,
&s,
&read_lock,
);
}
} else {
// Try capture all displays.
s.capture_displays(vec![], vec![], value);
}
break;
}
}
}
#[inline]
pub fn insert_session(session_id: SessionID, conn_type: ConnType, session: FlutterSession) {
SESSIONS

View File

@@ -429,13 +429,7 @@ pub fn session_ctrl_alt_del(session_id: SessionID) {
}
pub fn session_switch_display(session_id: SessionID, value: Vec<i32>) {
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
if value.len() == 1 {
session.switch_display(value[0]);
} else {
session.capture_displays(vec![], vec![], value);
}
}
sessions::session_switch_display(session_id, value);
}
pub fn session_handle_flutter_key_event(

View File

@@ -2177,8 +2177,9 @@ impl Connection {
}
// Send display changed message.
// For compatibility with old versions ( < 1.2.4 ).
// sciter need it in new version
// 1. For compatibility with old versions ( < 1.2.4 ).
// 2. Sciter version.
// 3. Update `SupportedResolutions`.
if let Some(msg_out) = video_service::make_display_changed_msg(self.display_idx, None) {
self.send(msg_out).await;
}
@@ -2194,7 +2195,11 @@ impl Connection {
lock.add_service(Box::new(video_service::new(display_idx)));
}
}
lock.subscribe(&old_service_name, self.inner.clone(), false);
// For versions greater than 1.2.4, a `CaptureDisplays` message will be sent immediately.
// Unnecessary capturers will be removed then.
if !crate::common::is_support_multi_ui_session(&self.lr.version) {
lock.subscribe(&old_service_name, self.inner.clone(), false);
}
lock.subscribe(&new_service_name, self.inner.clone(), true);
self.display_idx = display_idx;
}

View File

@@ -349,7 +349,7 @@ pub fn try_get_displays() -> ResultType<Vec<Display>> {
#[cfg(all(windows, feature = "virtual_display_driver"))]
pub fn try_get_displays() -> ResultType<Vec<Display>> {
let mut displays = Display::all()?;
if no_displays(&displays) {
if crate::platform::is_installed() && no_displays(&displays) {
log::debug!("no displays, create virtual display");
if let Err(e) = virtual_display_manager::plug_in_headless() {
log::error!("plug in headless failed {}", e);