2013-04-15 5 views
7

Ich habe versucht, eine große Anzahl von Instanzen einer SVG-Datei auf eine Leinwand mit Hilfe von DrawImage zu zeichnen. Durch das Erstellen eines einzelnen Bildelements mit der SVG als Quelle und der Verwendung von drawImage für jede Instanz auf der Zeichenfläche hoffte ich, dass ich ein zusammengesetztes Bild in der Zeichenfläche auch bei einer großen Anzahl von Instanzen sehr schnell erstellen konnte.Die Verwendung von drawImage mit Canvas ist sehr langsam in Chrome

Leistung funktioniert, das funktioniert gut in Firefox - ich kann 60.000 Instanzen in etwa 300ms zeichnen. Aber auf Chrome ist es schrecklich langsam: 16.000 Instanzen dauert 5 Sekunden. Ich habe eine Version des Codes auf jsfiddle, die das Problem in Chrome veranschaulicht.

Ich habe ein Beispiel dafür, wie ich drawImage aufrufen werde, wo die Zeichenfläche mit so vielen Bildern der Größe x wie möglich gefüllt wird. Ich hatte einen Vorschlag gelesen, um zu versuchen, eine zweite, versteckte Arbeitsfläche zu verwenden, um alle Instanzen zu puffern, und dann die sichtbare Arbeitsfläche mit einem Aufruf zu aktualisieren. Das hat sich jedoch nicht auf die Leistung ausgewirkt. Die einzelnen Aufrufe von drawImage scheinen immer noch Probleme zu beheben.

Irgendwelche Gedanken darüber, was schief geht und was ich tun kann, um es zu beheben?

  svgImg = new Image; 

      can.width = 1800; can.height = 900; 
      svgImg.onload = function() { 
       if (internalSize == size) 
        return; 
       internalSize = size; 
       var timeBefore = new Date().getTime(); 
       var tot = 0; 

       var canWidth = can.width; 
       var canHeight = can.height; 
       for (var x = 0; x < canWidth; x += size) { 
        for (var y = 0; y < canHeight; y += size) { 
         ctx.drawImage(svgImg, x, y, size, size); 
         tot++; 
        } 
       } 
       document.getElementById('count').innerHTML = "Total Count: " + tot; 
       var timeAfter = new Date().getTime(); 
      }; 
      svgImg.src = "http://www.w3.org/Icons/SVG/svg-logo.svg"; 
      svgImg.width = size; 
      svgImg.height = size; 

Antwort

5

Verlangsamung 1: Tritt ein, wenn entweder die Quelle oder das Ziel Leinwand in RAM ist und die andere Leinwand ist auf GPU.

Verlangsamung 2: Tritt ein, wenn src und dest Leinwände sind verschiedene Größen


Relevante Fehler: http://code.google.com/p/chromium/issues/detail?id=170021

ich das gleiche Problem bemerkt haben, und vereinfacht den Fall eine leere Leinwand zu zeichnen zu Ein weiterer. Es scheint kein Problem zu sein, wenn die Leinwände die gleiche Größe haben, aber an einem bestimmten Punkt nimmt die Leistung eine Nasenspitze. Hier ist die jspref, und meine Ergebnisse:

jspref chrome results

Beachten Sie den Unterschied in 255x255 bis 100x100 und 260x260 bis 100x100.

+0

Das ist verrückt. Danke, dass Sie diesen Test gemacht haben. – RadiantHex

+1

Das galt auch für mich. Ich habe große Mengen an Verzögerung gesehen, bis ich die Leinwände exakt gleich groß gemacht habe. –

+0

Obwohl der Bug-Tracker sagt, dass der Fehler behoben ist, gibt Sam an, dass es eine Verlangsamung gibt, wenn die Leinwände unterschiedliche Größen haben. Ich habe die Antwort aktualisiert, um dies zu berücksichtigen. – Charlie