浏览代码

Skip unnecessary render queue object creation

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.
Solly Ross 10 年之前
父节点
当前提交
f00193e08f
共有 2 个文件被更改,包括 93 次插入74 次删除
  1. 83 27
      include/display.js
  2. 10 47
      include/rfb.js

+ 83 - 27
include/display.js

@@ -339,18 +339,41 @@ var Display;
             this._renderQ = [];
             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
         // start updating a tile
@@ -382,7 +405,7 @@ var Display;
                     data[i + 3] = 255;
                     data[i + 3] = 255;
                 }
                 }
             } else {
             } else {
-                this.fillRect(x, y, width, height, color);
+                this.fillRect(x, y, width, height, color, true);
             }
             }
         },
         },
 
 
@@ -413,7 +436,7 @@ var Display;
                     }
                     }
                 }
                 }
             } else {
             } 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
             // 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);
                 this._bgrxImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset);
             } else {
             } else {
                 this._cmapImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset);
                 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);
                 this._rgbImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset);
             } else {
             } else {
                 // probably wrong?
                 // 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) {
         blitStringImage: function (str, x, y) {
@@ -626,13 +683,12 @@ var Display;
 
 
         _rgbxImageData: function (x, y, vx, vy, width, height, arr, offset) {
         _rgbxImageData: function (x, y, vx, vy, width, height, arr, offset) {
             // NB(directxman12): arr must be an Type Array view
             // NB(directxman12): arr must be an Type Array view
-            // NB(directxman12): this only works
             var img;
             var img;
             if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
             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 {
             } else {
                 img = this._drawCtx.createImageData(width, height);
                 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);
             this._drawCtx.putImageData(img, x - vx, y - vy);
         },
         },
@@ -657,19 +713,19 @@ var Display;
                 var a = this._renderQ[0];
                 var a = this._renderQ[0];
                 switch (a.type) {
                 switch (a.type) {
                     case 'copy':
                     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;
                         break;
                     case 'fill':
                     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;
                         break;
                     case 'blit':
                     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;
                         break;
                     case 'blitRgb':
                     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;
                         break;
                     case 'blitRgbx':
                     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;
                         break;
                     case 'img':
                     case 'img':
                         if (a.img.complete) {
                         if (a.img.complete) {

+ 10 - 47
include/rfb.js

@@ -1483,15 +1483,10 @@ var RFB;
         COPYRECT: function () {
         COPYRECT: function () {
             this._FBU.bytes = 4;
             this._FBU.bytes = 4;
             if (this._sock.rQwait("COPYRECT", 4)) { return false; }
             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.rects--;
             this._FBU.bytes = 0;
             this._FBU.bytes = 0;
             return true;
             return true;
@@ -1842,28 +1837,10 @@ var RFB;
                 var rgbx;
                 var rgbx;
                 if (numColors == 2) {
                 if (numColors == 2) {
                     rgbx = indexedToRGBX2Color(data, this._paletteBuff, this._FBU.width, this._FBU.height);
                     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 {
                 } else {
                     rgbx = indexedToRGBX(data, this._paletteBuff, this._FBU.width, this._FBU.height);
                     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));
                     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;
                 return true;
             }.bind(this);
             }.bind(this);
@@ -1960,16 +1930,9 @@ var RFB;
             // Determine FBU.bytes
             // Determine FBU.bytes
             switch (cmode) {
             switch (cmode) {
                 case "fill":
                 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;
                     break;
                 case "png":
                 case "png":
                 case "jpeg":
                 case "jpeg":