Merge pull request #6258 from fufesou/fix/remove_unused_capturer_on_peer
fix, remove unused capturer when switching display
This commit is contained in:
commit
faf99ffe14
@ -1223,8 +1223,9 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isVirtualDisplay = ffiModel.isVirtualDisplayResolution;
|
||||
final visible =
|
||||
ffiModel.keyboard && (isVirtualDisplay || resolutions.length > 1);
|
||||
final visible = ffiModel.keyboard &&
|
||||
(isVirtualDisplay || resolutions.length > 1) &&
|
||||
pi.currentDisplay != kAllDisplayValue;
|
||||
if (!visible) return Offstage();
|
||||
final showOriginalBtn =
|
||||
ffiModel.isOriginalResolutionSet && !ffiModel.isOriginalResolution;
|
||||
|
@ -431,15 +431,19 @@ class FfiModel with ChangeNotifier {
|
||||
|
||||
handleSwitchDisplay(
|
||||
Map<String, dynamic> evt, SessionID sessionId, String peerId) {
|
||||
final curDisplay = int.parse(evt['display']);
|
||||
final display = int.parse(evt['display']);
|
||||
|
||||
if (_pi.currentDisplay != kAllDisplayValue) {
|
||||
if (bind.peerGetDefaultSessionsCount(id: peerId) > 1) {
|
||||
if (curDisplay != _pi.currentDisplay) {
|
||||
if (display != _pi.currentDisplay) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_pi.currentDisplay = curDisplay;
|
||||
if (!_pi.isSupportMultiUiSession) {
|
||||
_pi.currentDisplay = display;
|
||||
}
|
||||
// If `isSupportMultiUiSession` is true, the switch display message should not be used to update current display.
|
||||
// It is only used to update the display info.
|
||||
}
|
||||
|
||||
var newDisplay = Display();
|
||||
@ -452,16 +456,24 @@ class FfiModel with ChangeNotifier {
|
||||
int.tryParse(evt['original_width']) ?? kInvalidResolutionValue;
|
||||
newDisplay.originalHeight =
|
||||
int.tryParse(evt['original_height']) ?? kInvalidResolutionValue;
|
||||
_pi.displays[curDisplay] = newDisplay;
|
||||
_pi.displays[display] = newDisplay;
|
||||
|
||||
updateCurDisplay(sessionId);
|
||||
try {
|
||||
CurrentDisplayState.find(peerId).value = curDisplay;
|
||||
} catch (e) {
|
||||
//
|
||||
if (!_pi.isSupportMultiUiSession || _pi.currentDisplay == display) {
|
||||
updateCurDisplay(sessionId);
|
||||
}
|
||||
|
||||
if (!_pi.isSupportMultiUiSession) {
|
||||
try {
|
||||
CurrentDisplayState.find(peerId).value = display;
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
parent.target?.recordingModel.onSwitchDisplay();
|
||||
handleResolutions(peerId, evt['resolutions']);
|
||||
if (!_pi.isSupportMultiUiSession || _pi.currentDisplay == display) {
|
||||
handleResolutions(peerId, evt['resolutions']);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user