Commit 3875f847 authored by Joel Martin's avatar Joel Martin

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.
parent 0a72cf90
...@@ -134,6 +134,63 @@ draw: function () { ...@@ -134,6 +134,63 @@ draw: function () {
Canvas.ctx.putImageData(img, 100, 100); 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) { rgbxImage: function(x, y, width, height, arr) {
/* Old firefox and Opera don't support createImageData */ /* Old firefox and Opera don't support createImageData */
var img = Canvas.ctx.getImageData(0, 0, width, height); var img = Canvas.ctx.getImageData(0, 0, width, height);
......
...@@ -604,12 +604,13 @@ display_hextile: function() { ...@@ -604,12 +604,13 @@ display_hextile: function() {
FBU.foreground = RQ.slice(idx, idx + RFB.fb_Bpp); FBU.foreground = RQ.slice(idx, idx + RFB.fb_Bpp);
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 if (FBU.subencoding & 0x08) { // AnySubrects
subrects = RQ[idx]; subrects = RQ[idx];
idx++; idx++;
var color, xy, sx, sy, wh, sw, sh; var xy, sx, sy, wh, sw, sh;
for (var i = 0; i < subrects; i ++) { for (var s = 0; s < subrects; s ++) {
if (FBU.subencoding & 0x10) { // SubrectsColoured if (FBU.subencoding & 0x10) { // SubrectsColoured
color = RQ.slice(idx, idx + RFB.fb_Bpp); color = RQ.slice(idx, idx + RFB.fb_Bpp);
idx += RFB.fb_Bpp; idx += RFB.fb_Bpp;
...@@ -618,17 +619,18 @@ display_hextile: function() { ...@@ -618,17 +619,18 @@ display_hextile: function() {
} }
xy = RQ[idx]; xy = RQ[idx];
idx++; idx++;
sx = x + (xy >> 4); sx = (xy >> 4);
sy = y + (xy & 0x0f); sy = (xy & 0x0f);
wh = RQ[idx]; wh = RQ[idx];
idx++; idx++;
sw = (wh >> 4) + 1; sw = (wh >> 4) + 1;
sh = (wh & 0x0f) + 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); RQ.shiftBytes(FBU.bytes);
FBU.lastsubencoding = FBU.subencoding; FBU.lastsubencoding = FBU.subencoding;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment