From ad1fc1f06d7a300fce833081f643f686c04fef79 Mon Sep 17 00:00:00 2001 From: mmcclaskey Date: Tue, 11 Jan 2022 15:31:39 -0500 Subject: [PATCH] KASM-2152 fps added to stats (#25) Co-authored-by: matt --- app/ui.js | 13 ++++++++++--- core/display.js | 37 ++++++++++++++++++++++++++++++++++++- core/rfb.js | 18 ++++++------------ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/app/ui.js b/app/ui.js index c706c3eb..ae5cc946 100644 --- a/app/ui.js +++ b/app/ui.js @@ -1185,9 +1185,16 @@ const UI = { //recieved bottleneck stats bottleneckStatsRecieve(e) { - var obj = JSON.parse(e.detail.text); - document.getElementById("noVNC_connection_stats").innerHTML = "CPU: " + obj[0] + "/" + obj[1] + " | Network: " + obj[2] + "/" + obj[3]; - console.log(e.detail.text); + if (UI.rfb) { + try { + let obj = JSON.parse(e.detail.text); + let fps = UI.rfb.statsFps; + document.getElementById("noVNC_connection_stats").innerHTML = "CPU: " + obj[0] + "/" + obj[1] + " | Network: " + obj[2] + "/" + obj[3] + " | FPS: " + fps; + console.log(e.detail.text); + } catch (err) { + console.log('Invalid bottleneck stats recieved from server.') + } + } }, popupMessage: function(msg, secs) { diff --git a/core/display.js b/core/display.js index 9069fa7f..ec11f0e8 100644 --- a/core/display.js +++ b/core/display.js @@ -57,6 +57,19 @@ export default class Display { Log.Debug("User Agent: " + navigator.userAgent); + // performance metrics, try to calc a fps equivelant + this._flipCnt = 0; + this._currentFrameDamages = []; + this._lastFlip = Date.now(); + setInterval(function() { + let delta = Date.now() - this._lastFlip; + if (delta > 0) { + this._fps = (this._flipCnt / (delta / 1000)).toFixed(2); + } + this._lastFlip = Date.now(); + this._flipCnt = 0; + }.bind(this), 5000); + Log.Debug("<< Display.constructor"); // ===== PROPERTIES ===== @@ -64,10 +77,11 @@ export default class Display { this._scale = 1.0; this._clipViewport = false; this._antiAliasing = 0; + this._fps = 0; // ===== EVENT HANDLERS ===== - this.onflush = () => {}; // A flush request has finished + this.onflush = () => { }; // A flush request has finished } // ===== PROPERTIES ===== @@ -107,6 +121,8 @@ export default class Display { this._renderMs = val; } + get fps() { return this._fps; } + // ===== PUBLIC METHODS ===== viewportChangePos(deltaX, deltaY) { @@ -256,6 +272,21 @@ export default class Display { } } + // Attempt to determine when updates overlap an area and thus indicate a new frame + isNewFrame(x, y, w, h) { + for (var i = 0; i < this._currentFrameDamages.length; i++) { + let area = this._currentFrameDamages[i]; + if (x >= area.x && x <= (area.x + area.w) && y >= area.y && y <= (area.y + area.h)) { + this._currentFrameDamages = []; + return true; + } + } + + var new_area = { x: x, y: y, w: w, h: h } + this._currentFrameDamages.push(new_area); + return false; + } + // Update the visible canvas with the contents of the // rendering canvas flip(fromQueue) { @@ -297,6 +328,10 @@ export default class Display { this._targetCtx.drawImage(this._backbuffer, x, y, w, h, vx, vy, w, h); + + if (this.isNewFrame(x, y, h, w)) { + this._flipCnt += 1; + } } this._damageBounds.left = this._damageBounds.top = 65535; diff --git a/core/rfb.js b/core/rfb.js index 3a081809..2850d972 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -108,23 +108,16 @@ export default class RFB extends EventTargetMixin { this._rfbTightVNC = false; this._rfbVeNCryptState = 0; this._rfbXvpVer = 0; - this._fbWidth = 0; this._fbHeight = 0; - this._fbName = ""; - this._capabilities = { power: false }; - this._supportsFence = false; - this._supportsContinuousUpdates = false; this._enabledContinuousUpdates = false; - this._supportsSetDesktopSize = false; this._screenID = 0; this._screenFlags = 0; - this._qemuExtKeyEventSupported = false; // kasm defaults @@ -655,6 +648,8 @@ export default class RFB extends EventTargetMixin { } } + get statsFps() { return this._display.fps; } + // ===== PUBLIC METHODS ===== /* @@ -2666,18 +2661,17 @@ export default class RFB extends EventTargetMixin { let first, ret; switch (msgType) { case 0: // FramebufferUpdate - let before = performance.now(); this._display.renderMs = 0; ret = this._framebufferUpdate(); if (ret && !this._enabledContinuousUpdates) { RFB.messages.fbUpdateRequest(this._sock, true, 0, 0, this._fbWidth, this._fbHeight); } - let elapsed = performance.now() - before; if (this._trackFrameStats) { - RFB.messages.sendFrameStats(this._sock, elapsed, this._display.renderMs); + RFB.messages.sendFrameStats(this._sock, this._display.fps, this._display.renderMs); this._trackFrameStats = false; } + return ret; case 1: // SetColorMapEntries @@ -3514,7 +3508,7 @@ RFB.messages = { const buff = sock._sQ; const offset = sock._sQlen; - if (buff == null) { return; } + if (buff == null) { return; } buff[offset] = 178; // msg-type @@ -3530,7 +3524,7 @@ RFB.messages = { const buff = sock._sQ; const offset = sock._sQlen; - if (buff == null) { return; } + if (buff == null) { return; } buff[offset] = 179; // msg-type