Repository: incubator-guacamole-client
Updated Branches:
  refs/heads/master 257c160aa -> 5776104f4


GUACAMOLE-187: Reduce the number of full canvas copies that occur when 
continuously resizing a layer.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/7f176d0d
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/7f176d0d
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/7f176d0d

Branch: refs/heads/master
Commit: 7f176d0dd15f7c10cebc67d78737c640fb850c45
Parents: d8f9d26
Author: Michael Jumper <[email protected]>
Authored: Fri Oct 7 21:14:17 2016 -0700
Committer: Michael Jumper <[email protected]>
Committed: Fri Jan 27 16:42:54 2017 -0800

----------------------------------------------------------------------
 .../src/main/webapp/modules/Layer.js            | 105 ++++++++++++-------
 1 file changed, 68 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/7f176d0d/guacamole-common-js/src/main/webapp/modules/Layer.js
----------------------------------------------------------------------
diff --git a/guacamole-common-js/src/main/webapp/modules/Layer.js 
b/guacamole-common-js/src/main/webapp/modules/Layer.js
index 98da309..a3eb227 100644
--- a/guacamole-common-js/src/main/webapp/modules/Layer.js
+++ b/guacamole-common-js/src/main/webapp/modules/Layer.js
@@ -43,6 +43,17 @@ Guacamole.Layer = function(width, height) {
     var layer = this;
 
     /**
+     * The number of pixels the width or height of a layer must change before
+     * the underlying canvas is resized. The underlying canvas will be kept at
+     * dimensions which are integer multiples of this factor.
+     *
+     * @private
+     * @constant
+     * @type Number
+     */
+    var CANVAS_SIZE_FACTOR = 64;
+
+    /**
      * The canvas element backing this Layer.
      * @private
      */
@@ -98,57 +109,78 @@ Guacamole.Layer = function(width, height) {
     };
 
     /**
-     * Resizes the canvas element backing this Layer without testing the
-     * new size. This function should only be used internally.
+     * Resizes the canvas element backing this Layer. This function should only
+     * be used internally.
      * 
      * @private
-     * @param {Number} newWidth The new width to assign to this Layer.
-     * @param {Number} newHeight The new height to assign to this Layer.
+     * @param {Number} [newWidth=0]
+     *     The new width to assign to this Layer.
+     *
+     * @param {Number} [newHeight=0]
+     *     The new height to assign to this Layer.
      */
-    function resize(newWidth, newHeight) {
+    var resize = function resize(newWidth, newHeight) {
 
-        // Only preserve old data if width/height are both non-zero
-        var oldData = null;
-        if (layer.width !== 0 && layer.height !== 0) {
+        // Default size to zero
+        newWidth = newWidth || 0;
+        newHeight = newHeight || 0;
 
-            // Create canvas and context for holding old data
-            oldData = document.createElement("canvas");
-            oldData.width = layer.width;
-            oldData.height = layer.height;
+        // Calculate new dimensions of internal canvas
+        var canvasWidth  = Math.ceil(newWidth  / CANVAS_SIZE_FACTOR) * 
CANVAS_SIZE_FACTOR;
+        var canvasHeight = Math.ceil(newHeight / CANVAS_SIZE_FACTOR) * 
CANVAS_SIZE_FACTOR;
 
-            var oldDataContext = oldData.getContext("2d");
+        // Resize only if canvas dimensions are actually changing
+        if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {
 
-            // Copy image data from current
-            oldDataContext.drawImage(canvas,
-                    0, 0, layer.width, layer.height,
-                    0, 0, layer.width, layer.height);
+            // Copy old data only if relevant
+            var oldData = null;
+            if (canvas.width !== 0 && canvas.height !== 0) {
 
-        }
+                // Create canvas and context for holding old data
+                oldData = document.createElement("canvas");
+                oldData.width = Math.min(layer.width, newWidth);
+                oldData.height = Math.min(layer.height, newHeight);
+
+                var oldDataContext = oldData.getContext("2d");
+
+                // Copy image data from current
+                oldDataContext.drawImage(canvas,
+                        0, 0, oldData.width, oldData.height,
+                        0, 0, oldData.width, oldData.height);
+
+            }
 
-        // Preserve composite operation
-        var oldCompositeOperation = context.globalCompositeOperation;
+            // Preserve composite operation
+            var oldCompositeOperation = context.globalCompositeOperation;
 
-        // Resize canvas
-        canvas.width = newWidth;
-        canvas.height = newHeight;
+            // Resize canvas
+            canvas.width = canvasWidth;
+            canvas.height = canvasHeight;
 
-        // Redraw old data, if any
-        if (oldData)
-                context.drawImage(oldData, 
-                    0, 0, layer.width, layer.height,
-                    0, 0, layer.width, layer.height);
+            // Redraw old data, if any
+            if (oldData)
+                context.drawImage(oldData,
+                    0, 0, oldData.width, oldData.height,
+                    0, 0, oldData.width, oldData.height);
 
-        // Restore composite operation
-        context.globalCompositeOperation = oldCompositeOperation;
+            // Restore composite operation
+            context.globalCompositeOperation = oldCompositeOperation;
 
+            // Acknowledge reset of stack (happens on resize of canvas)
+            stackSize = 0;
+            context.save();
+
+        }
+
+        // If the canvas size is not changing, manually force state reset
+        else
+            layer.reset();
+
+        // Assign new layer dimensions
         layer.width = newWidth;
         layer.height = newHeight;
 
-        // Acknowledge reset of stack (happens on resize of canvas)
-        stackSize = 0;
-        context.save();
-
-    }
+    };
 
     /**
      * Given the X and Y coordinates of the upper-left corner of a rectangle
@@ -781,8 +813,7 @@ Guacamole.Layer = function(width, height) {
     };
 
     // Initialize canvas dimensions
-    canvas.width = width;
-    canvas.height = height;
+    resize(width, height);
 
     // Explicitly render canvas below other elements in the layer (such as
     // child layers). Chrome and others may fail to render layers properly

Reply via email to