Ça me chiffonnait que le rendu sous Chromium soit aussi lent. Du coup j’ai décidé d’améliorer ça.

Comme vu dans la première partie, la méthode utilisée pour écrire dans chaque pixel n’est pas la meilleure, principalement sous Chrome (ou du moins sur ma version Linux de Chromium, mais j’imagine que ce serait vrai aussi sous Chrome).

De ce que j’en suppose, Chrome tente le rendu (et échoue…) dès qu’on pose un pixel dedans. Du coup, rien que l’affichage de la matrice mélangée de départ passe de 0,12 secondes sous Firefox à 59,255 sous Chromium !

Du coup, pas le choix, il faut passer en double buffering. Après tout on faisait déjà comme ça quand on faisait de l’openGL à la fac dans les années 90, donc pourquoi pas maintenant ?

Je crée un autre variable globale d’image

var fullImg = myContext.getImageData(0, 0, cw, ch);

et je modifie mon code

        // Remplir l'image de couleur au hasard
        for (yPos=0; yPos<ch; yPos++) {

            // On génère une ligne mélangée
            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);

Toujours pas aussi rapide que sous Firefox, mais on est passé à entre 0,033 et 0,055 secondes, et là c’est bien mieux !

J’ai donc modifié le code pour supprimermyImgDataet les appels àputPixel, et écrire directement dansfullImg.data

        function swapColors(x1, y1, dy1, x2, y2, dy2, r1, g1, b1, r2, g2, b2) {

            // Modifier le pixel 1 dans le tableau
            x = dy1 + (x1 * 4);
            fullImg.data[x] = r2;
            fullImg.data[x+1] = g2;
            fullImg.data[x+2] = b2;

            // Modifier le pixel 2 dans le tableau
            x = dy2 + (x2 * 4);
            fullImg.data[x] = r1;
            fullImg.data[x+1] = g1;
            fullImg.data[x+2] = b1;
        }

Et je n’écrit qu’une fois toute l’image modifiée

        function iteration() {

            // Traiter le cas de sortie
            if (boucle != ch) {
                for (l=0; l<ch; l++) {
                    dy = l * ch * 4;
                    for (j=0; j<(cw - 1 -boucle); j++) {
                        testColors(j, l, dy, (j+1), l, dy);
                    }
                }

                // Ecriture du buffer
                myContext.putImageData(fullImg, 0, 0);

                // Lancer l'itération suivante
                boucle++;
                setTimeout(iteration, 2);
            } else {
                t1 = new Date().getTime();
                output  = document.getElementById("output");
                output.innerHTML = "Done in " + (t1 - t0)/1000 + " seconds";
            }
        }

Déjà sous Firefox on divise le temps par 2 ! On arrive à reclasser tout ça en un peu moins d’une minute.

Par contre sous Chromium, là, on sent que ça lui fait de l’air ! 23 secondes !

Voilà, ça me chiffonnait, ça ne me chiffonne plus :-) Maintenant il n’y a plus qu’à utiliser un algorithme de tri plus rapide pour que ça aille encore plus vite. Mais si ça va trop vite ça ne sera pas intéressant visuellement.

On verra si ça me rechiffonne et que je veux me redéchiffonner.

Crédit photo : Dmitri Popov