Double hextile rendering performance in Chrome.

- For webkit engines, do array manipulation for each tile subrectangle
  and only use the array for putImageData after rendering is finished.

In Chrome 5.0.375.29 beta, the time to render a full 800x600 hextile
image dropped from 500ms to 250ms or so. Firefox 3.5.3 rendering of
a full 800x600 hextile image is about 2300ms.
This commit is contained in:
Joel Martin 2010-05-15 12:27:44 -05:00
parent 0a72cf9026
commit 3875f847f1
2 changed files with 65 additions and 6 deletions

View File

@ -134,6 +134,63 @@ draw: function () {
Canvas.ctx.putImageData(img, 100, 100);
},
/*
* Tile rendering functions optimized for rendering engines.
*
* - In Chrome/webkit, Javascript image data array manipulations are
* faster than direct Canvas fillStyle, fillRect rendering. In
* gecko, Javascript array handling is much slower.
*/
getTile: function(x, y, width, height, color) {
var img = {'x': x, 'y': y, 'width': width, 'height': height,
'data': []};
if (Browser.Engine.webkit) {
var p, red = color[0], green = color[1], blue = color[2];
var width = img.width, height = img.height;
for (var j = 0; j < height; j++) {
for (var i = 0; i < width; i++) {
p = (i + (j * width) ) * 4;
img.data[p + 0] = red;
img.data[p + 1] = green;
img.data[p + 2] = blue;
//img.data[p + 3] = 255; // Set Alpha
}
}
} else {
Canvas.fillRect(x, y, width, height, color);
}
return img;
},
setTile: function(img, x, y, w, h, color) {
if (Browser.Engine.webkit) {
var p, red = color[0], green = color[1], blue = color[2];
var width = img.width;
for (var j = 0; j < h; j++) {
for (var i = 0; i < w; i++) {
p = (x + i + ((y + j) * width) ) * 4;
img.data[p + 0] = red;
img.data[p + 1] = green;
img.data[p + 2] = blue;
//img.data[p + 3] = 255; // Set Alpha
}
}
} else {
Canvas.fillRect(img.x + x, img.y + y, w, h, color);
}
},
putTile: function(img) {
if (Browser.Engine.webkit) {
Canvas.rgbxImage(img.x, img.y, img.width, img.height, img.data);
//Canvas.ctx.putImageData(img, img.x, img.y);
} else {
// No-op, under gecko already done by setTile
}
},
rgbxImage: function(x, y, width, height, arr) {
/* Old firefox and Opera don't support createImageData */
var img = Canvas.ctx.getImageData(0, 0, width, height);

14
vnc.js
View File

@ -604,12 +604,13 @@ display_hextile: function() {
FBU.foreground = RQ.slice(idx, idx + RFB.fb_Bpp);
idx += RFB.fb_Bpp;
}
Canvas.fillRect(x, y, w, h, FBU.background);
var tile = Canvas.getTile(x, y, w, h, FBU.background);
if (FBU.subencoding & 0x08) { // AnySubrects
subrects = RQ[idx];
idx++;
var color, xy, sx, sy, wh, sw, sh;
for (var i = 0; i < subrects; i ++) {
var xy, sx, sy, wh, sw, sh;
for (var s = 0; s < subrects; s ++) {
if (FBU.subencoding & 0x10) { // SubrectsColoured
color = RQ.slice(idx, idx + RFB.fb_Bpp);
idx += RFB.fb_Bpp;
@ -618,17 +619,18 @@ display_hextile: function() {
}
xy = RQ[idx];
idx++;
sx = x + (xy >> 4);
sy = y + (xy & 0x0f);
sx = (xy >> 4);
sy = (xy & 0x0f);
wh = RQ[idx];
idx++;
sw = (wh >> 4) + 1;
sh = (wh & 0x0f) + 1;
Canvas.fillRect(sx, sy, sw, sh, color);
Canvas.setTile(tile, sx, sy, sw, sh, color);
}
}
Canvas.putTile(tile);
}
RQ.shiftBytes(FBU.bytes);
FBU.lastsubencoding = FBU.subencoding;