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>