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:
fufesou
2024-06-13 18:03:41 +08:00
committed by GitHub
parent 8e12a34634
commit bc875a35b0
10 changed files with 160 additions and 82 deletions

View File

@@ -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> {

View File

@@ -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())