mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-377: Flush frames asynchronously with requestAnimationFrame() if possible.
This commit is contained in:
@@ -163,10 +163,28 @@ Guacamole.Display = function() {
|
|||||||
var frames = [];
|
var frames = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes all pending 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
|
||||||
|
* asynchronous operation like an image load, this function will return
|
||||||
|
* after reaching that operation and the flush operation will
|
||||||
|
* automamtically resume after that operation completes.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function __flush_frames() {
|
var syncFlush = function syncFlush() {
|
||||||
|
|
||||||
var rendered_frames = 0;
|
var rendered_frames = 0;
|
||||||
|
|
||||||
@@ -185,6 +203,71 @@ Guacamole.Display = function() {
|
|||||||
// Remove rendered frames from array
|
// Remove rendered frames from array
|
||||||
frames.splice(0, rendered_frames);
|
frames.splice(0, rendered_frames);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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())
|
||||||
|
frames.shift().flush();
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user