Queue rect updates for each frame (and.. maybe? do rects in parallel)
both superqemu and vncvm have supported this but I never did it for some reason. its noticably faster than before. testing seems to imply that its actually slightly faster without the batcher enabled (maybe because it's actually able to split the work now if I had to guess)
This commit is contained in:
@@ -93,6 +93,9 @@ export default class CollabVMServer {
|
||||
// Ban manager
|
||||
private banmgr: BanManager;
|
||||
|
||||
// queue of rects, reset every frame
|
||||
private rectQueue: Rect[] = [];
|
||||
|
||||
private logger = pino({ name: 'CVMTS.Server' });
|
||||
|
||||
constructor(config: IConfig, vm: VM, banmgr: BanManager, auth: AuthManager | null, geoipReader: ReaderModel | null) {
|
||||
@@ -131,6 +134,7 @@ export default class CollabVMServer {
|
||||
// well aware this sucks but whatever
|
||||
self.VM.GetDisplay().on('resize', (size: Size) => self.OnDisplayResized(size));
|
||||
self.VM.GetDisplay().on('rect', (rect: Rect) => self.OnDisplayRectangle(rect));
|
||||
self.VM.GetDisplay().on('frame', () => self.OnDisplayFrame());
|
||||
}
|
||||
|
||||
if (newState == VMState.Stopped) {
|
||||
@@ -144,6 +148,7 @@ export default class CollabVMServer {
|
||||
// this sucks too fix this
|
||||
self.VM.GetDisplay().on('resize', (size: Size) => self.OnDisplayResized(size));
|
||||
self.VM.GetDisplay().on('rect', (rect: Rect) => self.OnDisplayRectangle(rect));
|
||||
self.VM.GetDisplay().on('frame', () => self.OnDisplayFrame());
|
||||
}
|
||||
|
||||
// authentication manager
|
||||
@@ -838,29 +843,8 @@ export default class CollabVMServer {
|
||||
}
|
||||
}
|
||||
|
||||
private async OnDisplayRectangle(rect: Rect) {
|
||||
let encoded = await this.MakeRectData(rect);
|
||||
let encodedb64 = encoded.toString('base64');
|
||||
let bmsg: CollabVMProtocolMessage = {
|
||||
type: CollabVMProtocolMessageType.rect,
|
||||
rect: {
|
||||
x: rect.x,
|
||||
y: rect.y,
|
||||
data: encoded
|
||||
}
|
||||
};
|
||||
var encodedbin = msgpack.encode(bmsg);
|
||||
this.clients
|
||||
.filter((c) => c.connectedToNode || c.viewMode == 1)
|
||||
.forEach((c) => {
|
||||
if (this.screenHidden && c.rank == Rank.Unregistered) return;
|
||||
if (c.Capabilities.bin) {
|
||||
c.socket.sendBinary(encodedbin);
|
||||
} else {
|
||||
c.sendMsg(cvm.guacEncode('png', '0', '0', rect.x.toString(), rect.y.toString(), encodedb64));
|
||||
c.sendMsg(cvm.guacEncode('sync', Date.now().toString()));
|
||||
}
|
||||
});
|
||||
private OnDisplayRectangle(rect: Rect) {
|
||||
this.rectQueue.push(rect);
|
||||
}
|
||||
|
||||
private OnDisplayResized(size: Size) {
|
||||
@@ -872,6 +856,46 @@ export default class CollabVMServer {
|
||||
});
|
||||
}
|
||||
|
||||
private async OnDisplayFrame() {
|
||||
let self = this;
|
||||
|
||||
let doRect = async (rect: Rect) => {
|
||||
let encoded = await this.MakeRectData(rect);
|
||||
let encodedb64 = encoded.toString('base64');
|
||||
let bmsg: CollabVMProtocolMessage = {
|
||||
type: CollabVMProtocolMessageType.rect,
|
||||
rect: {
|
||||
x: rect.x,
|
||||
y: rect.y,
|
||||
data: encoded
|
||||
}
|
||||
};
|
||||
|
||||
var encodedbin = msgpack.encode(bmsg);
|
||||
|
||||
self.clients
|
||||
.filter((c) => c.connectedToNode || c.viewMode == 1)
|
||||
.forEach((c) => {
|
||||
if (self.screenHidden && c.rank == Rank.Unregistered) return;
|
||||
if (c.Capabilities.bin) {
|
||||
c.socket.sendBinary(encodedbin);
|
||||
} else {
|
||||
c.sendMsg(cvm.guacEncode('png', '0', '0', rect.x.toString(), rect.y.toString(), encodedb64));
|
||||
c.sendMsg(cvm.guacEncode('sync', Date.now().toString()));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let promises: Promise<void>[] = [];
|
||||
|
||||
for(let rect of self.rectQueue)
|
||||
promises.push(doRect(rect));
|
||||
|
||||
this.rectQueue = [];
|
||||
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
private async SendFullScreenWithSize(client: User) {
|
||||
let display = this.VM.GetDisplay();
|
||||
if (display == null) return;
|
||||
|
||||
Reference in New Issue
Block a user