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
|
// Ban manager
|
||||||
private banmgr: BanManager;
|
private banmgr: BanManager;
|
||||||
|
|
||||||
|
// queue of rects, reset every frame
|
||||||
|
private rectQueue: Rect[] = [];
|
||||||
|
|
||||||
private logger = pino({ name: 'CVMTS.Server' });
|
private logger = pino({ name: 'CVMTS.Server' });
|
||||||
|
|
||||||
constructor(config: IConfig, vm: VM, banmgr: BanManager, auth: AuthManager | null, geoipReader: ReaderModel | null) {
|
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
|
// well aware this sucks but whatever
|
||||||
self.VM.GetDisplay().on('resize', (size: Size) => self.OnDisplayResized(size));
|
self.VM.GetDisplay().on('resize', (size: Size) => self.OnDisplayResized(size));
|
||||||
self.VM.GetDisplay().on('rect', (rect: Rect) => self.OnDisplayRectangle(rect));
|
self.VM.GetDisplay().on('rect', (rect: Rect) => self.OnDisplayRectangle(rect));
|
||||||
|
self.VM.GetDisplay().on('frame', () => self.OnDisplayFrame());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newState == VMState.Stopped) {
|
if (newState == VMState.Stopped) {
|
||||||
@@ -144,6 +148,7 @@ export default class CollabVMServer {
|
|||||||
// this sucks too fix this
|
// this sucks too fix this
|
||||||
self.VM.GetDisplay().on('resize', (size: Size) => self.OnDisplayResized(size));
|
self.VM.GetDisplay().on('resize', (size: Size) => self.OnDisplayResized(size));
|
||||||
self.VM.GetDisplay().on('rect', (rect: Rect) => self.OnDisplayRectangle(rect));
|
self.VM.GetDisplay().on('rect', (rect: Rect) => self.OnDisplayRectangle(rect));
|
||||||
|
self.VM.GetDisplay().on('frame', () => self.OnDisplayFrame());
|
||||||
}
|
}
|
||||||
|
|
||||||
// authentication manager
|
// authentication manager
|
||||||
@@ -838,29 +843,8 @@ export default class CollabVMServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async OnDisplayRectangle(rect: Rect) {
|
private OnDisplayRectangle(rect: Rect) {
|
||||||
let encoded = await this.MakeRectData(rect);
|
this.rectQueue.push(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 OnDisplayResized(size: Size) {
|
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) {
|
private async SendFullScreenWithSize(client: User) {
|
||||||
let display = this.VM.GetDisplay();
|
let display = this.VM.GetDisplay();
|
||||||
if (display == null) return;
|
if (display == null) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user