It really bothered me that it was that long on Chromium. So I decided to improve it.
As we saw in part one, the method used to write a pixel was not the best, especially under Chrome (or my Linux Chromium up to date version, but I guess it’s the same on Chrome).
From what I guess, Chrome tries to (and fails) to show every pixel change. For example, the initial random matrix, which is calculated and shown in 0.12s on Firefox, appears after around a minute on Chrome !
So it’s time for some double buffering. After all, I used it on OpenGL project as a student in the early 90’s, so why not now ?
So I create a new global Image wariable
var fullImg = myContext.getImageData(0, 0, cw, ch);
and I change my code
// Fill the image with random colors
for (yPos=0; yPos<ch; yPos++) {
// Make a shuffled line
colorLine = shuffleArray(colors);
dyPos = yPos * cw * 4;
for (xPos=0; xPos<cw; xPos++) {
x = dyPos + (xPos * 4);
fullImg.data[x] = colorLine[xPos][0];
fullImg.data[x+1] = colorLine[xPos][1];
fullImg.data[x+2] = colorLine[xPos][2];
fullImg.data[x+3] = 255;
}
}
myContext.putImageData(fullImg, 0, 0);
Still not as fast as on Firefox, but we’ve got from a minute to between 0.033 and 0.055 seconds, and it’s starts to be good !
So I changed the code to removemyImgDataand theputPixelfunction, and write directly intofullImg.data
function swapColors(x1, y1, dy1, x2, y2, dy2, r1, g1, b1, r2, g2, b2) {
// Change pixel 1 in the array
x = dy1 + (x1 * 4);
fullImg.data[x] = r2;
fullImg.data[x+1] = g2;
fullImg.data[x+2] = b2;
// Change pixel 2 in the array
x = dy2 + (x2 * 4);
fullImg.data[x] = r1;
fullImg.data[x+1] = g1;
fullImg.data[x+2] = b1;
}
And I only write when all the image have been modified
function iteration() {
// Test if over
if (boucle != 1024) {
for (l=0; l<1024; l++) {
myLine = myContext.getImageData(0, l, 1024, 1).data;
for (j=0; j<1023-boucle; j++) {
testColors(j, l, (j+1), l);
}
}
// Write the buffer
myContext.putImageData(fullImg, 0, 0);
// Launch next iteration
boucle++;
setTimeout(iteration, 100);
} else {
t1 = new Date().getTime();
output = document.getElementById("output");
output.innerHTML = "Done in " + (t1 - t0)/1000 + " seconds";
}
}
First, on Firefox, rendering time is divided by 2 ! The visual sorting takes less than a minute.
But on Chromium, it really goes faster ! 23 seconds !
So, it bothered me, it’s not bothering me anymore :-) Next it’s only using a better/faster sorting algorithm. But if it’s too fast, it will lose the visual interest.
We’ll see if it’s itching me again.
Crédit photo : Dmitri Popov