[go: nahoru, domu]

Skip to content

Commit

Permalink
Merge pull request novnc#488 from kanaka/feature/more-perf-improvements
Browse files Browse the repository at this point in the history
Performance Improvements
  • Loading branch information
DirectXMan12 committed Aug 14, 2015
2 parents a825582 + f00193e commit abf2b09
Show file tree
Hide file tree
Showing 26 changed files with 3,321 additions and 1,061 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "include/web-socket-js-project"]
path = include/web-socket-js-project
url = https://github.com/gimite/web-socket-js.git
7 changes: 4 additions & 3 deletions LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ licenses (all MPL 2.0 compatible):

include/jsunzip.js : zlib/libpng license

include/web-socket-js/ : New BSD license (3-clause). Source code at
http://github.com/gimite/web-socket-js

include/chrome-app/tcp-stream.js
: Apache 2.0 license

utils/websockify
utils/websocket.py : LGPL 3

utils/inflator.partial.js
include/inflator.js : MIT (for pako)

The following license texts are included:

Expand All @@ -70,6 +70,7 @@ The following license texts are included:
docs/LICENSE.BSD-2-Clause (Simplified BSD / FreeBSD)
docs/LICENSE.zlib
docs/LICENSE.Apache-2.0
docs/LICENSE.pako

Or alternatively the license texts may be found here:

Expand Down
10 changes: 2 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,7 @@ See more screenshots <a href="http://kanaka.github.com/noVNC/screenshots.html">h
* HTML5 Canvas (with createImageData): Chrome, Firefox 3.6+, iOS
Safari, Opera 11+, Internet Explorer 9+, etc.

* HTML5 WebSockets: For browsers that do not have builtin
WebSockets support, the project includes
<a href="http://github.com/gimite/web-socket-js">web-socket-js</a>,
a WebSockets emulator using Adobe Flash. iOS 4.2+ has built-in
WebSocket support.
* HTML5 WebSockets and Typed Arrays

* Fast Javascript Engine: this is not strictly a requirement, but
without a fast Javascript engine, noVNC might be painfully slow.
Expand Down Expand Up @@ -130,9 +126,7 @@ use a WebSockets to TCP socket proxy. There is a python proxy included
* tight encoding : Michael Tinglof (Mercuri.ca)

* Included libraries:
* web-socket-js : Hiroshi Ichikawa (github.com/gimite/web-socket-js)
* as3crypto : Henri Torgemane (code.google.com/p/as3crypto)
* base64 : Martijn Pieters (Digital Creations 2), Samuel Sieb (sieb.net)
* jsunzip : Erik Moller (github.com/operasoftware/jsunzip),
* tinflate : Joergen Ibsen (ibsensoftware.com)
* DES : Dave Zimmerman (Widget Workshop), Jef Poskanzer (ACME Labs)
* Pako : Vitaly Puzrin (https://github.com/nodeca/pako)
21 changes: 21 additions & 0 deletions docs/LICENSE.pako
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(The MIT License)

Copyright (C) 2014 by Vitaly Puzrin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
20 changes: 4 additions & 16 deletions docs/notes
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
Some implementation notes:
Rebuilding inflator.js

There is an included flash object (web-socket-js) that is used to
emulate websocket support on browsers without websocket support
(currently only Chrome has WebSocket support).

Javascript doesn't have a bytearray type, so what you get out of
a WebSocket object is just Javascript strings. Javascript has UTF-16
unicode strings and anything sent through the WebSocket gets converted
to UTF-8 and vice-versa. So, one additional (and necessary) function
of websockify is base64 encoding/decoding what is sent to/from the
browser.

Building web-socket-js emulator:

cd include/web-socket-js/flash-src
mxmlc -static-link-runtime-shared-libraries WebSocketMain.as
- Download pako from npm
- Install browserify using npm
- browserify utils/inflator.partial.js -o include/inflator.js
126 changes: 105 additions & 21 deletions include/display.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ var Display;
(function () {
"use strict";

var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
try {
new ImageData(new Uint8ClampedArray(1), 1, 1);
SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
} catch (ex) {
// ignore failure
}

Display = function (defaults) {
this._drawCtx = null;
this._c_forceCanvas = false;
Expand Down Expand Up @@ -351,18 +359,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
Expand Down Expand Up @@ -394,7 +425,7 @@ var Display;
data[i + 3] = 255;
}
} else {
this.fillRect(x, y, width, height, color);
this.fillRect(x, y, width, height, color, true);
}
},

Expand Down Expand Up @@ -425,7 +456,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);
}
},

Expand All @@ -438,23 +469,61 @@ 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?
this._cmapImageData(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) {
var img = new Image();
img.onload = function () {
Expand Down Expand Up @@ -632,6 +701,18 @@ var Display;
this._drawCtx.putImageData(img, x - vx, y - vy);
},

_rgbxImageData: function (x, y, vx, vy, width, height, arr, offset) {
// NB(directxman12): arr must be an Type Array view
var img;
if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
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, arr.byteOffset, width * height * 4));
}
this._drawCtx.putImageData(img, x - vx, y - vy);
},

_cmapImageData: function (x, y, vx, vy, width, height, arr, offset) {
var img = this._drawCtx.createImageData(width, height);
var data = img.data;
Expand All @@ -652,16 +733,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, true);
break;
case 'img':
if (a.img.complete) {
Expand Down
Loading

0 comments on commit abf2b09

Please sign in to comment.