WebGL Texture Loading Performance

JavaScript performance comparison

Revision 6 of this test case created by Ken Russell

Info

This demonstrates that the previous version of this test which attempted to specify an internal format of BGRA and type UNSIGNEDINT8888REV was incorrect. First, WebGL does not contain these enums, so "undefined" (which translates to 0) was being passed to the WebGL implementation for these enums, causing a GL error. Second, WebGL requires that the format and internalformat match, as in OpenGL ES 2.0. Consult the OpenGL ES 2.0 specification.

Preparation code

<script>
  var glcanvas = document.createElement('canvas');
  var gl = glcanvas.getContext('experimental-webgl');
 
  var canvas1024 = document.createElement('canvas');
  canvas1024.width = 1024;
  canvas1024.height = 1024;
  var img1024 = new Image();
  var tex1024 = gl.createTexture();
  img1024.onload = function() {
      gl.bindTexture(gl.TEXTURE_2D, tex1024);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, gl.BGRA, gl.UNSIGNED_INT_8_8_8_8_REV, img1024);
      if (gl.getError() != gl.NO_ERROR)
          throw "Error during setup";
  };
  img1024.src = canvas1024.toDataURL();
 
  var canvas512 = document.createElement('canvas');
  canvas512.width = 512;
  canvas512.height = 512;
  var img512 = new Image();
  var tex512 = gl.createTexture();
  img512.onload = function() {
      gl.bindTexture(gl.TEXTURE_2D, tex512);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, gl.BGRA, gl.UNSIGNED_INT_8_8_8_8_REV, img512);
      if (gl.getError() != gl.NO_ERROR)
          throw "Error during setup";
  };
  img512.src = canvas512.toDataURL();
 
  var canvas256 = document.createElement('canvas');
  canvas256.width = 256;
  canvas256.height = 256;
  var img256 = new Image();
  var tex256 = gl.createTexture();
  img256.onload = function() {
      gl.bindTexture(gl.TEXTURE_2D, tex256);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, gl.BGRA, gl.UNSIGNED_INT_8_8_8_8_REV, img256);
      if (gl.getError() != gl.NO_ERROR)
          throw "Error during setup";
  };
  img256.src = canvas256.toDataURL();
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
texImage2D 1024
gl.bindTexture(gl.TEXTURE_2D, tex1024);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, gl.BGRA, gl.UNSIGNED_INT_8_8_8_8_REV, img1024);
if (gl.getError() != gl.NO_ERROR)
    throw "Error running texImage2D 1024";
 
pending…
texSubImage2D 1024
gl.bindTexture(gl.TEXTURE_2D, tex1024);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.BGRA, gl.UNSIGNED_INT_8_8_8_8_REV, img1024);
if (gl.getError() != gl.NO_ERROR)
    throw "Error running texSubImage2D 1024";
 
pending…
texImage2D 512
gl.bindTexture(gl.TEXTURE_2D, tex512);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, gl.RGBA, gl.UNSIGNED_BYTE, img512);
if (gl.getError() != gl.NO_ERROR)
    throw "Error running texImage2D 512";
 
pending…
texSubImage2D 512
gl.bindTexture(gl.TEXTURE_2D, tex512);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.BGRA, gl.UNSIGNED_INT_8_8_8_8_REV, img512);
if (gl.getError() != gl.NO_ERROR)
    throw "Error running texSubImage2D 512";
 
pending…
texImage2D 256
gl.bindTexture(gl.TEXTURE_2D, tex256);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, gl.BGRA, gl.UNSIGNED_INT_8_8_8_8_REV, img256);
if (gl.getError() != gl.NO_ERROR)
    throw "Error running texImage2D 256";
 
pending…
texSubImage2D 256
gl.bindTexture(gl.TEXTURE_2D, tex256);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.BGRA, gl.UNSIGNED_INT_8_8_8_8_REV, img256);
if (gl.getError() != gl.NO_ERROR)
    throw "Error running texSubImage2D 256";
 
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

2 comments

Carlos R. commented :

BGRA and UNSIGNED_INT_8_8_8_8_REV do match, and are in fact a very common combination in desktop OpenGL and GLES land for fast uploads. You are right about UNSIGNED_INT_8_8_8_8_REV not being part of WebGL though, my mistake.

Brian Chirls commented :

I'm glad to see this test evolving.

But I'm concerned that gl.getError is supposed to be quite slow and may affect the test results. It should be sufficient to run once at the beginning.

Add a comment