Commit 97763d0e authored by Joel Martin's avatar Joel Martin

Double Chrome hextile perf again. Add canvas test.

- By dereferencing the 'data' field of the imageData object before the
  loop, the hextile performance on Chrome is down to 140ms or so for
  a full 800x600 update. Still have to fall back to Canvas operations
  for firefox.

- Fix RQ empty after reorder bug.
parent 3c1bead9
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
// Everything namespaced inside Canvas // Everything namespaced inside Canvas
var Canvas = { var Canvas = {
prefer_js : false,
c_x : 0, c_x : 0,
c_y : 0, c_y : 0,
c_wx : 0, c_wx : 0,
...@@ -99,6 +101,10 @@ init: function (id, width, height, keyDown, keyUp, ...@@ -99,6 +101,10 @@ init: function (id, width, height, keyDown, keyUp,
Canvas.prevStyle = ""; Canvas.prevStyle = "";
if (Browser.Engine.webkit) {
Canvas.prefer_js = true;
}
console.log("<< Canvas.init"); console.log("<< Canvas.init");
}, },
...@@ -122,35 +128,6 @@ stop: function () { ...@@ -122,35 +128,6 @@ stop: function () {
document.body.removeEvents('contextmenu'); document.body.removeEvents('contextmenu');
}, },
draw: function () {
var img, x, y;
/* Border */
Canvas.ctx.stroke();
Canvas.ctx.rect(0, 0, Canvas.c_wx, Canvas.c_wy);
Canvas.ctx.stroke();
/*
// Does not work in firefox
var himg = new Image();
himg.src = "head_ani2.gif"
Canvas.ctx.drawImage(himg, 10, 10);
*/
/* Test array image data */
//img = Canvas.ctx.createImageData(50, 50);
img = Canvas.ctx.getImageData(0, 0, 50, 50);
for (y=0; y< 50; y++) {
for (x=0; x< 50; x++) {
img.data[(y*50 + x)*4 + 0] = 255 - parseInt((255 / 50) * y, 10);
img.data[(y*50 + x)*4 + 1] = parseInt((255 / 50) * y, 10);
img.data[(y*50 + x)*4 + 2] = parseInt((255 / 50) * x, 10);
img.data[(y*50 + x)*4 + 3] = 255;
}
}
Canvas.ctx.putImageData(img, 100, 100);
},
/* /*
* Tile rendering functions optimized for rendering engines. * Tile rendering functions optimized for rendering engines.
* *
...@@ -159,10 +136,11 @@ draw: function () { ...@@ -159,10 +136,11 @@ draw: function () {
* gecko, Javascript array handling is much slower. * gecko, Javascript array handling is much slower.
*/ */
getTile: function(x, y, width, height, color) { getTile: function(x, y, width, height, color) {
var img, p, red, green, blue, j, i; var img, data, p, red, green, blue, j, i;
img = {'x': x, 'y': y, 'width': width, 'height': height, img = {'x': x, 'y': y, 'width': width, 'height': height,
'data': []}; 'data': []};
if (Browser.Engine.webkit) { if (Canvas.prefer_js) {
data = img.data;
red = color[0]; red = color[0];
green = color[1]; green = color[1];
blue = color[2]; blue = color[2];
...@@ -182,8 +160,9 @@ getTile: function(x, y, width, height, color) { ...@@ -182,8 +160,9 @@ getTile: function(x, y, width, height, color) {
}, },
setTile: function(img, x, y, w, h, color) { setTile: function(img, x, y, w, h, color) {
var p, red, green, blue, width, j, i; var data, p, red, green, blue, width, j, i;
if (Browser.Engine.webkit) { if (Canvas.prefer_js) {
data = img.data;
width = img.width; width = img.width;
red = color[0]; red = color[0];
green = color[1]; green = color[1];
...@@ -191,9 +170,9 @@ setTile: function(img, x, y, w, h, color) { ...@@ -191,9 +170,9 @@ setTile: function(img, x, y, w, h, color) {
for (j = 0; j < h; j++) { for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) { for (i = 0; i < w; i++) {
p = (x + i + ((y + j) * width) ) * 4; p = (x + i + ((y + j) * width) ) * 4;
img.data[p + 0] = red; data[p + 0] = red;
img.data[p + 1] = green; data[p + 1] = green;
img.data[p + 2] = blue; data[p + 2] = blue;
//img.data[p + 3] = 255; // Set Alpha //img.data[p + 3] = 255; // Set Alpha
} }
} }
...@@ -203,7 +182,7 @@ setTile: function(img, x, y, w, h, color) { ...@@ -203,7 +182,7 @@ setTile: function(img, x, y, w, h, color) {
}, },
putTile: function(img) { putTile: function(img) {
if (Browser.Engine.webkit) { if (Canvas.prefer_js) {
Canvas.rgbxImage(img.x, img.y, img.width, img.height, img.data); Canvas.rgbxImage(img.x, img.y, img.width, img.height, img.data);
//Canvas.ctx.putImageData(img, img.x, img.y); //Canvas.ctx.putImageData(img, img.x, img.y);
} else { } else {
...@@ -213,14 +192,17 @@ putTile: function(img) { ...@@ -213,14 +192,17 @@ putTile: function(img) {
rgbxImage: function(x, y, width, height, arr) { rgbxImage: function(x, y, width, height, arr) {
var img, i; var img, i, data;
/* Old firefox and Opera don't support createImageData */ /* Old firefox and Opera don't support createImageData */
img = Canvas.ctx.getImageData(0, 0, width, height); img = Canvas.ctx.getImageData(0, 0, width, height);
//console.log("rfbxImage: img: " + img + " x: " + x + " y: " + y + " width: " + width + " height: " + height);
//img.data = arr.slice();
data = img.data;
for (i=0; i < (width * height); i++) { for (i=0; i < (width * height); i++) {
img.data[i*4 + 0] = arr[i*4 + 0]; data[i*4 + 0] = arr[i*4 + 0];
img.data[i*4 + 1] = arr[i*4 + 1]; data[i*4 + 1] = arr[i*4 + 1];
img.data[i*4 + 2] = arr[i*4 + 2]; data[i*4 + 2] = arr[i*4 + 2];
img.data[i*4 + 3] = 255; // Set Alpha data[i*4 + 3] = 255; // Set Alpha
} }
Canvas.ctx.putImageData(img, x, y); Canvas.ctx.putImageData(img, x, y);
......
<html> <html>
<head><title>Canvas Experiments</title></head> <head><title>Canvas Performance Test</title></head>
<body> <body>
Iterations: <input id='iterations' style='width:50' value="100">&nbsp;
<input id='startButton' type='button' value='Start' style='width:100px'
onclick="start();">&nbsp;
<br><br>
Canvas:<br> Canvas:<br>
<canvas id="tutorial" width="640" height="480" <canvas id="canvas" width="640" height="20"
style="border-style: dotted; border-width: 1px;"> style="border-style: dotted; border-width: 1px;">
Canvas not supported. Canvas not supported.
</canvas> </canvas>
<br>
Results:<br>
<textarea id="messages" style="font-size: 9;" cols=80 rows=25></textarea>
</body> </body>
<!-- <!--
...@@ -18,11 +29,92 @@ ...@@ -18,11 +29,92 @@
<script src="../include/canvas.js"></script> <script src="../include/canvas.js"></script>
<script> <script>
var msg_cnt = 0;
var width = 800, height = 600;
var iterations;
function message(str) {
console.log(str);
cell = $('messages');
cell.innerHTML += msg_cnt + ": " + str + "\n";
cell.scrollTop = cell.scrollHeight;
}
function draw () {
var img, x, y;
/* Border */
Canvas.ctx.stroke();
Canvas.ctx.rect(0, 0, Canvas.c_wx, Canvas.c_wy);
Canvas.ctx.stroke();
/*
// Does not work in firefox
var himg = new Image();
himg.src = "head_ani2.gif"
Canvas.ctx.drawImage(himg, 10, 10);
*/
/* Test array image data */
//img = Canvas.ctx.createImageData(50, 50);
img = Canvas.ctx.getImageData(0, 0, 50, 50);
for (y=0; y< 50; y++) {
for (x=0; x< 50; x++) {
img.data[(y*50 + x)*4 + 0] = 255 - parseInt((255 / 50) * y, 10);
img.data[(y*50 + x)*4 + 1] = parseInt((255 / 50) * y, 10);
img.data[(y*50 + x)*4 + 2] = parseInt((255 / 50) * x, 10);
img.data[(y*50 + x)*4 + 3] = 255;
}
}
Canvas.ctx.putImageData(img, 100, 100);
}
function start () {
$('startButton').value = "Running";
$('startButton').disabled = true;
setTimeout(start_delayed, 250);
iterations = $('iterations').value;
}
function start_delayed () {
message("Running test: prefer Javascript");
Canvas.prefer_js = true;
var time1 = run_test();
message("prefer Javascript: " + time1 + "ms total, " +
(time1 / iterations) + "ms per frame");
message("Running test: prefer Canvas ops");
Canvas.prefer_js = false;
var time2 = run_test();
message("prefer Canvas ops: " + time2 + "ms total, " +
(time2 / iterations) + "ms per frame");
$('startButton').disabled = false;
$('startButton').value = "Start";
}
function run_test () {
var color, start_time = (new Date()).getTime();
for (var i=0; i < iterations; i++) {
color = [128, 128, (255 / iterations) * i, 0];
for (var x=0; x < width; x = x + 16) {
for (var y=0; y < width; y = y + 16) {
var tile = Canvas.getTile(x, y, 16, 16, color);
Canvas.setTile(tile, 0, 0, 16, 16, color);
Canvas.putTile(tile);
}
}
}
var end_time = (new Date()).getTime();
return (end_time - start_time);
}
window.onload = function() { window.onload = function() {
console.log("here1"); Canvas.init('canvas', width, height);
Canvas.init('tutorial', 640, 480); Canvas.stop(); // Shut-off event interception
Canvas.draw(); $('iterations').value = 10;
console.log("here2"); draw();
message("Canvas initialized");
} }
</script> </script>
</html> </html>
...@@ -835,7 +835,9 @@ recv_message_reorder: function(e) { ...@@ -835,7 +835,9 @@ recv_message_reorder: function(e) {
} }
} }
if (RFB.RQ.length > 0) {
RFB.handle_message(); RFB.handle_message();
}
//console.log("<< recv_message_reorder"); //console.log("<< recv_message_reorder");
}, },
......
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