]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Skip unnecessary render queue object creation
authorSolly Ross <sross@redhat.com>
Tue, 2 Jun 2015 19:32:14 +0000 (15:32 -0400)
committerSolly Ross <sross@redhat.com>
Thu, 6 Aug 2015 18:47:03 +0000 (14:47 -0400)
This commit skips object creation for the render queue when not
needed.  Instead of pushing an object onto the queue, and then
immediately running the result, you call the function directly.
Then, if the render queue is not empty, an object is created and
pushed onto the queue.  Otherwise, the functionality is just run
directly.

include/display.js
include/rfb.js

index 418b431d3acb1694d0bcae4c8b7ad8ee441e68bb..c30a977d78692e63b651ddd6f8a389b861ff33a8 100644 (file)
@@ -339,18 +339,41 @@ var Display;
             this._renderQ = [];
         },
 
-        fillRect: function (x, y, width, height, color) {
-            this._setFillColor(color);
-            this._drawCtx.fillRect(x - this._viewportLoc.x, y - this._viewportLoc.y, width, height);
-        },
-
-        copyImage: function (old_x, old_y, new_x, new_y, w, h) {
-            var x1 = old_x - this._viewportLoc.x;
-            var y1 = old_y - this._viewportLoc.y;
-            var x2 = new_x - this._viewportLoc.x;
-            var y2 = new_y - this._viewportLoc.y;
+        fillRect: function (x, y, width, height, color, from_queue) {
+            if (this._renderQ.length !== 0 && !from_queue) {
+                this.renderQ_push({
+                    'type': 'fill',
+                    'x': x,
+                    'y': y,
+                    'width': width,
+                    'height': height,
+                    'color': color
+                });
+            } else {
+                this._setFillColor(color);
+                this._drawCtx.fillRect(x - this._viewportLoc.x, y - this._viewportLoc.y, width, height);
+            }
+        },
+
+        copyImage: function (old_x, old_y, new_x, new_y, w, h, from_queue) {
+            if (this._renderQ.length !== 0 && !from_queue) {
+                this.renderQ_push({
+                    'type': 'copy',
+                    'old_x': old_x,
+                    'old_y': old_y,
+                    'x': new_x,
+                    'y': new_y,
+                    'width': w,
+                    'height': h,
+                });
+            } else {
+                var x1 = old_x - this._viewportLoc.x;
+                var y1 = old_y - this._viewportLoc.y;
+                var x2 = new_x - this._viewportLoc.x;
+                var y2 = new_y - this._viewportLoc.y;
 
-            this._drawCtx.drawImage(this._target, x1, y1, w, h, x2, y2, w, h);
+                this._drawCtx.drawImage(this._target, x1, y1, w, h, x2, y2, w, h);
+            }
         },
 
         // start updating a tile
@@ -382,7 +405,7 @@ var Display;
                     data[i + 3] = 255;
                 }
             } else {
-                this.fillRect(x, y, width, height, color);
+                this.fillRect(x, y, width, height, color, true);
             }
         },
 
@@ -413,7 +436,7 @@ var Display;
                     }
                 }
             } else {
-                this.fillRect(this._tile_x + x, this._tile_y + y, w, h, color);
+                this.fillRect(this._tile_x + x, this._tile_y + y, w, h, color, true);
             }
         },
 
@@ -426,16 +449,34 @@ var Display;
             // else: No-op -- already done by setSubTile
         },
 
-        blitImage: function (x, y, width, height, arr, offset) {
-            if (this._true_color) {
+        blitImage: function (x, y, width, height, arr, offset, from_queue) {
+            if (this._renderQ.length !== 0 && !from_queue) {
+                this.renderQ_push({
+                    'type': 'blit',
+                    'data': arr,
+                    'x': x,
+                    'y': y,
+                    'width': width,
+                    'height': height,
+                });
+            } else if (this._true_color) {
                 this._bgrxImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset);
             } else {
                 this._cmapImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset);
             }
         },
 
-        blitRgbImage: function (x, y , width, height, arr, offset) {
-            if (this._true_color) {
+        blitRgbImage: function (x, y , width, height, arr, offset, from_queue) {
+            if (this._renderQ.length !== 0 && !from_queue) {
+                this.renderQ_push({
+                    'type': 'blitRgb',
+                    'data': arr,
+                    'x': x,
+                    'y': y,
+                    'width': width,
+                    'height': height,
+                });
+            } else if (this._true_color) {
                 this._rgbImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset);
             } else {
                 // probably wrong?
@@ -443,8 +484,24 @@ var Display;
             }
         },
 
-        blitRgbxImage: function (x, y, width, height, arr, offset) {
-            this._rgbxImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset);
+        blitRgbxImage: function (x, y, width, height, arr, offset, from_queue) {
+            if (this._renderQ.length !== 0 && !from_queue) {
+                // NB(directxman12): it's technically more performant here to use preallocated arrays, but it
+                // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
+                // this probably isn't getting called *nearly* as much
+                var new_arr = new Uint8Array(width * height * 4);
+                new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
+                this.renderQ_push({
+                    'type': 'blitRgbx',
+                    'data': new_arr,
+                    'x': x,
+                    'y': y,
+                    'width': width,
+                    'height': height,
+                });
+            } else {
+                this._rgbxImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset);
+            }
         },
 
         blitStringImage: function (str, x, y) {
@@ -626,13 +683,12 @@ var Display;
 
         _rgbxImageData: function (x, y, vx, vy, width, height, arr, offset) {
             // NB(directxman12): arr must be an Type Array view
-            // NB(directxman12): this only works
             var img;
             if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
-                img = new ImageData(new Uint8ClampedArray(arr.buffer, 0, width * height * 4), width, height);
+                img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height);
             } else {
                 img = this._drawCtx.createImageData(width, height);
-                img.data.set(new Uint8ClampedArray(arr.buffer, 0, width * height * 4));
+                img.data.set(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4));
             }
             this._drawCtx.putImageData(img, x - vx, y - vy);
         },
@@ -657,19 +713,19 @@ var Display;
                 var a = this._renderQ[0];
                 switch (a.type) {
                     case 'copy':
-                        this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height);
+                        this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height, true);
                         break;
                     case 'fill':
-                        this.fillRect(a.x, a.y, a.width, a.height, a.color);
+                        this.fillRect(a.x, a.y, a.width, a.height, a.color, true);
                         break;
                     case 'blit':
-                        this.blitImage(a.x, a.y, a.width, a.height, a.data, 0);
+                        this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true);
                         break;
                     case 'blitRgb':
-                        this.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0);
+                        this.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0, true);
                         break;
                     case 'blitRgbx':
-                        this.blitRgbxImage(a.x, a.y, a.width, a.height, a.data, 0);
+                        this.blitRgbxImage(a.x, a.y, a.width, a.height, a.data, 0, true);
                         break;
                     case 'img':
                         if (a.img.complete) {
index b8615af85e6171e0b66b8ef0697ce886bd9276ea..b7a811d5603020225041a26ff2d7a54e84569710 100644 (file)
@@ -1483,15 +1483,10 @@ var RFB;
         COPYRECT: function () {
             this._FBU.bytes = 4;
             if (this._sock.rQwait("COPYRECT", 4)) { return false; }
-            this._display.renderQ_push({
-                'type': 'copy',
-                'old_x': this._sock.rQshift16(),
-                'old_y': this._sock.rQshift16(),
-                'x': this._FBU.x,
-                'y': this._FBU.y,
-                'width': this._FBU.width,
-                'height': this._FBU.height
-            });
+            this._display.copyImage(this._sock.rQshift16(), this._sock.rQshift16(),
+                                    this._FBU.x, this._FBU.y, this._FBU.width,
+                                    this._FBU.height);
+
             this._FBU.rects--;
             this._FBU.bytes = 0;
             return true;
@@ -1842,28 +1837,10 @@ var RFB;
                 var rgbx;
                 if (numColors == 2) {
                     rgbx = indexedToRGBX2Color(data, this._paletteBuff, this._FBU.width, this._FBU.height);
-
-                    /*this._display.renderQ_push({
-                        'type': 'blitRgbx',
-                        'data': rgbx,
-                        'x': this._FBU.x,
-                        'y': this._FBU.y,
-                        'width': this._FBU.width,
-                        'height': this._FBU.height
-                    });*/
-                    this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0);
+                    this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0, false);
                 } else {
                     rgbx = indexedToRGBX(data, this._paletteBuff, this._FBU.width, this._FBU.height);
-
-                    /*this._display.renderQ_push({
-                        'type': 'blitRgbx',
-                        'data': rgbx,
-                        'x': this._FBU.x,
-                        'y': this._FBU.y,
-                        'width': this._FBU.width,
-                        'height': this._FBU.height
-                    });*/
-                    this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0);
+                    this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0, false);
                 }
 
 
@@ -1905,14 +1882,7 @@ var RFB;
                     data = decompress(this._sock.rQshiftBytes(cl_data));
                 }
 
-                this._display.renderQ_push({
-                    'type': 'blitRgb',
-                    'data': data,
-                    'x': this._FBU.x,
-                    'y': this._FBU.y,
-                    'width': this._FBU.width,
-                    'height': this._FBU.height
-                });
+                this._display.blitRgbImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, data, 0, false);
 
                 return true;
             }.bind(this);
@@ -1960,16 +1930,9 @@ var RFB;
             // Determine FBU.bytes
             switch (cmode) {
                 case "fill":
-                    this._sock.rQskip8();  // shift off ctl
-                    var color = this._sock.rQshiftBytes(this._fb_depth);
-                    this._display.renderQ_push({
-                        'type': 'fill',
-                        'x': this._FBU.x,
-                        'y': this._FBU.y,
-                        'width': this._FBU.width,
-                        'height': this._FBU.height,
-                        'color': [color[2], color[1], color[0]]
-                    });
+                    // skip ctl byte
+                    this._display.fillRect(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, [rQ[rQi + 3], rQ[rQi + 2], rQ[rQi + 1]], false);
+                    this._sock.rQskipBytes(4);
                     break;
                 case "png":
                 case "jpeg":