add cvmts rect batcher (abstracted to only deal with rects & size since vnc library draws to the buffer beforehand)
This commit is contained in:
parent
126a6f6f56
commit
dcc6310dd4
3 changed files with 53 additions and 8 deletions
|
@ -136,7 +136,7 @@ class VirtualMachine extends EventEmitter {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.vm = vm;
|
this.vm = vm;
|
||||||
this.timer = new ExtendableTimer(2);
|
this.timer = new ExtendableTimer(15);
|
||||||
|
|
||||||
this.timer.on('expired', async () => {
|
this.timer.on('expired', async () => {
|
||||||
// bye bye!
|
// bye bye!
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { VncClient } from './rfb/client.js';
|
import { VncClient } from './rfb/client.js';
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import { Canvas, CanvasRenderingContext2D, createImageData } from 'canvas';
|
import { Canvas, CanvasRenderingContext2D, createImageData } from 'canvas';
|
||||||
|
import { BatchRects, Size, Rect } from './QemuUtil.js';
|
||||||
|
|
||||||
const kQemuFps = 30;
|
const kQemuFps = 30;
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ export class QemuDisplay extends EventEmitter {
|
||||||
this.displayCanvas.height = height;
|
this.displayCanvas.height = height;
|
||||||
});
|
});
|
||||||
|
|
||||||
let rects: VncRect[] = [];
|
let rects: Rect[] = [];
|
||||||
|
|
||||||
this.displayVnc.on('rectUpdateProcessed', (rect) => {
|
this.displayVnc.on('rectUpdateProcessed', (rect) => {
|
||||||
rects.push(rect);
|
rects.push(rect);
|
||||||
|
@ -89,9 +90,13 @@ export class QemuDisplay extends EventEmitter {
|
||||||
// TODO: optimize the rects a bit. using guacamole's cheap method
|
// TODO: optimize the rects a bit. using guacamole's cheap method
|
||||||
// of just flushing the whole screen if the area of all the updated rects gets too big
|
// of just flushing the whole screen if the area of all the updated rects gets too big
|
||||||
// might just work.
|
// might just work.
|
||||||
for (const rect of rects) {
|
//for (const rect of rects) {
|
||||||
this.emit('rect', rect.x, rect.y, this.displayCtx.getImageData(rect.x, rect.y, rect.width, rect.height));
|
// this.emit('rect', rect.x, rect.y, this.displayCtx.getImageData(rect.x, rect.y, rect.width, rect.height));
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
// cvmts batcher
|
||||||
|
let batched = BatchRects(this.Size(), rects);
|
||||||
|
this.emit('rect', batched.x, batched.y, this.displayCtx.getImageData(batched.x, batched.y, batched.width, batched.height));
|
||||||
|
|
||||||
rects = [];
|
rects = [];
|
||||||
|
|
||||||
|
@ -126,7 +131,7 @@ export class QemuDisplay extends EventEmitter {
|
||||||
return this.displayCanvas;
|
return this.displayCanvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
Size() {
|
Size(): Size {
|
||||||
return {
|
return {
|
||||||
width: this.displayVnc.clientWidth,
|
width: this.displayVnc.clientWidth,
|
||||||
height: this.displayVnc.clientHeight
|
height: this.displayVnc.clientHeight
|
||||||
|
|
|
@ -4,8 +4,48 @@
|
||||||
import { execa } from 'execa';
|
import { execa } from 'execa';
|
||||||
import * as crypto from 'node:crypto';
|
import * as crypto from 'node:crypto';
|
||||||
|
|
||||||
/// Temporary path base for hard drive images.
|
export type Size = { width: number, height: number };
|
||||||
const kVmHdaTmpPathBase = `/mnt/vmi/tmp/crusttest-hda`;
|
export type Rect = {height:number,width:number,x:number,y:number};
|
||||||
|
|
||||||
|
export function BatchRects(size: Size, rects: Array<Rect>): Rect {
|
||||||
|
var mergedX = size.width;
|
||||||
|
var mergedY = size.height;
|
||||||
|
var mergedHeight = 0;
|
||||||
|
var mergedWidth = 0;
|
||||||
|
|
||||||
|
// can't batch these
|
||||||
|
if(rects.length == 0) {
|
||||||
|
return {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: size.width,
|
||||||
|
height: size.height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rects.length == 1) {
|
||||||
|
if(rects[0].width == size.width && rects[0].height == size.height) {
|
||||||
|
return rects[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rects.forEach((r) => {
|
||||||
|
if (r.x < mergedX) mergedX = r.x;
|
||||||
|
if (r.y < mergedY) mergedY = r.y;
|
||||||
|
});
|
||||||
|
|
||||||
|
rects.forEach(r => {
|
||||||
|
if (((r.height + r.y) - mergedY) > mergedHeight) mergedHeight = (r.height + r.y) - mergedY;
|
||||||
|
if (((r.width + r.x) - mergedX) > mergedWidth) mergedWidth = (r.width + r.x) - mergedX;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: mergedX,
|
||||||
|
y: mergedY,
|
||||||
|
width: mergedWidth,
|
||||||
|
height: mergedHeight
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Generates a random unicast/local MAC address.
|
// Generates a random unicast/local MAC address.
|
||||||
export async function GenMacAddress(): Promise<string> {
|
export async function GenMacAddress(): Promise<string> {
|
||||||
|
|
Loading…
Reference in a new issue