From 1454a5deae0cbdc4825a2c0ab3387fa42b4bff24 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 13 Jan 2025 14:52:30 -0800 Subject: [PATCH] GUACAMOLE-377: Revert to synchronous flush (asynchronous is slower). The asynchronous flush mechanism leveraging requestAnimationFrame() does not perform as well as the old synchronous flush. This appears to be due to delays in when the browser actually allows the frame to proceed, causing the client to lag behind. The old synchronous flush mechanism does not suffer from such issues. --- .../src/main/webapp/modules/Display.js | 75 +------------------ 1 file changed, 1 insertion(+), 74 deletions(-) diff --git a/guacamole-common-js/src/main/webapp/modules/Display.js b/guacamole-common-js/src/main/webapp/modules/Display.js index 374a7620d6..57e8719400 100644 --- a/guacamole-common-js/src/main/webapp/modules/Display.js +++ b/guacamole-common-js/src/main/webapp/modules/Display.js @@ -185,19 +185,6 @@ Guacamole.Display = function() { */ var frames = []; - /** - * The ID of the animation frame request returned by the last call to - * requestAnimationFrame(). This value will only be set if the browser - * supports requestAnimationFrame(), if a frame render is currently - * pending, and if the current browser tab is currently focused (likely to - * handle requests for animation frames). In all other cases, this will be - * null. - * - * @private - * @type {number} - */ - var inProgressFrame = null; - /** * Flushes all pending frames synchronously. This function will block until * all pending frames have rendered. If a frame is currently blocked by an @@ -239,45 +226,6 @@ Guacamole.Display = function() { }; - /** - * Flushes all pending frames asynchronously. This function returns - * immediately, relying on requestAnimationFrame() to dictate when each - * frame should be flushed. - * - * @private - */ - var asyncFlush = function asyncFlush() { - - var continueFlush = function continueFlush() { - - // We're no longer waiting to render a frame - inProgressFrame = null; - - // Nothing to do if there are no frames remaining - if (!frames.length) - return; - - // Flush the next frame only if it is ready (not awaiting - // completion of some asynchronous operation like an image load) - if (frames[0].isReady()) { - var frame = frames.shift(); - frame.flush(); - notifyFlushed(frame.localTimestamp, frame.remoteTimestamp, frame.logicalFrames); - } - - // Request yet another animation frame if frames remain to be - // flushed - if (frames.length) - inProgressFrame = window.requestAnimationFrame(continueFlush); - - }; - - // Begin flushing frames if not already waiting to render a frame - if (!inProgressFrame) - inProgressFrame = window.requestAnimationFrame(continueFlush); - - }; - /** * Recently-gathered display render statistics, as made available by calls * to notifyFlushed(). The contents of this array will be trimmed to @@ -373,33 +321,12 @@ Guacamole.Display = function() { }; - // Switch from asynchronous frame handling to synchronous frame handling if - // requestAnimationFrame() is unlikely to be usable (browsers may not - // invoke the animation frame callback if the relevant tab is not focused) - window.addEventListener('blur', function switchToSyncFlush() { - if (inProgressFrame && !document.hasFocus()) { - - // Cancel pending asynchronous processing of frame ... - window.cancelAnimationFrame(inProgressFrame); - inProgressFrame = null; - - // ... and instead process it synchronously - syncFlush(); - - } - }, true); - /** * Flushes all pending frames. * @private */ function __flush_frames() { - - if (window.requestAnimationFrame && document.hasFocus()) - asyncFlush(); - else - syncFlush(); - + syncFlush(); } /**