mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
Refact/multi window soft rendering (#8343)
* refact: multi_window_soft_rendering Signed-off-by: fufesou <linlong1266@gmail.com> * fix: window pos, potential wait for image Signed-off-by: fufesou <linlong1266@gmail.com> * comments Signed-off-by: fufesou <linlong1266@gmail.com> * remove debug print Signed-off-by: fufesou <linlong1266@gmail.com> * explicitly set rgba_data.size_got to false after init Signed-off-by: fufesou <linlong1266@gmail.com> * refact: multi window, merge images, render with texture Signed-off-by: fufesou <linlong1266@gmail.com> * revert, flutter.rs, rgba valid Signed-off-by: fufesou <linlong1266@gmail.com> * Add displays index before sending capture msg Signed-off-by: fufesou <linlong1266@gmail.com> * refact: multi window, soft rendering 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:
@@ -408,6 +408,25 @@ 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")))]
|
||||
pub fn on_rgba(&self, display: usize, rgba: &scrap::ImageRgb) -> bool {
|
||||
let mut write_lock = self.map_display_sessions.write().unwrap();
|
||||
@@ -768,9 +787,9 @@ impl InvokeUiSession for FlutterHandler {
|
||||
#[inline]
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
fn on_rgba(&self, display: usize, rgba: &mut scrap::ImageRgb) {
|
||||
if self.use_texture_render.load(Ordering::Relaxed) {
|
||||
self.on_rgba_flutter_texture_render(display, rgba);
|
||||
} else {
|
||||
let use_texture_render = self.use_texture_render.load(Ordering::Relaxed);
|
||||
self.on_rgba_flutter_texture_render(use_texture_render, display, rgba);
|
||||
if !use_texture_render {
|
||||
self.on_rgba_soft_render(display, rgba);
|
||||
}
|
||||
}
|
||||
@@ -1039,22 +1058,43 @@ impl FlutterHandler {
|
||||
}
|
||||
drop(rgba_write_lock);
|
||||
|
||||
// Non-texture-render UI does not support multiple displays in the one UI session.
|
||||
// It's Ok to notify each session for now.
|
||||
for h in self.session_handlers.read().unwrap().values() {
|
||||
if let Some(stream) = &h.event_stream {
|
||||
stream.add(EventToUI::Rgba(display));
|
||||
// `map_display_sessions` stores the display indices that are used by the video renderer.
|
||||
let map_display_sessions = h.renderer.map_display_sessions.read().unwrap();
|
||||
// The soft renderer does not support multi ui session for now.
|
||||
if map_display_sessions.len() > 1 {
|
||||
continue;
|
||||
}
|
||||
if h.renderer
|
||||
.map_display_sessions
|
||||
.read()
|
||||
.unwrap()
|
||||
.contains_key(&display)
|
||||
{
|
||||
if map_display_sessions.contains_key(&display) {
|
||||
if let Some(stream) = &h.event_stream {
|
||||
stream.add(EventToUI::Rgba(display));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
fn on_rgba_flutter_texture_render(&self, display: usize, rgba: &mut scrap::ImageRgb) {
|
||||
fn on_rgba_flutter_texture_render(
|
||||
&self,
|
||||
use_texture_render: bool,
|
||||
display: usize,
|
||||
rgba: &mut scrap::ImageRgb,
|
||||
) {
|
||||
for (_, session) in self.session_handlers.read().unwrap().iter() {
|
||||
if session.renderer.on_rgba(display, rgba) {
|
||||
if let Some(stream) = &session.event_stream {
|
||||
stream.add(EventToUI::Rgba(display));
|
||||
if use_texture_render || session.renderer.map_display_sessions.read().unwrap().len() > 1
|
||||
{
|
||||
if session.renderer.on_rgba(display, rgba) {
|
||||
if let Some(stream) = &session.event_stream {
|
||||
stream.add(EventToUI::Rgba(display));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1522,6 +1562,21 @@ 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]
|
||||
#[cfg(not(feature = "vram"))]
|
||||
pub fn get_adapter_luid() -> Option<i64> {
|
||||
|
||||
@@ -110,13 +110,6 @@ pub fn session_add_existed_sync(id: String, session_id: SessionID) -> SyncReturn
|
||||
}
|
||||
}
|
||||
|
||||
pub fn session_try_add_display(session_id: SessionID, displays: Vec<i32>) -> SyncReturn<()> {
|
||||
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
|
||||
session.capture_displays(displays, vec![], vec![]);
|
||||
}
|
||||
SyncReturn(())
|
||||
}
|
||||
|
||||
pub fn session_add_sync(
|
||||
session_id: SessionID,
|
||||
id: String,
|
||||
@@ -153,6 +146,27 @@ pub fn session_start(
|
||||
session_start_(&session_id, &id, events2ui)
|
||||
}
|
||||
|
||||
pub fn session_start_with_displays(
|
||||
events2ui: StreamSink<EventToUI>,
|
||||
session_id: SessionID,
|
||||
id: String,
|
||||
displays: Vec<i32>,
|
||||
) -> ResultType<()> {
|
||||
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) {
|
||||
session.capture_displays(displays.clone(), vec![], vec![]);
|
||||
for display in displays {
|
||||
session.refresh_video(display as _);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn session_get_remember(session_id: SessionID) -> Option<bool> {
|
||||
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
|
||||
Some(session.get_remember())
|
||||
|
||||
Reference in New Issue
Block a user