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.
This commit is contained in:
parent
3c1bead9a0
commit
97763d0eb8
|
@ -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,
|
||||||
|
|
||||||
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 () {
|
||||||
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 () {
|
||||||
* 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) {
|
||||||
},
|
},
|
||||||
|
|
||||||
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) {
|
||||||
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) {
|
||||||
},
|
},
|
||||||
|
|
||||||
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) {
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,22 @@
|
||||||
<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">
|
||||||
|
|
||||||
|
<input id='startButton' type='button' value='Start' style='width:100px'
|
||||||
|
onclick="start();">
|
||||||
|
|
||||||
|
<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 @@
|
||||||
<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>
|
||||||
|
|
Loading…
Reference in New Issue