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

@@ -1187,10 +1187,11 @@ class ImageModel with ChangeNotifier {
onRgba(int display, Uint8List rgba) {
final pid = parent.target?.id;
final rect = parent.target?.ffiModel.pi.getDisplayRect(display);
img.decodeImageFromPixels(
rgba,
parent.target?.ffiModel.rect?.width.toInt() ?? 0,
parent.target?.ffiModel.rect?.height.toInt() ?? 0,
rect?.width.toInt() ?? 0,
rect?.height.toInt() ?? 0,
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888,
onPixelsCopied: () {
// Unlock the rgba memory from rust codes.
@@ -2397,9 +2398,10 @@ class FFI {
cursorModel.peerId = id;
}
final isNewPeer = tabWindowId == null;
// If tabWindowId != null, this session is a "tab -> window" one.
// Else this session is a new one.
if (tabWindowId == null) {
if (isNewPeer) {
// ignore: unused_local_variable
final addRes = bind.sessionAddSync(
sessionId: sessionId,
@@ -2424,14 +2426,25 @@ class FFI {
'Unreachable, failed to add existed session to $id, $addRes');
return;
}
bind.sessionTryAddDisplay(
sessionId: sessionId, displays: Int32List.fromList(displays));
ffiModel.pi.currentDisplay = display;
}
if (isDesktop && connType == ConnType.defaultConn) {
textureModel.updateCurrentDisplay(display ?? 0);
}
final stream = bind.sessionStart(sessionId: sessionId, id: id);
// CAUTION: `sessionStart()` and `sessionStartWithDisplays()` are an async functions.
// Though the stream is returned immediately, the stream may not be ready.
// Any operations that depend on the stream should be carefully handled.
late final Stream<EventToUI> stream;
if (isNewPeer || display == null || displays == null) {
stream = bind.sessionStart(sessionId: sessionId, id: id);
} else {
// We have to put displays in `sessionStart()` to make sure the stream is ready
// and then the displays' capturing requests can be sent.
stream = bind.sessionStartWithDisplays(
sessionId: sessionId, id: id, displays: Int32List.fromList(displays));
}
if (isWeb) {
platformFFI.setRgbaCallback((int display, Uint8List data) {
onEvent2UIRgba();
@@ -2442,14 +2455,6 @@ class FFI {
final cb = ffiModel.startEventListener(sessionId, id);
// Force refresh displays.
// The controlled side may not refresh the image when the (peer,display) is already subscribed.
if (displays != null) {
for (final display in displays) {
bind.sessionRefresh(sessionId: sessionId, display: display);
}
}
imageModel.updateUserTextureRender();
final hasGpuTextureRender = bind.mainHasGpuTextureRender();
final SimpleWrapper<bool> isToNewWindowNotified = SimpleWrapper(false);
@@ -2500,8 +2505,8 @@ class FFI {
}
} else if (message is EventToUI_Rgba) {
final display = message.field0;
if (imageModel.useTextureRender) {
debugPrint("EventToUI_Rgba display:$display");
if (imageModel.useTextureRender || ffiModel.pi.forceTextureRender) {
//debugPrint("EventToUI_Rgba display:$display");
textureModel.setTextureType(display: display, gpuTexture: false);
onEvent2UIRgba();
} else {
@@ -2692,6 +2697,7 @@ class PeerInfo with ChangeNotifier {
bool get isSupportMultiDisplay =>
(isDesktop || isWebDesktop) && isSupportMultiUiSession;
bool get forceTextureRender => currentDisplay == kAllDisplayValue;
bool get cursorEmbedded => tryGetDisplay()?.cursorEmbedded ?? false;
@@ -2700,30 +2706,32 @@ class PeerInfo with ChangeNotifier {
bool get isAmyuniIdd =>
platformAdditions[kPlatformAdditionsIddImpl] == 'amyuni_idd';
Display? tryGetDisplay() {
Display? tryGetDisplay({int? display}) {
if (displays.isEmpty) {
return null;
}
if (currentDisplay == kAllDisplayValue) {
display ??= currentDisplay;
if (display == kAllDisplayValue) {
return displays[0];
} else {
if (currentDisplay > 0 && currentDisplay < displays.length) {
return displays[currentDisplay];
if (display > 0 && display < displays.length) {
return displays[display];
} else {
return displays[0];
}
}
}
Display? tryGetDisplayIfNotAllDisplay() {
Display? tryGetDisplayIfNotAllDisplay({int? display}) {
if (displays.isEmpty) {
return null;
}
if (currentDisplay == kAllDisplayValue) {
display ??= currentDisplay;
if (display == kAllDisplayValue) {
return null;
}
if (currentDisplay >= 0 && currentDisplay < displays.length) {
return displays[currentDisplay];
if (display >= 0 && display < displays.length) {
return displays[display];
} else {
return null;
}
@@ -2747,6 +2755,12 @@ class PeerInfo with ChangeNotifier {
}
return 1.0;
}
Rect? getDisplayRect(int display) {
final d = tryGetDisplayIfNotAllDisplay(display: display);
if (d == null) return null;
return Rect.fromLTWH(d.x, d.y, d.width.toDouble(), d.height.toDouble());
}
}
const canvasKey = 'canvas';