tor-browser

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

object-deletion-behaviour.html (27408B)


      1 <!--
      2 Copyright (c) 2019 The Khronos Group Inc.
      3 Use of this source code is governed by an MIT-style license that can be
      4 found in the LICENSE.txt file.
      5 -->
      6 
      7 <!DOCTYPE html>
      8 <html>
      9 <head>
     10 <meta charset="utf-8">
     11 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
     12 <script src="../../js/js-test-pre.js"></script>
     13 <script src="../../js/webgl-test-utils.js"></script>
     14 </head>
     15 <body>
     16 <div id="description"></div>
     17 <div id="console"></div>
     18 
     19 <script>
     20 "use strict";
     21 description("Tests deletion behavior for buffer, texture, renderbuffer, shader, and program");
     22 
     23 var wtu = WebGLTestUtils;
     24 var gl = wtu.create3DContext();
     25 var shouldGenerateGLError = wtu.shouldGenerateGLError;
     26 var contextVersion = wtu.getDefault3DContextVersion();
     27 
     28 debug("");
     29 debug("shader and program deletion");
     30 
     31 var vertexShader = wtu.loadStandardVertexShader(gl);
     32 assertMsg(vertexShader, "vertex shader loaded");
     33 var fragmentShader = wtu.loadStandardFragmentShader(gl);
     34 assertMsg(fragmentShader, "fragment shader loaded");
     35 
     36 var program = gl.createProgram();
     37 shouldBeNonNull("program");
     38 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, vertexShader)");
     39 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, fragmentShader)");
     40 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.linkProgram(program)");
     41 shouldBeTrue("gl.getProgramParameter(program, gl.LINK_STATUS)");
     42 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.useProgram(program)");
     43 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteShader(vertexShader)");
     44 shouldBeTrue("gl.isShader(vertexShader)");
     45 shouldBeTrue("gl.getShaderParameter(vertexShader, gl.DELETE_STATUS)");
     46 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.detachShader(program, vertexShader)");
     47 shouldBeFalse("gl.isShader(vertexShader)");
     48 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteShader(fragmentShader)");
     49 shouldBeTrue("gl.isShader(fragmentShader)");
     50 shouldBeTrue("gl.getShaderParameter(fragmentShader, gl.DELETE_STATUS)");
     51 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteProgram(program)");
     52 shouldBeTrue("gl.isProgram(program)");
     53 shouldBeTrue("gl.getProgramParameter(program, gl.DELETE_STATUS)");
     54 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.useProgram(null)");
     55 shouldBeFalse("gl.isProgram(program)");
     56 shouldBeFalse("gl.isShader(fragmentShader)");
     57 
     58 debug("");
     59 debug("texture deletion");
     60 
     61 var fbo = gl.createFramebuffer(), fbo2 = gl.createFramebuffer(), fbo3 = gl.createFramebuffer();
     62 shouldBeNonNull("fbo");
     63 shouldBeNonNull("fbo2");
     64 shouldBeNonNull("fbo3");
     65 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
     66 
     67 var tex = gl.createTexture();
     68 shouldBeNonNull("tex");
     69 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
     70 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex");
     71 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
     72 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
     73 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.TEXTURE");
     74 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
     75 // Deleting a texture bound to the currently-bound fbo is the same as
     76 // detaching the textue from fbo first, then delete the texture.
     77 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
     78 if (contextVersion > 1) {
     79  shouldBeNull("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
     80 } else {
     81  shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
     82 }
     83 shouldBeFalse("gl.isTexture(tex)");
     84 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
     85 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindTexture(gl.TEXTURE_2D, tex)");
     86 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
     87 
     88 var texCubeMap = gl.createTexture();
     89 shouldBeNonNull("texCubeMap");
     90 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)");
     91 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)", "texCubeMap");
     92 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(texCubeMap)");
     93 shouldBeFalse("gl.isTexture(texCubeMap)");
     94 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)");
     95 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)");
     96 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)");
     97 
     98 var t = gl.createTexture();
     99 shouldBeNonNull("t");
    100 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)");
    101 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)");
    102 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t)");
    103 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindTexture(gl.TEXTURE_2D, t)");
    104 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)");
    105 
    106 var t2 = gl.createTexture();
    107 shouldBeNonNull("t2");
    108 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)");
    109 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)");
    110 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2");
    111 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE1)");
    112 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)");
    113 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2");
    114 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t2)");
    115 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
    116 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)");
    117 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
    118 
    119 debug("");
    120 debug("renderbuffer deletion");
    121 
    122 var rbo = gl.createRenderbuffer(), rbo2 = gl.createRenderbuffer(), rbo3 = gl.createRenderbuffer();
    123 shouldBeNonNull("rbo");
    124 shouldBeNonNull("rbo2");
    125 shouldBeNonNull("rbo3");
    126 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
    127 shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo");
    128 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
    129 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
    130 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
    131 // Deleting a renderbuffer bound to the currently-bound fbo is the same as
    132 // detaching the renderbuffer from fbo first, then delete the renderbuffer.
    133 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
    134 if (contextVersion > 1) {
    135  shouldBeNull("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
    136 } else {
    137  shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
    138 }
    139 shouldBeFalse("gl.isRenderbuffer(rbo)");
    140 shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)");
    141 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
    142 shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)");
    143 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)");
    144 shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo2");
    145 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo3)");
    146 shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo2");
    147 
    148 debug("");
    149 debug("using deleted renderbuffer");
    150 rbo = gl.createRenderbuffer();
    151 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
    152 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
    153 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    154 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
    155 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
    156  // make backbuffer red
    157  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    158  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
    159  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    160  // make fbo green
    161  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    162  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
    163  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    164  // Bind backbuffer.
    165  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    166  // delete renderbuffer. It should still be attached to fbo though.
    167  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
    168  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
    169  // Use fbo that has deleted rbo.
    170  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    171  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
    172  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
    173  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    174  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")');
    175  // Bind backbuffer.
    176  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    177  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
    178 }
    179 
    180 debug("");
    181 debug("renderbuffer attached twice to same framebuffer");
    182 rbo = gl.createRenderbuffer();
    183 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
    184 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
    185 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    186 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
    187 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
    188  rbo2 = gl.createRenderbuffer();
    189  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)");
    190  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
    191  // attach rbo2 at two attachment points incompatible with it
    192  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rbo2)");
    193  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo2)");
    194  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo2");
    195  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo2");
    196  // fbo can't be complete as rbo2 is attached at incompatible attachment points
    197  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    198  // now we delete rbo2, which detaches it from the two attachment points where it currently is attached
    199  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo2)");
    200  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
    201  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
    202  // we should now be in the same state as before with only rbo attached, so fbo should be complete again
    203  shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    204  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
    205 }
    206 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
    207 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    208 
    209 
    210 
    211 debug("");
    212 debug("using deleted texture");
    213 tex = gl.createTexture();
    214 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
    215 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    216 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
    217 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)");
    218 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
    219  // make fbo green
    220  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    221  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
    222  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    223  // Bind backbuffer.
    224  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    225  // delete texture. It should still be attached to fbo though.
    226  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
    227  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255,0,0,255], "backbuffer should be red")');
    228  // Use fbo that has deleted texture.
    229  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    230  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")');
    231  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
    232  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    233  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")');
    234  // Bind backbuffer.
    235  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    236  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
    237 }
    238 
    239 debug("");
    240 debug("using deleted renderbuffer");
    241 rbo = gl.createRenderbuffer();
    242 shouldBeNonNull("rbo");
    243 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
    244 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
    245 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    246 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
    247 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
    248  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
    249  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
    250  shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    251  // make backbuffer red
    252  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    253  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
    254  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    255  // make fbo green
    256  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    257  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
    258  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    259  // delete renderbuffer. It should still be attached to fbo2 though.
    260  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
    261  // fbo has no attachments
    262  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    263  // Use fbo2 that has deleted rbo.
    264  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
    265  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
    266  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
    267  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    268  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")');
    269  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
    270 
    271  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    272  if (contextVersion > 1) {
    273    shouldBeNull("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
    274  } else {
    275    shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
    276  }
    277  shouldGenerateGLError(gl, gl.NONE, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)");
    278  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    279  // Bind backbuffer.
    280  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    281  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
    282 }
    283 
    284 debug("");
    285 debug("using deleted texture");
    286 tex = gl.createTexture();
    287 shouldBeNonNull("tex");
    288 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
    289 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    290 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
    291 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)");
    292 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
    293  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
    294  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
    295  // make fbo green
    296  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    297  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
    298  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    299  // delete texture. It should still be attached to fbo2 though.
    300  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
    301  // fbo has no attachments
    302  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    303  // Use fbo that has deleted texture.
    304  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
    305  shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    306  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")');
    307  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
    308  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    309  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")');
    310  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
    311 
    312  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    313  if (contextVersion > 1) {
    314    shouldBeNull("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
    315  } else {
    316    shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
    317  }
    318  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
    319  // Bind backbuffer.
    320  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    321  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
    322 }
    323 
    324 debug("");
    325 debug("buffer deletion");
    326 
    327 var buffer = gl.createBuffer();
    328 shouldBeNonNull("buffer");
    329 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
    330 shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer");
    331 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer)");
    332 shouldBeFalse("gl.isBuffer(buffer)");
    333 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
    334 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
    335 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
    336 
    337 var buffer2 = gl.createBuffer();
    338 shouldBeNonNull("buffer2");
    339 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)");
    340 shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer2");
    341 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, null)");
    342 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
    343 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer2)");
    344 shouldBeFalse("gl.isBuffer(buffer2)");
    345 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)");
    346 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
    347 
    348 var bufferElement = gl.createBuffer();
    349 shouldBeNonNull("bufferElement");
    350 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)");
    351 shouldBe("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)", "bufferElement");
    352 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferElement)");
    353 shouldBeFalse("gl.isBuffer(bufferElement)");
    354 shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
    355 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)");
    356 shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
    357 
    358 var b = gl.createBuffer();
    359 shouldBeNonNull("b");
    360 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)");
    361 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)");
    362 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b)");
    363 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBuffer(gl.ARRAY_BUFFER, b)");
    364 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)");
    365 
    366 var b1 = gl.createBuffer();
    367 shouldBeNonNull("b1");
    368 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b1);");
    369 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(1);");
    370 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);");
    371 var b2 = gl.createBuffer();
    372 shouldBeNonNull("b2");
    373 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b2);");
    374 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(2);");
    375 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0);");
    376 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(3);");
    377 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(3, 4, gl.FLOAT, false, 0, 0);");
    378 shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1");
    379 shouldBe("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2");
    380 shouldBe("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2");
    381 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b2);");
    382 shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1");
    383 shouldBeNull("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
    384 shouldBeNull("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
    385 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b1);");
    386 shouldBeNull("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
    387 
    388 debug("");
    389 debug("framebuffer deletion");
    390 
    391 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    392 shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo");
    393 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo)");
    394 shouldBeFalse("gl.isFramebuffer(fbo)");
    395 shouldBeNull("gl.getParameter(gl.FRAMEBUFFER_BINDING)");
    396 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    397 shouldBeNull("gl.getParameter(gl.FRAMEBUFFER_BINDING)");
    398 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
    399 shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2");
    400 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo3)");
    401 shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2");
    402 
    403 fbo = gl.createFramebuffer();
    404 rbo = gl.createRenderbuffer();
    405 shouldBeNonNull("fbo");
    406 shouldBeNonNull("rbo");
    407 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    408 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
    409 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
    410 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
    411 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
    412  // set backbuffer to red
    413  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    414  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
    415  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    416  // set framebuffer to green
    417  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
    418  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
    419  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    420  // check framebuffer
    421  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
    422  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 16, 16, 1, 1, [0,0,0,0], "outside fbo should be black")');
    423  // delete framebuffer. because this was the bound fbo the backbuffer should be active now
    424  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo)");
    425  // check backbuffer
    426  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [255,0,0,255], "backbuffer should be red")');
    427  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 300, 0, 300, 300, [0,0,0,0], "outside backbuffer should be black")');
    428  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 150, 300, 300, [0,0,0,0], "outside backbuffer should be black")');
    429  // check drawing to backbuffer
    430  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
    431  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
    432  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green")');
    433  shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
    434  // check again because many buggy implementations will have bound to the true backbuffer on deleteFramebuffer.
    435  shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green")');
    436 }
    437 
    438 var successfullyParsed = true;
    439 </script>
    440 
    441 <script src="../../js/js-test-post.js"></script>
    442 </body>
    443 </html>