title: Speed up HTML5 Canvas pixel rendering
body: <p>I am designing a Photoshop-style web application running on the HTML5 Canvas element. The program runs well and is very speedy until I add blend modes into the equation. I achieve blend modes by merging each canvas element into one and combining each pixel from each canvas using the right blend modes starting from the bottom canvas.</p>
  
  <pre><code>for (int i=0; i&lt;width*height*4; i+=4) {
      var base = [layer[0][i],layer[0][i+1],layer[0][i+2],layer[0][i+3]];
      var nextLayerPixel = [layer[1][i],layer[1][i+1],layer[1][i+2],layer[1][i+3]];
      //Apply first blend between first and second layer
      basePixel = blend(base,nextLayerPixel);
      for(int j=0;j+1 != layer.length;j++){
          //Apply subsequent blends here to basePixel
          nextLayerPixel = [layer[j+1][i],layer[j+1][i+1],layer[j+1][i+2],layer[j+1][i+3]];
          basePixel = blend(basePixel,nextLayerPixel);
     }
     pixels[i] = base[0];
     pixels[i+1] = base[1];
     pixels[i+2] = base[2];
     pixels[i+3] = base[3];
  }
  canvas.getContext('2d').putImageData(imgData,x,y);
  </code></pre>
  
  <p>With it calling blend for different blend modes. My 'normal' blend mode is as follows:</p>
  
  <pre><code>var blend = function(base,blend) {
      var fgAlpha = blend[3]/255;
      var bgAlpha = (1-blend[3]/255)*base[3]/255;
      blend[0] = (blend[0]*fgAlpha+base[0]*bgAlpha);
      blend[1] = (blend[1]*fgAlpha+base[1]*bgAlpha);
      blend[2] = (blend[2]*fgAlpha+base[2]*bgAlpha);
      blend[3] = ((blend[3]/255+base[3])-(blend[3]/255*base[3]))*255;
      return blend;
  }
  </code></pre>
  
  <p>My test results in Chrome (yielding some of the best out of the tested browsers) was around 400ms blending three layers together on a canvas 620x385 (238,700 pixels).</p>
  
  <p>This is a very small implementation as most projects will be larger in size and include more layers which will make the execution time skyrocket under this method.</p>
  
  <p>I'm wondering if there is any faster way to combine two canvas contexts with a blend mode without having to go through every pixel.</p>