summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2016-09-22 10:57:56 +0200
committerSamuel Mannehed <samuel@cendio.se>2016-10-24 14:42:45 +0200
commitd9ca5e5b6b418bf9c9e8c6281fa2edfaa695ac02 (patch)
treec702b2b85eb651935addfa7f9f0aad838ea6589d
parentbb6965f2e60c2301dd638383bdc792d1f10af942 (diff)
downloadnovnc-d9ca5e5b6b418bf9c9e8c6281fa2edfaa695ac02.tar.gz
Don't allow more than one pending update
-rw-r--r--core/display.js25
-rw-r--r--core/rfb.js32
2 files changed, 53 insertions, 4 deletions
diff --git a/core/display.js b/core/display.js
index e17e295..d9f66d7 100644
--- a/core/display.js
+++ b/core/display.js
@@ -20,6 +20,7 @@
this._c_forceCanvas = false;
this._renderQ = []; // queue drawing actions for in-oder rendering
+ this._flushing = false;
// the full frame buffer (logical canvas) size
this._fb_width = 0;
@@ -44,7 +45,8 @@
'colourMap': [],
'scale': 1.0,
'viewport': false,
- 'render_mode': ''
+ 'render_mode': '',
+ "onFlush": function () {},
});
Util.Debug(">> Display.constructor");
@@ -363,6 +365,18 @@
this._renderQ = [];
},
+ pending: function() {
+ return this._renderQ.length > 0;
+ },
+
+ flush: function() {
+ if (this._renderQ.length === 0) {
+ this._onFlush();
+ } else {
+ this._flushing = true;
+ }
+ },
+
fillRect: function (x, y, width, height, color, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
this._renderQ_push({
@@ -795,6 +809,11 @@
this._renderQ.shift();
}
}
+
+ if (this._renderQ.length === 0 && this._flushing) {
+ this._flushing = false;
+ this._onFlush();
+ }
},
};
@@ -814,7 +833,9 @@
['render_mode', 'ro', 'str'], // Canvas rendering mode (read-only)
['prefer_js', 'rw', 'str'], // Prefer Javascript over canvas methods
- ['cursor_uri', 'rw', 'raw'] // Can we render cursor using data URI
+ ['cursor_uri', 'rw', 'raw'], // Can we render cursor using data URI
+
+ ['onFlush', 'rw', 'func'], // onFlush(): A flush request has finished
]);
// Class Methods
diff --git a/core/rfb.js b/core/rfb.js
index 7567519..224e822 100644
--- a/core/rfb.js
+++ b/core/rfb.js
@@ -78,6 +78,7 @@
this._sock = null; // Websock object
this._display = null; // Display object
+ this._flushing = false; // Display flushing state
this._keyboard = null; // Keyboard input handler object
this._mouse = null; // Mouse input handler object
this._disconnTimer = null; // disconnection timer
@@ -189,7 +190,8 @@
// NB: nothing that needs explicit teardown should be done
// before this point, since this can throw an exception
try {
- this._display = new Display({target: this._target});
+ this._display = new Display({target: this._target,
+ onFlush: this._onFlush.bind(this)});
} catch (exc) {
Util.Error("Display exception: " + exc);
throw exc;
@@ -567,7 +569,17 @@
Util.Error("Got data while disconnected");
break;
case 'connected':
- while (this._normal_msg() && this._sock.rQlen() > 0);
+ while (true) {
+ if (this._flushing) {
+ break;
+ }
+ if (!this._normal_msg()) {
+ break;
+ }
+ if (this._sock.rQlen() === 0) {
+ break;
+ }
+ }
break;
default:
this._init_msg();
@@ -1232,6 +1244,14 @@
}
},
+ _onFlush: function() {
+ this._flushing = false;
+ // Resume processing
+ if (this._sock.rQlen() > 0) {
+ this._handle_message();
+ }
+ },
+
_framebufferUpdate: function () {
var ret = true;
var now;
@@ -1246,6 +1266,14 @@
now = (new Date()).getTime();
Util.Info("First FBU latency: " + (now - this._timing.fbu_rt_start));
}
+
+ // Make sure the previous frame is fully rendered first
+ // to avoid building up an excessive queue
+ if (this._display.pending()) {
+ this._flushing = true;
+ this._display.flush();
+ return false;
+ }
}
while (this._FBU.rects > 0) {