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