tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ext-sRGB.html (15092B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8"/>
      5 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
      6 <script src="../../js/js-test-pre.js"></script>
      7 <script src="../../js/webgl-test-utils.js"></script>
      8 </head>
      9 <body>
     10 <div id="description"></div>
     11 <div id="console"></div>
     12 <canvas id="canvas" width="16" height="16" style="width: 50px; height: 50px; border: 1px solid black;"></canvas>
     13 
     14 <!-- Shaders to test output -->
     15 <script id="vertexShader" type="x-shader/x-vertex">
     16 attribute vec4 aPosition;
     17 void main() {
     18  gl_Position = aPosition;
     19 }
     20 </script>
     21 
     22 <script id="fragmentShader" type="x-shader/x-fragment">
     23 precision mediump float;
     24 uniform float uColor;
     25 void main() {
     26  gl_FragColor = vec4(uColor, uColor, uColor, 1);
     27 }
     28 </script>
     29 
     30 <script id="vshader" type="x-shader/x-vertex">
     31 attribute vec4 vPosition;
     32 attribute vec2 texCoord0;
     33 varying vec2 texCoord;
     34 void main()
     35 {
     36    gl_Position = vPosition;
     37    texCoord = texCoord0;
     38 }
     39 </script>
     40 
     41 <script id="fshader" type="x-shader/x-fragment">
     42 precision mediump float;
     43 uniform sampler2D tex;
     44 varying vec2 texCoord;
     45 void main()
     46 {
     47    gl_FragColor = texture2D(tex, texCoord);
     48 }
     49 </script>
     50 
     51 <script>
     52 "use strict";
     53 
     54 var wtu = WebGLTestUtils;
     55 var canvas;
     56 var gl;
     57 var ext = null;
     58 
     59 var extConstants = {
     60  "SRGB_EXT": 0x8C40,
     61  "SRGB_ALPHA_EXT": 0x8C42,
     62  "SRGB8_ALPHA8_EXT": 0x8C43,
     63  "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT": 0x8210
     64 };
     65 
     66 function getExtension() {
     67  ext = gl.getExtension("EXT_sRGB");
     68 }
     69 
     70 function listsExtension() {
     71  var supported = gl.getSupportedExtensions();
     72  return (supported.indexOf("EXT_sRGB") >= 0);
     73 }
     74 
     75 function toVec3String(val) {
     76  if (typeof(val) == 'number') {
     77    return toVec3String([val, val, val]);
     78  }
     79  return '[' + val[0] + ', ' + val[1] + ', ' + val[2] + ']';
     80 }
     81 
     82 var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
     83 
     84 function expectResult(target) {
     85  wtu.checkCanvasRect(gl,
     86                      Math.floor(gl.drawingBufferWidth / 2),
     87                      Math.floor(gl.drawingBufferHeight / 2),
     88                      1,
     89                      1,
     90                      [target, target, target, 255],
     91                      undefined,
     92                      e);
     93 }
     94 
     95 function createGreysRGBTexture(gl, color, format) {
     96  var numPixels = gl.drawingBufferWidth * gl.drawingBufferHeight;
     97  var elements;
     98  switch (format) {
     99    case ext.SRGB_EXT: elements = 3; break;
    100    case ext.SRGB_ALPHA_EXT: elements = 4; break;
    101    default: return null;
    102  }
    103 
    104  var size = numPixels * elements;
    105  var buf = new Uint8Array(size);
    106  for (var ii = 0; ii < numPixels; ++ii) {
    107    var off = ii * elements;
    108    buf[off + 0] = color;
    109    buf[off + 1] = color;
    110    buf[off + 2] = color;
    111    if (format == ext.SRGB_ALPHA_EXT) {
    112      buf[off + 3] = 255;
    113    }
    114  }
    115 
    116  var tex = gl.createTexture();
    117  gl.bindTexture(gl.TEXTURE_2D, tex);
    118  gl.texImage2D(gl.TEXTURE_2D,
    119                0,
    120                format,
    121                gl.drawingBufferWidth,
    122                gl.drawingBufferHeight,
    123                0,
    124                format,
    125                gl.UNSIGNED_BYTE,
    126                buf);
    127  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    128  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    129  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    130  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    131  return tex;
    132 }
    133 
    134 function testValidFormat(fn, internalFormat, formatName, enabled) {
    135  if (enabled) {
    136    fn(internalFormat);
    137    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "was able to create type " + formatName);
    138  } else {
    139    testInvalidFormat(fn, internalFormat, formatName, enabled);
    140  }
    141 }
    142 
    143 function testInvalidFormat(fn, internalFormat, formatName, enabled) {
    144  fn(internalFormat);
    145  var err = gl.getError();
    146  if (err == gl.NO_ERROR) {
    147    testFailed("should NOT be able to create type " + formatName);
    148  } else if (err == gl.INVALID_ENUM || err == gl.INVALID_VALUE) {
    149    testPassed("not able to create invalid format: " + formatName);
    150  }
    151 }
    152 
    153 var textureFormatFixture = {
    154  desc: "Checking texture formats",
    155  create: function(format) {
    156    var tex = gl.createTexture();
    157    gl.bindTexture(gl.TEXTURE_2D, tex);
    158    gl.texImage2D(gl.TEXTURE_2D,
    159                  0,                      // level
    160                  format,                 // internalFormat
    161                  gl.drawingBufferWidth,  // width
    162                  gl.drawingBufferHeight, // height
    163                  0,                      // border
    164                  format,                 // format
    165                  gl.UNSIGNED_BYTE,       // type
    166                  null);                  // data
    167  },
    168  tests: [
    169    {
    170      desc: "Checking valid formats",
    171      fn: testValidFormat,
    172      formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
    173    },
    174    {
    175      desc: "Checking invalid formats",
    176      fn: testInvalidFormat,
    177      formats: [ 'SRGB8_ALPHA8_EXT' ]
    178    }
    179  ]
    180 };
    181 
    182 var renderbufferFormatFixture = {
    183  desc: "Checking renderbuffer formats",
    184  create: function(format) {
    185    var rbo = gl.createRenderbuffer();
    186    gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
    187    gl.renderbufferStorage(gl.RENDERBUFFER,
    188                           format,
    189                           gl.drawingBufferWidth,
    190                           gl.drawingBufferHeight);
    191  },
    192  tests: [
    193    {
    194      desc: "Checking valid formats",
    195      fn: testValidFormat,
    196      formats: [ 'SRGB8_ALPHA8_EXT' ]
    197    },
    198    {
    199      desc: "Checking invalid formats",
    200      fn: testInvalidFormat,
    201      formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
    202    }
    203  ]
    204 };
    205 
    206 
    207 description("Test sRGB texture support");
    208 
    209 debug("");
    210 debug("Canvas.getContext");
    211 
    212 canvas = document.getElementById("canvas");
    213 gl = wtu.create3DContext(canvas);
    214 if (!gl) {
    215  testFailed("context does not exist");
    216 } else {
    217  testPassed("context exists");
    218 
    219  debug("");
    220  debug("Checking sRGB texture support with extension disabled");
    221 
    222  runFormatTest(textureFormatFixture, false);
    223  runFormatTest(renderbufferFormatFixture, false);
    224 
    225  {
    226    var fbo = gl.createFramebuffer();
    227    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    228 
    229    debug("Checking getFramebufferAttachmentParameter with a renderbuffer");
    230    {
    231      var rbo = gl.createRenderbuffer();
    232      gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
    233      gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB565, 1, 1);
    234      gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
    235      wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    236      shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8210 /* FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT */)');
    237      wtu.glErrorShouldBe(gl, gl.INVALID_ENUM);
    238      gl.bindRenderbuffer(gl.RENDERBUFFER, null);
    239      gl.deleteRenderbuffer(rbo);
    240    }
    241 
    242    debug("Checking getFramebufferAttachmentParameter with a texture");
    243    {
    244      var tex = gl.createTexture();
    245      gl.bindTexture(gl.TEXTURE_2D, tex);
    246      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    247      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
    248      wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    249      shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8210 /* FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT */)');
    250      wtu.glErrorShouldBe(gl, gl.INVALID_ENUM);
    251      gl.bindTexture(gl.TEXTURE_2D, null);
    252      gl.deleteTexture(tex);
    253    }
    254 
    255    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    256    gl.deleteFramebuffer(fbo);
    257  }
    258 
    259  debug("");
    260  debug("Checking sRGB texture support");
    261 
    262  // Query the extension and store globally so shouldBe can access it
    263  ext = gl.getExtension("EXT_sRGB");
    264 
    265  if (!ext) {
    266    testPassed("No EXT_sRGB support -- this is legal");
    267 
    268    runSupportedTest(false);
    269    finishTest();
    270  } else {
    271    testPassed("Successfully enabled EXT_sRGB extension");
    272 
    273    runSupportedTest(true);
    274 
    275    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
    276 
    277    runConstantsTest();
    278    runFormatTest(textureFormatFixture, true);
    279    runFormatTest(renderbufferFormatFixture, true);
    280    runTextureReadConversionTest();
    281    runFramebufferTextureConversionTest(ext.SRGB_EXT);
    282    runFramebufferTextureConversionTest(ext.SRGB_ALPHA_EXT);
    283    runFramebufferRenderbufferConversionTest();
    284    runGenerateMipmapTest();
    285    runLoadFromImageTest(function() {
    286      finishTest();
    287    });
    288  }
    289 }
    290 
    291 function runConstantsTest() {
    292  debug("");
    293  debug("Checking extension constants values");
    294 
    295  for (var constant in extConstants) {
    296    if (constant in ext) {
    297      if (extConstants[constant] != ext[constant]) {
    298        testFailed("Value of " + constant + " should be: " + extConstants[constant] + ", was: " + ext[constant]);
    299      } else {
    300        testPassed("Value of " + constant + " was expected value: " + extConstants[constant]);
    301      }
    302    } else {
    303      testFailed(constant + " not found in extension object");
    304    }
    305  }
    306 }
    307 
    308 function runSupportedTest(extensionEnabled) {
    309  if (listsExtension()) {
    310    if (extensionEnabled) {
    311      testPassed("EXT_sRGB listed as supported and getExtension succeeded");
    312    } else {
    313      testFailed("EXT_sRGB listed as supported but getExtension failed");
    314    }
    315  } else {
    316    if (extensionEnabled) {
    317      testFailed("EXT_sRGB not listed as supported but getExtension succeeded");
    318    } else {
    319      testPassed("EXT_sRGB not listed as supported and getExtension failed -- this is legal");
    320    }
    321  }
    322 }
    323 
    324 function runFormatTest(fixture, enabled) {
    325  debug("");
    326  debug(fixture.desc);
    327 
    328  for (var tt = 0; tt < fixture.tests.length; ++tt) {
    329    var test = fixture.tests[tt];
    330    debug(test.desc);
    331 
    332    for (var ii = 0; ii < test.formats.length; ++ii) {
    333      var formatName = test.formats[ii];
    334      test.fn(fixture.create, extConstants[formatName], "ext." + formatName, enabled);
    335    }
    336 
    337    if (tt != fixture.tests.length - 1)
    338      debug("");
    339  }
    340 }
    341 
    342 function runTextureReadConversionTest() {
    343  debug("");
    344  debug("Test the conversion of colors from sRGB to linear on texture read");
    345 
    346  // Draw
    347  var conversions = [
    348    [   0,   0 ],
    349    [  63,  13 ],
    350    [ 127,  54 ],
    351    [ 191, 133 ],
    352    [ 255, 255 ]
    353  ];
    354 
    355  var program = wtu.setupTexturedQuad(gl);
    356  gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
    357 
    358  for (var ii = 0; ii < conversions.length; ii++) {
    359    var tex = createGreysRGBTexture(gl, conversions[ii][0], ext.SRGB_EXT);
    360    wtu.drawUnitQuad(gl);
    361    expectResult(conversions[ii][1]);
    362  }
    363 }
    364 
    365 function runFramebufferTextureConversionTest(format) {
    366  var formatString;
    367  var validFormat;
    368  switch (format) {
    369    case ext.SRGB_EXT: formatString = "sRGB"; validFormat = false; break;
    370    case ext.SRGB_ALPHA_EXT: formatString = "sRGB_ALPHA"; validFormat = true; break;
    371    default: return null;
    372  }
    373  debug("");
    374  debug("Test " + formatString + " framebuffer attachments." + (validFormat ? "" : " (Invalid)"));
    375 
    376  var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
    377  var tex = createGreysRGBTexture(gl, 0, format);
    378  var fbo = gl.createFramebuffer();
    379  gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    380  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
    381  wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    382 
    383  shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
    384 
    385  if (validFormat) {
    386    shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    387 
    388    debug("");
    389    debug("Test the conversion of colors from linear to " + formatString + " on framebuffer (texture) write");
    390 
    391    // Draw
    392    var conversions = [
    393      [   0,   0 ],
    394      [  13,  63 ],
    395      [  54, 127 ],
    396      [ 133, 191 ],
    397      [ 255, 255 ]
    398    ];
    399 
    400    wtu.setupUnitQuad(gl, 0);
    401 
    402    for (var ii = 0; ii < conversions.length; ii++) {
    403      gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0);
    404      wtu.drawUnitQuad(gl, [0, 0, 0, 0]);
    405      wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    406      expectResult(conversions[ii][1]);
    407    }
    408  } else {
    409    shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
    410 
    411    wtu.setupUnitQuad(gl, 0);
    412    gl.uniform1f(gl.getUniformLocation(program, "uColor"), 0.5);
    413    wtu.drawUnitQuad(gl, [0, 0, 0, 0]);
    414    wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
    415  }
    416 
    417  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    418 }
    419 
    420 function runFramebufferRenderbufferConversionTest() {
    421  debug("");
    422  debug("Test the conversion of colors from linear to sRGB on framebuffer (renderbuffer) write");
    423 
    424  function createsRGBFramebuffer(gl, width, height) {
    425    var rbo = gl.createRenderbuffer();
    426    gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
    427    gl.renderbufferStorage(gl.RENDERBUFFER, ext.SRGB8_ALPHA8_EXT, width, height);
    428    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    429 
    430    var fbo = gl.createFramebuffer();
    431    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    432    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
    433                               gl.RENDERBUFFER, rbo);
    434    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    435 
    436    shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
    437    shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    438 
    439    return fbo;
    440  }
    441 
    442  // Draw
    443  var conversions = [
    444    [   0,   0 ],
    445    [  13,  63 ],
    446    [  54, 127 ],
    447    [ 133, 191 ],
    448    [ 255, 255 ]
    449  ];
    450 
    451  var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
    452  wtu.setupUnitQuad(gl, 0);
    453  var fbo = createsRGBFramebuffer(gl, gl.drawingBufferWidth, gl.drawingBufferHeight);
    454 
    455  for (var ii = 0; ii < conversions.length; ii++) {
    456    gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0);
    457    wtu.drawUnitQuad(gl, [0, 0, 0, 0]);
    458    expectResult(conversions[ii][1]);
    459  }
    460 }
    461 
    462 function runLoadFromImageTest(callback) {
    463  debug("");
    464  debug("Tests to ensure that SRGB textures can successfully use image elements as their source");
    465 
    466  var img = wtu.makeImage("../../resources/gray-1024x1024.jpg", function() {
    467    var tex = gl.createTexture();
    468    gl.bindTexture(gl.TEXTURE_2D, tex);
    469    gl.texImage2D(gl.TEXTURE_2D, 0, ext.SRGB_EXT, ext.SRGB_EXT, gl.UNSIGNED_BYTE, img);
    470    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    471 
    472    gl.texImage2D(gl.TEXTURE_2D, 0, ext.SRGB_ALPHA_EXT, ext.SRGB_ALPHA_EXT, gl.UNSIGNED_BYTE, img);
    473    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    474 
    475    callback();
    476  }, function() {
    477    testFailed("Image could not be loaded");
    478    callback();
    479  });
    480 }
    481 
    482 function runGenerateMipmapTest()
    483 {
    484    debug("");
    485    debug("GenerateMipmaps for sRGB textures is forbidden");
    486 
    487    var tex = gl.createTexture();
    488    gl.bindTexture(gl.TEXTURE_2D, tex);
    489 
    490    gl.texImage2D(gl.TEXTURE_2D, 0, ext.SRGB_ALPHA_EXT, 2, 2, 0, ext.SRGB_ALPHA_EXT,
    491                  gl.UNSIGNED_BYTE, null);
    492    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    493    gl.generateMipmap(gl.TEXTURE_2D);
    494    wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
    495 
    496    gl.deleteTexture(tex);
    497 }
    498 
    499 var successfullyParsed = true;
    500 </script>
    501 </body>
    502 </html>