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();
|
||||
|
||||
this.vm = vm;
|
||||
this.timer = new ExtendableTimer(2);
|
||||
this.timer = new ExtendableTimer(15);
|
||||
|
||||
this.timer.on('expired', async () => {
|
||||
// bye bye!
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { VncClient } from './rfb/client.js';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import { Canvas, CanvasRenderingContext2D, createImageData } from 'canvas';
|
||||
import { BatchRects, Size, Rect } from './QemuUtil.js';
|
||||
|
||||
const kQemuFps = 30;
|
||||
|
||||
|
@ -77,7 +78,7 @@ export class QemuDisplay extends EventEmitter {
|
|||
this.displayCanvas.height = height;
|
||||
});
|
||||
|
||||
let rects: VncRect[] = [];
|
||||
let rects: Rect[] = [];
|
||||
|
||||
this.displayVnc.on('rectUpdateProcessed', (rect) => {
|
||||
rects.push(rect);
|
||||
|
@ -89,9 +90,13 @@ export class QemuDisplay extends EventEmitter {
|
|||
// 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
|
||||
// might just work.
|
||||
for (const rect of rects) {
|
||||
this.emit('rect', rect.x, rect.y, this.displayCtx.getImageData(rect.x, rect.y, rect.width, rect.height));
|
||||
}
|
||||
//for (const rect of rects) {
|
||||
// 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 = [];
|
||||
|
||||
|
@ -126,7 +131,7 @@ export class QemuDisplay extends EventEmitter {
|
|||
return this.displayCanvas;
|
||||
}
|
||||
|
||||
Size() {
|
||||
Size(): Size {
|
||||
return {
|
||||
width: this.displayVnc.clientWidth,
|
||||
height: this.displayVnc.clientHeight
|
||||
|
|
|
@ -4,8 +4,48 @@
|
|||
import { execa } from 'execa';
|
||||
import * as crypto from 'node:crypto';
|
||||
|
||||
/// Temporary path base for hard drive images.
|
||||
const kVmHdaTmpPathBase = `/mnt/vmi/tmp/crusttest-hda`;
|
||||
export type Size = { width: number, height: number };
|
||||
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.
|
||||
export async function GenMacAddress(): Promise<string> {
|
||||
|
|
Loading…
Reference in a new issue